基于PCA-WA(Principal Component Analysis-weight average)的图像融合方法 Matlab代码及示例

摘要:

        高效地将多通道的图像数据压缩(如高光谱、多光谱成像数据)至较低的通道数,对提高深度学习(DL)模型的训练速度和预测至关重要。本文主要展示利用PCA降维结合weight-average的图像融合方法。文章主要参考了题为“Noninvasive Detection of Salt Stress in Cotton Seedlings by Combining Multicolor Fluorescence–Multispectral Reflectance Imaging with EfficientNet-OB2”在论文中使用的方法。

论文源:Noninvasive Detection of Salt Stress in Cotton Seedlinmbining Multicolor Fluorescence–Multispectral Reflectance Imaging with EfficientNet-OB2 | Plant Phenomics (science.org)

PCA-WA简介:

PCA-WA(主成分分析-加权平均)是一种图像融合方法,结合了主成分分析(PCA,principal component analysis)和加权平均(WA,weight average)两种技术。

优点:

  1. 保留主要信息:通过PCA方法,可以提取出源图像中的主要成分,即包含最多信息的特征。这有助于在融合过程中保留关键信息,使得融合后的图像在保留重要特征方面表现较好。
  2. 降低维度:PCA方法可以将高维数据降维,从而减少计算量和存储需求。这在处理大规模图像数据时尤为重要,可以加快处理速度和节省存储空间。

缺点:

  1. 对源图像质量敏感:PCA-WA方法的性能在很大程度上取决于源图像的质量。如果源图像存在噪声、模糊或对比度低等问题,那么融合后的图像质量可能会受到影响。
  2. 可能产生光谱失真:在使用PCA进行降维时,可能会丢失一些光谱信息。这可能导致融合后的图像在光谱特性上与源图像存在差异,从而产生光谱失真现象。

注意事项

数据预处理:在进行数据融合之前需要将数据进行对应的校正,避免后续噪声污染

输入数据:为M*N*C的double矩阵也就是校正后的图像浮点数值。需要事先将这些变量存储为.mat文件。储存变量命为a

操作示范

首先是输入的文件:如图,PCA需要所有处理的样本信息,所以按照格式将所有样本整理好

单个样本的信息如图:我测试的数据是自己采集的4K分辨率且有14个通道的多源光谱数据,变量统一为a,其中几个未融合的通道的图像可以展示如下

 使用PCA-WA算法进行图像融合后,生成的图像会存放至预设的文件夹中

融合后的数据,前三个主成分占95%的贡献率,所以融合后为3个主成分通道。手动将这些数据归一化映射至uint8(0-255)展示如下:融合后数据量得到了充分的压缩。

代码

主脚本代码FusionProject

