提取PCA变换后的图像的各主成分(matlab代码)

参考:
https://blog.csdn.net/duanyule_cqu/article/details/54975867
该篇文章主要是使用PCA对一幅图像进行处理,并提取和显示该图像经过PCA的变换后的各主成分。
这里就直接贴代码,PCA原理的部分相信大家都看了许多,其实看来看去,不去实践一个具体的目的,总还有些概念不是很清楚的。

PCA对图像处理的特点

*疑问:
经过PCA变换排在前面的主成分就一定没有噪声吗?
我觉得是不一定的。也就是说排在前面的主成分未必很“纯”。
通过PCA变换,可以把多波段图像中的有用信息集中到数量尽可能少的新的主成分图像中,并使这些主成分图像之间互不相关,从而大大减少总的数据量。但PCA变换对噪声比较敏感,即信息量大的主成分分量,信噪比(信号与噪声的比)不一定高,当某个信息量大的主成分中包含的噪声的方差大于信号的方差时,该主成分分量形成的图像质量就差, PCA变换用于融合处理并不是为了减少噪声,而是通过该变换,使得多光谱影像在各个波段具有统计独立性,即这些波段间的数据互不相关,便于分别采用相应的融合策略。

提取并显示PCA 的各主成分

主代码

>> mul = imread('PCA/low.jpg');
>> extract_pca(mul);

实现 PCA的代码

function [vector ,value,tempMul] = my_pca(mul)
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
% % % 该函数用来实现多光谱图像的PCA算法
% % %    param:
% % %          mul--输入的多光谱图像也可以是多通道的
% % %          value--特征值从大到小排列
% % %          vector--特征向量对应特征值排列,一列是一个特征向量
% % %          tempMul--mul的reshape成pixels*bands形式的2维矩阵
% % % 
% % %  @author:chaolei
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
mul=double(mul)/255;
[r ,c ,bands]=size(mul);
pixels = r*c;
% reshape成pixels*channel
mul = reshape(mul, [pixels,bands]);
tempMul = mul;
% 求各通道的均值
meanValue =  mean(mul,1);

% 数据去中心化
mul = mul - repmat(meanValue,[r*c,1]);
% 求协方差矩阵
correlation = (mul'*mul)/pixels;
%求特征向量与特征值
[vector ,value] = eig(correlation);
% 特征值和特征向量从大到小排序
vector = fliplr(vector);
value = fliplr(value);
value = flipud(value);

end

提取并显示PCA的各主成分

function extract_pca(mul)
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
% % % 该函数用来抽取并显示pca的各个主成分
% % %   param:
% % %       mul--输入图像是多光谱图像或者高光谱图像
% % %  @author:chaolei
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
[r,c,bands]=size(mul);
[vector,~,tempMul]= my_pca(mul);
% Y=AX(X中列为样本,若X行为样本,则Y =XA)
% PCA正变换
PC = tempMul*vector; 
% 提取多光谱图像的各个主成分
for i = 1:bands
    outPic = PC(:,i);
    min_value = min(outPic);
    max_value = max(outPic);
    outPic = reshape(outPic,[r,c]);
    figure;
    str = sprintf('%s%d%s','第',i,'主成分');
    imshow(outPic,[min_value,max_value]);title(str);
%     filename = sprintf('%d%s',i,'.jpg');
%     imwrite(outPic,filename);
end
end

结果

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

实现PCA进行压缩

原本这一小节不想写的,可是觉得自己对用PCA进行压缩一直不清楚。所以还是要赘述一下,写一点代码。从上面的分析中可以看出,由于我输入的图像是3通道的,也即只有3个特征,所以只有3个主成分。
那我们要思考的是如何进行图像压缩?针对这个实例,以前理解的误区在于,即使我选取了2个或者1个主成分,可是我PCA逆变换回去的图像仍是和原始图像一样的尺寸。那这怎么叫压缩呢?
后来帮大金明实现提取PCA的主成分的过程中,理解了这个PCA压缩的概念。假设我们选取其中最前面的2个主成分。从图中可以看出这2个主成分已经包括了大部分的信息。那么我们的PCA压缩实现的就是存储这2个主成分,并且存储2个主成分对应的特征向量。这样算起来其实我们大约少存储了原图像一个通道的数据。也就是实现了压缩。下面贴一下代码。

function  pca_comp_show(mul,n)
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
% % % 该函数用来显示经过PCA压缩后的图像
% % %  param:
% % %     mul--输入的多光谱或者高光谱图像  
% % %     n--指定用多少个主成分
% % % @author:chaolei
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
[vector ,value,tempMul] = my_pca(mul);
% 使用其中最重要的n个主成分,并还原到原图像大小
% PCA逆变换
% 原始数据reshape*特征向量矩阵*特征向量矩阵'
re = tempMul*vector(:,1:n)*vector(:,1:n)';
[r,c,bands] =size(mul);
comp = reshape(re,[r,c,bands]);

str =sprintf('%d%s',n,'个主成分');
figure;imshow(comp);title(str);
end

这里写图片描述

猜你喜欢

转载自blog.csdn.net/chaolei3/article/details/79775937
今日推荐