灰度图像形状的识别分类算法实现matlab

摘  要: 针对已经给出的图像,在分类之前,因为存在噪声和光照的不同,所以要先进行图像增强,并统一将图像转为二值图像。对图像进行边缘检测,可以很容易算出各个图像面积与周长二次方的比值关系,对图像进行直线检测, 可以获得图像中直线的特征,结合图像的以上两种特种对形状进行分类。

 

 

算法设计和推导:

    

  1. 图像预处理部分,通过 9X9 均值滤波器,先对图像进行去噪,然后二值化图像。

  2. 各个形状的面积和周长存在一定的特征关系,可据此对图像进行分类。

(令各形状的面积为S,周长为L,计算

   (1)圆形(半径为r1):S/L2 =(π*r12) / (2*π*r1)2

                                              = 1 / 4*π= 0.0796

(2)正方形(边长为r2:S/L2  =  r22 / (4*r2)2

                                         =  1/16 = 0.0652

(3) 矩形(不包含正方形)  S/L2  < 1/16 = 0.0652

(4) 椭圆(不包含原)   S/L2  <  1 / 4*π= 0.0796

   据此方法,可对圆和正方形进行分类,将圆和正方形与另外两种形状区分开来,但无法对椭圆和矩形进行恰当分类。

   3. 用霍夫变换对形状进行直线检测,获得直线特征(直线数量,直线长度),

若检测到直线数量不等于四条,可直接判断为圆或椭圆,计算直线长度,找出相等的直线对,若四条直线相等,可判断为正方形,若有两对相等的直线,可判断为矩形。

    结合以上两种判断方法,对形状进行识别并分类。

  

实验设计和结果

  1.预处理部分,对图像进行增强并二值化,实现代码如下:

function K2 = quzao(I)

 

K1=filter2(fspecial('average',[9,9]),I)/255;

 

thresh = graythresh(I);

K2 = im2bw(K1,thresh);

end

实现效果:

 

              原图像             处理过的图像  

 

             原图像              处理过的图像 

 

 

            原图像               处理过的图像 

 

        原图像                   处理过的图像 

 

 2.为了计算S/L2,需要获得图像中各形状对应的面积和周长,对二值化后的图像进行边缘提取,来获得形状的边界(以圆为例)

   

两张图像大小一样,分别计算每张图像值为1 的像素数量,计算比率,实现代码如下:

function r = Ratio(K,E)

    [r1,c1] = size(K);

  %  [r2,c2] = size(E);

    

    area = 0;

    perimeter = 0;

    

    for i = 1:r1

        for j = 1:c1

            if(K(i,j)==1)

                area = area+1;

            end

            if(E(i,j)==1)

                perimeter = perimeter+1;

            end

        end

    end

   

    r = area/(perimeter*perimeter);

    

end

 

每个形状各选择50张图像进行测试,查看各个不同形状所计算出的比率的分布情况,结果如下:

  

  

               圆                              正方形

   

             长方形                           椭圆

 

观察实验结果发现,圆和正方形的S/L2比值并未像预期那样为定值,但圆形的比值基本分布在0.0850.09之间,而其他形状算出的比值均未超过0.085,可据此将圆形与其他三个形状区分开来。

 

3.对图像进行直线检测

利用霍夫变换进行直线检测 ,可通过分析直线特征,根据获得的直线数量,计算出的直线长度来进行比较,具体实现如下

直线检测并进行正方形和长方形的判断并写入相应文件夹:

 

 

 

BW=edge(K,'canny');                                    %边缘检测

            [H,T,R]=hough(BW);                                     %霍夫变换进行直线检测

            P=houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));

            lines=houghlines(BW,T,R,P,'FillGap',30,'MinLength',60);  %获得检测到的直线

            [num1,num2] = size(lines);                               %获得直线的数量num2

            if(num2 == 4)                                           %若检测到为四条直线,逐一计算各条直线长度,存入l

                for count=1:4

                    lines(count).long = sqrt((lines(count).point1(1)-lines(count).point2(1))^2 + (lines(count).point1(2)-lines(count).point2(2))^2);

                    l(count) = lines(count).long;

                end

                num = lineCompare(l);                           %比较直线长度,判断是否为矩形或正方形形

            end

            if(num==4 && num2 == 4)                               %判断为正方形

                    path = strcat('square\',int2str(index1));

                    imwrite(K,strcat(path,'.jpg'));

                    index1 = index1+1;

            elseif(num==2 && num2 == 4)                           %判断为矩形

                    path = strcat('rectangle\',int2str(index2));

                    imwrite(K,strcat(path,'.jpg'));

                    index2 = index2+1;

 

通过直线的长度比较来进行判断,lineCompare函数代码如下

 

function num = lineCompare(l)

    num = 0;

    diff(12) = abs(l(1)-l(2));            %第一条直线与各直线进行比较,计算与其他直线的差值diff

    diff(13) = abs(l(1)-l(3));

    diff(14) = abs(l(1)-l(4));  

    

    if(diff(12)<5.5 || diff(13)<5.5 || diff(14)<5.5)

        if(diff(12)<5.5 && diff(13)<5.5 && diff(14)<5.5)         %若四条直线相等(即直线长度差值小于5.5),即判断为正方形

            num = 4;

        elseif(diff(12) < 5.5)                                   %四条直线不相等,但直线1,2相等,判断直线3,4是否相等,若相等,即为矩形

            diff(34) = abs(l(3) - l(4));

            if(diff(34) < 5.5)

                num = 2;

            end

        elseif(diff(13) < 5.5)

            diff(24) = abs(l(2) - l(4));

            if(diff(24) < 5.5)

                num = 2;

            end

        elseif(diff(14) < 5.5)

            diff(23) = abs(l(2)-l(3));

            if(diff(23) < 5.5)

                num = 2;

            end

        end

    end

    

end

 

 

最终确定的程序执行步骤为,先进行直线检测将图像分为正方形和长方形,圆形和椭圆两类,正方形和长方形通过直线长度比较进一步分类,圆形和椭圆通过计算S/L2进一步划分。将每一张图像进行形状分类后写入对应的文件夹

 

4. 将最终程序用于形状的划分,统计分到每个问价下的各形状数量性能统计如下

文件夹\形状

正方形

长方形

椭圆

circle

276

2

3

60

square

0

188

0

2

rectangle

 0

  14

156

  2

ellipse

 3

  75

120

215

合计

279

  279

279

  279

正确率

98.9%

 67.4%

56.0%

77.1%


完整实现代码:

图像预处理:

function K2 = quzao(I)


K1=filter2(fspecial('average',9),I)/255;


thresh = graythresh(I);
K2 = im2bw(K1,thresh);

end


周长面积比率:

function r = Ratio(K,E)
    [r1,c1] = size(K);
  %  [r2,c2] = size(E);
    
    area = 0;
    perimeter = 0;
    
    for i = 1:r1
        for j = 1:c1
            if(K(i,j)==1)
                area = area+1;
            end
            if(E(i,j)==1)
                perimeter = perimeter+1;
            end
        end
    end
   
    r = area/(perimeter*perimeter);
    
end



开始分类:



function split(file_path)
%file_path =  'test1\';% 图像文件夹路径
img_path_list = dir(strcat(file_path,'*.jpg'));%获取该文件夹中所有jpg格式的图像
img_num = length(img_path_list);%获取图像总数量
index1 = 1;
index2 = 1;
index3 = 1;
index4 = 1;
num = 0;
if img_num > 0 %有满足条件的图像
        for j = 1:img_num %逐一读取图像
            image_name = img_path_list(j).name;% 图像名
            image =  imread(strcat(file_path,image_name));
            fprintf('%d %d %s\n',i,j,strcat(file_path,image_name));% 显示正在处理的图像名
            K = quzao(image);                                      % 调用去噪函数进行去噪
            BW=edge(K,'canny');                                    %边缘检测
            [H,T,R]=hough(BW);                                     %霍夫变换进行直线检测
            P=houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));
            lines=houghlines(BW,T,R,P,'FillGap',30,'MinLength',60);  %获得检测到的直线
            [num1,num2] = size(lines);                               %获得直线的数量num2
            if(num2 == 4)                                           %若检测到为四条直线,逐一计算各条直线长度,存入l
                for count=1:4
                    lines(count).long = sqrt((lines(count).point1(1)-lines(count).point2(1))^2 + (lines(count).point1(2)-lines(count).point2(2))^2);
                    l(count) = lines(count).long;
                end
                num = lineCompare(l);                           %比较直线长度,判断是否为矩形或正方形形
            end
            if(num==4 && num2 == 4)                               %判断为正方形
                    path = strcat('square\',int2str(index1));
                    imwrite(K,strcat(path,'.jpg'));
                    index1 = index1+1;
            elseif(num==2 && num2 == 4)                           %判断为矩形
                    path = strcat('rectangle\',int2str(index2));
                    imwrite(K,strcat(path,'.jpg'));
                    index2 = index2+1;
                
            else                                                
                 E = edge(K);
                  r = Ratio(K,E);                                      
                 if(r>0.086)                                          %判断为圆
                     path = strcat('circle\',int2str(index3));
                     imwrite(K,strcat(path,'.jpg'));
                     index3 = index3+1;
                 else                                                %判断为椭圆
                     path = strcat('ellipse\',int2str(index4));
                     imwrite(K,strcat(path,'.jpg'));
                     index4 = index4+1;
                 end
             end
       
          
        end
       
            %图像处理过程 省略
       
else
    fprintf('文件夹不存在!');% 显示正在处理的图像名
end
end


function num = lineCompare(l)
    num = 0;
    diff(12) = abs(l(1)-l(2));            %第一条直线与各直线进行比较,计算与其他直线的差值diff
    diff(13) = abs(l(1)-l(3));
    diff(14) = abs(l(1)-l(4));
    
   
    
    if(diff(12)<5.5 || diff(13)<5.5 || diff(14)<5.5)
        if(diff(12)<5.5 && diff(13)<5.5 && diff(14)<5.5)         %若四条直线相等(即直线长度差值小于5.5),即判断为正方形
            num = 4;
        elseif(diff(12) < 5.5)                                   %四条直线不相等,但直线1,2相等,判断直线3,4是否相等,若相等,即为矩形
            diff(34) = abs(l(3) - l(4));
            if(diff(34) < 5.5)
                num = 2;
            end
        elseif(diff(13) < 5.5)
            diff(24) = abs(l(2) - l(4));
            if(diff(24) < 5.5)
                num = 2;
            end
        elseif(diff(14) < 5.5)
            diff(23) = abs(l(2)-l(3));
            if(diff(23) < 5.5)
                num = 2;
            end
        end
    end
    
end

  • 17
    点赞
  • 155
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值