├── BCM.m ├── Ptrue.mat ├── demo.mat ├── BCM_Spatial.m ├── BCM_Spectral.m ├── BCMParameters.m ├── Spatial and Spectral Unmixing Using the Beta Compositional Model.pdf ├── License ├── hyperFcls.m ├── unmix2.m ├── PError.m ├── unmix_qpas_correct.m ├── README.md ├── unmixGaussian.m └── demo_allMethods.m /BCM.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GatorSense/BetaCompositionalModel/HEAD/BCM.m -------------------------------------------------------------------------------- /Ptrue.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GatorSense/BetaCompositionalModel/HEAD/Ptrue.mat -------------------------------------------------------------------------------- /demo.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GatorSense/BetaCompositionalModel/HEAD/demo.mat -------------------------------------------------------------------------------- /BCM_Spatial.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GatorSense/BetaCompositionalModel/HEAD/BCM_Spatial.m -------------------------------------------------------------------------------- /BCM_Spectral.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GatorSense/BetaCompositionalModel/HEAD/BCM_Spectral.m -------------------------------------------------------------------------------- /BCMParameters.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GatorSense/BetaCompositionalModel/HEAD/BCMParameters.m -------------------------------------------------------------------------------- /Spatial and Spectral Unmixing Using the Beta Compositional Model.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GatorSense/BetaCompositionalModel/HEAD/Spatial and Spectral Unmixing Using the Beta Compositional Model.pdf -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 TigerSense 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /hyperFcls.m: -------------------------------------------------------------------------------- 1 | function [ X ] = hyperFcls( M, U ) 2 | %HYPERFCLS Performs fully constrained least squares on pixels of M. 3 | % hyperFcls performs fully constrained least squares of each pixel in M 4 | % using the endmember signatures of U. Fully constrained least squares 5 | % is least squares with the abundance sum-to-one constraint (ASC) and the 6 | % abundance nonnegative constraint (ANC). 7 | % 8 | % Usage 9 | % [ X ] = hyperFcls( M, U ) 10 | % Inputs 11 | % M - HSI data matrix (p x N) 12 | % U - Matrix of endmembers (p x q) 13 | % Outputs 14 | % X - Abundance maps (q x N) 15 | % 16 | % References 17 | % "Fully Constrained Least-Squares Based Linear Unmixing." Daniel Heinz, 18 | % Chein-I Chang, and Mark L.G. Althouse. IEEE. 1999. 19 | % 20 | % Written by 21 | % Matlab Hyperspectral Toolbox - Toolbox of advanced algorithms for 22 | % hyperspectral processing and exploitation. 23 | % http://sourceforge.net/apps/mediawiki/matlabhyperspec/index.php?title=Main_Page. 24 | % Toolbox Available at http://sourceforge.net/projects/matlabhyperspec/. 25 | 26 | if (ndims(U) ~= 2) 27 | error('M must be a p x q matrix.'); 28 | end 29 | 30 | [p1, N] = size(M); 31 | [p2, q] = size(U); 32 | if (p1 ~= p2) 33 | error('M and U must have the same number of spectral bands.'); 34 | end 35 | 36 | p = p1; 37 | X = zeros(q, N); 38 | Mbckp = U; 39 | for n1 = 1:N 40 | count = q; 41 | done = 0; 42 | ref = 1:q; 43 | r = M(:, n1); 44 | U = Mbckp; 45 | while not(done) 46 | als_hat = inv(U.'*U)*U.'*r; 47 | s = inv(U.'*U)*ones(count, 1); 48 | 49 | % IEEE Magazine method (http://www.planetary.brown.edu/pdfs/3096.pdf) 50 | % Contains correction to sign. Error in original paper. 51 | afcls_hat = als_hat - inv(U.'*U)*ones(count, 1)*inv(ones(1, count)*inv(U.'*U)*ones(count, 1))*(ones(1, count)*als_hat-1); 52 | 53 | % See if all components are positive. If so, then stop. 54 | if (sum(afcls_hat>0) == count) 55 | alpha = zeros(q, 1); 56 | alpha(ref) = afcls_hat; 57 | break; 58 | end 59 | % Multiply negative elements by their counterpart in the s vector. 60 | % Find largest abs(a_ij, s_ij) and remove entry from alpha. 61 | idx = find(afcls_hat<0); 62 | afcls_hat(idx) = afcls_hat(idx) ./ s(idx); 63 | [val, maxIdx] = max(abs(afcls_hat(idx))); 64 | maxIdx = idx(maxIdx); 65 | alpha(maxIdx) = 0; 66 | keep = setdiff(1:size(U, 2), maxIdx); 67 | U = U(:, keep); 68 | count = count - 1; 69 | ref = ref(keep); 70 | end 71 | X(:, n1) = alpha; 72 | end 73 | 74 | return; 75 | -------------------------------------------------------------------------------- /unmix2.m: -------------------------------------------------------------------------------- 1 | function [P] = unmix2(data, endmemberMean) 2 | % This function performs NCM-QP unmixing (Normal Compositional Model, Quadratic Programming approach). 3 | % INPUTS 4 | % data - double Mat - DxN matrix of image data. 5 | % endmemberMean - double Mat - DxM matrix of endmember mean value (known). 6 | % OUTPUTS 7 | % P - double Mat - MxN matrix of abundances/proportions corresponding to N input 8 | % pixels and M endmembers 9 | % 10 | % This product is Copyright (c) 2014 University of Missouri 11 | % All rights reserved. 12 | % 13 | % Redistribution and use in source and binary forms, with or without 14 | % modification, are permitted provided that the following conditions 15 | % are met: 16 | % 17 | % 1. Redistributions of source code must retain the above copyright 18 | % notice, this list of conditions and the following disclaimer. 19 | % 2. Redistributions in binary form must reproduce the above copyright 20 | % notice, this list of conditions and the following disclaimer in the 21 | % documentation and/or other materials provided with the distribution. 22 | % 3. Neither the name of the University nor the names of its contributors 23 | % may be used to endorse or promote products derived from this software 24 | % without specific prior written permission. 25 | % 26 | % THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF MISSOURI AND 27 | % CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 28 | % INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 29 | % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | % DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS 31 | % BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 32 | % EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | % LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, 34 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | % HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 | % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 37 | % OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | 40 | options = optimset('Display', 'off', 'LargeScale', 'off'); 41 | warning off all 42 | 43 | %endmemberMean should be column vectors 44 | X = data; 45 | %number of endmemberMean 46 | M = size(endmemberMean, 2); 47 | %number of pixels 48 | N = size(X, 2); 49 | 50 | %set up constraint matrices 51 | A1 = eye(M); 52 | A1 = -1*A1; 53 | b1 = zeros([M, 1]); 54 | 55 | A2 = ones([1, M]); 56 | b2 = 1; 57 | 58 | A3 = -1*ones([1, M]); 59 | b3 = -1; 60 | 61 | A = vertcat(A1, A2); 62 | A = vertcat(A, A3); 63 | 64 | b = vertcat(b1, b2); 65 | b = vertcat(b, b3); 66 | 67 | H = (2*endmemberMean'*endmemberMean); 68 | 69 | parfor i = 1:N 70 | Xi = X(:,i); 71 | F = (-2*Xi'*endmemberMean)'; 72 | P(i,:) = quadprog(H, F, A, b, [], [], [], [], [], options);%QP unmixing 73 | end 74 | 75 | P(P<0) = 0; 76 | 77 | end 78 | 79 | -------------------------------------------------------------------------------- /PError.m: -------------------------------------------------------------------------------- 1 | function [PErrorOutput, PErrorOutputmean, PErrorOutputvar] = PError(N,Ptrue,Pestimate) 2 | 3 | % This function computes the proportion erros per pixel per endmember 4 | % given true and estimated proportion values. 5 | % 6 | % SYNTAX : [PErrorOutput, PErrorOutputmean, PErrorOutputvar] = PError(N,Ptrue,Pestimate) 7 | % 8 | % INPUTS 9 | % N: Total number of data points. N=N1*N2 in hyperspectral 10 | % image data. 11 | % Ptrue: True proportion values. N*M, where M is the number of 12 | % endmembers. 13 | % Pestimate: Estimated proportion values. N*M. 14 | % OUTPUTS 15 | % PErrorOutput: PError per pixel 16 | % PErrorOutputmean: Mean of PErrorOutput, PError per pixel per 17 | % endmember. (This is the result in the Tables in the paper) 18 | % PErrorOutputvar: Variance of PErrorOutput across endmembers. 19 | % 20 | % This product is Copyright (c) 2014 University of Missouri 21 | % All rights reserved. 22 | % 23 | % Redistribution and use in source and binary forms, with or without 24 | % modification, are permitted provided that the following conditions 25 | % are met: 26 | % 27 | % 1. Redistributions of source code must retain the above copyright 28 | % notice, this list of conditions and the following disclaimer. 29 | % 2. Redistributions in binary form must reproduce the above copyright 30 | % notice, this list of conditions and the following disclaimer in the 31 | % documentation and/or other materials provided with the distribution. 32 | % 3. Neither the name of the University nor the names of its contributors 33 | % may be used to endorse or promote products derived from this software 34 | % without specific prior written permission. 35 | % 36 | % THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF MISSOURI AND 37 | % CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 38 | % INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 39 | % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 | % DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS 41 | % BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 42 | % EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 | % LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, 44 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 | % HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 46 | % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 47 | % OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 48 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 49 | 50 | M = size(Ptrue,2); 51 | t = (Ptrue- Pestimate).^2; 52 | PErrorOutput = sum(sum(t)) / N; % PError per pixel 53 | 54 | 55 | PErrorOutputmean = PErrorOutput/M; %Mean of PErrorOutput, PError per pixel per endmember 56 | PErrorOutputvar= var(PErrorOutput); %Variance of PErrorOutput 57 | 58 | %%Plot histogram across iterations for one N. FOR DEMO PURPOSES. 59 | % figure(100); 60 | % plot(PErrorOutput); 61 | % xlabel('N');ylabel('PError'); 62 | % title('Plot of PErrorOutput'); 63 | % figure(200); 64 | % hist(PErrorOutput); 65 | % xlabel('PError');ylabel('# of Data Points'); 66 | % title('Histogram of PErrorOutput'); 67 | 68 | end -------------------------------------------------------------------------------- /unmix_qpas_correct.m: -------------------------------------------------------------------------------- 1 | function [P2] = unmix_qpas_correct(data, endmembers,methodFlag) 2 | % This function performs quadratic unmixing given endmember mean values 3 | % SYNTAX : [P2] = unmix_qpas_correct(data, endmembers) 4 | % INPUTS 5 | % data - double Mat - DxN matrix of N data points of dimensionality D 6 | % (i.e. N pixels with D spectral bands, each pixel is a column vector). 7 | % endmembers - double Mat - DxM matrix of M endmembers (endmember mean spectra) of dimensionality D. 8 | % methodFlag - double Mat - 1x1 integer. 9 | % If methodFlag == 1, BCM Spectral QP unmixing; 10 | % If methodFlag == 3, BCM Spatial QP unmixing. 11 | % OUTPUTS 12 | % P2 - double Mat - NxM matrix of abundances/proportions corresponding to N input 13 | % pixels and M endmembers 14 | % 15 | % This product is Copyright (c) 2014 University of Missouri. 16 | % All rights reserved. 17 | % 18 | % Redistribution and use in source and binary forms, with or without 19 | % modification, are permitted provided that the following conditions 20 | % are met: 21 | % 22 | % 1. Redistributions of source code must retain the above copyright 23 | % notice, this list of conditions and the following disclaimer. 24 | % 2. Redistributions in binary form must reproduce the above copyright 25 | % notice, this list of conditions and the following disclaimer in the 26 | % documentation and/or other materials provided with the distribution. 27 | % 3. Neither the name of the University nor the names of its contributors 28 | % may be used to endorse or promote products derived from this software 29 | % without specific prior written permission. 30 | % 31 | % THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF MISSOURI AND 32 | % CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 33 | % INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 34 | % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 35 | % DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS 36 | % BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 37 | % EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 38 | % LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, 39 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 | % HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 41 | % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 42 | % OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 43 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | 45 | warning('off', 'all'); 46 | options = optimset('Display', 'off', 'LargeScale', 'off'); 47 | 48 | %endmembers should be column vectors 49 | X = data; 50 | 51 | %number of endmembers 52 | M = size(endmembers, 2); 53 | %number of pixels 54 | N = size(X, 2); 55 | 56 | 57 | %Equation constraint Aeq*x = beq 58 | %All values must sum to 1 (X1+X2+...+XM = 1) 59 | Aeq = ones([1, M]); 60 | beq = 1; 61 | 62 | %Boundary Constraints lb >= x >= ub 63 | %All values must be greater than 0 (0 ? X1,0 ? X2,...,0 ? XM) 64 | lb = zeros([M, 1]); 65 | ub = ones([M,1]); 66 | 67 | H = 2*(endmembers'*endmembers); 68 | 69 | P2 = zeros(N,M); 70 | 71 | constraintErrorTrip = 0.01; %off by 0.01% indicates error 72 | %F = ((-2*X'*endmembers)+repmat(gammaVecs,N,1))'; 73 | 74 | if methodFlag == 1 75 | h = waitbar(0,'Stage 2/2: QP unmixing...','Name','BCM Spectral Unmixing'); 76 | elseif methodFlag == 3 77 | h = waitbar(0,'Stage 2/2: QP unmixing...','Name','BCM Spatial Unmixing'); 78 | else 79 | error('not yet implemented'); 80 | P2 = []; 81 | end 82 | % parfor i = 1:N 83 | 84 | for i = 1:N 85 | F = (-2*X(:,i)'*endmembers)'; 86 | % qpas_ans = qpas(H, F, [], [], Aeq, beq, lb, ub, 0); 87 | qpas_ans = quadprog(H, F, [], [], Aeq, beq, lb, [], [], options); 88 | qpas_sum = sum(qpas_ans); 89 | constraintPercentError = abs(1-qpas_sum)*100; 90 | constraintError = (constraintPercentError > constraintErrorTrip); %set if constraints are not met 91 | if (constraintError) 92 | %disp('constraint error detected and corrected'); 93 | P2(i,:) = quadprog(H, F, [], [], Aeq, beq, lb, [], [], options); 94 | else 95 | P2(i,:) = qpas_ans; 96 | end 97 | 98 | perc = round(i/N*100); 99 | if (mod(perc, 20) == 0) 100 | waitbar(i/N,h,sprintf('Stage 2/2: QP unmixing...%d%%',perc)); 101 | end 102 | end 103 | 104 | P2(P2<0) = 0; 105 | close(h); 106 | end 107 | 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BetaCompositionalModel 2 | 3 | MATLAB implementation of the Beta Compositional Model algorithm for Hyperspectral unmixing. See related paper, doi: 10.1109/JSTARS.2014.2330347 4 | *************************************************************** 5 | 6 | ***If this code is used, cite it: Xiaoxiao Du, & Alina Zare. (2019, April 12). GatorSense/BetaCompositionalModel: Initial Release (Version v1.0). Zenodo. http://doi.org/10.5281/zenodo.2638288 7 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.2638288.svg)](https://doi.org/10.5281/zenodo.2638288) 8 | 9 | ***NOTE: If the BCM Unmixing Algorithm is used in any publication or presentation, the following reference must be cited: 10 | 11 | X. Du, A. Zare, P. Gader, D. Dranishnikov, ìSpatial and Spectral Unmixing Using the Beta Compositional Model,î IEEE Journal of Selected Topics in Applied Earth Observations and Remote Sensing, vol. 7, no. 6, pp. 1994-2003, June 2014. 12 | 13 | *************************************************************** 14 | 15 | The BCM Unmixing Algorithm runs using the following function: 16 | 17 | [Parameters] = BCMParameters(endmembers); 18 | [P] = BCM(Xim, Parameters, MethodFlag) 19 | 20 | The endmembers input is a 1xM cell of endmember samples (known) where M is the number of endmembers. 21 | 22 | DxNumESamples double matrix within each cell, where D is the number of spectral bands and NumESamples is the number of endmember samples. 23 | 24 | The Xim input is a N1xN2xD matrix of N1xN2 image data points of dimensionality D. 25 | 26 | The parameters input is a struct with the following fields: 27 | Parameters - struct - The struct contains the following fields: 28 | % These parameters are user defined (can be modified) 29 | 1. NumberIterations: Number of iterations 30 | 2. K: Number of nearest neighbors 31 | 3. c: Number of clusters for spatial K-means 32 | 4. SigV: Weighting on SigmaV 33 | 5. SigM: Weighting on SigmaMean 34 | 6. s: Scaling parameter for location information 35 | 7. ECovariance: diagonal covariance on endmembers, currently same for all endmembers 36 | % These parameters are computed from input data and known endmembers (does not need modification) 37 | 8. MaxNumEMs, M: Number of endmembers 38 | 9. bandnum, D: Number of spectral bands/dimensions 39 | 10. N: Number of pixels(input data points) 40 | 11. Emean: Mean of endmember samples 41 | 12. BetaParameters: parameters for fitting a Beta distribution to each band of each endmember 42 | *Parameters can be modified in [Parameters] = BCMParameters(endmembers) function. 43 | 44 | The MethodFlag input is an 1x1 integer, choose from 1, 2, 3, 4, where each number indicates one BCM approach: 45 | 1. BCM-Spectral-QP (Quadratic Programming Approach) 46 | 2. BCM-Spectral-MH (Metropolis-Hastings Sampling Approach) 47 | 3. BCM-Spatial-QP 48 | 4. BCM-Spatial-MH 49 | 50 | 51 | ********************************************************************* 52 | Description of files: 53 | 54 | demo_allMethods.m - This is the main file. The demo performs BCM unmixing and compares with FCLS and NCM unmixing methods. 55 | BCM.m - BCM (Beta Compositional Model) Spatial and Spectral Unmixing Algorithms. 56 | BCMParameters.m - Sets the parameters to be used during the BCM unmixing algorithm. Please change accordingly. 57 | BCM_Spectral.m- Performs BCM-Spectral unmixing, including BCM-Spectral-QP and BCM-Spectral-MH approaches. 58 | BCM_Spatial.m - Performs BCM-Spatial unmixing, including BCM-Spatial-QP and BCM-Spatial-MH approaches. 59 | hyperFcls.m - Performs fully constrained least squares on pixels of M. Written by I. Gerg (2012): Matlab Hyperspectral Toolbox [Online]. Available at https://github.com/isaacgerg/matlabHyperspectralToolbox.git. 60 | unmix_qpas_correct.m - Performs quadratic unmixing given endmember mean values. 61 | unmix2.m - Performs NCM-QP unmixing. 62 | unmixGaussian.m - Performs NCM-MH unmixing. 63 | PError.m - Computes the proportion errors per pixel per endmember given true and estimated proportion values. 64 | demo.mat - Hyperspectral image and endmember samples (provided for demo purposes) 65 | Ptrue.mat - Manual ground truth for the demo hyperspectral image (provided for demo purposes) 66 | *********************************************************************** 67 | 68 | 69 | Authors: Xiaoxiao Du, Alina Zare 70 | University of Missouri, Department of Electrical and Computer Engineering 71 | Email Address: xdy74@mail.missouri.edu; zarea@missouri.edu 72 | Latest Revision: November 3, 2014 73 | 74 | This code uses MATLAB Statistics Toolbox and Matlab Optimization Toolbox. 75 | 76 | 77 | -------------------------------------------------------------------------------- /unmixGaussian.m: -------------------------------------------------------------------------------- 1 | function [Pbest] = unmixGaussian(X,Parameters) 2 | 3 | % This function performs NCM-MH unmixing (Normal Compositional Model, MH Sampling approach). 4 | % Update Proportions Part ONLY (given endmembers), Gaussian Sampling method unmix 5 | % INPUTS 6 | % X - double Mat - NxD image data. 7 | % Parameters - struct - Parameters. 8 | % OUTPUTS 9 | % Pbest - double Mat - MxN matrix of abundances/proportions corresponding to N input 10 | % pixels and M endmembers 11 | % 12 | % Author: Xiaoxiao Du, Alina Zare 13 | % University of Missouri, Department of Electrical and Computer Engineering 14 | % Email Address: xdy74@mail.missouri.edu; zarea@missouri.edu 15 | % Created: August 2013 16 | % Latest Revision: November 3, 2014 17 | % 18 | % This product is Copyright (c) 2014 University of Missouri 19 | % All rights reserved. 20 | % 21 | % Redistribution and use in source and binary forms, with or without 22 | % modification, are permitted provided that the following conditions 23 | % are met: 24 | % 25 | % 1. Redistributions of source code must retain the above copyright 26 | % notice, this list of conditions and the following disclaimer. 27 | % 2. Redistributions in binary form must reproduce the above copyright 28 | % notice, this list of conditions and the following disclaimer in the 29 | % documentation and/or other materials provided with the distribution. 30 | % 3. Neither the name of the University nor the names of its contributors 31 | % may be used to endorse or promote products derived from this software 32 | % without specific prior written permission. 33 | % 34 | % THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF MISSOURI AND 35 | % CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 36 | % INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 37 | % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | % DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS 39 | % BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 40 | % EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | % LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, 42 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 | % HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 44 | % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 45 | % OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 46 | % SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 47 | 48 | NumberIterationsforUpdateP = Parameters.NumberIterations; 49 | NPts = size(X,1); % number of data points 50 | M = size(Parameters.Emean,1); %number of endmembers 51 | D = size(Parameters.Emean,2); %number of bands 52 | Parameters.AlphaPropVector = ones(1, Parameters.MaxNumEMs);%Parameters for Sampling Proportions, currently all ones (symmetric dirichlet) 53 | 54 | P(:,:,1) = DirichletSample(Parameters.AlphaPropVector,size(X,1)); %Initialize P 55 | 56 | onesLengthAlpha = ones(1, Parameters.MaxNumEMs); 57 | 58 | E = Parameters.Emean; 59 | LogLikelihoodOld = ComputeLogLikelihoodAll(X, E, P, Parameters, NPts);%Initialize LogLikelihoodOld 60 | LogLikelihoodTraceBest = LogLikelihoodOld; 61 | Pbest = P; 62 | 63 | %% 64 | for iteration = 2:NumberIterationsforUpdateP+1 65 | 66 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 67 | % Update Proportions % 68 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 69 | Y = randg(Parameters.AlphaPropVector(1), NPts, Parameters.MaxNumEMs) ; %Sample proportions under consideration 70 | v = sum(Y,2); 71 | samples = Y./v(:, onesLengthAlpha); 72 | LogLikelihoodNew = ComputeLogLikelihoodAll(X, E(:,:,1), samples, Parameters, NPts); 73 | Ratios = exp(LogLikelihoodNew - LogLikelihoodOld(:,1)); 74 | rands = rand(NPts,1); 75 | Vals = rands < Ratios; 76 | Vrep = Vals(:, onesLengthAlpha); 77 | P(:,:,1) = samples.*Vrep + P( :,:,1).*(1-Vrep); 78 | LogLikelihoodOld(:,1) = (1-Vals).*LogLikelihoodOld(:,1) + (Vals).*LogLikelihoodNew; 79 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 80 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 81 | 82 | LogLikelihoodNewTrace = LogLikelihoodOld ; 83 | 84 | for i =1:NPts 85 | if LogLikelihoodNewTrace(i,:) > LogLikelihoodTraceBest(i,:) 86 | Pbest(i,:) = P(i,:); 87 | LogLikelihoodTraceBest(i,:) = LogLikelihoodNewTrace(i,:); 88 | end 89 | end 90 | 91 | % %Display and track Log Likelihood values 92 | % if(mod(iteration, 200) == 0); 93 | % disp(['Iteration ', num2str(iteration), ' of ', num2str(NumberIterationsforUpdateP)]); 94 | % disp(['sum of LogLikelihoodOld = ' num2str(sum(LogLikelihoodOld))]); 95 | % end 96 | 97 | end 98 | 99 | end 100 | 101 | function [LogLikelihoodAll] = ComputeLogLikelihoodAll(X, E, P, Parameters, NumPoints) 102 | %compute log likelihood 103 | NumSets = size(E,3); 104 | LogLikelihoodAll = zeros(NumPoints, NumSets); 105 | C = (-1/2)*1./sum(P.*P*Parameters.ECovariance,2); 106 | N = -1*log(squeeze(sum(P.*P*Parameters.ECovariance,2)).*size(X,2)); 107 | for i = 1:NumSets 108 | Recon = P(:,:,i)*E(:,:,i); 109 | D = (X - Recon)'; 110 | D = sum(D.*D); 111 | LogLikelihoodAll(:,i) = N(:,i) + C(:,1,i).*D'; 112 | end 113 | 114 | end 115 | 116 | function [samples] = DirichletSample(alpha, numSamples) 117 | %Generate samples from Dirichlet distribution 118 | if(size(alpha,1) == 1) 119 | Y = randg(repmat(alpha, [numSamples,1])); 120 | samples = Y./repmat(sum(Y')', [1, length(alpha)]); 121 | else 122 | Y = randg(alpha); 123 | samples = Y./repmat(sum(Y')', [1, size(alpha,2)]); 124 | end 125 | end 126 | 127 | -------------------------------------------------------------------------------- /demo_allMethods.m: -------------------------------------------------------------------------------- 1 | prompt = 'Running this code will clear your workspace. Would you like to continue?[Y/N]'; 2 | str = input(prompt,'s'); 3 | if (str=='N') || (str=='n') 4 | ; 5 | elseif (str=='Y') || (str=='y') 6 | 7 | clear;close all;clc 8 | load('demo.mat') 9 | 10 | [Parameters] = BCMParameters(endmembers); 11 | 12 | %% BCM Unmixing 13 | %%% Approximate running time: 70 seconds per BCM approach*. 14 | %%% *Measured on a desktop PC with Intel i7 3.20 GHz processor and 12 GB RAM. 15 | 16 | disp('BCM-Spectral-QP Unmixing...'); 17 | [P1] = BCM(Xim, Parameters, 1);%BCM-Spectral-QP 18 | P1r = reshape(P1,[13 19 4]); 19 | 20 | disp('BCM-Spectral-MH Unmixing...'); 21 | [P2] = BCM(Xim, Parameters, 2);%BCM-Spectral-MH 22 | P2r = reshape(P2,[13 19 4]); 23 | 24 | disp('BCM-Spatial-QP Unmixing...'); 25 | [P3] = BCM(Xim, Parameters, 3);%BCM-Spatial-QP 26 | P3r = reshape(P3,[13 19 4]); 27 | 28 | disp('BCM-Spatial-MH Unmixing...'); 29 | [P4] = BCM(Xim, Parameters, 4);%BCM-Spatial-MH 30 | P4r = reshape(P4,[13 19 4]); 31 | %% FCLS and NCM Unmixing (for comparison) 32 | X = reshape(Xim,[size(Xim,1)*size(Xim,2),size(Xim,3)]); 33 | 34 | disp('FCLS Unmixing...'); 35 | [ PFCLS ] = hyperFcls( X', Parameters.Emean' ); %FCLS 36 | PFCLS = PFCLS'; 37 | PFCLSr = reshape(PFCLS,[13 19 4]); 38 | 39 | disp('NCM-QP Unmixing...'); 40 | [PestimateNCM1] = unmix2(X', Parameters.Emean'); %NCM-QP 41 | PNCM1r = reshape(PestimateNCM1,[13 19 4]); 42 | 43 | disp('NCM-MH Unmixing...'); 44 | [PestimateNCM2] = unmixGaussian(X,Parameters); %NCM-MH 45 | PNCM2r = reshape(PestimateNCM2,[13 19 4]); 46 | %% Plot proportion maps 47 | fig = figure(100); 48 | set(gcf,'Position',get(0,'ScreenSize')); 49 | subplot(2,2,1);imagesc(P1r(:,:,1),[0 1]);title('Asphalt');axis equal tight 50 | subplot(2,2,2);imagesc(P1r(:,:,2),[0 1]);title('Yellow Curb');axis equal tight 51 | subplot(2,2,3);imagesc(P1r(:,:,3),[0 1]);title('Grass');axis equal tight 52 | subplot(2,2,4);imagesc(P1r(:,:,4),[0 1]);title('Oak Leaves');axis equal tight 53 | ha = axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 54 | 1],'Box','off','Visible','off','Units','normalized', 'clipping' , 'off'); 55 | text(0.5, 1,'\bf BCM-Spectral-QP Unmixing: Proportion Maps','HorizontalAlignment' ,'center','VerticalAlignment', 'top') 56 | 57 | 58 | fig = figure(200); 59 | set(gcf,'Position',get(0,'ScreenSize')); 60 | subplot(2,2,1);imagesc(P2r(:,:,1),[0 1]);title('Asphalt');axis equal tight 61 | subplot(2,2,2);imagesc(P2r(:,:,2),[0 1]);title('Yellow Curb');axis equal tight 62 | subplot(2,2,3);imagesc(P2r(:,:,3),[0 1]);title('Grass');axis equal tight 63 | subplot(2,2,4);imagesc(P2r(:,:,4),[0 1]);title('Oak Leaves');axis equal tight 64 | ha = axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 65 | 1],'Box','off','Visible','off','Units','normalized', 'clipping' , 'off'); 66 | text(0.5, 1,'\bf BCM-Spectral-MH Unmixing: Proportion Maps','HorizontalAlignment' ,'center','VerticalAlignment', 'top') 67 | 68 | 69 | fig = figure(300); 70 | set(gcf,'Position',get(0,'ScreenSize')); 71 | subplot(2,2,1);imagesc(P3r(:,:,1),[0 1]);title('Asphalt');axis equal tight 72 | subplot(2,2,2);imagesc(P3r(:,:,2),[0 1]);title('Yellow Curb');axis equal tight 73 | subplot(2,2,3);imagesc(P3r(:,:,3),[0 1]);title('Grass');axis equal tight 74 | subplot(2,2,4);imagesc(P3r(:,:,4),[0 1]);title('Oak Leaves');axis equal tight 75 | ha = axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 76 | 1],'Box','off','Visible','off','Units','normalized', 'clipping' , 'off'); 77 | text(0.5, 1,'\bf BCM-Spatial-QP Unmixing: Proportion Maps','HorizontalAlignment' ,'center','VerticalAlignment', 'top') 78 | 79 | 80 | fig = figure(400); 81 | set(gcf,'Position',get(0,'ScreenSize')); 82 | subplot(2,2,1);imagesc(P4r(:,:,1),[0 1]);title('Asphalt');axis equal tight 83 | subplot(2,2,2);imagesc(P4r(:,:,2),[0 1]);title('Yellow Curb');axis equal tight 84 | subplot(2,2,3);imagesc(P4r(:,:,3),[0 1]);title('Grass');axis equal tight 85 | subplot(2,2,4);imagesc(P4r(:,:,4),[0 1]);title('Oak Leaves');axis equal tight 86 | ha = axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 87 | 1],'Box','off','Visible','off','Units','normalized', 'clipping' , 'off'); 88 | text(0.5, 1,'\bf BCM-Spatial-MH Unmixing: Proportion Maps','HorizontalAlignment' ,'center','VerticalAlignment', 'top') 89 | 90 | 91 | fig = figure(500); 92 | set(gcf,'Position',get(0,'ScreenSize')); 93 | subplot(2,2,1);imagesc(PFCLSr(:,:,1),[0 1]);title('Asphalt');axis equal tight 94 | subplot(2,2,2);imagesc(PFCLSr(:,:,2),[0 1]);title('Yellow Curb');axis equal tight 95 | subplot(2,2,3);imagesc(PFCLSr(:,:,3),[0 1]);title('Grass');axis equal tight 96 | subplot(2,2,4);imagesc(PFCLSr(:,:,4),[0 1]);title('Oak Leaves');axis equal tight 97 | ha = axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 98 | 1],'Box','off','Visible','off','Units','normalized', 'clipping' , 'off'); 99 | text(0.5, 1,'\bf FCLS Unmixing: Proportion Maps','HorizontalAlignment' ,'center','VerticalAlignment', 'top') 100 | 101 | 102 | fig = figure(600); 103 | set(gcf,'Position',get(0,'ScreenSize')); 104 | subplot(2,2,1);imagesc(PNCM1r(:,:,1),[0 1]);title('Asphalt');axis equal tight 105 | subplot(2,2,2);imagesc(PNCM1r(:,:,2),[0 1]);title('Yellow Curb');axis equal tight 106 | subplot(2,2,3);imagesc(PNCM1r(:,:,3),[0 1]);title('Grass');axis equal tight 107 | subplot(2,2,4);imagesc(PNCM1r(:,:,4),[0 1]);title('Oak Leaves');axis equal tight 108 | ha = axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 109 | 1],'Box','off','Visible','off','Units','normalized', 'clipping' , 'off'); 110 | text(0.5, 1,'\bf NCM-QP Unmixing: Proportion Maps','HorizontalAlignment' ,'center','VerticalAlignment', 'top') 111 | 112 | 113 | fig = figure(700); 114 | set(gcf,'Position',get(0,'ScreenSize')); 115 | subplot(2,2,1);imagesc(PNCM2r(:,:,1),[0 1]);title('Asphalt');axis equal tight 116 | subplot(2,2,2);imagesc(PNCM2r(:,:,2),[0 1]);title('Yellow Curb');axis equal tight 117 | subplot(2,2,3);imagesc(PNCM2r(:,:,3),[0 1]);title('Grass');axis equal tight 118 | subplot(2,2,4);imagesc(PNCM2r(:,:,4),[0 1]);title('Oak Leaves');axis equal tight 119 | ha = axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 120 | 1],'Box','off','Visible','off','Units','normalized', 'clipping' , 'off'); 121 | text(0.5, 1,'\bf NCM-MH Unmixing: Proportion Maps','HorizontalAlignment' ,'center','VerticalAlignment', 'top') 122 | 123 | %% Compute PError against manual ground truth and display results 124 | load('Ptrue.mat') 125 | N = size(Xim,1)*size(Xim,2); 126 | [~, PErrorOutputmean1, ~] = PError(N,Ptrue,P1); 127 | [~, PErrorOutputmean2, ~] = PError(N,Ptrue,P2); 128 | [~, PErrorOutputmean3, ~] = PError(N,Ptrue,P3); 129 | [~, PErrorOutputmean4, ~] = PError(N,Ptrue,P4); 130 | [~, PErrorOutputmeanF, ~] = PError(N,Ptrue,PFCLS); 131 | [~, PErrorOutputmeanN1, ~] = PError(size(X,1),Ptrue,PestimateNCM1); 132 | [~, PErrorOutputmeanN2, ~] = PError(size(X,1),Ptrue,PestimateNCM2); 133 | 134 | 135 | % Display PErrorOutputmean result 136 | fprintf('PErrorOutputMean for FCLS: '); 137 | fprintf(' %f \n', PErrorOutputmeanF); 138 | 139 | fprintf('PErrorOutputMean for NCM-QP: '); 140 | fprintf(' %f \n', PErrorOutputmeanN1); 141 | 142 | fprintf('PErrorOutputMean for NCM-MH: '); 143 | fprintf(' %f \n', PErrorOutputmeanN2); 144 | 145 | fprintf('PErrorOutputMean for BCM-Spectral-QP: '); 146 | fprintf(' %f \n', PErrorOutputmean1); 147 | 148 | fprintf('PErrorOutputMean for BCM-Spectral-MH: '); 149 | fprintf(' %f \n', PErrorOutputmean2); 150 | 151 | fprintf('PErrorOutputMean for BCM-Spatial-QP: '); 152 | fprintf(' %f \n', PErrorOutputmean3); 153 | 154 | fprintf('PErrorOutputMean for BCM-Spatial-MH: '); 155 | fprintf(' %f \n', PErrorOutputmean4); 156 | 157 | end 158 | --------------------------------------------------------------------------------