直线提取与边界追踪

ε祈祈猫儿з 提交于 2020-01-14 02:17:41


图像的基本特征之一是直线。一般物体平面图像的轮廓可近似为直线及弧线的组合,对物体轮廓的检测与识别可以转化为对这些基元的检测与提取。另外,在运动图像分析和估计领域也可以采用直线对应法实现刚体旋转量和位移量的测量,所以直线检测对图像算法的研究具有重要意义。
边缘是一个局部的概念,一个区域的边界是一个整体的概念,边界追踪是一种串行的图像分割技术。图像由于噪声以及光照不均匀等原因,边缘点可能是不连续的,边界追踪可以将其变为有意义的信息。下面分别介绍直线的提取与边界追踪。

1.用霍夫变换提取直线

Hough变换是一种利用图像的全局特征将特定形状的边缘连接起来,形成连续平滑边缘的一种方法。它通过将原图像上的点映射到用于累加的参数空间,实现对已知解析式曲线的识别。由于利用了图像的全局特性,所以受噪声和边界间断的影响较小,鲁棒性能好。Hough变换常用来对图像中的直线进行识别。
图像上任意直线区域都可以一一对应参数空间中的点,而图像上的任意像素都同时存在于很多直线区域之上。将图像上的直线区域想象为容器,把特定像素想象成放在容器中的棋子,只不过在这里,每个棋子都可以同时存在于多个容器中。那么Hough变换可以理解为依次检查图像上的每个棋子(特定像素),对于每个棋子,找到所有包含它的容器(平面上的直线区域),并为每个容器的计数器加1,这样就可以统计出每个容器(平面上的直线区域)所包含的棋子(特定像素数量)。当图像上某个直线区域包含的特定像素足够多时,就可以认为这个直线区域表示的直线存在。
在MATLAB中,通过Hough变换在图像中检测直线需要以下3个步骤。
(1)利用hough()函数执行霍夫变换,得到霍夫矩阵;
(2)利用houghpeaks()函数在霍夫矩阵中寻找峰值点;
(3)利用houghlines()函数在前两步结果的基础上得到原二值图像中的直线信息。这些函数的调用方法为

[H,theta,rho]=hough(BW,param1,vall,param2,val2)

其中,BW是边缘检测后的图像;param1、val1及param2、val2为可选参数;H是变换得到的Hough矩阵;theta和rho为分别对应于Hough矩阵每一列和每一行的θ和ρ值组成的向量。

peaks=houghpeaks(H,numpeaks,param1,val1,param2,val2)

其中,H是由hough()函数得到的Hough矩阵;numpeaks是要寻找的峰值数目,默认为1;peaks是一个Q×2的矩阵,每行的两个元素分别为某一峰值点在Hough矩阵中的行、列索引,Q为找到的峰值点的数目。

lines=houghlines(BW,theta,rho,peaks,param1,val1,param2,val2)

其中,BW是边缘检测后的图像;theta和rho是Hough矩阵每一列和每一行的θ和ρ值组成的向量,由hough函数返回;peaks是一个包含峰值点信息的Q×2的矩阵,由houghpeaks函数返回;lines是一个结构体数组,数组长度是找到的直线条数。
对图像进行Hough变换提取直线

**clear all
close all
RGB=imread('peppers.png');
I=rgb2gray(RGB);
BW=edge(I,'Canny');
[H,T,R]=hough(BW,'RhoResolution',0.5,'Theta',-90:0.5:89.5);%计算霍夫变换
subplot(121)
imshow(RGB)
title('原始图像')
subplot(122)
imshow(imadjust(mat2gray(H)),'XData',T,'YData',R,...
    'InitialMagnification','fit');
title('Hough变换')
xlabel('\theta轴'),ylabel('\rho轴');
axis on
axis normal
hold on
colormap(hot)

在这里插入图片描述
将一幅图像进行Hough变换,标出峰值位置

clear all
close all
I=imread('eight.tif');
subplot(121)
imshow(I)
title('原始图像')
BW=edge(imrotate(I,50,'crop'),'prewitt');
[H,T,R]=hough(BW);
P=houghpeaks(H,2);
subplot(122)
imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit');%显示Hough变换
title('Hough变换')
xlabel('\theta轴'),ylabel('\rho轴')
axis on,axis normal
hold on
plot(T(P(:,2)),R(P(:,1)),'s','color','white');%标记颜色为白色

在这里插入图片描述
对图像进行Hough变换,并标出最长的线段

