提取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

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章