本节介绍cv2.HoughLines()用来实现霍夫,以及改进版函数cv2.HoughLinesP()

HougLines函数

OpenCV中,cv2.HoughLines()用来实现霍夫直线变换。该函数要求所操作的原图像是一个二值图像

因此,在进行霍夫变换之前,需要将原图像进行二值化,或者进行Canny进行边缘检测。

语法:

lines = cv2.HoughLines( image, rho, theta, threshold )
  • image为原图像,必须是8位的单通道二值图像。如果是其他图像,需要进行转化。
  • rho为以像素为单位的距离r的精度。一般情况下,使用的精度为1
  • theta为角度θ的精度。一般情况下,使用的精度为π/180,表示要搜索所有可能的角度
  • threshold表示阈值。在上一节原理中有介绍。如果大于阈值,则认为存在,如果小于阈值,则认为这些点刚好碰巧在一条直线上,而不是实际存在直线
  • 返回值lines中的每个元素都是一对浮点数,表示检测到的直线的参数,即(r,θ),是numpy.ndarray类型

需要注意的是,检测出来的是直线而不是线段。

例:使用函数cv2.HoughLines()对图像进行霍夫变换,并观察结果。

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('building.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize=3)
orgb = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
oShow = orgb.copy()

lines = cv2.HoughLines(edges,1,np.pi/180,220)
for line in lines:
    rho,theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0+1000*(-b))
    y1 = int(y0+1000*(a))
    x2 = int(x0-1000*(-b))
    y2 = int(y0-1000*(a))
    cv2.line(orgb,(x1,y1),(x2,y2),(0,0,255),2)
plt.subplot(121)
plt.imshow(oShow)
plt.axis('off')
plt.subplot(122)
plt.imshow(orgb)
plt.axis('off')

plt.show()

运行结果:

霍夫变换结果

效果

不难看出,检测的效果并不好。

为了解决这样的误检测,人们提出了霍夫的改进版——概率霍夫变换。

HoughLinesP函数

概率霍夫变换对基本霍夫变换算法进行了一些修正,是霍夫变换算法的优化,它没有考虑所有的点相反,它只需要一个足以进行线检测的随机点子集即可。

为了更好地判断直线线段概率,霍夫变换算法还对选取直线的方法做了两点改进:

  • 所接受直线的最小长度。如果有超过阈值个数的像素点构成了一条直线,但是这条直线很短,那么就不会接受该直线作为判断结果,而认为该直线仅仅是图像中的若干像素点恰好随机组成了一种算法上的直线关系而已,实际原图上并不存在这条直线。
  • 接受直线时允许的最大像素点间距。如果有超过阈值个数的像素点构成一条直线,但是这组像素点之间的距离都很远,就不会接受该直线作为判断结果,而认为这些直线仅仅是图像中的若干个像素点恰好随机构成了一种算法上的直线关系而已,原始图像中不存在这条直线。

语法:

lines = cv2.HoughLinesP(img, rho, theta, threshold, minLineLength, maxLineGap)
  • image为原图像,必须是8位的单通道二值图像。如果是其他图像,需要进行转化。
  • rho为以像素为单位的距离r的精度。一般情况下,使用的精度为1
  • theta为角度θ的精度。一般情况下,使用的精度为π/180,表示要搜索所有可能的角度
  • minLineLength用来控制“接受直线的最小长度”的值,默认为0
  • maxLineGap用来控制共线线段的最小间隔,即一条线中两点的最大间隔。默认值为0。如果两点间的间隔超过了这个参数的值,就认为这两点不在一条线上
  • 返回值lines中的每个元素都是一对浮点数,表示检测到的直线的参数,即(r,θ),是numpy.ndarray类型

例:使用函数cv2.HoughLineP()对一幅图像进行霍夫变换,并观察结果。

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('building.jpg',-1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize=3)
orgb = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
oShow = orgb.copy()

lines = cv2.HoughLinesP(edges,1,np.pi/180,1,minLineLength=150,maxLineGap=20)
for line in lines:
    x1,y1,x2,y2 = line[0]
    cv2.line(orgb,(x1,y1),(x2,y2),(255,0,0),5)
plt.subplot(121)
plt.imshow(oShow)
plt.axis('off')
plt.subplot(122)
plt.imshow(orgb)
plt.axis('off')
plt.show()

实验1

实验2


素材:

building.jpg

net.png


博主个人公众号
版权声明 ▶ 本网站名称:陶小桃Blog
▶ 本文链接:https://www.52txr.cn/2022/OpenCV51.html
▶ 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行核实删除。
▶ 转载本站文章需要遵守:商业转载请联系站长,非商业转载请注明出处!!

最后修改:2022 年 05 月 26 日
如果觉得我的文章对你有用,请随意赞赏