├── CNN ├── ViewNetworkStructure.m ├── alexnetInit.m ├── mnistInit.m ├── modelTrain.m └── util │ ├── displayConvolutionCore.m │ ├── hyperConvert2d.m │ ├── hyperNormalize.m │ ├── twoDimensionalizationPixelSpectrum.m │ └── vl_imarraysc.m ├── DataAnalysis ├── SpectralCurveDistribution.m ├── SpectralMatrixAndCurve.m ├── changeColorbar.m ├── getDataSetBasicInformation.m └── showSurfaceFeatures.m ├── README.md └── SVM ├── HSIClassificationSVM.m └── kappa.m /CNN/ViewNetworkStructure.m: -------------------------------------------------------------------------------- 1 | % Viewing the Structure of Convolutional Neural Networks 2 | load net-epoch-100.mat 3 | vl_simplenn_display(net); -------------------------------------------------------------------------------- /CNN/alexnetInit.m: -------------------------------------------------------------------------------- 1 | % AlexNet Model Initialization 2 | 3 | function net = alexnetInit(varargin) 4 | opts.networkType = 'simplenn' ; 5 | opts = vl_argparse(opts, varargin) ; 6 | 7 | lr = [.1 2] ; 8 | 9 | % Define network CIFAR10-quick 10 | net.layers = {} ; 11 | 12 | % Block 1 13 | net.layers{end+1} = struct('type', 'conv', ... 14 | 'weights', {{0.01*randn(5,5,1,32, 'single'), zeros(1, 32, 'single')}}, ... 15 | 'learningRate', lr, ... 16 | 'stride', 1, ... 17 | 'pad', 2) ; 18 | net.layers{end+1} = struct('type', 'pool', ... 19 | 'method', 'max', ... 20 | 'pool', [2 2], ... 21 | 'stride', 2, ... 22 | 'pad', 0) ; 23 | net.layers{end+1} = struct('type', 'relu') ;%7*7 24 | 25 | % Block 2 26 | net.layers{end+1} = struct('type', 'conv', ... 27 | 'weights', {{0.05*randn(4,4,32,32, 'single'), zeros(1,32,'single')}}, ... 28 | 'learningRate', lr, ... 29 | 'stride', 1, ... 30 | 'pad', 2) ; 31 | net.layers{end+1} = struct('type', 'relu') ; 32 | net.layers{end+1} = struct('type', 'pool', ... 33 | 'method', 'avg', ... 34 | 'pool', [2 2], ... 35 | 'stride', 2, ... 36 | 'pad', 0) ; % Emulate caffe 4*4 37 | 38 | % Block 3 39 | net.layers{end+1} = struct('type', 'conv', ... 40 | 'weights', {{0.05*randn(5,5,32,64, 'single'), zeros(1,64,'single')}}, ... 41 | 'learningRate', lr, ... 42 | 'stride', 1, ... 43 | 'pad', 2) ; 44 | net.layers{end+1} = struct('type', 'relu'); 45 | net.layers{end+1} = struct('type', 'pool', ... 46 | 'method', 'avg', ... 47 | 'pool', [2 2], ... 48 | 'stride', 2, ... 49 | 'pad', 0); % Emulate caffe 4*4 50 | 51 | % Block 4 52 | net.layers{end+1} = struct('type', 'conv', ... 53 | 'weights', {{0.05*randn(2,2,64,64, 'single'), zeros(1,64,'single')}}, ... 54 | 'learningRate', lr, ... 55 | 'stride', 1, ... 56 | 'pad', 0) ; 57 | net.layers{end+1} = struct('type', 'relu') ; 58 | 59 | % Block 5 60 | net.layers{end+1} = struct('type', 'conv', ... 61 | 'weights', {{0.05*randn(1,1,64,16, 'single'), zeros(1,16,'single')}}, ... 62 | 'learningRate', .1*lr, ... 63 | 'stride', 1, ... 64 | 'pad', 0) ; 65 | 66 | % Loss layer 67 | net.layers{end+1} = struct('type', 'softmaxloss') ; 68 | 69 | % Meta parameters 70 | net.meta.inputSize = [14 14 1] ; 71 | net.meta.trainOpts.learningRate = [0.05*ones(1,50) 0.005*ones(1,30) 0.0005*ones(1,20)] ; 72 | net.meta.trainOpts.weightDecay = 0.0001 ; 73 | net.meta.trainOpts.batchSize = 100 ; 74 | net.meta.trainOpts.numEpochs = numel(net.meta.trainOpts.learningRate) ; 75 | 76 | % Fill in default values 77 | net = vl_simplenn_tidy(net) ; 78 | 79 | % Switch to DagNN if requested 80 | switch lower(opts.networkType) 81 | case 'simplenn' 82 | % done 83 | case 'dagnn' 84 | net = dagnn.DagNN.fromSimpleNN(net, 'canonicalNames', true) ; 85 | net.addLayer('error', dagnn.Loss('loss', 'classerror'), ... 86 | {'prediction','label'}, 'error') ; 87 | otherwise 88 | assert(false) ; 89 | end 90 | 91 | -------------------------------------------------------------------------------- /CNN/mnistInit.m: -------------------------------------------------------------------------------- 1 | % MNIST Model Initialization 2 | 3 | function net = mnistInit(varargin) 4 | 5 | opts.batchNormalization = true ; 6 | opts.networkType = 'simplenn' ; 7 | opts = vl_argparse(opts, varargin) ; 8 | 9 | rng('default'); 10 | rng(0) ; 11 | 12 | %conv->maxpool->conv->maxpool->conv->relu->conv->softmaxloss 13 | 14 | f=1/100 ; 15 | net.layers = {} ; 16 | net.layers{end+1} = struct('type', 'conv', ... 17 | 'weights', {{f*randn(3,3,1,20, 'single'), zeros(1, 20, 'single')}}, ... 18 | 'stride', 1, ... 19 | 'pad', 0) ; 20 | net.layers{end+1} = struct('type', 'pool', ... 21 | 'method', 'max', ... 22 | 'pool', [2 2], ... 23 | 'stride', 2, ... 24 | 'pad', 0) ; 25 | net.layers{end+1} = struct('type', 'conv', ... 26 | 'weights', {{f*randn(3,3,20,50, 'single'),zeros(1,50,'single')}}, ... 27 | 'stride', 1, ... 28 | 'pad', 0) ; 29 | net.layers{end+1} = struct('type', 'pool', ... 30 | 'method', 'max', ... 31 | 'pool', [1 1], ... 32 | 'stride', 1, ... 33 | 'pad', 0) ; 34 | net.layers{end+1} = struct('type', 'conv', ... 35 | 'weights', {{f*randn(4,4,50,500, 'single'), zeros(1,500,'single')}}, ... 36 | 'stride', 1, ... 37 | 'pad', 0) ; 38 | net.layers{end+1} = struct('type', 'relu') ; 39 | net.layers{end+1} = struct('type', 'conv', ... 40 | 'weights', {{f*randn(1,1,500,16, 'single'), zeros(1,16,'single')}}, ... 41 | 'stride', 1, ... 42 | 'pad', 0) ; 43 | net.layers{end+1} = struct('type', 'softmaxloss') ; 44 | 45 | 46 | if opts.batchNormalization 47 | net = insertBnorm(net, 1) ; 48 | net = insertBnorm(net, 4) ; 49 | net = insertBnorm(net, 7) ; 50 | end 51 | 52 | 53 | net.meta.inputSize = [14 14 1] ; 54 | net.meta.trainOpts.learningRate = [0.0005*ones(1,30) 0.0001*ones(1,10) 0.00001*ones(1,10)] ; 55 | net.meta.trainOpts.numEpochs = 50; 56 | net.meta.trainOpts.batchSize = 20 ; 57 | 58 | 59 | net = vl_simplenn_tidy(net) ; 60 | 61 | switch lower(opts.networkType) 62 | case 'simplenn' 63 | % done 64 | case 'dagnn' 65 | net = dagnn.DagNN.fromSimpleNN(net, 'canonicalNames', true) ; 66 | net.addLayer('top1err', dagnn.Loss('loss', 'classerror'), ... 67 | {'prediction', 'label'}, 'error') ; 68 | net.addLayer('top5err', dagnn.Loss('loss', 'topkerror', ... 69 | 'opts', {'topk', 5}), {'prediction', 'label'}, 'top5err') ; 70 | otherwise 71 | assert(false) ; 72 | end 73 | 74 | function net = insertBnorm(net, l) 75 | assert(isfield(net.layers{l}, 'weights')); 76 | ndim = size(net.layers{l}.weights{1}, 4); 77 | 78 | layer = struct('type', 'lrn', ... 79 | 'weights', {{ones(ndim, 1, 'single'), zeros(ndim, 1, 'single')}}, ... 80 | 'learningRate', [1 1 0.05], ... 81 | 'weightDecay', [0 0]) ; 82 | net.layers{l}.biases = [] ; 83 | net.layers = horzcat(net.layers(1:l), layer, net.layers(l+1:end)) ; 84 | -------------------------------------------------------------------------------- /CNN/modelTrain.m: -------------------------------------------------------------------------------- 1 | % The Main Function of CNN Training 2 | 3 | function [net, info] = modelTrain(varargin) 4 | 5 | s = getDataSetBasicInformation('Salinas'); 6 | 7 | opts.batchNormalization = false ; 8 | opts.network = [] ; 9 | opts.networkType = 'simplenn' ; 10 | opts.modelType = 'alexnet'; 11 | [opts, varargin] = vl_argparse(opts, varargin) ; 12 | 13 | sfx = opts.networkType ; 14 | if opts.batchNormalization, sfx = [sfx '-bnorm'] ; end 15 | opts.expDir = fullfile(vl_rootnn, 'DataOutput', s.name, [opts.modelType '-' sfx]) ; 16 | [opts, varargin] = vl_argparse(opts, varargin) ; 17 | opts.imdbPath = fullfile(opts.expDir, 'imdb.mat'); 18 | opts.train = struct() ; 19 | opts = vl_argparse(opts, varargin) ; 20 | 21 | if ~isfield(opts.train, 'gpus'), opts.train.gpus = []; end; 22 | 23 | % -------------------------------------------------------------------- 24 | % Constructing network 25 | % -------------------------------------------------------------------- 26 | switch opts.modelType 27 | case 'alexnet' 28 | net = alexnetInit('networkType', opts.networkType) ; 29 | case 'mnist' 30 | net = mnistInit('networkType', opts.networkType) ; 31 | otherwise 32 | error('Unknown model type ''%s''.', opts.modelType) ; 33 | end 34 | % if isempty(opts.network) 35 | % net = CNNModelInitialization('batchNormalization', opts.batchNormalization, ... 36 | % 'networkType', opts.networkType) ; 37 | % else 38 | % net = opts.network ; 39 | % opts.network = [] ; 40 | % end 41 | if exist(opts.imdbPath, 'file') 42 | imdb = load(opts.imdbPath) ; 43 | else 44 | imdb = getMnistImdb(s) ; 45 | mkdir(opts.expDir) ; 46 | save(opts.imdbPath, '-struct', 'imdb') ; 47 | end 48 | net.meta.classes.name = arrayfun(@(x)sprintf('%d',x),1:s.class_num,'UniformOutput',false) ; 49 | 50 | % -------------------------------------------------------------------- 51 | % Train 52 | % -------------------------------------------------------------------- 53 | switch opts.networkType 54 | case 'simplenn', trainfn = @cnn_train ; 55 | case 'dagnn', trainfn = @cnn_train_dag ; 56 | end 57 | %Call the training function to start training the network 58 | [net, info] = trainfn(net, imdb, getBatch(opts), ... 59 | 'expDir', opts.expDir, ... 60 | net.meta.trainOpts, ... 61 | opts.train, ... 62 | 'val', find(imdb.images.set == 3)) ; 63 | 64 | 65 | function fn = getBatch(opts) 66 | switch lower(opts.networkType) 67 | case 'simplenn' 68 | fn = @(x,y) getSimpleNNBatch(x,y) ; 69 | case 'dagnn' 70 | bopts = struct('numGpus', numel(opts.train.gpus)) ; 71 | fn = @(x,y) getDagNNBatch(bopts,x,y) ; 72 | end 73 | 74 | function [images, labels] = getSimpleNNBatch(imdb, batch) 75 | images = imdb.images.data(:,:,:,batch) ; 76 | labels = imdb.images.labels(1,batch) ; 77 | 78 | function inputs = getDagNNBatch(opts, imdb, batch) 79 | images = imdb.images.data(:,:,:,batch) ; 80 | labels = imdb.images.labels(1,batch) ; 81 | if opts.numGpus > 0 82 | images = gpuArray(images) ; 83 | end 84 | inputs = {'input', images, 'label', labels} ; 85 | 86 | function imdb = getMnistImdb(s) 87 | [x1,y1,x2,y2]=twoDimensionalizationPixelSpectrum(s,0,5/6); 88 | 89 | 90 | set = [ones(1,numel(y1)) 3*ones(1,numel(y2))];% train=1;test=3 91 | data = single(reshape(cat(3, x1, x2),sqrt(s.dd),sqrt(s.dd),1,[]));% Spectral matrix 92 | dataMean = mean(data(:,:,:,set == 1), 4); 93 | data = bsxfun(@minus, data, dataMean) ; 94 | 95 | imdb.images.data = data; 96 | imdb.images.data_mean = dataMean; 97 | imdb.images.labels = cat(2, y1, y2); 98 | imdb.images.set = set ; 99 | imdb.meta.sets = {'train', 'val', 'test'} ; 100 | imdb.meta.classes = arrayfun(@(x)sprintf('%d',x),1:s.class_num,'uniformoutput',false) ; 101 | -------------------------------------------------------------------------------- /CNN/util/displayConvolutionCore.m: -------------------------------------------------------------------------------- 1 | % Output convolution layer core 2 | 3 | net=load('net-epoch-100.mat'); 4 | net.layers=net.net.layers(1:12); 5 | fig=figure(2) ; clf ; colormap jet; 6 | set(gca,'XtickLabel',[],'YtickLabel',[]); 7 | layer_th = 10; 8 | vl_imarraysc(squeeze(net.net.layers{layer_th}.weights{1}(:,:,1,:)),'spacing',2) 9 | colorbar; 10 | axis off; 11 | title('Fourth convolution layer ') ; 12 | 13 | -------------------------------------------------------------------------------- /CNN/util/hyperConvert2d.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linlinle/HSI-CNN/b3b231b8c93a0bc7b3af29b60ccf40ead2e1fddb/CNN/util/hyperConvert2d.m -------------------------------------------------------------------------------- /CNN/util/hyperNormalize.m: -------------------------------------------------------------------------------- 1 | function [ normalizedM ] = hyperNormalize( M ) 2 | %HYPERNORMALIZE Normalized data to be in range [0, 1] 3 | % hyperNormalize Normalizes data to be in range [0, 1] 4 | % 5 | % Usage 6 | % hyperNormalize(M) 7 | % Inputs 8 | % M - Input data 9 | % Outputs 10 | % normalizedM - Normalized data 11 | 12 | minVal = min(M(:)); 13 | maxVal = max(M(:)); 14 | 15 | normalizedM = M - minVal; 16 | if (maxVal == minVal) 17 | normalizeData = zeros(size(M)); 18 | else 19 | normalizedM = normalizedM ./ (maxVal-minVal); 20 | end 21 | -------------------------------------------------------------------------------- /CNN/util/twoDimensionalizationPixelSpectrum.m: -------------------------------------------------------------------------------- 1 | % Two-Dimensionalization of Pixel Spectrum 2 | 3 | function [x1,y1,x2,y2] = twoDimensionalizationPixelSpectrum(s,Normalized,proportion) 4 | 5 | Total_sample_num = s.H*s.W; 6 | Category_Sort = 1:s.class_num; 7 | Each_category_num = zeros(1,s.class_num); 8 | for i= 1:1:s.class_num 9 | Each_category_num(i)=length(find(s.y==Category_Sort(i))); 10 | end 11 | before_reshape_x = hyperConvert2d(s.x(:,:,1:s.dd)); 12 | u = mean(before_reshape_x.').'; 13 | before_reshape_x = before_reshape_x - repmat(u, 1, Total_sample_num); 14 | 15 | % normalization 16 | switch(Normalized) 17 | case 1 18 | before_reshape_x = hyperNormalize(before_reshape_x); % 0 ~ 1 19 | case -1 20 | before_reshape_x = mapminmax(before_reshape_x); %-1 ~ 1 21 | otherwise 22 | end 23 | 24 | before_reshape_y = reshape(s.y,Total_sample_num,1); 25 | before_reshape_yx = [before_reshape_y,before_reshape_x']; 26 | yx_train = []; 27 | yx_test = []; 28 | for i=1:1:s.class_num 29 | row_index = before_reshape_yx(:,1) == Category_Sort(i); 30 | Single_category_yx = before_reshape_yx(row_index,:); 31 | 32 | RandIndex = randperm(Each_category_num(i)); %Random order 33 | Single_category_yx = Single_category_yx( RandIndex,: ); 34 | 35 | train_index = floor(Each_category_num(i)*proportion); 36 | Single_category_yx_train = Single_category_yx(1:train_index,:); 37 | Single_category_yx_test = Single_category_yx(train_index+1:Each_category_num(i),:); 38 | yx_train = [yx_train;Single_category_yx_train]; 39 | yx_test = [yx_test;Single_category_yx_test]; 40 | 41 | end 42 | 43 | RandIndex = randperm( length( yx_train ) ); % Random order between categories 44 | yx_train_random = yx_train( RandIndex,: ); 45 | RandIndex = randperm( length( yx_test ) ); 46 | yx_test_random = yx_test( RandIndex,: ); 47 | 48 | train_set_num = size(yx_train_random,1); 49 | test_set_num = size(yx_test_random,1); 50 | train_set_x = (yx_train_random(:,2:s.dd+1))'; % split x and y 51 | y1 =yx_train_random(:,1)'; 52 | test_set_x = (yx_test_random(:,2:s.dd+1))'; 53 | y2 = yx_test_random(:,1)'; 54 | 55 | 56 | x1 = permute(reshape(train_set_x,sqrt(s.dd),sqrt(s.dd),train_set_num),[1 2 3]); 57 | x2 = permute(reshape(test_set_x,sqrt(s.dd),sqrt(s.dd),test_set_num),[1 2 3]); 58 | end 59 | -------------------------------------------------------------------------------- /CNN/util/vl_imarraysc.m: -------------------------------------------------------------------------------- 1 | function J = vl_imarraysc(A, varargin) 2 | % VL_IMARRAYSC Scale and flattens image array 3 | % J=VL_IMARRAYSC(A) constructs an image mosaic similar to 4 | % J=VL_IMARRAY(A), but it rescales the range of each image in the 5 | % array. If A is an array of grayscale images, J will index all the 6 | % colors in the current colormap; if A is a true color image, J will 7 | % span the range [0,1]. 8 | % 9 | % If A is of an integer class, J will be of class single SINGLE class. 10 | % 11 | % VL_IMARRAYSC(...) displays the image J rather than returning it. 12 | % 13 | % VL_IMARRAYSC() accepts the options of VL_IMARRAY() and: 14 | % 15 | % CLim:: [] 16 | % Rescale the specified range of values rather than the actual 17 | % range of each image. 18 | % 19 | % Uniform:: [false] 20 | % Rescale the range of all the images together, rather than on 21 | % an image-by-image basis. 22 | % 23 | % CMap:: [] 24 | % Use the specified color map as a reference rather than the 25 | % current or default one. 26 | % 27 | % Algorithm:: 28 | % CLim is seet to the image range [m, M], where m is the minimum 29 | % value of an image and M is the maximum. The image range CLim is 30 | % then affinely mapped to the integers from 1 to C, where C is the 31 | % number of colors in the colormap, or to the range [0,1] for true 32 | % color images. The mapping is done so that the first color is 33 | % assigned the first subinterval of length C of the range [m,M] 34 | % and so on. 35 | % 36 | % See also: VL_IMARRAY(), VL_HELP(), IMAGE(). 37 | 38 | % Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson. 39 | % All rights reserved. 40 | % 41 | % This file is part of the VLFeat library and is made available under 42 | % the terms of the BSD license (see the COPYING file). 43 | 44 | opts.clim = [] ; 45 | opts.cmap = colormap ; 46 | opts.uniform = false ; 47 | [opts, varargin] = vl_argparse(opts, varargin) ; 48 | 49 | numDimensions = ndims(A) ; 50 | if numDimensions <= 3 51 | numChannels = 1 ; 52 | numImages = size(A,3) ; 53 | numLevels = size(opts.cmap,1) ; 54 | elseif numDimensions == 4 55 | numChannels = size(A,3) ; 56 | numImages = size(A,4) ; 57 | numLevels = 1 ; 58 | if numChannels ~= 3 59 | error('A has more than three dimensions and the third one is not equal to three.') ; 60 | end 61 | else 62 | error('A has neither 2, 3 or 4 dimensions.') ; 63 | end 64 | 65 | if opts.uniform & ~isempty(opts.clim) 66 | error('UNIFORM cannot be used in combination with CLIM.') ; 67 | end 68 | 69 | if isinteger(A) 70 | A = single(A) ; 71 | end 72 | 73 | if opts.uniform && numDimensions < 4 74 | opts.clim = [min(A(:)) max(A(:))] ; 75 | end 76 | 77 | for k = 1:numImages 78 | if isempty(opts.clim) 79 | if numChannels == 1 80 | tmp = A(:,:,k) ; 81 | else 82 | tmp = A(:,:,:,k) ; 83 | end 84 | dataMin = min(tmp(:)) ; 85 | dataMax = max(tmp(:)) ; 86 | else 87 | dataMin = opts.clim(1) ; 88 | dataMax = opts.clim(2) ; 89 | end 90 | a = numLevels / (dataMax - dataMin + eps) ; 91 | b = - dataMin * a ; 92 | if numChannels == 1 93 | A(:,:,k) = max(min(floor(a * A(:,:,k) + b + 1),numLevels),1) ; 94 | else 95 | A(:,:,:,k) = max(min(a * A(:,:,:,k) + b,numLevels),0) ; 96 | end 97 | end 98 | 99 | if nargout == 0 100 | vl_imarray(A,varargin{:}, 'cmap', opts.cmap) ; 101 | else 102 | J = vl_imarray(A,varargin{:}, 'cmap', opts.cmap) ; 103 | end 104 | -------------------------------------------------------------------------------- /DataAnalysis/SpectralCurveDistribution.m: -------------------------------------------------------------------------------- 1 | % Spectral Curve Distribution of different Objects in Data Set 2 | 3 | clc; 4 | clear; 5 | s = getDataSetBasicInformation('Indian_pines'); 6 | label=s.y; 7 | image=permute(s.x,[3,1,2]); 8 | d = ceil(sqrt(double(s.class_num))); 9 | 10 | 11 | f1=figure(1); 12 | set(f1,'Position',[0 0 1000 1000]) 13 | 14 | for i=1:1:double(s.class_num) 15 | one_class_index=find(label==i); 16 | one_class_dataset=image(:,one_class_index)'; 17 | subplot(d,d,i); 18 | for k=1:1:length(one_class_index) 19 | plot(one_class_dataset(k,:)); 20 | hold on; 21 | end 22 | end 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /DataAnalysis/SpectralMatrixAndCurve.m: -------------------------------------------------------------------------------- 1 | % Difference between Spectral Matrix and Spectral Curve 2 | 3 | clc; 4 | clear; 5 | s = getDataSetBasicInformation('Indian_pines'); 6 | spectral_matrix_size = (floor(sqrt(s.D)))^2; 7 | d = ceil(sqrt(double(s.class_num))); 8 | % Spectral curves for each category 9 | find_array = zeros(s.class_num,s.D); 10 | for i=1:1:s.class_num; 11 | [row,col] = find(s.y==i); 12 | find_array(i,:) = s.x(row(10),col(10),:); % sampling 10th 13 | end 14 | 15 | % 1D -> 2D 16 | show_3D = reshape(find_array(:,1:s.dd)',sqrt(s.dd),sqrt(s.dd),[]); 17 | 18 | % plot Spectral matrix 19 | f1=figure(1); 20 | set(f1,'Position',[0 0 1000 1000]) 21 | for j=1:1:double(s.class_num) 22 | subplot(d,d,j); 23 | imagesc(show_3D(:,:,j)); 24 | end 25 | % plot curve of spectrum 26 | f2=figure(2); 27 | set(f2,'Position',[0 0 1000 1000]) 28 | for i=1:1:s.class_num 29 | plot(find_array(i,:)); 30 | hold on; 31 | end 32 | 33 | 34 | -------------------------------------------------------------------------------- /DataAnalysis/changeColorbar.m: -------------------------------------------------------------------------------- 1 | 2 | function [] = changeColorbar( class_num ) 3 | basic_map=[ 255 255 255 4 | 0 107 253 5 | 0 186 253 6 | 111 248 255 7 | 0 150 50 8 | 0 220 0 9 | 180 255 180 10 | 0 0 0 11 | 196 166 0 12 | 255 255 0 13 | 255 200 0 14 | 255 0 0 15 | 255 100 100 16 | 255 180 180 17 | 200 100 155 18 | 150 0 180 19 | 255 0 255]; 20 | map=basic_map/255.0; 21 | colormap(map(1:class_num+1,:)); 22 | basic_color_YTickLabel = {'Background', '1', '2', '3', '4', '5', '6', '7', '8', '9','10','11','12','13','14','15','16'}; 23 | colorbar('YTick',0:class_num/(class_num+1):class_num+2, 'YTickLabel',[basic_color_YTickLabel(1:class_num+1),' ']); 24 | end 25 | 26 | -------------------------------------------------------------------------------- /DataAnalysis/getDataSetBasicInformation.m: -------------------------------------------------------------------------------- 1 | function [ s ] = getDataSetBasicInformation( HSIDataSet) 2 | % @ HSIDataSet: 'Indian_pines' 'Salinas' 'PaviaU' ... 3 | data_struct = load(HSIDataSet); 4 | label_struct = load([HSIDataSet,'_gt']); 5 | data = getfield(data_struct,char(fieldnames(data_struct))); 6 | label = getfield(label_struct,char(fieldnames(label_struct))); 7 | [H,W,D] = size(data); 8 | class_num = max(max(label)); 9 | dd = (floor(sqrt(D)))^2; 10 | s.name = HSIDataSet; 11 | s.x = data; 12 | s.y = double(label); 13 | s.H = H; 14 | s.W = W; 15 | s.D = D; 16 | s.class_num = class_num; 17 | s.dd = dd; 18 | end 19 | 20 | -------------------------------------------------------------------------------- /DataAnalysis/showSurfaceFeatures.m: -------------------------------------------------------------------------------- 1 | % Using Different Colors to Display Different Ground Objects 2 | 3 | clc; 4 | clear; 5 | s = getDataSetBasicInformation('Indian_pines'); 6 | imagesc(s.y); 7 | changeColorbar(s.class_num) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HSI-CNN 2 | This project is a hyperspectral supervised classification model based on convolution neural network. 3 | You can get more information from these two papers:[Overlappooling](https://link.springer.com/content/pdf/10.1007%2Fs11063-018-9876-7.pdf) [2D-Spectrum](https://www.hindawi.com/journals/js/2018/8602103/) 4 | ## Dependency 5 | * [MatConvNet](http://www.vlfeat.org/matconvnet/) 6 | * [LIBSVM](https://www.csie.ntu.edu.tw/~cjlin/libsvm/) 7 | ## setup 8 | 1. setup MatConvNet with CPU or GPU 9 | 2. Place the project directly in a matlab environment with the dependency paths described above 10 | ## running program 11 | ### data processing 12 | * Data sets used include ‘Indian_Pines’ ‘Salinas’ ‘PaviaU’ .... 13 | * Remove “_corrected" from mat file name 14 | ### SVM 15 | Run /SVM/HSIClassificationSVM.m 16 | ### CNN 17 | Run /CNN/modelTrain.m 18 | -------------------------------------------------------------------------------- /SVM/HSIClassificationSVM.m: -------------------------------------------------------------------------------- 1 | 2 | clc; 3 | clear; 4 | s = getDataSetBasicInformation('Indian_pines'); 5 | label=s.y; 6 | image=permute(s.x,[3,1,2]); 7 | %[p m n] = size(image); 8 | 9 | % Proportional Division of Training Set and Test Set 10 | ratio=0.1; % Proportion of training set 11 | 12 | train_index=[]; 13 | train_set=[]; 14 | train_label=[]; 15 | 16 | test_index=[]; 17 | test_set=[]; 18 | test_label=[]; 19 | 20 | for i=1:1:s.class_num 21 | index=find(label==i); 22 | sample_number=length(index); 23 | 24 | train_oen_index=randsample(index,round(ratio*sample_number)); 25 | train_index=[train_index;train_oen_index]; 26 | train_label=[train_label;label(train_oen_index)]; 27 | train_set=[train_set;image(:,train_oen_index)']; 28 | 29 | test_oen_index=setdiff(index,train_oen_index); 30 | test_index=[test_index;test_oen_index]; 31 | test_label=[test_label;label(test_oen_index)]; 32 | test_set=[test_set;image(:,test_oen_index)']; 33 | end 34 | 35 | % normalization 36 | for i=1:length(train_label) 37 | train_set(i,:)=train_set(i,:)/norm(train_set(i,:)); 38 | end 39 | for i=1:length(test_label) 40 | test_set(i,:)=test_set(i,:)/norm(test_set(i,:)); 41 | end 42 | 43 | % PCA 44 | [coef,score,latent,t2]=princomp(train_set); 45 | x0 = bsxfun(@minus,train_set,mean(train_set,1)); 46 | train_set=x0*coef(:,1:80); 47 | x0 = bsxfun(@minus,test_set,mean(test_set,1)); 48 | test_set=x0*coef(:,1:80); 49 | 50 | % SVM 51 | opt_svm = '-s 0 -t 2 -c 1024 -g 2^-7 -b 1'; 52 | model=svmtrain(train_label,train_set,opt_svm); 53 | [predict_label, a, cof]=svmpredict(test_label,test_set,model,'-b 1'); 54 | 55 | % Confusion matrix 56 | conf_m=zeros(s.class_num); 57 | for i=1:1:s.class_num 58 | i_index=find(predict_label==i); 59 | i_test_label=test_label(i_index); 60 | for j=1:1:s.class_num 61 | id=find(i_test_label==j); 62 | conf_m(i,j)=length(id); 63 | end 64 | end 65 | 66 | % Overall accuracy 67 | Overall_accuracy = sum(diag(conf_m))/sum(sum(conf_m)); 68 | % Average accuracy 69 | Average_accuracy = diag(conf_m)'./sum(conf_m); 70 | % Kappa 71 | kappa = kappa(conf_m); 72 | 73 | % Drawing plot 74 | Train_image=zeros(s.H,s.W); 75 | Test_image=zeros(s.H,s.W); 76 | Predic_image=zeros(s.H,s.W); 77 | 78 | Original_image=label; 79 | Train_image([train_index])=[train_label]; 80 | Test_image([test_index])=[test_label]; 81 | 82 | Predic_image([train_index;test_index])=[train_label;predict_label]; 83 | f=figure(1); 84 | set(f, 'Position', [0 114 1400 600]); 85 | subplot(121); 86 | imagesc(Original_image); 87 | subplot(122); 88 | imagesc(Predic_image); 89 | changeColorbar(s.class_num); 90 | f2=figure(2); 91 | set(f2,'Position',[0 144 1400 600]) 92 | subplot(121); 93 | imagesc(Train_image); 94 | subplot(122); 95 | imagesc(Test_image); 96 | changeColorbar(s.class_num); -------------------------------------------------------------------------------- /SVM/kappa.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linlinle/HSI-CNN/b3b231b8c93a0bc7b3af29b60ccf40ead2e1fddb/SVM/kappa.m --------------------------------------------------------------------------------