clear all获得PCA-WA融合的数据
WA图像融合,全称为Weighted Averaging图像融合,
也叫简单加权融合或者像素加权平均法,是一种图像融合方法。
这种方法的基本思想是将多源信道采集到的关于同一目标的图像
数据经过处理和计算,将各自信道中的有利信息提取出来,然后综合成
一幅高质量的图像。在具体实现时,WA图像融合通过对来自不同图像的对应像素进行加权平均,
以得到融合后图像中的每个像素值。这种方法具有简单易实现、运算速度快
的优点,并能提高融合图像的信噪比。然而,它也存在一些缺点,比如可能
会削弱图像中的细节信息,降低图像的对比度,并在一定程度上使图像中的
边缘变得模糊。为了改进这些缺点,可以采用一些优化方法,
如主成分分析(Principal Component Analysis,PCA)来优化权值的选择,
从而得到一幅亮度方差最大的融合图像。%输入部分(根据自己的需求修改这部分内容)%要处理文件所在的文件夹
% (多个文件夹则输入多个文件夹,要包含所有样本,PCA计算才准确),样本变量名均为a
% 注意地址要单引号标志
DealPath{1}='F:\Test\A';
DealPath{2}='F:\Test\B';%处理好的文件输出位置,对应你输入文件的数量
OutputPath{1}='C:\Users\ljy\Desktop\Test1\A';
OutputPath{2}='C:\Users\ljy\Desktop\Test1\B';%%图片的基本信息
%通道数
ChannelNum=14;
%红色荧光(F740)所在的通道
fluo_CNum=4;
%图像输出的分辨率
outputReso=[300 400];orinPath=cd();
%%这一过程可能很漫长,运行时间主要取决于你的样本量、数据大小、CPU性能及硬盘速度。
%%1000个样本跑一个小时以上是正常的%%阶段1:获取数据的通道均值
fileNum=length(DealPath);
allData=[];
%启用红色荧光分割图像,(如果前期工作已经校正及图像分割了,请关闭)
% 其他数据把分割关掉(1改为0)
for i=1:fileNumallData=[allData;AverageChannelData(DealPath{i},ChannelNum,[0,fluo_CNum])];
end%阶段二:PCA分析%归一化
[ynum,~]=size(allData);
stdr =std(allData); %计算标准差,计算每一列的标准差
averageD=mean(allData,1);for i=1:ynumdata2(i,:)=allData(i,:)-averageD(1,:);
end
%sr是预处理后的数据,使原始数据每个参数除于其标准差
sr =data2./repmat(stdr,size(allData,1),1);%% PCA%获取主成分系数
[coeff,~,~,~,explained,~]= pca(sr);%分析占 95% 解释性的主成分
for i=1:ChannelNumif sum(explained(1:i))>95numP=ibreakend
end%阶段3融合图像
for i=1:fileNumsrcDir=dir(DealPath{i}); %获得选择的文件夹[numFile,~]=size(srcDir);for j=3 :numFilenames_Fir=srcDir(j).('name');newfile_Fir=[DealPath{i},'\',names_Fir];%数据文件名load(newfile_Fir);%图像归一化for cn=1:numPNora(:,:,cn)=(a(:,:,cn)-averageD(cn))./stdr(cn);end%融合FusionPic=imresize(FusionPic_WA_PCA(Nora,coeff),outputReso);cd(OutputPath{i});save(names_Fir,"FusionPic");%储存cd(orinPath);end
end

附带自定义函数

T_SGM
%阈值分割函数,获得分割的蒙版%输入:img:图像(灰度图像)  
% ThresH:阈值
% (为0时为二值化分割,为1时为迭代法全局阈值分割,为2时为全局阈值Otsu法阈值分割,三为基于形态学元素的局部分割,4为指定阈值分割)
%pluse:补充数据,当ThresH为3时,pluse表示形态学的元素的半径,其值越大,分割区域越大,为4时为分割的数function output=T_SGM(img,ThresH,pluse)img=im2double(img);%图像二值化if ThresH==0output =im2double(imbinarize(I));
elseif ThresH==1T=0.5*(min(img(:))+max(img(:)));done=false;while ~doneg=(img>=T);%建立区域g,为大于阈值的部分Tn=0.5*(mean(img(g))+mean(img(~g)));%当图像中g的区域与非g的区域的均值接近于目标阈值时,分割完成done = abs(T-Tn)<0.1;T=Tn;endoutput=imbinarize(img,T);
elseif ThresH==2Th=graythresh(img);%阈值output=imbinarize(img,Th);
elseif ThresH==3se=strel('disk',pluse);%建立形态学 结构元素ft=imtophat(img,se);%使用结构元素进行滤波Thr=graythresh(ft);%早对滤波后的图像进行阈值取值output = imbinarize(ft,Thr);
elseif ThresH==4output=imbinarize(img,pluse);
endend
 SelecValueOfPic
function [actualaverageValue,actualNum,segama,K,S] = SlecValueOfPic(img,range,method)
%SLECVALUEOFPIC
%输入一张分割后的灰度图片;根据这这张图片的像素值统计(除零外),取中间range值的范围的内容;并返回这个范围的平均值;
%这个取值的逻辑是取像素值中间的分布,以个数划分,如10个像素取60%取平均,就是取中间值的6个像素的平均;这种方法可以提高图像反射率的数值的鲁棒性,将噪点和背景的反射屏蔽掉一部分;%   actualavergeValue:最后输出的平均值
%   img:输入的图像
%   range:范围,大小为0-1之间;(折合百分数)
%   method:方法 1为中位数法 2为正太分布法 3为平均数法
%   actualnum:为成像面积
%   segama:偏度segama=0;
K=0;
S=0;
if method==1staticD=imhist(img);allN=sum(staticD(2:256,1));rangeN=ceil(allN*range);thresholdNum=ceil((allN-rangeN)/2);thresholdValue=0;%初始化thresholdValueHigh=0;actualNum=0;for i=2:256%计算区间,为0的背景不算;nowSum=sum(staticD(2:i,1));if nowSum>thresholdNumif thresholdValue==0thresholdValue=i;%获得了最低门槛;endendif nowSum>(thresholdNum+rangeN)if thresholdValueHigh==0thresholdValueHigh=i;%获得了最高门槛;endendendallV=0;if thresholdValue~=0for j=thresholdValue:thresholdValueHigh%计算这个像素区间的平均值repreValue=staticD(j,1)*(j-1);%统计是从零开始统计;allV=allV+repreValue;endactualNum=sum(staticD(thresholdValue:thresholdValueHigh,1));actualaverageValue=allV/rangeN;elseactualNum=0;actualaverageValue=0;endelseif method==2%正太分布估计,此时actualnum为偏度[r,c]=find(img);[actualaverageValue,segama] = normfit(img(find(img)));K=kurtosis(img(find(img)));%峰度S=skewness(img(find(img)));%偏度[actualNum,~]=size(r);elseif method==3%平均,正太分布和平均效果一致(如果符合正太分布的话);[r,c]=find(img);actualaverageValue = mean(img(find(img)),'all');[actualNum,~]=size(r);
endend
Map_uint8
function U8_p =Map_uint8(doubleP,num_min,num_max)
band_div=(num_max-num_min)/256;
U8_p=(doubleP-num_min)/band_div;
MapMax=find(U8_p(:,:)>255);
MapMin=find(U8_p(:,:)<0);
U8_p(MapMax)=255;
U8_p(MapMin)=0;
U8_p=uint8(U8_p);
end
FusionPic_WA_PCA
function FusionPic=FusionPic_WA_PCA(IMGmat,PCAdet)%输入:IMGmat 为基本处理(校正)后的成像数据(储存格式为matlab data *.mat)
%               大小为M(图像高度)*N(图像宽度)*C(图像通道数)
%输入: PCAdet 为PCA的降维数据,为PCA-WA的权重提供参考[y,x,cnum]=size(IMGmat);
FusionPic=zeros(y,x,cnum);
%数据叠加
for i=1:cnumfor j=1:cnumFusionPic(:,:,i)=FusionPic(:,:,i)+PCAdet(i,j)*IMGmat(:,:,j);end
end
 DeleNos_dot
%输入 mask为2值化图像
%在特定区域内的分割若达不到比例,则进行消除function output=DeleNos_dot(mask,length,Percent)numDiv=ceil(Percent*length^2);
[ysize,xsize]=size(mask);for i=length:xsize-length%用区域蒙版的量做判断消除杂点for j=length:ysize-lengthif mask(j,i)==1if sum(sum(mask(j-3:j+3,i-3:i+3)))<numDivmask(j,i)=0;endendend
end
output=mask;
AverageOneSample

function data = AverageOneSample(Sample,EX)
%主要是求图像校正后,分割后的平均值
%EX为1*2的double 分别代表范围和取值的方法 默认【0.6,3】%[actualaverageValue,actualNum,segama,K,S] = slecValueOfPic(img,range,method)
%SLECVALUEOFPIC
%输入一张分割后的灰度图片;根据这这张图片的像素值统计(除零外),取中间range值的范围的内容;并返回这个范围的平均值;
%   actualavergeValue:最后输出的平均值
%   img:输入的图像
%   range:范围,大小为0-1之间;
%   method:方法 1为中位数法 2为正太分布法 3为平均数法,基本上2和3一致
%   actualnum:为成像面积
%   segama:偏度[x,y,z]=size(Sample);
for i=1:z[data(i,1),data(i,2),~,~,~] = SlecValueOfPic(Sample(:,:,i),EX(1),EX(2));
endend
AverageChannelData
%检查文件数量是否匹配
function allData=AverageChannelData(aimPath,numchannel,IFSGM)%输入部分
%aimPath:采集目标的路径
%aimPath='F:\23新疆大田数据校正后\SSS';%目标路径,得用单引号"
%IFSGM 大小为1*2,(1,1)若为1则执行基于荧光的分割,(1,2)为红色荧光所在的位置orinPath=cd();%函数执行所在的路径,默认原路径
%目标文件
srcDir=dir(aimPath); %获得选择的文件夹
[numFile,~]=size(srcDir);
data=zeros(numchannel,2);
for j=3 :numFilenames_Fir=srcDir(j).('name');newfile_Fir=[aimPath,'\',names_Fir];%数据文件名load(newfile_Fir);if IFSGM(1,1)==1tureMask=T_SGM(Map_uint8(a(:,:,3),min(min(a(:,:,3))),max(max(a(:,:,3)))),4,0.045);%图像分割tureMask2=DeleNos_dot(tureMask,10,0.2);%清理噪点[yn,xn,zn]=size(a);b=zeros(yn,xn,zn);for i=1:14b(:,:,i)=a(:,:,i).*tureMask2;endelseb=a;enddata = AverageOneSample(b,[0.6,3]);allData(j-2,1:14)=data(1:14,1)';
endend

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/592660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode第206题反转链表❤

一&#xff1a;题目&#xff1a; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网…

互补滤波简述

互补滤波也可以用来做IMU的姿态解算&#xff0c;它相比于卡尔曼滤波计算更简单&#xff0c;实时性更好&#xff0c;但精度不如卡尔曼滤波。 互补滤波的原理是利用了角度计算中加速度计和陀螺仪的特点&#xff0c;即加速度计长时间更准确&#xff0c;陀螺仪短时间更准确&#x…

【OpenCV】在MacOS上源码编译OpenCV

在MacOS上源码编译OpenCV 1. 下载项目源码2. 创建CMake编译文件3. 编译安装4. 案例测试5. 总结 前言 在做视觉任务时&#xff0c;我们经常会用到开源视觉库OpenCV&#xff0c;OpenCV是一个基于Apache2.0许可&#xff08;开源&#xff09;发行的跨平台计算机视觉和机器学习软件…

js中函数动态调用

文章目录 一、场景二、方法2.1、动态函数2.2、eval()函数 三、最后 一、场景 在JS开发中&#xff0c;例如有些场景下&#xff0c;后端要求一个功能要请求不同的接口&#xff0c;但是传参及后续逻辑其实都是一样的&#xff0c;有些同学可能会想到在接口url处统一处理就好&#…

在 docker 容器中配置双网卡,解决通讯的问题

目录 1. 查看当前网络信息 2. 创建自定义网络 3. 查看网卡信息 4. 建立双网卡模式 5. 查看容器的网络 6. 从双网卡中删除默认网卡 已经创建好了的 Docker 容器&#xff0c;要修改它的IP比较麻烦&#xff0c;网上找了几种不同的方法&#xff0c;经过试验都没有成功&…

HeyGen怎么使用想使用高级功能如何订阅

HeyGen是一款AI视频工具&#xff0c;可以让用户轻松地用不同语言说话。 HeyGen是一个用于生成“虚拟化身&#xff08;数字人&#xff09;”视频的工具。 根据其官网的介绍&#xff0c;HeyGen可以通过文本生成视频&#xff0c;有不同的视频模板&#xff0c;可以定制化人物形象、…

Android Studio报错:connect refused

报错信息 解决办法&#xff1a;在System settings里取消代理&#xff0c;将HTTP Proxy设置为 No proxy 但是我发现我的还不行&#xff0c;还是报错&#xff0c;还是connect refused&#xff1a; 我发现虽然在System settings里已经取消代理&#xff0c;但实际项目运行时还是走…

鸿蒙原生应用/元服务开发-Serverless账户验证码的问题

在应用/元服务早期使用过程中&#xff0c;-Serverless账户验证码的格式是[AGC][应用/元服务名称]&#xff0c;如下图。 但是&#xff0c;在最近&#xff0c;[应用/元服务]名称直接变成了【default】,用户收到这种验证码后&#xff0c;心里存有疑虑的&#xff0c;这是哪里配置…

OSG-渲染状态、纹理映射(一)

1、渲染状态 OSG 支持绝大部分的OpenGL固定功能管道(fixed function pipeline)渲染,如Alpha检验、Blending融合剪切平面、颜色蒙板、面选(face culling)深度和模板检验、雾效、点和线的光栅化(rasterization)等。OSG 的渲染状态也允许应用程序指定顶点着色(vertex shader)和片段…

墙裂分享的免费好用api接口

企业工商三要素核验 API&#xff1a;通过输入企业名称、法人、注册号 /组织机构代码 /统一社会信用代码&#xff0c;验证三者是否匹配一致。企业工商四要素核验&#xff1a;传入企业名称、社会统一信用代码、法人名称、法人身份证&#xff0c;校验此四项是否一致。空气质量查询…

Python 数据库(一):使用 mysql-connector-python 操作 MySQL 数据库

大家好&#xff0c;我是水滴~~ 当涉及到使用 Python 操作 MySQL 数据库时&#xff0c;mysql-connector-python 库是一个强大而常用的选择。该库提供了与 MySQL 数据库的交互功能&#xff0c;使您能够执行各种数据库操作&#xff0c;如连接数据库、执行查询和插入数据等。在本文…

【业务中台-上线总结篇】

上线总结篇&#xff1a;从项目切换、问题处理、项目总结、项目验收环节展开 一、项目切换&#xff1a; 在上一章我们提到有制定详细规划的切换计划&#xff0c;在实际切换过程中&#xff0c;我们也是严格按照既定时间节点进行。然而&#xff0c;及时再详情的计划&#xff0c;也…

R语言——R函数、选项参数、数学统计函数(六)

目录 一、R函数 二、选项参数 三、数学统计函数 四、参考 一、R函数 1.lm() lm()是R语言中经常用到的函数&#xff0c;用来拟合回归模型。它是拟合线性模型最基本的函数 lm()格式如下&#xff1a; fit<-lm(formula,data) 其中&#xff0c;formula指要拟合的模型形式…

draw流程图工具导入云原生(CNCF)相关控件

目录 1、通过draw导入xml文件&#xff0c;获取云原生相关的空间 2、引用自己的资源链接&#xff1a; 1、通过draw导入xml文件&#xff0c;获取云原生相关的空间 导入资源图库&#xff0c;资源放在下方&#xff0c;大家可以下载&#xff1a; 2、引用自己的资源链接&#xff1a;…

Vue实现JSON字符串格式化编辑器组件

相信很多同学都用过网上的在线JSON格式化工具来将杂乱的JSON数据转换成易于我们阅读和编辑的格式。那么&#xff0c;你有没有想过自己动手实现一个这样的工具呢&#xff1f;今天&#xff0c;我将介绍如何使用Vue.js来构建一个简单的JSON格式化工具。 功能简述 支持格式化JSON字…

Linux使用yum命令安装postgrepsql

1.检查安装源 yum search postgresql 2.安装 yum install postgresql-server 3.启动数据库 service postgresql start 4.查看启动状态 service postgresql status 5.登陆测试 su - postgrep psql \l6.远程连接 6.1修改配置文件 在pg_hba.conf增加host all all 0.0.0…

解决Android AAPT: error: resource android:attr/lStar not found. 问题

错误信息 /xxx/gjc/.gradle/caches/transforms-2/files-2.1/930c42acd29d295ce5bc495c3b84423e/core-1.9.0/res/values/values.xml:104:5-113:25: AAPT: error: resource android:attr/lStar not found. not found 资源位置 场景 原Android studio中的项目都是在git上面拉的老项…

linux大于2TB磁盘分区方法

linux大于2TB磁盘分区方法 通过parted命令进行分区。步骤如下&#xff1a; 查询要挂的有磁盘路径, 输入 parted -l 。 进入parted对/dev/vdb盘的交互方式&#xff1a;输入&#xff1a; parted /dev/vdb&#xff0c;再输入&#xff1a;print 查看磁盘信息。 修改磁盘格式为gp…

数据结构与算法python版本之线性结构之队列Quene

什么是队列&#xff1f; 队列是一种有次序的数据集合&#xff0c;其特征是&#xff1a;新数据项的添加总发生在一端&#xff08;通常称为“尾rear”端&#xff09;&#xff0c;而现存数据项的移除总发生在另一端&#xff08;通常称为“首front”端&#xff09;&#xff1b;当数…

详解静态网页数据获取以及浏览器数据和网络数据交互流程-Python

目录 前言 一、静态网页数据 二、网址通讯流程 1.DNS查询 2.建立连接 3.发送HTTP请求 4.服务器处理请求 5.服务器响应 6.渲染页面 7.页面交互 三、URL/POST/GET 1.URL 2.GET 形式 3.POST 形式 四.获取静态网页数据 1.requests库 点关注&#xff0c;防走丢&am…