简介:
处理多维光谱的图像数据时,常常需要将某一波段的平均反射提取出来,但是图像中本身含有一些噪音和一些关于反射的分布特征(分布的偏度、峰度)。这些噪音去除和分布特征的提取有助于后续模型预测准度提升(这些偏度和峰度也可作为特征喂给机器学习模型)。因此这里给出了一个运用于提取中位数均值或分布特征的matlab函数示例,用于参考。
代码部分:
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==1
staticD=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>thresholdNum
if thresholdValue==0
thresholdValue=i;%获得了最低门槛;
end
end
if nowSum>(thresholdNum+rangeN)
if thresholdValueHigh==0
thresholdValueHigh=i;%获得了最高门槛;
end
end
end
allV=0;
if thresholdValue~=0
for j=thresholdValue:thresholdValueHigh%计算这个像素区间的平均值
repreValue=staticD(j,1)*(j-1);%统计是从零开始统计;
allV=allV+repreValue;
end
actualNum=sum(staticD(thresholdValue:thresholdValueHigh,1));
actualaverageValue=allV/rangeN;
else
actualNum=0;
actualaverageValue=0;
end
elseif 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);
end
end
运用示例:
我这里使用一张植物幼苗的灰度图作为示例,你可以另存到自己的电脑进行尝试,使用该函数时时,程序会对图像进行分割(把0值的像素点作为非目标对象,即背景,其不会计入中位数、均值、正态分布的计算范畴),中位数会在此基础上进一步取中间分布像素点的平均值,我给的是20%,而均值和正太分布则考虑100%的目标对象的像素,偏度和峰度的数值也是基于此。
使用代码示例:
>> pic=imread("025\16_10_12#Multispectral\0008.jpg"); %图片路径
>> [actualaverageValue,actualNum,segama,K,S] = slecValueOfPic(pic,0.2,1) %中位数法
anwser:
actualaverageValue =
15.8761
actualNum =
704806
segama =
0
K =
0
S =
0
>> [actualaverageValue,actualNum,segama,K,S] = slecValueOfPic(pic,0.2,2) %分布数据获取
anwser:
actualaverageValue =
17.8500
actualNum =
2302681
segama =
4.1742
K =
0.0681
S =
0.2600