17、二值图边缘追踪

二值图边缘追踪

二值图边缘追踪,就是用该函数找出二值图中连通区域的边界。

borders = bwboundaries( bw );

该函数返回一个cell型数据,该类型的数据包括若干个矩阵,每个矩阵保存一个连通区域的边界点的坐标对。对于有坑洞的(如,下图齿轮中的圆形区域),将会分为两个矩阵来存储两个边界。注意,这个函数必须作用于二值图。对于下图使用该函数,得到的返回数据如下:
在这里插入图片描述          在这里插入图片描述
在这里插入图片描述

应用

1、用红线将下图齿轮的边框标记出来

在这里插入图片描述

思路:将图片转换为二值图,齿轮部分的值置为1,去除其他对象之后用 bwboundaries 找到齿轮的边界,用 plot 函数做标记。
步骤:

  1. 先将图片转换为二值图
    从图中可以看到,齿轮的部分为黑色,我们需要先对图片取反,将齿轮部分转换为白色(1)。
    在这里插入图片描述

  2. 对图片取反
    matlab中的符号 ~ 是取反号,会把 1 取反为 0,0 取反为 1 。
    在这里插入图片描述
    代码:

    clc,clear,close all;
    f=imread('c.jpg');
    imshow(f);
    g=rgb2gray(f);
    bw=~imbinarize(g);
    figure,imshow(bw);
    
  3. 去除小对象,去除齿轮旁边的东西
    在这里插入图片描述
    新增代码:

    bwao=bwareaopen(bw,300);
    figure,imshow(bwao);
    
  4. 用函数 bwboundaries 找到以上二值图中的齿轮边界信息。
    在这里插入图片描述
    新增代码:

    bs=bwboundaries(bwao);
    

    从右侧工作区可以看到该返回值为12×1的cell型数据,下面我们打开 bs 变量查看数据,并打开其中的第一个矩阵查看:
    在这里插入图片描述      在这里插入图片描述

    可以看到cell型数据里有若干矩阵,每个矩阵保存的是边界的坐标对,我们可以借助于这些信息,在原图中表明这些坐标。

  5. 首先用 imshow 显示原图是为了用 hold onplot 函数在图中做标记。下面用 for 循环遍历每一个边缘,然后用 plot 函数在每个边缘做标记。

    size(bs,1);%计算 bs 第一列的长度
    borders=bs{i};%将 bs 的第一个矩阵赋值给 borders
    x=borders(:,2);%将borders的第二列的值赋值给 xx 中保存的是该边界的列信息
    y=borders(:,1);%将borders的第一列的值赋值给 yy 中保存的是该边界的行信息,x和y中的每个同位置坐标组成一个坐标点
    plot(x,y,‘r’,‘lineWidth’,2);%在第x列第y行的地方画红线 (r),线宽(lineWidth)为 2。(plot函数的用法详情请查看matlab帮助文件)

    在这里插入图片描述
    本例代码:

    clc,clear,close all;
    f=imread('c.jpg');
    imshow(f);
    g=rgb2gray(f);
    bw=~imbinarize(g);
    figure,imshow(bw);
    
    bwao=bwareaopen(bw,300);
    figure,imshow(bwao);
    
    bs=bwboundaries(bwao);
    figure,imshow(f);
    
    for i=1:size(bs,1)
        borders=bs{i};
        x=borders(:,2);
        y=borders(:,1);
        hold on;
        plot(x,y,'r','lineWidth',2);
    end
    
  6. 对于齿轮的边缘追踪函数,我们可以添加参数,使其只提取外部边界,对于上图来说,将齿轮内部的边界可以忽略。用这样的参数实现:

    bs=bwboundaries(bwao,‘noholes’);

    下图和上面的例子只改变了这个函数的参数。在这里插入图片描述


2、用方框标记下方人脸

