图像分割实战之基于Hough变换提取图像中的直线

图像分割的依据是基于图像中各区域具有不同的特性(比如,灰度、颜色、纹理)。图像分割的目的是将图像划分成若干具有相近或相同特性的子区域,以便继续在分割成的相关区域中提取目标,并进而根据目标的特征或结构信息对其进行分类和识别,最后再给出对整幅图像分析结果的描述信息。所以,图像分割就显得尤为重要。

        在数字图像中,对图像分割一个比较严格的定义:
1、分割成的所有子区域的并应能够构成原来的区域R。

2、分割成的各个子区域互不重叠。

3、分割得到的属于同一区域的像素应具有某些相同的特性。

4、分割得到的属于不同区域的像素应具有不同的性质。

5、同一子区域内的像素应当是连通的。

首先介绍一下图像边缘的概念,由于自然景物中物体、背景、区域的物理形状、几何特性、材质特性及其反射系数的不同,导致了图像中灰度的突变,并在图像中形成了一个不同的区域。图像边缘意味着图像中一个区域的终结和另一个区域的开始。,也就是两个相邻区域之间的像素几何构成了图像的边缘。图像边缘的特点是两个的灰度在通过边缘时将发生某种显著的变化

        理想的阶跃变化如左图,实际上大多数是右图

理想的边缘特点
实际的边缘特点

 基于边缘的图像分割方法,第一步就应该是先确定图像中的边缘信息,然后将他们连在一块作为边界。

Hough变换的边缘检测算法

在实际中,我们多用极坐标的方式来表示一个直线,如下图所示:

 通过极坐标的方式来表示X-Y坐标中的一条直线,其实也就相当于把X-Y空间中的一条直线与极坐标中的一组曲线的交点对应起来, 下面这个图很好地表示出了这种关系:

 

  对于怎么具体提取图像中的直线,就不细讲了,可以查阅相关图像处理书籍,简略讲一下实现过程,以及用到的两个重要函数:

实现过程:

        首先通过Canny算子获取直线的边缘,然后通过Hough变换获取直线边缘在图像中的坐标,最后按照坐标绘画出来。

        Canny函数:

cv.Canny( image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]] ) -> edges

这里是cv中的canny函数的一种用法,他需要输入6个参数:

image:这是需要输入的图像数据。

threshold1:这是下阈值

threshold2:这是上阈值

可以对照上文中实际的边缘特点的曲线图来理解,灰度值在这两个阈值中间会被认定为边界

apertureSize:Sobel算子的孔径大小。一般用3×3大小的卷积核

Canny算子最终返回的是一个与原图像大小相同的存储边缘数据的矩阵,它是一个二值图像。

        HoughLinesP()函数:

cv.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]]) ->lines

这是cv中HoughLinesP()函数,它需要输入6个参数。

image:这是存储了边缘数据的图像,也就是经过Canny算子提取出来的边缘。

rho:以像素为单位的累加器的距离分辨率。

theta:以弧度表示的累加器的角度分辨率。

threshold:这是与累加器中的结果进行对比,只有大于这个阈值的点,才会被认定是一条直线

minLineLength:最小的线长度,如果线长度低于这个设定的最小长度,将不会被认定为一条直线

maxLineGap:同一直线上的点之间连接的最大允许间距。

HoughLinesP函数最终返回的是一个存储每一段线段起点和终点的矩阵[x1,y1,x2,y2]

实现程序如下所示,所用的图片是用绘图软件随意绘制的图像:

import cv2
import numpy as np
img = cv2.imread('C:\\Users\\yu\\Desktop\\picture_csdn\\lines_test.png', cv2.IMREAD_COLOR)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('img_gray', img_gray)
# Canny边缘检测
img_Canny = cv2.Canny(img_gray, 0, 250, (3, 3))
cv2.imshow('img_canny', img_Canny)

result_HoughLinesP = cv2.HoughLinesP(img_Canny, 1, 1 * np.pi / 180, 10, minLineLength=1, maxLineGap=5)

# 画出检测的线段
for result in result_HoughLinesP:
    for x1, y1, x2, y2 in result:
        cv2.line(img, (x1, y1), (x2, y2), (0, 255, 255), 2)
cv2.imshow('result', img)

cv2.waitKey(0)

实验图像:

经过Canny算子提取的边缘图像:

 

最终画出直线的图像:

参考资料:hough变换检测直线(python)_静谧、淡雅-CSDN博客_hough变换直线检测 python

猜你喜欢

转载自blog.csdn.net/kuwola/article/details/122507069