霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法。主要用来从图像中分离出具有某种相同特征的几何形状(如,直线,圆等)。最基本的霍夫变换是从黑白图像中检测直线(线段)。

直线检测

  • 直线的表示方式

对于平面中的一条直线,在笛卡尔坐标系中,常见的有点斜式,两点式两种表示方法。然而在hough变换中,考虑的是另外一种表示方式:使用(r,theta)来表示一条直线。其中r为该直线到原点的距离,theta为该直线的垂线与x轴的夹角。如下图所示。

也就是霍夫变换中表示一条直线的参数变成了(r,theta)。

  • 如何判断多个点是否在同一直线上

当我们的对象变成点时,我们知道一个点可以发射出无数条直线,根据霍夫变换的直线表达形式,假设这个点为i,则通过这个点的直线我们用(ri,thetai)表示。再假设一个点为j,则通过点j的一系列直线我们用(rj,thetaj)表示。我们知道两点决定一条直线,所以这两个点的直线必定有ri=rj,thetai= thetaj的时候。

那如果是三个点呢,假设第三个点是k,则通过k点的一系列直线为(rk,thetak),如果三点在一条直线上,那必定有某个ri=rj=rk = r,thetai = thetaj= thetak = theta。

在霍夫变换检测直线时我们需要找到这样一样直线,如何找到这条直线呢?

  • 如何检测出直线

假设有N个点,我们要检测其中的直线,也就是我们要找到具体的r和theata。对于上面所说的每个点可以通过无数条直线,这里我们设为n条(通常 n = 180),则我们一起可以找到Nn个(r, theata),对这Nn个(r,theata),我们可以利用统计学,统计到在theta=某个值theta_i时,多个点的r近似相等于r_i。也就是说这多个点都在直线(r_i,theta_i)上。

  • 举例说明

如果空间中有3个点,如何判断这三个点在不在一个直线上,如果在,这条直线是的位置为?

这个例子中,对于每个点均求过该点的6条直线的(r,theta)坐标,共求了3*6个(r,theta)坐标。可以发现在theta=60时,三个点的r都近似为80.7,由此可判定这三个点都在直线(80.7,60)上。

通过 r-o-theta 坐标系可更直观表示这种关系,如下图:图中三个点的(r,theta)曲线汇集在一起,该交点就是同时经过这三个点的直线。

在实际的直线检测情况中,如果超过一定数目的点拥有相同的(r,theta)坐标,那么就可以判定此处有一条直线。在r-O-theta 坐标系图中,明显的交汇点就标示一条检测出的直线。
如下图,可以判定出平面上的点共构成了两条直线,即检测出两条直线。

OpenCV的算法中内部实际维护的是一个二维数组,当出现相同的(r,theta)则acc[r][theta]自增一,最后我们通过acc[r][theta]阈值的大小来判断极坐标下的该点对应的是否是一条直线

上面参考:http://blog.163.com/yuyang_tech/blog/static/21605008320130233343990/

这里插入一个用opencv进行霍夫变化检测直线的例子

http://blog.sina.com.cn/s/blog_60b330b801018md4.html

先进行边缘提取,再设置一些线段的容忍长度,可以检测到直线。

变换图示

霍夫直线检测的两种方法

1.获取灰度图像
2.canny边缘检测
3.获取霍夫直线信息
4.算出直线位置,画出每条直线

一:HoughLines霍夫变换

def line_detection(image):gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)edges = cv.Canny(gray,50,150,apertureSize=3)    #apertureSize是sobel算子大小,只能为1,3,5,7lines = cv.HoughLines(edges,1,np.pi/180,200)  #函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线for line in lines:rho,theta = line[0]  #获取极值ρ长度和θ角度a = np.cos(theta)  #获取角度cos值b = np.sin(theta)  #获取角度sin值x0 = a * rho  #获取x轴值y0 = b * rho  #获取y轴值  x0和y0是直线的中点x1 = int(x0 + 1000*(-b))  #获取这条直线最大值点x1y1 = int(y0 + 1000*(a))   #获取这条直线最大值点y1x2 = int(x0 - 1000 * (-b))  #获取这条直线最小值点x2  y2 = int(y0 - 1000 * (a))  #获取这条直线最小值点y2  其中*1000是内部规则cv.line(image,(x1,y1),(x2,y2),(0,0,255),2)  #开始划线cv.imshow("image line",image)src = cv.imread("./l.png")  #读取图片
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)    #创建GUI窗口,形式为自适应
cv.imshow("input image",src)    #通过名字将图像和窗口联系line_detect_possible_demo(src)cv.waitKey(0)   #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作
cv.destroyAllWindows()  #销毁所有窗口

