基于matlab的绿色番茄识别定位方法

        在图像处理识别番茄时,现今大多数方法都是基于颜色进行识别筛选的。这中方法大多只能识别成熟的或者即将成熟的番茄,而对于未成熟的番茄是很难发现的。

       做过图像处理的朋友应该会了解,rgb颜色空间在图像处理中适用范围较小,因此在图像处理时通常需要将图像转换到hsv或者hsi空间。虽然两者在空间模型上有区别,但本人在实际操作中发现两者的差距并不明显,所以此次研究是基于hsv颜色空间的。

我们先来看一组图片

基于matlab的绿色番茄识别定位方法_第1张图片 图1-1

        左边是原始图像,右边是转换为hsv后的图像。通过观察可以发现对于绿色的番茄,它在hsv图像中大部分表现为蓝色只有一小部分稍微有些泛绿 ;比较黑的叶片或者茎表现为红和蓝的中和;其余不相关部分大多为绿色。所以这就给我们提供了解决思路,那就是以v分量为主体,配合其他分量进行相关处理。

以下是分别提取得到的各个分量图像:

基于matlab的绿色番茄识别定位方法_第2张图片 图1-2

         在这三个图像中依次是h,s,v分量图像。通过观察可知在v分量图像中,果实部分的亮度最高,在h分量图像中,果实部分最黑,而在中间的s分量图像中可以看到,果实部分与背景部分的区分度并不太明显,且果实部分有许多黑斑,这是由于拍摄时果实反光造成的。所以我认为提高拍照设备的硬件水平也很有必要,例如可以加上偏振镜来减少反光的干扰,这压根可以在一定程度上降低算法的复杂程度。

        鉴于以上观察结果,我决定采用h和v图像来进行下一步处理。将h图像进行处理,令h=abs(1-h),然后h和v相乘得到一个新的灰度图像。用这个灰度图像再进行二值转换,就可以筛选出图中的番茄。如下图所示,虽然还包含一部分背景区域,但是大部分已经分离出来了。

基于matlab的绿色番茄识别定位方法_第3张图片 图1-3

下面再看一组处理结果 。

基于matlab的绿色番茄识别定位方法_第4张图片 图2-1
基于matlab的绿色番茄识别定位方法_第5张图片 图2-2
基于matlab的绿色番茄识别定位方法_第6张图片 图2-3

         这一组的处理效果不如上一组,图像比较混乱,其中包含大量的枝叶部分。因此,该方法还需进一步改进。

定位番茄

        只是图像分割,简单的分离背景和番茄是远远不够的,还要对番茄进行定位才能真正的‘找到’番茄。下面这幅图中红色的点是每个番茄上的点,通过对这些点进行聚类、概括,得到图中蓝色的点作为番茄位置的标记点。

基于matlab的绿色番茄识别定位方法_第7张图片 图1-4 基于matlab的绿色番茄识别定位方法_第8张图片 图2-4

 

         聚类的方法理论很简单,就是将红色点中距离比较近的算作是一类。所谓‘比较近的点’是指两点的数值都大于两点之间的距离,这样的点就属于同一个点集。(红色的点是计算二值图像中每个白色的像素点到最近的黑色像素点的位置后挑选的‘一部分’局部极大值点。之所以这样做是因为二值图像中番茄部分是圆的,其面积比较大,在所有局部极大值点中挑选数值比较大的局部极大值点就有很大概率落在番茄区域内,从而进一步剔除白色区域中的背景部分。)

基于matlab的绿色番茄识别定位方法_第9张图片 图1-5 mex2矩阵

         上图对应的是图1-4中的红点的分类,图中不同颜色的各部分是对不同点的聚类。(mex2矩阵详见下面代码) 

完整代码如下

clc 
clf
clear
[filename,pathname]=uigetfile({'*.*';'*.bmp';'*.tif';'*.png'},'select picture');  %选择图片路径
if (filename)
str1=[pathname filename];  %合成路径+文件名
RGB=imread(str1);   %读取图片
rgb=im2double(RGB);
hsv=rgb2hsv(rgb);
figure(1)%分别显示rgb图像和HSV图像
subplot(121)
imshow(rgb)
subplot(122)
imshow(hsv)

