資源簡介
N-FINDR是一種端元提取方法,本代碼是利用MATLAB結合N-FINDR原理,進行編程,輸入是高光譜數據,程序內包括了高光譜數據輸入,N-FINDR處理,端元結果輸出
代碼片段和文件信息
function?N_FINDR()
%?read?a?hyperspectral?image?from?sample?data?of?ENVI.
nlines??=?254;
npixels?=?3454;
nbands??=?37;
nlength?=?nlines*npixels;
%hs_img??=?multibandread(‘cup95eff.int‘?[nlines?npixels?nbands]?...
???????????????????????%?‘int16‘?0?‘bil‘?‘ieee-le‘);?%從二進制文件中讀取BSQBILBIP數據
%hs_img=?multibandread(‘F:\285-destripe_new_flaash_wv_sg_37‘[nlines?npixels?nbands]...
?%?????????????????????‘double‘0‘bsq‘‘ieee-be‘);%從二進制文件中讀取BSQ文件
test_hdr=‘F:\test_img.hdr‘;%頭文件的地址
maindata?=?ReadImg(test_hdr);%讀取頭文件相應的.img高光譜數據
hs_img=maindata;
%?reduct?the?dimensionality?of?image?to?be?one?less?the?number?of?end-
%?mumbers?by?using?PCA.
%?standardize?the?data?by?dividing?each?column?by?its?standard?deviation.
hs_img?=?reshape(hs_img?[]?nbands);%改變矩陣的形狀,但是元素個數不變
meanh??=?mean(hs_img);%求均值
stdh???=?std(hs_img);%求標準差
sd_img?=?(hs_img-repmat(meanhnlength1))./repmat(stdhnlength1);%repmat:將meanh作為元素復制nlength*1塊%標準化圖像
[pcoef?score?latent]?=?princomp(sd_img);
???????????????????????????????????????%做PCA。~是對主分的打分也就是原矩陣在主成分空間的表示,pcoef是元矩陣對應的協方差矩陣對的所有特征向量,latent協方差矩陣的特征值
???????????????????????????????????????%latent是向量還是矩陣?
%?determine?the?number?of?endmembers?by?calculating?the?contribution?of
%?%計算主成分的貢獻來確定端元的數量
%?principal?components.
perc?=?cumsum(latent)/sum(latent)*100;%cumsum計算一個數據各行的累加值返回值與latent行列相同,sum是將latent的所有元素相加
Nend?=?sum(perc<99.5)+1;%確定端元的數量
%?get?the?principal?components.確定主成分的貢獻量
pca_img?=?sd_img*pcoef(:1:Nend-1);
%?repeat?50?times?to?find?the?endmembers?with?largest
%?volume.%迭代50次找到最大體積的端元
Ntimes?=?50;
locs???=?zeros(NtimesNend);
V_max??=?zeros(Ntimes1);
for?i?=?1:Ntimes%tic和toc計算程序的時間
???
????[locs(i:)?V_max(i1)]?=?finder(pca_img?nlength?Nend);%N-finder的函數
???
end
[score?ind]?=?max(V_max);
loc?=?locs(ind?:);
%?calculate?the?abundance?of?each?endmember?for?each
%?pixel.計算對于每個像素的每個端元的豐度(最小二乘法)
M???=?ones(Nend);
M(2:end:)?=?pca_img(loc:)‘;
C?=?zeros(Nend?nlength);
for?i?=?1:nlength
????p?=?[1;?pca_img(i:)‘];
????C(:i)?=?lsqnonneg(M?p);%返回C>=0約束下norm(M*C-p)的最小值向量
%?????C(:i)?=?lsqlin(E?p?[][][][]01);
end
save(‘F:\NFINDR_res.txt‘‘C‘‘-ASCII‘);
%stop;
%?end?function?N_FINDR.
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function?[loc?V_max]?=?finder(pca_img?nlength?Nend)
%?randomly?select?pixels?as?initial?endmembers.隨機選擇像素作為初始端元,求單形體的體積
ind?=?unidrnd(nlength?1?Nend);%產生從1到nlength所指定的最大數數之間的離散均勻隨機數,生成1*nend矩陣
E???=?ones(Nend);%產生nend*nend全是1的數組
E(2:end:)?=?pca_img(ind:)‘;%隨機選擇nend個像素組成最初的端元矩陣
dentor?=?factorial(Nend-1);%求(端元-1)的階乘
V_max??=?abs(det(E))/dentor;%求E的行列式在取絕對值最后除以dentor。求體積
%?find?the?largest?volume?and?set?the?corresponding?pixels?as
%?endmembers.找到最大的體積,并設置相應的像素作為端元
for?i?=?1:Nend??%?loop?over?each?endmember.循環每個端元
????i_max?=?ind(i);
????for?j?=?1:nlength??%?loop?over?each?pixel.循環每個像素
????????E(2:endi)?=?pca_img(j:)‘;
????????V?=?abs(det(E))/dentor;
??????
評論
共有 條評論