相关知识补充

(一)求取直线的最大值和最小值

pt1.x = cvRound(x0 + 1000*(-b));这段代码。一开始可能不是很好理解。查阅了资料和原理,现在写下来分享。

这里的pt1和pt2是一条直线的两个端点,这里已知下图中的rh0 和θ,现在只需要求图中“任意”两点, 使用OpenCV的cvLine函数画出pt1点到pt2的直线 。

看看下图 就明白这里1000什么的是为什么了。

这里是取了点(x0,y0)在直线上上下1000的距离,那么用cvLine画出来的线段就是从pt1 -> pt2的了。那么pt1->pt2的直线距离就是2000。可以取其他的距离,不一定去1000,如600也可以,具体的数字可以自己定义。

1.这个地方也许会出现检测出来的线段长度比pt1->pt2还大,即包含了我们画的线段 , 这是肯定的。

2. 还会出现本来线段没有pt1->pt2这么长,那么我们画的就会过长了。 也是肯定会出现的情况。

因为:CV_HOUGH_STANDARD方法 只能得出rh0 和 θ的值。 这两个值只能确定直线,而不能确定线段是从哪开始到哪结束。

此方法标准型的霍夫变换检测只能确定线段对应的直线。如果你想得到一条直线的两个端点的具体坐标,可以使用CV_HOUGH_PROBABILISTIC(概率型霍夫变换).

(二)HoughLines方法

def HoughLines(image, rho, theta, threshold, lines=None, srn=None, stn=None, min_theta=None, max_theta=None): # real signature unknown; restored from __doc__
cv.HoughLines(edges,1,np.pi/180,200)
cv2.HoughLines函数输出的是[float, float]形式的ndarray,其中每个值表示检测到的线(ρ , θ)中浮点点值的参数。
第一个参数image:是canny边缘检测后的图像

第二个参数rho和第三个参数theta:对应直线搜索的步长。在本例中,函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线。

最后一个参数threshold:是经过某一点曲线的数量的阈值,超过这个阈值,就表示这个交点所代表的参数对(rho, theta)在原图像中为一条直线
观察前面的例子得到的结果图片,其中Hough变换看起来就像在图像中查找对齐的边界像素点集合。但这样会在一些情况下导致虚假检测,如像素偶然对齐或多条直线穿过同样的对齐像素造成的多重检测。

二:HoughLinesP概率霍夫变换(是加强版)使用简单,效果更好,检测图像中分段的直线(而不是贯穿整个图像的直线)

def line_detect_possible_demo(image):gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)edges = cv.Canny(gray, 50, 150, apertureSize=3)  # apertureSize是sobel算子大小,只能为1,3,5,7lines = cv.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50,maxLineGap=10)  #函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线for line in lines:print(type(line))   #多维数组x1,y1,x2,y2 = line[0]cv.line(image,(x1,y1),(x2,y2),(0,0,255),2)cv.imshow("line_detect_possible_demo",image)

相关知识补充:

(一)HoughLinesP方法

def HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None): # real signature unknown; restored from __doc__
cv.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50,maxLineGap=10)

第一个参数是需要处理的原图像,该图像必须为cannay边缘检测后的图像;

第二和第三参数:步长为1的半径和步长为π/180的角来搜索所有可能的直线

第四个参数是阈值,概念同霍夫变换

第五个参数:minLineLength-线的最短长度,比这个线短的都会被忽略。

第六个参数:maxLineGap-两条线之间的最大间隔,如果小于此值,这两条线就会被看成一条线。

这个函数的返回值就是直线的起点和终点。

