Main Content

Classify Hyperspectral Image Using Support Vector Machine Classifier

This example shows how to preprocess a hyperspectral image and classify it using a support vector machine (SVM) classifier.

This example requires the Hyperspectral Imaging Library for Image Processing Toolbox™. You can install the Hyperspectral Imaging Library for Image Processing Toolbox from Add-On Explorer. For more information about installing add-ons, see Get and Manage Add-Ons. The Hyperspectral Imaging Library for Image Processing Toolbox requires desktop MATLAB®, as MATLAB® Online™ and MATLAB® Mobile™ do not support the library.

Hyperspectral images are acquired over multiple spectral bands and consist of several hundred band images, each representing the same scene across different wavelengths. This example uses the Indian Pines data set, acquired by the Airborne Visible/Infrared Imaging Spectrometer (AVIRIS) sensor across a wavelength range of 400 to 2500 nm. This data set contains 16 classes and 220 band images. Each image is of size 145-by-145 pixels.

Indian_Pines_Dataset.png

In this example, you:

  1. Preprocess a hyperspectral image using a 2-D Gaussian filter.

  2. Perform classification using a SVM classifier.

  3. Display classification results, such as the classification accuracy, classification map, and confusion matrix.

Load Hyperspectral Data Set

Read the hyperspectral data into the workspace by using the hypercube function.

hcube = hypercube("indian_pines.dat");

Load the ground truth for the data set into the workspace.

gtLabel = load("indian_pines_gt.mat");
gtLabel = gtLabel.indian_pines_gt;
numClasses = 16;

Preprocess Hyperspectral Data

Remove the water absorption bands from the data by using the removeBands function.

band = [104:108 150:163 220]; % Water absorption bands
newhcube = removeBands(hcube,BandNumber=band);

Estimate RGB images of the input hypercube by using the colorize function.

rgbImg = colorize(newhcube,method="rgb");

Apply a Gaussian filter (σ=2) to each band image of the hyperspectral data using the imgaussfilt function, and then convert them to grayscale images.

hsData = newhcube.DataCube;
[M,N,C] = size(hsData);
hsDataFiltered = zeros(size(hsData));
for band = 1:C
    bandImage = hsData(:,:,band); 
    bandImageFiltered = imgaussfilt(bandImage,2); 
    bandImageGray = mat2gray(bandImageFiltered);
    hsDataFiltered(:,:,band) = uint8(bandImageGray*255);
end

Prepare Data for Classification

Reshape the filtered hyperspectral data to a set of feature vectors containing filtered spectral responses for each pixel.

DataVector = reshape(hsDataFiltered,[M*N C]);

Reshape the ground truth image to a vector containing class labels.

gtVector = gtLabel(:);

Find the location indices of the ground truth vector that contain class labels. Discard labels with the value 0, as they are unlabeled and do not represent a class.

gtLocs = find(gtVector~=0);
classLabel = gtVector(gtLocs);

Create training and testing location indices for the specified training percentage by using the cvpartition (Statistics and Machine Learning Toolbox) function.

per = 0.1; % Training percentage
cv = cvpartition(classLabel,HoldOut=1-per);

Split the ground truth location indices into training and testing location indices.

locTrain = gtLocs(cv.training);
locTest = gtLocs(~cv.training);

Classify Using SVM

Train the SVM classifier using the fitcecoc (Statistics and Machine Learning Toolbox) function.

svmMdl = fitcecoc(DataVector(locTrain,:),gtVector(locTrain,:));

Test the SVM classifier using the test data.

[svmLabelOut,~] = predict(svmMdl,DataVector(locTest,:));

Display Classification Results

Calculate and display the classification accuracy.

svmAccuracy = sum(svmLabelOut == gtVector(locTest))/numel(locTest);
disp(["Overall Classification Accuracy (%) = ",num2str(svmAccuracy.*100)])
    "Overall Classification Accuracy (%) = "    "95.9996"

Create an SVM classification map.

svmPredLabel = gtLabel;
svmPredLabel(locTest) = svmLabelOut;

Display the RGB image, ground truth map, and SVM classification map.

cmap = parula(numClasses);
figure
montage({rgbImg,gtLabel,svmPredLabel},cmap,Size=[1 3],BorderSize=10)
title("RGB Image | Ground Truth Map | SVM Classification Map")
% Specify the intensity limits for the colorbar
minR = min(min(gtLabel(:)),min(svmPredLabel(:)));
maxR = max(max(gtLabel(:)),max(svmPredLabel(:)));
clim([minR maxR])
colorbar

Figure contains an axes object. The hidden axes object with title RGB Image | Ground Truth Map | SVM Classification Map contains an object of type image.

Display the confusion matrix.

fig = figure;
confusionchart(gtVector(locTest),svmLabelOut,ColumnSummary="column-normalized")
fig_Position = fig.Position;
fig_Position(3) = fig_Position(3)*1.5;
fig.Position = fig_Position;
title("Confusion Matrix: SVM Classification Results")

Figure contains an object of type ConfusionMatrixChart. The chart of type ConfusionMatrixChart has title Confusion Matrix: SVM Classification Results.

References

[1] Patro, Ram Narayan, Subhashree Subudhi, Pradyut Kumar Biswal, and Fabio Dell’acqua. “A Review of Unsupervised Band Selection Techniques: Land Cover Classification for Hyperspectral Earth Observation Data.” IEEE Geoscience and Remote Sensing Magazine 9, no. 3 (September 2021): 72–111. https://doi.org/10.1109/MGRS.2021.3051979.

See Also

| | | (Statistics and Machine Learning Toolbox) | (Statistics and Machine Learning Toolbox) |

Related Topics