clear all
close all
I=imread('blobs.png');
subplot(131)
imshow(I)
title('原始图像')
rotI=imrotate(I,45,'crop');
BW=edge(rotI,'sobel');
[H,T,R]=hough(BW);
subplot(132)
imshow(H,[],'XData',T,'YData',R,...
    'InitialMagnification','fit')
title('Hough变换')
xlabel('\theta轴'),ylabel('\rho轴')
axis on,axis normal
hold on
P=houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));%寻找极值点
x=T(P(:,2));
y=R(P(:,1));
plot(x,y,'s','color','white');
lines=houghlines(BW,T,R,P,'FillGap',5,'MinLength',7);%找出对应的直线边缘
subplot(133)
imshow(rotI)
title('检测线段')
hold on
max_len=0;
for k=1:length(lines)
    xy=[lines(k).point1;lines(k).point2];
    plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
    %标记直线边缘对应的起点
    plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','blue')
    plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red')
    len=norm(lines(k).point1-lines(k).point2);%计算直线边缘长度
    if(len>max_len)
        max_len=len;
        xy_long=xy;
    end
end
plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','b')

在这里插入图片描述

2.边界跟踪

边界追踪是指从图像的一个边缘点出发,然后根据某种判别准则搜索下一个边缘点以此跟踪目标边界。边界跟踪的算法步骤如下:
(1)确定边界的起始搜索点,起始点的选择很关键,对某些图像,选择不同的起始点会导致不同的结果
(2)确定合适边界判别准则和搜索准则,判别准则用于判断一个点是不是边界点,搜索准则用于指导如何搜索下一个边缘点;
(3)确定搜索终止的条件
在MATLAB中,bwtraceboundary函数采用基于曲线跟踪的策略,给定搜索起始点和搜索方向及其返回该起始点的一条边界;bwboundaries函数用于获取二值图像中对象的轮廓。这两种函数的用法如下所示:

B=bwtraceboundary(BW,P,fstep)
B=bwtraceboundary(BW,P,fstep,conn)
B=bwtraceboundary(...,N,dir)

其中,非零像素表示对象,零像素构成背景;bwtraceboundary返回值为B,一个Q×2的矩阵,Q是区域边界像素的数量;B保存有边界像素的行、列坐标;参数P是一个指定行、列坐标的二元矢量,表示对象边界上开始跟踪的那个点;fstep表示初始查找方向,用于寻找对象中与P相连的下一个像素,fstep是寻找下一个相连像素点的初始方向;dir是寻找边界的方向,即顺时针还是逆时针。

B=bwboundaries(BW,conn)

其中,B是一个P×1数组,P为对象个数,每个对象是Q×2的矩阵,对应于对象轮廓像素的坐标。
对图像进行边界跟踪提取。

clear all
close all
RGB=imread('saturn.png');
figure
subplot(131)
imshow(RGB)
title('原始图像')
I=rgb2gray(RGB);
threshold=graythresh(I);
BW=im2bw(I,threshold);
subplot(132)
imshow(BW)
title('二值图像')
dim=size(BW);
col=round(dim(2)/2)-90;%计算起始点的列坐标
row=find(BW(:,col),1);%计算起始点行坐标
connectivity=8;
num_points=180;
contour=bwtraceboundary(BW,[row col],'N',connectivity,num_points);%提取边界
subplot(133)
imshow(RGB)
hold on
plot(contour(:,2),contour(:,1),'g','LineWidth',2)
title('结果图像')

在这里插入图片描述
对图像进行边界跟踪提取

clear all
close all
I=imread('blobs.png');
figure(1)
subplot(121)
imshow(I)
title('原始图像')
B=bwboundaries(I);
D=B{1,1};
subplot(122)
plot(D(:,2),D(:,1))
set(gca,'YDir','reverse')
title('边界标记后的图像')

在这里插入图片描述
对图像中不同的区域表示不同的颜色

clear all
close all
I=imread('tape.png');
figure(1)
subplot(131)
imshow(I)
title('原始图像')
BW=im2bw(I,graythresh(I));%生成二值图像
subplot(132)
imshow(BW)
title('二值图像')
[B,L]=bwboundaries(BW,'noholes');%提取边界,并返回边界元胞数组B和区域标志数组L
subplot(133)
imshow(label2rgb(L,@jet,[.5,.5,.5]))%以不同的颜色标志不同的区域
title('彩色标机图像')
hold on
for k=1:length(B)
    boundary=B{k};
    plot(boundary(:,2),boundary(:,1),'w','LineWidth',2)%在图像上叠画边界
end

在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!