PCA 图像融合 matlab+ python

可能存在错误内容 但是程序能通

可以从AI earth 网站下载不同波段的遥感图像数据(遥感图很大)
图像格式为tif 上传不了 用于融合的两张图像
在这里插入图片描述

RGB图像与灰度图像的PCA图像融合

% RGB图像与灰度图像的PCA图像融合,RGB得到通过PCA降维后三维数据,和灰度图像得到通过PCA降维后单维数据,然后直接进行替换,通过PCA逆变换(特征向量求逆后重构原矩阵)得到融合后的数据,有采用直方图配准的没有直接替换,不过估计直方图配准可以解决数据不同维度之间的问题,进行补数据
clear
clc
close all
img1 = double(imread('bldr_tm_6.tif'))/255; %归一化
img1=imresize(img1,[512,512]);% 设定图像大小
img3 = img1;
img2 = double(rgb2gray(imread('bldr_sp_1.tif')))/255;%全色图像 单光谱的 应当是单通道 但是由于图像读取图像是RGB三色 所以要转灰度
img2=imresize(img2,[512,512]);% 设定图像大小 保证两个图像降维后数据长度一致
figure;
% subplot(2,2,1);
imshow(img1,[]);title('多光谱图像');
figure;
% subplot(2,2,2);
imshow(img2,[]);title('全色光谱图像');

% PCA 过程 ,将各通道数据转为单维数据
[s1,s2,s3] = size(img1);
img1 = reshape(img1,[s1*s2,s3]); % s1*s2为图像长*宽 s3图像通道个数 重组成具有图像长*宽 长度的三个单维数据
% 零均值化(标准化) 这里标准化之后 数据会丢失
% ming = mean(img1);
% for i = 1:s3
% img1(:,i) = img1(:,i)-ming(:,i);% mean(img1)计算 img1三维度的均值
% end