%%%提取两个分量用于图像分割
h=hsv(:,:,1);
v=hsv(:,:,3);
h1=abs(1-h);%将h取反,白变黑
xhv=h1.*v;
k=graythresh(xhv);
bw=imbinarize(xhv,k);%分离背景与番茄

%%%寻找番茄的大体位置
BW=~bw;
D = bwdist(BW);
regionmax = imregionalmax(D);%寻找区域极大值
maxnum=regionmax.*D;%提取在番茄区域上的极大值点,这些点中大部分都在番茄所在区域内
maxnum=im2double(maxnum);
maxnum1=max(max(maxnum));%挑选出局部极大值点中的最大值
maxnum(maxnum<0.5*maxnum1)=0;%去掉可能不在番茄上的点
[x,y,v]=find(maxnum);%挑选出最有可能在番茄上的点,v是每个坐标点的值
F(:,1)=x; F(:,2)=y;

%%%按照点的值及点之间的距离进行聚类
G=pdist(F);%计算点与点之间的欧里几德距离
DIS=squareform(G);%将距离转换为矩阵形式
mex=zeros(size(DIS));
%mex矩阵用于记录点与点之间是否符合距离条件,例如点4和点3之间符合条件,则mex(4,3)=1
for i=2:length(x)
    for j=1:i-1
        num=DIS(i,j);
        if(num<2*v(i)&&num<2*v(j))%判断两个点是否相关,是否属于同一点集
            mex(i,j)=1;
        end                 
    end
end

%%%按照标记区域之间的位置关系进行整合,划分聚类
mex=mex+mex.';
mex1=bwlabel(mex,4);%按照4连通域标记
for r=1:length(x)
a=unique(mex1(r,:));
if(length(a)>2)%如果同一行有不同的非0值
  for m=3:length(a)
      mex1(mex1==a(m))=a(2);%让它们的值都等同于第一个不为零的数
  end    
end
b=unique(mex1(:,r));
if(length(b)>2)%如果同一列有不同的非0值
  for n=3:length(b)
      mex1(mex1==b(n))=b(2);%让它们的值都等同于第一个不为零的数
  end    
end
end

%%%完成点的聚类,计算每一个点集的‘代表点’
mex2=tril(mex1);%mex2中每个大于零的数值代表一类点集
figure(2)
imshow(label2rgb(mex2))
f=unique(mex2);%f数组用于记录不同聚类的标记值
f(1)=[];%去掉f中的0元素
class_1=[length(f),2];%设置数组存储每个点集的代表点坐标
for p=1:length(f)
    [x1,y1]=find(mex2==f(p));
    Frow=unique(cat(2,x1,y1));%找到同一点集中的点属于F的哪几行
    sum_x=0;sum_y=0;
    for ii=1:length(Frow)
      sum_x=sum_x+x(Frow(ii));
      sum_y=sum_y+y(Frow(ii));
    end
    class_1(p,1)=sum_x/length(Frow);
    class_1(p,2)=sum_y/length(Frow);%将一个点集的横纵坐标的平均值作为这一点集‘代表点'的坐标
end

%%%有的点与任何点都不相关,在mex矩阵中表现为mex(i,i)=0.可单独作为一个点集
independentpoint=find((any(mex)==0)==1);%找到全为0的行和列这是独立个体的类
class_2=[length(independentpoint),2];
for t=1:length(independentpoint)
    class_2(t,1)=x(independentpoint(t));
    class_2(t,2)=y(independentpoint(t));
end

%%%整合坐标点数组,显示在图像上
class=cat(1,class_1,class_2);
figure(3)
imshow(bw)
hold on
plot(class(:,2),class(:,1),'*');
plot(y,x,'*');
hold off

end

你可能感兴趣的:(图像处理,计算机视觉,matlab)