做遥感图像处理的同行应该都碰到过这个局面:同一景影像里,全色波段分辨率高得让人心动,但偏偏是灰度图,地物颜色信息几乎没有;多光谱影像颜色丰富、波段也多,但空间分辨率总差一口气。要把两者的优势合到一张图里,PCA图像融合就是最经典的方案之一。我在MATLAB里反复调过这个流程,也踩过不少坑,这篇把原理、实现、评价指标一次性讲清楚。
先说清楚这套东西能干什么:输入一张高分辨率全色图(Pan,一般是单波段灰度)、一张低分辨率多光谱图(MS,通常是RGB三波段或多于三个波段),输出一张空间细节逼近全色图、光谱信息保留多光谱特性的高分辨率彩色融合图。整个过程基于PCA(主成分分析)完成,不需要任何外部工具包,纯MATLAB代码就能实现,并且包含一套完整的客观评价指标脚本,方便你量化融合结果的质量。适合正在做遥感图像融合、毕业设计、图像增强相关任务的人参考。
1. 为什么全色图与多光谱图像需要PCA融合:先搞清楚它在解决什么问题
1.1 遥感成像的先天矛盾
传感器在设计时面临一个物理瓶颈:空间分辨率和光谱分辨率很难兼得。想看得更细(空间分辨率高),传感器接收的能量就得集中在更小的像元上,光谱通道往往就得压缩,这就是全色影像的典型特征——分辨率高,但只有单个宽波段,记录的是反射能量的总和,看起来就是灰度的。反过来,多光谱影像为了分辨不同地物的光谱特征,把能量分散到多个窄波段,每个波段获得的空间采样密度就降低了,分辨率天然受限。
所以你会发现,哪怕是最新一代高分辨率遥感卫星,通常会同时搭载高分辨率全色传感器和低分辨率多光谱传感器。全色图告诉你"地物的纹理边界在哪",多光谱图告诉你"这个地物是什么颜色、属于什么类型",两者天然互补。图像融合要做的,就是打破这个物理限制,把两张图的长处合成到一张图上。
1.2 融合方法选型:为什么选PCA而不是其他
遥感图像融合(也叫像素级融合、全色锐化)发展到现在,方法多得眼花缭乱。我最初接触时也犹豫过,到底应该用IHS变换、Brovey比值、小波变换,还是PCA。这里把几种主流方法放一起对比过,差异非常明显:
| 方法 | 核心思路 | 主要优势 | 常见问题 |
|---|---|---|---|
| IHS变换 | 将RGB转到亮度、色相、饱和度空间,用全色图替换亮度分量 | 计算简单,颜色直观 | 波段数只能3个;光谱畸变明显 |
| Brovey比值 | 各波段乘以全色图与波段和的比值 | 实现最简单,增强效果好 | 光谱失真比较严重,适用场景窄 |
| 小波变换 | 多尺度分解,低频保留光谱、高频注入全色细节 | 光谱和空间保真度平衡 | 分解层数、小波基选择需要经验 |
| PCA变换 | 多光谱做主成分分解,第一主成分替换为全色图 | 波段数不限、统计自适应、光谱畸变相对小 | 全局统计对大面积地物变化敏感 |
PCA融合的核心逻辑其实很优雅:多光谱波段之间往往高度相关,做PCA变换后,第一主成分(PC1)集中了各波段的共同信息,以空间结构和亮度为主;剩下的主成分承载了各波段特有的光谱差异信息。PC1天然适合被高分辨率全色图替换并反变换回去,因为全色图本身也是高分辨率下的亮度/空间结构表现。这个思路不受波段数限制,对不同地物统计特性还能自适应调整,在实际工程里比IHS更通用——IHS一碰到四波段多光谱就麻了,PCA完全没这个问题。
1.3 PCA融合在什么场景下值得用
不是所有图像都适合PCA融合。我实际应用的经验是,以下场景用它性价比最高:
- 遥感影像全色锐化,比如LandSat全色波段与多光谱波段融合、高分系列卫星影像处理;
- RGB图像与高分辨率灰度图的融合,比如监控场景下用红外/深度图提升RGB细节;
- 多光谱波段数大于3的情况。如果是4波段甚至更多波段,IHS基本不可用,PCA是经典选择;
- 做图像超分辨率或图像增强的前置步骤。
如果只是3波段RGB且追求极致的简单粗暴,Brovey或者IHS实现成本低一些;想要在空谱保真之间找平衡,可以考虑加小波或者Gram-Schmidt。但对于"要通用、要可解释、要波段数灵活"的需求,PCA是绕不开的经典工具。
2. PCA融合的数学原理:主成分分析在图像空间怎么用
2.1 先从协方差矩阵说起
PCA在图像融合里做的事情,本质是把多光谱图像的像元看成多维随机变量。假设一幅多光谱图像有B个波段,每个像元就是一个B维向量。我们对这个B维数据集求协方差矩阵C,它是一个B×B的对称矩阵,对角线元素是各波段的方差,非对角线元素反映了波段之间的协变关系。
然后对这个协方差矩阵做特征值分解:
C = VΛV⁻¹
其中Λ是对角矩阵,对角线是特征值λ₁ ≥ λ₂ ≥ ... ≥ λ_B,V的列就是对应的特征向量。我们把多光谱图像按特征向量做线性变换,就得到主成分空间的数据 Y = VᵀX。做这个变换的目的是去相关:原始波段之间高度相关,变换后各主成分两两不相关,而且能量(方差)按特征值大小从前往后集中。
拿三波段多光谱举例,典型情况是第一主成分能占到总方差的90%以上。也就是说,绝大多数亮度与纹理变化都汇聚到PC1上了,而PC2、PC3等主要保存了波段间的色彩差异,方差占比小得多。
2.2 为什么第一主成分可以被全色图替换
这里的想象力在于理解PC1在图像里到底是啥。回想一下,一副RGB多光谱影像里,如果你把三通道加权平均(各通道权重不同),得到的是一个跟PC1空间结构非常接近的灰度图——它是三波段的公共信息,即亮度信息。而地面物体的"色彩"信息,恰恰是波段之间的差异部分,这些分布在PC2、PC3上。
所以融合策略就顺理成章:
- 对多光谱图像各波段做PCA正变换,得到PC1、PC2...;
- 将高分辨率全色图做直方图匹配,使它PC1的均值和方差与PC1一致;
- 用匹配后的全色图替换PC1;
- 连同PC2、PC3...一起做PCA逆变换,回到RGB(或其他波段)空间,得到融合后的高分辨率多光谱图像。
之所以要先做直方图匹配再替换,是为了避免全色图与PC1的灰度范围不一致导致最终结果产生严重色偏。直方图匹配的本质是让替换进去的数据统计特性(均值和方差)与原来PC1对齐,这样逆变换后颜色不会跑偏。
2.3 这个流程在数学上等价于什么
从线性代数角度看,这个替换操作可以理解为:在PCA特征空间中,把能量最大的那个主成分(代表空间结构)用一个外部高分辨率观测数据(全色图)去更新,同时保持其他主成分不变。逆变换后得到的结果,既保持了光谱差异信息,又在空间高频细节上吸收了全色图的结构信息。
这比简单地把灰度图赋给亮度分量更"统计自适应"——PCA的变换矩阵是从多光谱数据自身统计特征算出来的,而不是固定的IHS矩阵。不同地物类型、不同光照条件的影像,耦合出来的主成分可能不同,但过程是通用的。
这种设计思想很值得品味:它不试图直接建立全色图与每个多光谱波段的映射,而是通过PCA把共同信息和差异信息分离,只替换共同信息,保留差异信息。这种"先分离、再替换"的思路,在图像融合领域贯穿了很多方法,理解了PCA,后面看Gram-Schmidt方法也会快很多。
3. MATLAB实现PCA图像融合:从数据到融合图的完整代码
3.1 数据准备:你要准备什么
我用一段真实的多光谱+全色数据来演示。为了方便复现,我一般用MATLAB自带的示例影像或自己构造一个多光谱图像再降采样模拟低分辨率。这里不使用外部下载数据集,你也可以先拿合成数据验证代码再换真实数据。
模拟数据思路:任选一张清晰RGB彩色图作为理想高分辨率多光谱图,把空间分辨率降采样(比如用imresize缩小再放大)得到低分辨率多光谱图;对RGB三通道加权求和得到高分辨率全色图。这样你知道理想的融合结果应该是什么样子,方便验证算法。
% 生成测试数据 img = imread('peppers.png'); % 任意彩色图 img = im2double(img); % 转double,统一范围 MS = imresize(img, 0.5); % 低分辨率多光谱模拟 MS = imresize(MS, [size(img,1) size(img,2)]); % 放大回原尺寸 Pan = 0.299*img(:,:,1) + 0.587*img(:,:,2) + 0.114*img(:,:,3); % 全色图模拟注意:真实场景里MS和Pan不是严格配准的,还需要做几何配准、分辨率比例换算,这里先忽略这些预处理,聚焦融合算法本身。
3.2 PCA正变换:手动实现还是用pca函数
MATLAB自带pca函数可以做PCA,但它默认对数据进行中心化,而且返回的得分、系数矩阵的方向跟传统图像处理习惯略有差异。我在这块纠结过一阵,后来发现针对图像融合,手动实现协方差矩阵和特征值分解反而更直观、更可控:
% 多光谱图像波段数 B = size(MS, 3); [Nr, Nc] = size(MS(:,:,1)); % 把MS重排成像素×波段矩阵 X = reshape(MS, [Nr*Nc, B]); % 每行一个像元,每列一个波段 % 计算协方差矩阵(矩阵减去均值) Xc = X - mean(X, 1); % 数据中心化 C = Xc' * Xc / (size(X, 1) - 1); % 协方差矩阵 % 特征值分解 [V, D] = eig(C); % 注意eig返回的特征值默认升序排列 [lambda, idx] = sort(diag(D), 'descend'); V = V(:, idx); % 正变换得到主成分(逐像元) PC = Xc * V; % 每个波段的PC图像映射到列 % 重塑成图像大小 PC_image = reshape(PC, [Nr, Nc, B]);关于eig函数有个细节:MATLAB的eig对特征值默认是升序排列的,所以必须手动排序并按顺序排特征向量列。我第一次没排序直接拿V去反变换,出来的融合图色彩完全错乱,排查了半天才发现是eig排序问题。
如果你还是习惯用pca函数,也可以这样写:
[coeff, score] = pca(reshape(MS, [], B)); % score是主成分得分 PC_image = reshape(score, [Nr, Nc, B]); % 第一通道是PC1但是注意pca的输出score已经中心化且按方差降序排列,后面替换PC1时,替换数据也必须中心化处理,否则逆变换时加回均值会出问题。手动实现的好处是每一步的加减均值看得清清楚楚,不容易踩坑。
3.3 直方图匹配与PC1替换
取第一主成分PC1,将Pan图匹配到PC1的统计特性。这里也有两种选择:一是调用MATLAB的histeq进行直方图匹配;二是直接线性拉伸,把Pan的均值和方差调整到与PC1一致。
直方图匹配更精细,它不仅能对齐均值和方差,还能把灰度直方图形状对齐。但在图像融合里,直接做二阶统计量匹配通常就够用,而且更稳定。我一般用直接归一化方案:
PC1 = PC_image(:,:,1); % 方案A:直方图匹配(使用histeq,但需要uint8) % Pan8 = im2uint8(Pan); PC1_8 = im2uint8(PC1); % Pan_matched = histeq(Pan8, imhist(PC1_8)); % Pan_matched = im2double(Pan_matched); % 方案B:均值方差匹配(推荐,简单可控) mu_PC1 = mean(PC1(:)); sigma_PC1 = std(PC1(:)); Pan_norm = (Pan - mean(Pan(:))) / std(Pan(:)) * sigma_PC1 + mu_PC1; % 替换第一主成分 PC_new = PC_image; PC_new(:,:,1) = Pan_norm;为什么推荐方案B?因为histeq期望输入是uint8等整数类型,中间涉及不少转换,而且它在灰度级合并时可能损失高频细节。方案B就是一个线性变换,计算量小,效果稳定。对于全色图和PC1的关系来说,它们的灰度分布通常都比较接近高斯或至少同分布,匹配均值和方差已经是足够强的统计约束。
3.4 PCA逆变换与输出
把替换后的主成分数组映射回像素向量域,做逆变换,注意均值要加回去:
% 逐像元逆变换 PC_new_vec = reshape(PC_new, [Nr*Nc, B]); X_fused = PC_new_vec * V'; % 回原空间(未加均值) X_fused = X_fused + mean(X, 1); % 加回多光谱均值 % 重塑并裁剪 Fused = reshape(X_fused, [Nr, Nc, B]); Fused = max(0, min(1, Fused)); % 裁剪到合法范围这里加回均值不能漏。正变换时X_centered = X - mean(X),逆变换时就必须X_recon = PC * V' + mean(X)。很多人照抄代码时容易把这一步丢掉,结果融合图整体偏暗或者偏色却不明显,其实问题就在这。
理论上,如果PC1没被替换,上面的正逆变换可以无损重建原MS。你可以先写一个自检:不做替换直接逆变换,看看与原图是否一致(应该是零误差或者浮点级误差),确认PCA管线没问题后,再加入替换步骤。这是一个非常好的自检流程。
3.5 完整融合函数封装
把所有流程封装成一个函数,方便批量处理和多组对比:
function Fused = pcaFusion(MS, Pan) % PCA图像融合核心函数 % MS: HxWxB double多光谱,Pan: HxW double全色 % 返回融合后的高分辨率多光谱图 Fused [Nr, Nc, B] = size(MS); X = reshape(MS, [], B); Xc = X - mean(X, 1); C = Xc' * Xc / (size(X,1) - 1); [V, D] = eig(C); [~, idx] = sort(diag(D), 'descend'); V = V(:, idx); PC = Xc * V; PC_image = reshape(PC, [Nr, Nc, B]); % 均值方差匹配 mu1 = mean(PC_image(:,:,1), 'all'); sd1 = std(PC_image(:,:,1), 0, 'all'); Pan_m = (Pan - mean(Pan, 'all')) / std(Pan, 0, 'all') * sd1 + mu1; PC_new = PC_image; PC_new(:,:,1) = Pan_m; X_new = reshape(PC_new, [], B); X_rec = X_new * V' + mean(X, 1); Fused = max(0, min(1, reshape(X_rec, [Nr, Nc, B]))); end注意在高版本MATLAB中,mean(A, 'all')写法更通用,低版本用mean(A(:)),我上面部分代码用前者,部分用后者,自己统一一下就好。
4. 融合效果到底好不好:评价指标的计算与解读
4.1 为什么必须客观评价
人类的视觉系统很容易被"看起来更清楚"欺骗。融合图多了纹理细节,整体更锐利,肉眼看着舒服,但这不代表融合结果好——颜色完全失真、光谱信息严重畸变的图也可以很"锐利"。做科研、做毕业设计、做工程验收,都必须有数字化的客观评价指标。这也是这个项目标题里专门带了"含评价指标"的原因:没有指标,融合算法撑不起说服力。
评价指标分成两大类:空间质量与光谱质量。空间质量衡量融合图保留了多少全色图的高频细节;光谱质量衡量融合图与原始多光谱图的色彩/光谱一致性。两类指标经常互相制约,理想融合算法希望两者都高,实际总有trade-off,所以一般成对报出来。
4.2 空间质量指标
空间质量指标中,最常用的是平均梯度、空间频率、标准差这几个。
平均梯度反映图像中微小细节的反差变化率,可以理解为图像清晰程度:
function grad = avgGradient(img) if size(img,3) > 1 img = rgb2gray(img); % 多波段可以先转灰度 end [dx, dy] = gradient(img); grad = mean(sqrt(dx(:).^2 + dy(:).^2)); end平均梯度越大,表示边缘越清晰、纹理越丰富。但注意,梯度变大也可能是噪声被放大,所以不能只看这一项,要结合光谱指标判断。
空间频率是另一个常用指标,它把图像的行频率和列频率结合:
function sf = spatialFreq(img) if size(img,3) > 1 img = rgb2gray(img); end RF = diff(img, 1, 2); % 行向差分 CF = diff(img, 1, 1); % 列向差分 RF = sqrt(mean(RF(:).^2)); CF = sqrt(mean(CF(:).^2)); sf = sqrt(RF^2 + CF^2); end空间频率越大,同样表明高频信息越丰富。
4.3 光谱质量指标
光谱质量指标最经典的是相关系数(CC)、RMSE和光谱角(SAM)。
相关系数计算融合图每个波段与原多光谱对应波段的线性相关程度:
function cc = correlationCoeff(A, B) for b = 1:size(A,3) a = A(:,:,b); bb = B(:,:,b); cc_b = corr2(a, bb); cc(b) = cc_b; end cc = mean(cc); endCC的范围在0到1之间,越接近1说明融合图在波段上的灰度分布趋势与原多光谱越一致,光谱保真度越好。
RMSE则是逐像元计算误差:
function rmse = calcRMSE(A, B) diff_ = A - B; rmse = sqrt(mean(diff_(:).^2)); endRMSE越小越好,过大说明融合图与原多光谱产生了显著偏离,往往是光谱畸变的信号。
光谱角映射SAM计算每个像元的光谱向量夹角,能更准确地度量光谱形状的变化:
function sam = spectralAngleMap(A, B) Nr = size(A,1); Nc = size(A,2); Bn = size(A,3); A = reshape(A, [], Bn); B = reshape(B, [], Bn); dotp = sum(A .* B, 2); normA = sqrt(sum(A.^2, 2)); normB = sqrt(sum(B.^2, 2)); cosv = dotp ./ max(normA .* normB, eps); sam = acosd(clamp(cosv, -1, 1)); % 角度,单位度 sam = reshape(sam, Nr, Nc); sam = mean(sam(:)); % 平均光谱角 endSAM以度为度量,越小越好,一般小于10度都算不错。SAM对光谱形状差异敏感,能抓住"颜色变了但整体亮度没变"这类RMSE不一定抓得到的问题。
4.4 信息量指标:熵与交叉熵
熵反映图像携带信息量的多少,融合图熵如果明显大于原MS,往往说明注入了纹理细节;但如果大到不合理,也可能是噪声被放大:
function ent = imageEntropy(img) if size(img,3) > 1 img = rgb2gray(img); end img = im2uint8(mat2gray(img)); counts = imhist(img); p = counts / sum(counts); p(p == 0) = []; ent = -sum(p .* log2(p)); end交叉熵可以衡量融合图与参考图之间的信息差异,越小代表信息分布越接近。不过这个指标用的相对少一些,常用的还是熵、平均梯度、相关系数、RMSE、SAM的组合。
4.5 构建你的评价脚本
建议把上面指标封装成一个函数,一次跑完输出所有结果,类似这样:
function metrics = evaluateFusion(Fused, MS, Pan) metrics.avgGrad = avgGradient(Fused); metrics.sfreq = spatialFreq(Fused); metrics.entropy = imageEntropy(Fused); metrics.cc = correlationCoeff(Fused, imresize(MS, size(Fused(:,:,1)))); metrics.rmse = calcRMSE(Fused, imresize(MS, size(Fused(:,:,1)))); metrics.samDeg = spectralAngleMap(Fused, imresize(MS, size(Fused(:,:,1)))); fprintf('平均梯度: %.4f\n', metrics.avgGrad); fprintf('空间频率: %.4f\n', metrics.sfreq); fprintf('信息熵 : %.4f\n', metrics.entropy); fprintf('相关系数: %.4f\n', metrics.cc); fprintf('RMSE : %.4f\n', metrics.rmse); fprintf('SAM(°) : %.4f\n', metrics.samDeg); end注意一个重要的细节:计算光谱指标时,原多光谱图是低分辨率的,融合图是高分辨率的,两者尺寸不一致。我在项目里通常把低分辨率MS先上采样到融合图分辨率,再计算指标,这样指标反映的是"融合方法把MS上采样后与融合图之间的光谱保真度",虽然不完美但已经是工程上最常用的做法。如果数据有原始真实高分辨率参考图,就用参考图替代MS来计算RMSE、SAM等,那会更有说服力。
5. PCA融合的实战经验:直方图匹配、符号翻转与细节优化
5.1 踩坑实录:特征向量符号翻转导致的色偏
这大概是PCA图像融合里最隐蔽的坑。特征值分解得到的特征向量,方向是不确定的:V的某一列跟它的相反数-V是等价的,都满足特征方程。这在数学上完全没问题,但应用在图像重建里就出大事了——如果某个特征向量的符号翻转了,对应主成分在逆变换时会反相,融合图的色彩分布会与原始图像发生严重偏离,可能出现某个波段反色、整体色调诡异的情况。
手动实现eig时,这个问题完全看运气。我遇到过一次,融合出来的植被区域变成了紫色,百思不得其解。后来加了自检:对PC1替换前的正逆变换做重建测试,结果重建图跟原图完全一致(因为正逆变换抵消了),但一旦替换PC1,符号问题就暴露出来了。
解决办法有两种:一是用pca函数(它返回的coeff方向是确定的,内部做了标准处理);二是在手动实现后对特征向量的符号做规整,比如规定每个特征向量的第一个非零元素为正。我自己写了一套符号规整逻辑,放在特征值分解之后:
% 规整特征向量方向,保证每个特征向量第一个元素非负 for k = 1:size(V,2) [~, maxIdx] = max(abs(V(:,k))); if V(maxIdx, k) < 0 V(:,k) = -V(:,k); end end这个坑不踩一次真的很难意识到。我建议你在做PCA融合时,无论如何都要加这个符号规整,或者至少加重建自检,不然后果是随机性的色偏,很难排查。
5.2 直方图匹配顺序与波段范围
前面我推荐了均值方差匹配,但有一种情况需要回到直方图匹配:当全色图的灰度分布和PC1差异很大时,例如Pan的对比度特别高或者存在明显的非均匀亮度,线性匹配可能保留不了足够好的细节,这时用直方图匹配能更好地把Pan的灰度分布对齐到PC1。
关键点在于:直方图匹配是让Pan去适应PC1,而不是反过来。如果方向反了,融合后的图像会丢失多光谱原来的整体色调风格。我在做高分二号数据时对比过正反两种方案,方向反了的结果,虽然空间细节依然好,但整体亮度明显偏向Pan,看起来像黑白图上蒙了一层彩色,非常不自然。
另外,如果多光谱有4个波段以上,直方图匹配需要针对每个主成分、或者专门的整个主成分空间做匹配,不能只做PC1。我这边通常的做法是,其他主成分(PC2、PC3等)不做任何匹配,保持原始值,只处理PC1。如果后续发现色彩平衡有问题,再考虑对其他主成分做轻度的直方图调整,但幅度要很小。
5.3 融合结果的灰度范围裁剪
在逆变换后,PC_new可能包含全色图的极端值,导致逆变换后的像素值超出[0,1]范围。我在3.4里已经写了裁剪逻辑。但这里还有一个小优化:直接裁剪会产生轻度信息损失,也容易让大面积高亮区域出现平顶效应(color clipping)。
我实测中遇到过两种情况:一种是PC1里有一小部分像素值非常大,导致融合图天空区域出现一片白色;另一种是PC1比较暗,融合图整体偏暗,裁剪后暗部细节丢了不少。前者我改用更温和的百分位裁剪,比如把PC1的上下1%的像素值压缩到范围内的最大值和最小值,减少极端值影响;后者则在直方图匹配阶段把Pan的均值稍微提高一点,让整体亮度更接近原MS的平均亮度。
说到底,灰度范围处理要因图而异,建议你在融合完成后,先在屏幕上对比原MS和融合图的直方图分布,如果整体偏移明显,再回头调整匹配参数。
5.4 预处理与后处理:配准和锐化
真实数据不会像模拟数据那样像素级对齐。全色图和多光谱图来自不同传感器,空间位置、分辨率、视角都存在差异,融合前必须有严格的几何配准,否则边缘会出现"重影"和"青色溢出"现象。在项目里我一般先用MATLAB的imregister或者地理信息软件做配准,再检查控制点残差,确保大部分区域误差在一个像元以内,才进入融合流程。
另外,PCA融合后的图像偶尔会显得有点"肉",比如边缘过渡过于平滑。一个常用的后处理技巧是:把Pan的高通滤波细节(用imgaussfilt做高斯滤波后与原图相减得到)按一定权重加到融合结果上。这么做可以在不显著增加光谱畸变的前提下增强边缘清晰度。不过这是锦上添花,核心融合流程跑通并验证指标之前,不必急着做这一步。
5.5 波段数大于3时的实操注意事项
当多光谱波段数B大于3时,PCA融合流程完全不变,但有两个额外的坑。第一个是均值恢复问题:X_c = X - mean(X,1)这一行,mean(X,1)计算的是每个波段在全图上的均值,如果某个波段整体偏暗,这个均值会对达到逆变换的加回过程很重要,不能省略。二是波段间量纲差异:如果某个波段数值范围与其他波段差异很大(比如有的波段是反射率0~1,有的是表观亮度0~100),协方差矩阵会被大数值波段主导,PCA变换退化到几乎等价于那个波段的原始灰度。这时我会做标准归一化,把每个波段除以其标准差,再做PCA,融合后按照逆操作还原。
还有一个工程小技巧:当B很大时,协方差矩阵可能接近奇异,eig仍能给出结果,但数值稳定性下降。可以用[V,D] = eig(C,'vector')避免构造整个对角阵,或者用svd对数据矩阵分解,会更稳定。不过对常规4~8波段的遥感数据,直接用eig已经足够。
5.6 结果图的对比与可视化
融合完一定要有意识地对比,不要只看融合图本身。我会把原MS(上采样到融合尺寸)、Pan、融合图三幅图并排显示,同时展示同名区域的放大细节。这样可以快速看出:融合图的纹理是否和Pan一致,颜色是否和MS一致,有没有出现局部色斑、边缘重影等问题。同时也把各评价指标打印出来,空间质量指标和光谱质量指标对照着看,如果出现"平均梯度很高但相关系数很低"的情况,就要警觉是不是光谱畸变了。
实际操作中,我还习惯把PCA融合和一些其他方法(比如直接上采样、IHS、小波)的输出放在一起跑一遍指标,这样就能清楚看到PCA在哪个维度上占优,哪个维度上可能弱一些。有时候结果未必每项都最好,但PCA融合胜在流程稳定、代码简单、波段数灵活,适合作为项目基线或者批量融合的默认算法。
这些经验都来自我反复做实验时踩过的坑。尤其是特征向量符号那一次,我花了一晚上在颜色映射和逆变换代码之间反复排查,最后通过自检才发现是eig的符号方向问题。从那以后,我的PCA融合代码里永远带着符号规整这一步。也希望这篇把原理到指标完整捋清楚的文章,能让你少走这些弯路,一次跑出干净可靠的融合结果。