顶点成分分析算法(Vertex Component Analysis,
VCA)是一种快速无监督提取高光谱图像端元的算法。该算法的主要思想是利用端元在高维特征空间中形成数据云的顶点的性质,通过迭代寻找位于数据云边界的端元,从而实现端元提取。下面将详细介绍该算法的数学原理和求解过程。
问题描述
设有一幅
波段的高光谱图像,每个像素的光谱向量为 ,整个图像可表示为 ,其中
为像素个数。根据线性混合模型,每个光谱向量 可表示为 个端元 的线性组合:
其中 为满足条件
的端元丰度系数,
为高斯白噪声。将上式写成矩阵形式:
其中
为端元矩阵, 为丰度矩阵, 为噪声矩阵。
VCA算法的目标是从高光谱数据 中无监督地提取出端元矩阵 。
VCA算法原理
数据云顶点性质
假设存在 个端元,
那么所有光谱向量都落在由这
个端元张成的
维单纯形内。在没有噪声的情况下,位于单纯形边界的光谱向量必定是某个端元。因此,VCA算法的核心思想是寻找位于数据云边界的光谱向量,将其作为提取的端元。
投影方法
为了寻找边界光谱向量,
VCA算法利用投影技术将高维数据投影到低维空间,从而使边界光谱向量的几何特征更加明显。
首先利用奇异值分解(SVD)计算
阶投影矩阵 ( 或 ,取决于信噪比SNR),并将数据 投影到 维空间:
其中 为投影后的数据。
接下来需要从
中找到边界光谱向量。观察到在
维单纯形中,点到边界的距离大于点到内部的距离。因此可以通过最大化投影矩阵中的行向量
与所有点的夹角余弦值,从而找到距离最远的边界点。
根据Cauchy-Schwarz不等式,上式可化简为求 的最大绝对值分量:
因此,VCA算法采取以下迭代方式求边界光谱向量:
- 对任意非零向量 ,令 为
在当前求解向量的补空间的投影,并归一化 。
- 对归一化后的 ,计算
,其中 ( 为尺度常数)。
- 找到
的最大绝对值分量对应的下标 ,将
的第 列赋值为 的第 列。
重复以上步骤,最终可获得
个顶点向量,即提取的端元矩阵 。
算法求解过程
根据上述原理,VCA算法的具体求解步骤如下:
计算数据均值向量 ,并对数据进行中心化: 。
计算噪声协方差矩阵的
阶投影矩阵 :
将数据投影到 维空间: 。
根据信噪比 SNR 判断是否需要尺度约束:
初始化 矩阵 :
对每个端元进行迭代:
- 生成随机向量 。
- 计算 ,并归一化 。
- 计算 ,找到
的最大绝对值分量对应的下标 。
- 将 的当前列赋值为
的第 列。
估计端元矩阵 :
其中
为由提取端元对应的列向量组成的矩阵。
以上就是VCA算法的完整求解过程。该算法巧妙地利用了数据投影和顶点特性,通过迭代方式无监督地提取出高光谱图像的端元,具有很好的效率和稳健性。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| function [ U, indicies ] = vca( R, p ) %--------------------------------------------------------------------------
[L, N]=size(R); r_m = mean(R,2); R_o = R - repmat(r_m,[1 N]); [Ud,~,~] = svds(R_o*R_o'/N,p); x_p = Ud' * R_o; P_y = sum(R(:).^2)/N; P_x = sum(x_p(:).^2)/N + r_m'*r_m; SNR = abs(10*log10( (P_x - p/L*P_y)/(P_y- P_x) ));
SNRth = 15 + 10*log(p) + 8;
if (SNR > SNRth) d = p; [Ud,~,~] = svds(R*R'/N,d); X = Ud'*R; u = mean(X, 2); Y = X ./ repmat( sum( X .* repmat(u,[1 N]) ) ,[d 1]); else d = p-1; r_m = mean(R,2); R_m = repmat(r_m,[1 N]); R_o = R - R_m; [Ud,~,~] = svds(R_o*R_o'/N,d); X = Ud'*R_o; X = X(1:d,:); c = max(sum(X.^2,1))^0.5; Y = [X ; c*ones(1,N)] ; end
e_u = zeros(p, 1); e_u(p) = 1; A = zeros(p, p); A(:, 1) = e_u; indicies = zeros(1,p);
for i=1:p w = rand(p, 1); f = w - A*pinv(A)*w; f = f / sqrt(sum(f.^2)); v = f'*Y; [~, indicies(i)] = max(abs(v)); A(:,i) = Y(:,indicies(i)); end
if (SNR > SNRth) U = Ud*X(:,indicies); else U = Ud*X(:,indicies) + repmat(r_m,[1 p]); end end
MATLAB
|