% 求算协方差矩阵 由于上述已经减去过均值了 所以直接 各个变量与其他维度对应位置变量相乘 累加后的值 除以 单维变量总个数(图像像素个数) 就是 协方差矩阵
% covimg = (img1'*img1)/(s1*s2);% 两个矩阵的乘法 就是 各个变量与其他维度对应位置变量相乘 累加后的值,所以除以图像像素个数(size(img1,1)*size(img1,2))
covimg1 = sqrt((img1'*img1)/(s1*s2));% 开不开根号没区别
% 获取协方差矩阵特征值和特征向量
[V,D]=eig(covimg1);%[V,D] = eig(A) 返回特征值的对角矩阵 D 和特征向量矩阵 V,其列是对应的右特征向量,使得 A*V = V*D[d,ind] = sort(diag(D));%diag(D)D 的对角线上提取特征值,然后按升序对得到的向量进行排序。sort 的第二个输出返回索引的置换向量。
Ds = D(ind,ind);%mathwork里面eig()函数使用有说明
Vs = V(:,ind);
% 获取各数据在所有成分上投影结果
for i =1 :s3
    img1vs(:,i) = img1*Vs(:,i);%将img1 所有 通道 的数据 投影到第 i 个主成分坐标轴上,其中i越大 对应主成分坐标的特征值越大,且 PCA逆变换为:img1vs(:,1)*Vs(:,i)= img1 然后将所有的叠加即可还原
end

figure;
plot(img1vs(:,1),'.');
hold on 
plot(img1vs(:,2),'.');
hold on 
plot(img1vs(:,3),'.');
title('多光谱主成分降维数据')
legend(['第三主成分降维数据' ;'第二主成分降维数据' ;'第一主成分降维数据'])
% 获取 全色光谱的主成分数据 
% 由于全色光谱数据为单通道数据 一维度数据主成分是否为其本身(暂不确定,所以还是直接求一次)
[z1,z2] = size(img2);
img2 = reshape(img2,[z1*z2,1]); % s1*s2为图像长*宽 s3图像通道个数
covimg2 = sqrt((img2'*img2)/(z1*z2));
[V2,D2]=eig(covimg2);%[V,D] = eig(A) 返回特征值的对角矩阵 D 和矩阵 V,其列是对应的右特征向量,使得 A*V = V*D[d2,ind2] = sort(diag(D2));%diag(D)D 的对角线上提取特征值,然后按升序对得到的向量进行排序。sort 的第二个输出返回索引的置换向量。
Ds2 = D2(ind2,ind2);%mathwork里面eig()函数使用有说明
Vs2 = V2(:,ind2);
img2vs = img2*Vs2;
figure;
plot(img2vs,'.');title('全色光谱降维数据')
% % 图像融合 就是将两个图像对应的主成分 数据进行替换 会有多种组合 此处选择第一主成分的数据进行替换
% 替换主成分数据 能实现图像融合 是因为主成分中包含了 色彩之间的差异信息 (PCA降维后保留数据之间的相对关系)
% 所以进行替换后能够提高色彩差异,并能够保留自身 的一些色彩差异
% PCA逆变换,将 替换后的主成分数据 进行 还原成图像 完成图像融合

n=3;
temp = img1vs(:,n); % n 表示要多光谱图像中要被替换的第n主成分 由于排序了 所以n越大对应的特征向量越大
img1vs(:,n) =0.3* img1vs(:,n) + 0.7*img2vs;% 0.30.7为权重系数

% subplot(2,2,3)
figure
imshow(reshape((img1vs)*(Vs'),[s1,s2,s3]),[]);title(['全色光谱降维数据 替换多光谱第 ' num2str(s3-n+1) ' 主成分数据']);% 由于n为升序 而第1主成分为最大,所以s3-n+1变一下
% subplot(2,2,4)
figure
imshow(reshape(temp*Vs2',[z1,z2]),[]);title([' 多光谱第 ' num2str(s3-n+1) ' 主成分数据 替换 全色光谱降维数据']);

% 被替换后的多光谱降维数据
figure;
plot(img1vs(:,1),'.');
hold on 
plot(img1vs(:,2),'.');
hold on 
plot(img1vs(:,3),'.');
title('替换后的多光谱主成分降维数据')
legend(['第三主成分降维数据' ;'第二主成分降维数据' ;'第一主成分降维数据'])

%%
% % 第一主成分提取得到色彩差异信息图像,
close all
img1vs1 = img1*Vs(:,end);
img1re1 = reshape(img1vs1,[s1,s2]);
% subplot(2,2,3);imshow(img1re1,[]);title('多光谱图像第一主成分投影结果图像');%是把多光谱中的色彩进行降维投影,第一主成分投影位置保留了最大色彩差异信息.

% %  第一主成分提取得到色彩差异信息图像,与 多光谱图像对应灰度图像的 差异
img1gray = rgb2gray(img3);
figure;
subplot(1,3,1);imshow(img1re1,[]);title('多光谱图像第一主成分投影结果图像');
subplot(1,3,2);imshow(img1gray,[]);title('多光谱图像的灰度图像')
sum(sum(abs(img1gray-img1re1)))%计算 多光谱图像的灰度图像 与 多光谱图像第一主成分投影结果图像之间的 差值 
subplot(1,3,3);
imshow(abs(img1gray-img1re1),[])% 显示 多光谱图像的灰度图像 与 多光谱图像第一主成分投影结果图像之间的 差值图像 (加了绝对值)
title('两者差异');

% %  最小特征值对应主成分提取得到色彩差异信息图像,及其与第一主成分提取得到色彩差异信息图像, 的差异
img1vs2 = img1*Vs(:,1);%最小特征值对应 主成分提取得到色彩差异信息图像 肯定是一个模糊图像
img1re2 = reshape(img1vs2,[s1,s2]);
figure;
sum(sum(abs(img1re2-img1re1)))
subplot(1,3,1);imshow(img1re1 ,[]);title('多光谱图像第一主成分投影结果图像')
subplot(1,3,2);imshow(img1re2 ,[]);title('多光谱图像最小特征值对应主成分投影结果图像')
subplot(1,3,3);imshow(abs(img1re1-img1re2) ,[]);title('两者差异图像')

%  所有主成分的投影结果
% img1vs = img1*Vs;
% img1re = reshape(img1vs,[s1,s2,s3]);
% figure;imshow(img1re,[]);title('多光谱图像所有主成分投影结果图像');%保留了所有色彩差异信息.一个投影维度(主成分)表示一个色彩差异信息分布,那这多个投影结果叠加好像没啥意义

% pca(img1);
% 
figure;
imshow(reshape(img1,[s1,s2,s3]),[])
figure;
img1vs3 = img1vs1*V(:,end)';
img1vs3 = reshape(img1vs3,[s1,s2,s3]);
imshow(img1vs3,[])

在这里插入图片描述

RGB1 和 RGB2图像融合

% RGB1RGB2 分别重组成两个一维数据,2维数据放一起降维后
% 选取第一主成分投影数据作为图像融合结果 

clear
clc
close all
img2 = imread('bldr_tm_6.tif');
img1 = (imread('bldr_sp_1.tif'));
a = size(img1);
if ~isequal(size(img1), size(img2))
    img2 = imresize3(img2, [a(1) a(2) a(3)]);
end

% Concatenate the two images into a single matrix
img = [1.3*img2(:) img1(:)]; % 1.3 为参数 调整两个图像之间的权重
% Perform PCA on the image matrix

%这个不归一化 会失真严重 
[coeff, score, latent] = pca(double(img)./255);

% Create the fused image by taking the first principal component
fused_img = reshape(score(:, 1), size(img1));

% Display the fused image
figure;
subplot(1,3,1)
imshow(fused_img, []);title('融合图像')
subplot(1,3,2)
imshow(img1, []);title('img1')
subplot(1,3,3)
imshow(img2, []);title('img2')

在这里插入图片描述

% RGB1RGB2 组成一个6维数据,6维放一起降维后
% 选取第一主成分投影数据作为图像融合结果 
clear
clc
close all
% 这个归一化和不归一化 没看出区别 不知道是不是因为是灰度图像 差异不大,而且在这归一化才行

img2 = double(imread('bldr_tm_6.tif'))./255;
img1 = double(imread('bldr_sp_1.tif'))./255;

% Resize the images to the same size if they have different dimensions
if ~isequal(size(img1), size(img2))
    img2 = imresize3(img2, size(img1));
end



% Concatenate the three images into a single matrix
[m,n,c]=size(img1);
img = cat(3, 0.8*img1, img2);% 0.8 为参数 调整两个图像之间的权重
img = reshape(img,[m*n,6]);

[coeff, score, latent] = pca(double(img));

figure;
for i=1:6
    subplot(2,3,i)
    imshow(reshape(score(:,i), [m,n]), []);title(['第' num2str(i) ' 主成分数据成像结果']);
end

figure;
imshow(img1, []);title('img1')
figure;
imshow(img2, []);title('img2')

在这里插入图片描述

补上python 版 (matlab 自带配准方法不好用 )


import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

img1 = cv.cvtColor(cv.imread('2.tif'),cv.COLOR_BGR2RGB)  # 多光谱 RGB 
img2 = cv.cvtColor(cv.imread('1.tif'),cv.COLOR_BGR2RGB)  # 全色光谱 读出来也是RGB 
plt.figure(figsize=([10,10]))
plt.imshow(img2) # 显示全色 图像 
plt.show()

在这里插入图片描述

# sift 图像配准 
sift_detector = cv.SIFT_create()
# Find the keypoints and descriptors with SIFT
kp1, des1 = sift_detector.detectAndCompute(img1, None)
kp2, des2 = sift_detector.detectAndCompute(img2, None)
# BFMatcher with default params
bf = cv.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
# Filter out poor matches
good_matches = []
for m,n in matches:
    if m.distance < 0.89*n.distance:
        good_matches.append(m)
matches = good_matches
points1 = np.zeros((len(matches), 2), dtype=np.float32)
points2 = np.zeros((len(matches), 2), dtype=np.float32)
for i, match in enumerate(matches):
    points1[i, :] = kp1[match.queryIdx].pt
    points2[i, :] = kp2[match.trainIdx].pt
# Find homography
H, mask = cv.findHomography(points1, points2, cv.RANSAC)
# Warp image 1 to align with image 2
img1Reg = cv.warpPerspective(img1, H, (img2.shape[1], img2.shape[0]))
# cv.imwrite('aligned_img1.jpg', img1Reg)#可以用于保存配准后的图像 
# The problem is that this matrix H is found via a compute-intensive optimization process
plt.figure(figsize=([10,10]))
plt.imshow(img1Reg)# 显示配准后的图像
plt.show()

在这里插入图片描述

from sklearn.decomposition import PCA  # 加载PCA算法包
img3 = np.reshape(img1Reg,( img1Reg.shape[0]*img1Reg.shape[1],3)) # 用np.reshape 重组 多光谱数据为RGB 转为 二维数据,第二维为3 
img4 = cv.cvtColor(img2,cv.COLOR_RGB2GRAY)  # 全色图转灰度
img4 = np.reshape(img4,(img4.shape[0]*img4.shape[1],1)) # 用np.reshape 重组 全色光谱数据为 二维数据,第二维为1
plt.figure(figsize=([10,10]))
plt.imshow(np.reshape(img5[:,0],(1390,1071)),'gray') #将多光谱数据为RGB 转为 二维数据,中的第一维数据转成图像
# plt.imshow(np.reshape(img4[:,0],(1390,1071)),'gray')
plt.show()

在这里插入图片描述

pca1 = PCA(n_components=3)  # 加载PCA算法,设置降维后主成分数目为3
reduced_x1 = pca1.fit_transform(img3)  # 对多光谱进行降维
pca2 = PCA(n_components=1)  # 加载PCA算法,设置降维后主成分数目为1
reduced_x2 = pca2.fit_transform(img4)  # 对全色进行降维

reduced_x1[:,0] = reduced_x2[:,0] + 1*reduced_x1[:,0] # 用全色降维数据 加权替换 多光谱降维数据  其中多光谱降维数据的0表示第一主成分数据 

reduced_x = np.dot(reduced_x1, pca1.components_) + pca1.mean_  # 还原数据,得到融合后的数据
reduced= np.reshape(reduced_x,(img2.shape[0],img2.shape[1],img2.shape[2]))# 重组融合后的数据成图像

plt.figure(figsize=([10,10]))
plt.imshow(np. uint8(reduced),'gray')# 显示重组融合后的图像
# plt.imshow(np.reshape(img4[:,0],(1390,1071)),'gray')
plt.show()

在这里插入图片描述

plt.figure(figsize=([10,10]))
plt.subplot(1,2,1)
plt.imshow(img1Reg,'gray')
plt.subplot(1,2,2)
plt.imshow(img2,'gray')
plt.show()

在这里插入图片描述

  • 4
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值