在高光谱图像的特征提取过程中,采用非线性降维的方式对高光谱图像降维的过程中,采用图自编码器来对数据进行降维,需要将利用高光谱图像的结构信息和内容信息,则需要将高光谱图像数据构造为一个图结构,图结构的构建需要通过KNN算法来构建邻接矩阵。
主要介绍图结构的构建方法。
1.1 高光谱波段向量集合,X = { x i _i i} i = 1 N _{i = 1}^N i=1N ∈ R N ∗ B ^{N * B} N∗B,即 X为一个像素对应的波段集合,N和B分别为像素数和光谱波段数。
将高光谱图像维度变换为R N ∗ B ^{N * B} N∗B形式,通过如下代码。
load('SalinasA_corrected.mat')
data = salinasA_corrected;
[width,height,band] = size(data);
hsi = reshape(data,width * height,band);
1.2 同时考虑光谱特征X和光谱波段的结构信息,我们首先将带集转换成一个带图G = (V,E, A),其中光谱带x i _i i被视为图上的一个节点v i _i i,E是通过计算每个光谱带的k近邻(kNN)来构造的。其中,邻域矩阵A∈R b × b _{b×b} b×b。
1.3 通过计算欧几里得距离得到了邻域关系,用这种方法构造的图称为kNN图。
1.4 由于KNN算法是一个监督算法,需要使用到数据的标签信息,通过如下代码加载标签信息,便进行维度变换,通常情况下,标签0对应的像素我们不用来构造KNN图。
load('SalinasA_gt.mat')
label = reshape(salinasA_gt,width * height,1);
1.5 KNN算法模型的搭建
kNNClassifier = fitcknn(X, Y, ‘NumNeighbors’, 1)
构造一个KNN分类器,分为5个类,默认采用欧几里得距离公式;
KnnClassifier = fitcknn(hsi,label,'NumNeighbors', 5);
1.6 KNN模型预测分类
采用predict函数,输出参数为分类器模型,测试数据;测试数据为每一行为一条数据。
test = hsi(label ~= 0,:); % 获取测试数据,排除0标签的数据;
result = predict(KnnClassifier,test);% 预测,返回值为数据对应的标签
1.7 k近邻计算
load('SalinasA_gt.mat');
load('SalinasA_corrected.mat');
[width,height,band] = size(salinasA_corrected);
data = reshape(salinasA_corrected,width * height,band);
X = data';
Q = X(:,1);
% 构建kd树
kdtree = vl_kdtreebuild(X);
% 计算Q的k个近邻
[index, distance] = vl_kdtreequery(kdtree, X, Q, 'NumNeighbors', 5) ;
KNN原理介绍:https://www.cnblogs.com/pinard/p/6061661.html
采用如下的公式来构造链接矩阵A,其中N k _k k(x i _i i)为x i _i i的kNN。
基于上述知识,来构造高光谱图像的KNN图,对于高光谱图像,我们把每个像素作为一个样本,B个波段作为特征,让后对每个像素的波段集合,计算其k近邻,让后根据公式构造邻接矩阵;
clc
clear
%% 获取文件数据
load('SalinasA_corrected.mat');
load('SalinasA_gt.mat');
% 获取数据
data = salinasA_corrected;
label = salinasA_gt;
%% 获取数据维度以及对数据进行维度变换
[width,height,band] = size(data);
% 维度变换并转置矩阵
N = width * height;
X = reshape(data,N,band)';% 样本
Y = reshape(label,N,1)'; % 标签
%% 计算每个样本的k近邻,并构造邻接矩阵
% 邻接矩阵,每个像素作为图中一个节点,则邻接矩阵为N * N维度
A = zeros(N,N);
% 构建Kd树
kdtree = vl_kdtreebuild(X);
% 计算样本X(:,i)的k个近邻,并构造邻接矩阵A
for i = 1 : N
[index, ~] = vl_kdtreequery(kdtree, X, X(:,i), 'NumNeighbors', 6) ;
% 排除样本本身
index = index(index ~= i);
% 构造邻接矩阵A,此处可以体会邻接矩阵为整个高光谱图的邻接矩阵
A(i,index) = 1;
end
if A == A'
disp("对称矩阵");
else
disp("非对称矩阵");
end
%%
clc
clear
%% 获取文件数据
load('KSC.mat');
load('KSC_gt.mat');
% 获取数据
data = KSC;
label = KSC_gt;
%% 获取数据维度以及对数据进行维度变换
[width,height,band] = size(data);
% 维度变换
N = width * height;
X = reshape(data,N,band);% 样本
Y = reshape(label,N,1); % 标签
%% 计算每个样本的k近邻,并构造邻接矩阵
% 邻接矩阵,每个波段作为图中一个节点,则邻接矩阵为B * B维度
A = zeros(band,band);
% 构建Kd树
kdtree = vl_kdtreebuild(X);
% 计算样本X(:,i)的k个近邻,并构造邻接矩阵A
for i = 1 : band
[index, ~] = vl_kdtreequery(kdtree, X, X(:,i), 'NumNeighbors', 6) ;
% 排除样本本身
index = index(index ~= i);
% 构造邻接矩阵A,此处可以体会邻接矩阵为整个高光谱图的邻接矩阵
A(i,index) = 1;
end
if A == A'
disp("对称矩阵");
else
disp("非对称矩阵");
end
%%
3.1 像素作为图结构的节点,则G = (V,E,X),V = { v i = 1 , . . . , n _{i = 1,...,n} i=1,...,n}是顶点集合,E = { e i j _{ij} ij}是边集合,X = { x i _i i;…;x n _n n}是属性值。
3.2 需要构造邻接矩阵A,需要知道图结构的边集;
主要介绍高光谱图像利用结构信息和内容信息进行特征提取时,结构信息的构造,在这里主要就是邻接矩阵A的构造,梳理两篇论文中的方法,为自己理清思路,并做些编码记录;
KNN 分类器:https://www.dazhuanlan.com/2019/10/23/5db00bf7d8ffb/
邻接矩阵A相关资料:https://www.cnblogs.com/pinard/p/6221564.html