OpenCV---直线检测相关推荐

  1. opencv 直线检测

    直线检测必须对着边缘检测的结果二值图检测,不能对着灰度图检测 二值图和边缘检测的结果图还是不一样的, 二值图的检测结果: api: cv.HoughLines(image, rho, theta, t ...

  2. OpenCV 直线检测应用:识别试卷中填空题

    上图是待检测的图,主要目标是识别图中填空题的下划线,这样也就找到了试卷中的答案 1.配置OpenCV 环境:Win10+VS2015 + OpenCV3.4.1 1.下载OpenCV,到官网下载相对应 ...

  3. opencv 直线检测 java_OpenCV实现图像的直线检测

    上一篇博文介绍了图像的Canny边缘检测,本文主要介绍图像的直线检测部分,主要使用概率霍夫变换来检测直线,调用的函数为HoughLinesP(),下面给出代码部分以及直线检测效果图: 1.代码部分: ...

  4. opencv 直线检测笔记

    目录 c++ 检测垂直线 检测所有线: c++ C++: void HoughLinesP(InputArray image, OutputArray lines, double rho, doubl ...

  5. OpenCV直线检测(一)—— LSD

    头文件 #include "opencv2/imgproc.hpp" 类定义 cv::LineSegmentDetector Class Reference Example 官方示 ...

  6. opencv判断 线夹角_python opencv实现直线检测并测出倾斜角度(附源码+注释)

    由于学习需要,我想要检测出图片中的直线,并且得到这些直线的角度.于是我在网上搜了好多直线检测的代码,但是没有搜到附有计算直线倾斜角度的代码,所以我花了一点时间,自己写了一份直线检测并测出倾斜角度的代码 ...

  7. cvHoughLines2霍夫直线检测函数详解及源码解析

    转载请注明出处. 文章链接:https://blog.csdn.net/duiwangxiaomi/article/details/126406184 博文目录 一. 前言 二. cvHoughLin ...

  8. OpenCV标准霍夫直线检测详解

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转载自:OpenCV学堂 霍夫直线检测 对于图像来说可以从笛卡 ...

  9. OpenCV直线拟合检测

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:opencv学堂 OpenCV直线拟合检测 霍夫直线检测 ...

  10. LSD快速直线检测的原理概要及OpenCV代码实现(CV类LineSegmentDetector)

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 LSD快速直线检测算法是由Rafael Grom ...

最新文章

  1. 对象冒充_使用您的精神探照灯进行冒充冒名顶替综合症
  2. h5的语义化部分_H5 部分新语义化标签
  3. 【Web安全】利用burp抓包和CSRF伪造进入admin真实后台
  4. 二维数组中的查找问题
  5. 理解关联容器“map”的关键点
  6. Java Formatter toString()方法与示例
  7. 6 日期字符串转日期_日期居然用字符串保存?我笑了
  8. 力扣题目——88. 合并两个有序数组
  9. 有的同学提出安全问题
  10. 实对称矩阵的特征值求法_理解矩阵得相似对角化
  11. postman下载安装和基础使用教程(官网)
  12. VMware虚拟机无法识别U盘
  13. Python 实现简单的客户端认证
  14. 工具传送门(持续更新)
  15. java解压在线tgz文件
  16. 2022年危险化学品经营单位主要负责人及危险化学品经营单位主要负责人模拟考试
  17. 工作、求职需要记住的英文缩写,offer讨论避免尴尬
  18. 数据库课程设计《教务信息管理系统》
  19. AndroidStudio layout Inspector工具无法连接真机
  20. python repair修复功能_NI 技术支持|我的插件显示需要修复(REPAIR)了该怎么办?...

热门文章

  1. DFS 下沙小面的(2)
  2. [ZT]软件质量属性
  3. WIN7 7100+TOAD最新版本9.7.2.5切换到SCRIPT显示注释的时候是乱码。表数据中文显示正常!求解决方案。...
  4. 最近学习 variant configuration
  5. Spark性能优化指南——高级篇【2】
  6. 【原创】打造基于Dapper的数据访问层
  7. PhpStorm中如何使用Xdebug工具,入门级操作方法
  8. eclipse、MyEclipse实现批量改动文件编码
  9. wireless 时好时断的一些解决的建议
  10. Dagger 注入的简单原理