OpenCV-Python教程(9、使用霍夫变换检测直线)
来源:互联网 发布:uipath软件 编辑:程序博客网 时间:2024/06/05 19:12
相比C++而言,Python适合做原型。本系列的文章介绍如何在Python中用OpenCV图形库,以及与C++调用相应OpenCV函数的不同之处。这篇文章介绍在Python中使用OpenCV的霍夫变换检测直线。
提示:
- 转载请详细注明原作者及出处,谢谢!
- 本文介绍在OpenCV-Python中使用霍夫变换检测直线的方法。
- 本文不介详细的理论知识,读者可从其他资料中获取相应的背景知识。笔者推荐清华大学出版社的《图像处理与计算机视觉算法及应用(第2版) 》。
霍夫变换
Hough变换是经典的检测直线的算法。其最初用来检测图像中的直线,同时也可以将其扩展,以用来检测图像中简单的结构。
OpenCV提供了两种用于直线检测的Hough变换形式。其中基本的版本是cv2.HoughLines。其输入一幅含有点集的二值图(由非0像素表示),其中一些点互相联系组成直线。通常这是通过如Canny算子获得的一幅边缘图像。cv2.HoughLines函数输出的是[float, float]形式的ndarray,其中每个值表示检测到的线(ρ , θ)中浮点点值的参数。下面的例子首先使用Canny算子获得图像边缘,然后使用Hough变换检测直线。其中HoughLines函数的参数3和4对应直线搜索的步长。在本例中,函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线。最后一个参数是经过某一点曲线的数量的阈值,超过这个阈值,就表示这个交点所代表的参数对(rho, theta)在原图像中为一条直线。具体理论可参考这篇文章。
- #coding=utf-8
- import cv2
- import numpy as np
- img = cv2.imread("/home/sunny/workspace/images/road.jpg", 0)
- 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[0]:
- rho = line[0] #第一个元素是距离rho
- theta= line[1] #第二个元素是角度theta
- print 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()
结果如下:
注意:
在C++中,HoughLines函数得到的结果是一个向量lines,其中的元素是由两个元素组成的子向量(rho, theta),所以lines的访问方式类似二维数组。因此,可以以类似:
- std::vector<cv::Vec2f>::const_iterator it= lines.begin();
- float rho= (*it)[0];
- float theta= (*it)[1];
这样的方式访问rho和theta。
而在Python中,返回的是一个三维的np.ndarray!。可通过检验HoughLines返回的lines的ndim属性得到。如:
- lines = cv2.HoughLines(edges,1,np.pi/180,118)
- print lines.ndim
- #将得到3
- #上面例子中检测到的lines的数据
- 3 #lines.ndim属性
- (1, 5, 2) #lines.shape属性
- #lines[0]
- [[ 4.20000000e+01 2.14675498e+00]
- [ 4.50000000e+01 2.14675498e+00]
- [ 3.50000000e+01 2.16420817e+00]
- [ 1.49000000e+02 1.60570288e+00]
- [ 2.24000000e+02 1.74532920e-01]]
- ===============
- #lines本身
- [[[ 4.20000000e+01 2.14675498e+00]
- [ 4.50000000e+01 2.14675498e+00]
- [ 3.50000000e+01 2.16420817e+00]
- [ 1.49000000e+02 1.60570288e+00]
- [ 2.24000000e+02 1.74532920e-01]]]
概率霍夫变换
观察前面的例子得到的结果图片,其中Hough变换看起来就像在图像中查找对齐的边界像素点集合。但这样会在一些情况下导致虚假检测,如像素偶然对齐或多条直线穿过同样的对齐像素造成的多重检测。
要避免这样的问题,并检测图像中分段的直线(而不是贯穿整个图像的直线),就诞生了Hough变化的改进版,即概率Hough变换(Probabilistic Hough)。在OpenCV中用函数cv::HoughLinesP 实现。如下:
- #coding=utf-8
- import cv2
- import numpy as np
- img = cv2.imread("/home/sunny/workspace/images/road.jpg")
- 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()
- #经验参数
- minLineLength = 200
- maxLineGap = 15
- lines = cv2.HoughLinesP(edges,1,np.pi/180,80,minLineLength,maxLineGap)
- for x1,y1,x2,y2 in lines[0]:
- cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)
- cv2.imshow('Result', img)
- cv2.waitKey(0)
- cv2.destroyAllWindows()
未完待续。。。
参考资料:
1、《Opencv2 Computer Vision Application Programming Cookbook》
2、《OpenCV References Manule》
- OpenCV-Python教程(9、使用霍夫变换检测直线)
- OpenCV-Python教程(9、使用霍夫变换检测直线)
- OpenCV-Python教程(9)(10)(11): 使用霍夫变换检测直线 直方图均衡化 轮廓检测
- python+opencv实现霍夫变换检测直线
- opencv 霍夫变换检测直线
- opencv 霍夫变换检测直线
- opencv 霍夫变换检测直线(转)
- opencv 霍夫变换检测直线
- opencv-霍夫变换 检测直线
- opencv 霍夫变换检测直线
- Python下opencv使用笔记(十一)(详解hough变换检测直线与圆)
- OpenCV笔记11:霍夫变换检测直线
- opencv 霍夫变换检测直线 例程中的1000
- 霍夫变换直线检测及opencv实现
- 霍夫变换直线检测及opencv实现
- 霍夫变换检测直线及openCV代码
- 【OpenCV】利用霍夫变换进行直线检测
- opencv检测直线方法——霍夫变换
- 程序员最常去的网站
- 三种方式使得iOS应用能够在后台进行数据更新和下载
- OpenCV-Python教程(8、Canny边缘检测)
- 取消百度SiteApp转码
- Android 编程下 App Install Location
- OpenCV-Python教程(9、使用霍夫变换检测直线)
- xml输入点击事件是如传递给java的
- 是什么时候开始发现,你在教父母东西了
- android studio 删除、导入jar包
- OpenCV-Python教程(10、直方图均衡化)
- Android多种方式实现自定义Dialog对话框
- C++建议
- 用网页服务器实现钢琴弹奏(使用Wizwiki-W7500)
- GRID汇总