在这里插入图片描述
思路:先将图片转换为YCbCr图,找到人脸区域,然后本例介绍了一个函数可以在指定区域画方框,进行标记。
步骤:

  1. 先将图片转为YCbCr图,提取Cr分量图,将图片转换为二值图
    在这里插入图片描述
    代码:
    clc,clear,close all;
    f=imread('xu.jpg');
    imshow(f);
    y=rgb2ycbcr(f);
    cr=y(:,:,3);
    cr(cr<140|cr>160)=0;
    cr(cr~=0)=255;
    bw=imbinarize(cr);
    figure,imshow(bw);
    
  2. 先用腐蚀将耳朵和脸部分开,填补脸上的小坑洞,再去除旁边的小对象。
    在这里插入图片描述
    新增代码:
    bwf=imfill(bw,'holes');
    figure,imshow(bwf);
    bwe=imerode(bwf,strel('disk',5));
    figure,imshow(bwf);
    bwao=bwareaopen(bwe,1100);
    figure,imshow(bwao);
    
  3. 先找到二值图中的非 0 元素,赋值给 r 和 c ,对于函数:
    rectangle(‘position’,[min©,min®,w,h],‘EdgeColor’,‘r’);
    表示在位置(position) 为 [最左侧位置坐标 , 最上方位置坐标 , 宽度 , 长度] 的地方,画颜色(EdgeColor)为红色(r)的方形。
    因此我们在上面先计算了脸部的最宽的宽度和最高的高度,方便下面画方形。
    在这里插入图片描述本例代码:
    clc,clear,close all;
    f=imread('xu.jpg');
    imshow(f);
    y=rgb2ycbcr(f);
    cr=y(:,:,3);
    cr(cr<140|cr>160)=0;
    cr(cr~=0)=255;
    bw=imbinarize(cr);
    figure,imshow(bw);
    bwf=imfill(bw,'holes');
    figure,imshow(bwf);
    bwe=imerode(bwf,strel('disk',5));
    figure,imshow(bwf);
    bwao=bwareaopen(bwe,1100);
    figure,imshow(bwao);
    
    [r,c]=find(bwao);
    w=max(c)-min(c);
    h=max(r)-min(r);
    
    figure,imshow(f);
    hold on;
    rectangle('position',[min(c),min(r),w,h],'EdgeColor','r');
    

3、将下方所有人脸区域用方框标记

在这里插入图片描述思路:先转换为YCbCr图,找到所有的人脸连通区域然后分别做标记。
步骤:

  1. 先转换为YCbCr图,分割出来Cr分量图,将肤色部分置为 1 ,其余置为 0 。再转换为二值图。
    观察下图,可以看到有些衣服和肤色值范围较相近,因此被选择,我们可以调整肤色分布的范围,将肤色的检测范围缩小到 146-160。
    在这里插入图片描述

  2. 调整肤色的检测范围,可以得到下图,可以发现衣服部分被去除了。
    在这里插入图片描述
    代码:

    clc,clear,close all;
    f=imread('girls.jpg');
    imshow(f);
    y=rgb2ycbcr(f);
    cr=y(:,:,3);
    cr(cr<146|cr>160)=0;
    cr(cr~=0)=255;
    bw=imbinarize(cr);
    figure,imshow(bw);
    
  3. 然后先填充图中连通区域中的小坑洞。
    在这里插入图片描述
    新增代码:

    bwf=imfill(bw,'holes');
    figure,imshow(bwf);
    
  4. 去除小对象。
    在这里插入图片描述
    新增代码:

    bwao=bwareaopen(bwf,1900);
    figure,imshow(bwao);
    
  5. imboundaries 找到每个边界的坐标点,然后根据这些坐标点画方框。但是我们怎么根据上图找到人脸区域呢?这里给出一种方法,通过观察可以看到,人的头部的高和宽的比例都在1-2之间。我们便可以利用该信息在这些区域画框。
    首先还是展示原图,然后 hold on 等待标记。根据每个连通区域坐标点的数值,计算出来长和宽,这个长和宽既可以用作画方框时候的参数,也可以用来判断这部分的高和宽的比。
    在这里插入图片描述
    本例代码:

    clc,clear,close all;
    f=imread('girls.jpg');
    imshow(f);
    y=rgb2ycbcr(f);
    cr=y(:,:,3);
    cr(cr<146|cr>160)=0;
    cr(cr~=0)=255;
    bw=imbinarize(cr);
    figure,imshow(bw);
    bwf=imfill(bw,'holes');
    figure,imshow(bwf);
    
    bwao=bwareaopen(bwf,1900);
    figure,imshow(bwao);
    
    bs=bwboundaries(bwao);
    
    imshow(f);
    hold on;
    for i=1:size(bs,1)
        borders=bs{i};
        c=borders(:,2);
        r=borders(:,1);
        w=max(c)-min(c);
        h=max(r)-min(r);
        if(h/w>1&&h/w<2)
            rectangle('position',[min(c),min(r),w,h],'EdgeColor','r');
        end
    end
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值