hough变换_霍夫变换——形状特征提取算法:车道线检测

 霍夫变换是一种特征提取,被广泛应用在图像分析、电脑视觉以及数位影像处理。霍夫变换是用来辨别找出物件中的特征,例如:线条。他的算法流程大致如下,给定一个物件、要辨别的形状的种类,算法会在参数空间中执行投票来决定物体的形状,而这是由累加空间(accumulator space)里的局部最大值来决定。

理论上,霍夫变换就是对于原图上的每一个直线都在参数空间画一条线,最终找出参数空间变换线比较密集的地方在对应回到xy 空间坐标系。为了方便理解,下面简单写了一下草稿,希望对你有帮助。

注意:建正交直角坐标系过程中, 要选取好以图片的某个方位左起始点,以像素作为标度。

3e9df9dcc3c67d0b855d181776689c8a.png

下图所示:

图像是一个 2D 矩阵,超过一些 x 和 y 坐标系,一条线可以描述为y = mx + b

6afc3860070d5fe5c2d0e03d620953fe.png

霍夫空间的形成:

73286501bcd64582470e09e72345c247.png

输入的图片中有两条粗直线,经过霍夫变换后的结果得到accumaltor矩阵,右图就是把accumaltor矩阵画出来,越亮值越大,越黑值越小。在右图中,有两个很明显的亮点, 这两个亮点分别代表两条不同参数的直线,与输入的图片(下图)吻合。然后读取矩阵的两个最大值就可以得出这两条线距画面中心距离以及角度。

e94aada019f145e2cb09c15d8f69b9c7.png

类似地,如果给的点坐标越多,形成的霍夫空间为:

ddbf987f47e04d5b4e67ffc3795fb752.png

图像如何使用霍夫变换?

Hough 变换是一种用于检测图像中简单形状(如圆、线等)的特征提取方法。

"简单"特征由形状表示以参数表示派生。"简单"形状仅由几个参数表示,例如,一条线可以由其斜率和截距表示,也可以用 x、y 和半径表示。

在我们下面的行示例中,Hough 变换将负责处理图像上的点并计算霍夫空间中的值。在 OpenCV 中,使用霍夫变换的线路检测在函数和(概率霍夫变换)中实现。

直线检测cv2.HoughLinesP()函数原型:HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None) image:必须是二值图像,推荐使用canny边缘检测的结果图像;rho: 线段以像素为单位的距离精度,double类型的,推荐用1.0theta:线段以弧度为单位的角度精度,推荐用numpy.pi/180threshod: 累加平面的阈值参数,int类型,超过设定阈值才被检测出线段,值越大,基本上意味着检出的线段越长,检出的线段个数越少。根据情况推荐先用100试试lines:这个参数的意义未知,发现不同的lines对结果没影响,但是不要忽略了它的存在 minLineLength:线段以像素为单位的最小长度,根据应用场景设置 maxLineGap:同一方向上两条线段判定为一条线段的最大允许间隔(断裂),超过了设定值,则把两条线段当成一条线段,值越大,允许线段上的断裂越大,越有可能检出潜在的直线段
import cv2import numpy as np
original_img = cv2.imread("lane.png", 0)
img = cv2.resize(original_img, None, fx=0.8, fy=0.8,interpolation=cv2.INTER_CUBIC)
img = cv2.GaussianBlur(img, (3, 3), 0)
edges = cv2.Canny(img, 50, 150, apertureSize=3)
lines = cv2.HoughLines(edges, 1, np.pi / 180, 118) # 这里对最后一个参数使用了经验型的值result = img.copy()for line in lines:rho = line[0][0] # 第一个元素是距离rhotheta = line[0][1] # 第二个元素是角度thetaprint(rho)print(theta)if (theta < (np.pi / 4.)) or (theta > (3. * np.pi / 4.0)): # 垂直直线pt1 = (int(rho / np.cos(theta)), 0) # 该直线与第一行的交点# 该直线与最后一行的焦点pt2 = (int((rho - result.shape[0] * np.sin(theta)) / np.cos(theta)), result.shape[0])
cv2.line(result, pt1, pt2, (255)) # 绘制一条白线else: # 水平直线pt1 = (0, int(rho / np.sin(theta))) # 该直线与第一列的交点# 该直线与最后一列的交点pt2 = (result.shape[1], int((rho - result.shape[1] * np.cos(theta)) / np.sin(theta)))
cv2.line(result, pt1, pt2, (255), 1) # 绘制一条直线cv2.imshow('Canny', edges)
cv2.imshow('Result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 另一解法:import cv2import numpy as np# Read imageimg = cv2.imread('lane.jpg', cv2.IMREAD_COLOR)# Convert the image to gray-scalegray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Find the edges in the image using canny detectoredges = cv2.Canny(gray, 50, 200)# Detect points that form a linelines = cv2.HoughLinesP(edges, 1, np.pi/180, 100,minLineLength=10, maxLineGap=250)# Draw lines on the imagefor line in lines:    x1, y1, x2, y2 = line[0]    cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 3)# Show resultcv2.imshow("Result Image", img) cv2.waitKey() ##记得写上,否则闪退cv2.destroyAllWindows()

972e504c54d5cb4522c0da6f4ed38552.png

1acd88595c245be0c28c202f6de573d9.png

类似地还有圆形检测,这里就不介绍了,感兴趣的替换一下面的代码,并且找有圆形照片测试一下函数就可以。

霍夫圆形检测cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) → circles参数说明:image- 8位,单通道, 灰度输入图像。circles- 找到的圆的输出向量。每个向量被编码为3元素的浮点向量 (x,y,半径)。circle_storage - 在C函数中,这是一个将包含找到的圆的输出序列的内存存储。method- 使用检测方法。目前,唯一实现的方法是 CV_HOUGH_GRADIENT,基本上是 21HT,在[Yuen90]中有描述 。dp - 累加器分辨率与图像分辨率的反比。例如,如果 dp = 1,则累加器具有与输入图像相同的分辨率。如果 dp = 2,则累加器的宽度和高度都是一半。minDist -检测到的 圆的中心之间的最小距离。如果参数太小,除了真正的参数外,可能会错误地检测到多个邻居圈。如果太大,可能会错过一些圈子。param1 - 第一个方法特定的参数。在CV_HOUGH_GRADIENT的情况下, 两个传递给Canny()边缘检测器的阈值较高(较小的两个小于两倍)。param2 - 第二种方法参数。在CV_HOUGH_GRADIENT的情况下,它是检测阶段的圆心的累加器阈值。越小,可能会检测到越多的虚假圈子。首先返回对应于较大累加器值的圈子。minRadius -最小圆半径。maxRadius - 最大圆半径。

参考文献

https://zhuanlan.zhihu.com/p/47649796https://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html?highlight=houghlines#houghlineshttps://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值