python opencv -详解hough变换检测直线与圆
来源:互联网 发布:猴王开心水果源码php 编辑:程序博客网 时间:2024/05/17 22:47
标签:python opencv 图像处理 霍夫变换 数字图像
在数字图像中,往往存在着一些特殊形状的几何图形,像检测马路边一条直线,检测人眼的圆形等等,有时我们需要把这些特定图形检测出来,hough变换就是这样一种检测的工具。
Hough变换的原理是将特定图形上的点变换到一组参数空间上,根据参数空间点的累计结果找到一个极大值对应的解,那么这个解就对应着要寻找的几何形状的参数(比如说直线,那么就会得到直线的斜率k与常熟b,圆就会得到圆心与半径等等)。
关于hough变换,核心以及难点就是关于就是有原始空间到参数空间的变换上。以直线检测为例,假设有一条直线L,原点到该直线的垂直距离为p,垂线与x轴夹角为
可以看到的是这条直线在极坐标系下只有一个
可以看到,光是空间上的一个点在极坐标系下就可能在很多极坐标对所对应的直线上,具体有多少个极坐标对呢?那得看你的
ok前面说的是单单这一个点对应的极坐标系下的参数对,那么如果每个点都这么找一圈呢?也就是每个点在参数空间上都对应一系列参数对吧,现在把它们华仔同一个坐标系下会怎么样呢?为了方便,假设在这个直线上取3个点画一下:
那么可以看到,首先对于每一个点,在极坐标下,会存在一个周期的曲线来表示通过这个点,其次,这三个极坐标曲线同时经过一个点,要搞清楚的是,极坐标上每一个点对
再来分析这个算法。可以看到hough变换就是参数映射变换。对每一个点都进行映射,并且每一个映射还不止一次,
继续算法,分析这么多,可想而知那么一个hough变换在算法设计上就可以如下步骤:
(1)将参数空间
(2)然后对图像边界上的每一个点进行变换,变换到属于哪一组
(3)当所有点处理完成后,就来分析得到的
(4)有了
说了这么多,这就是原理上hough变换的最底层原理,事实上完全可以自己写程序去实现这些,然而,也说过,hough变换是一个耗时耗力的算法,自己写循环实现通常很慢,曾经用matlab写过这个,也有实际的hough变换例子可以看看:
虹膜识别(三):Hough变换检测内圆边缘
那么我们在实际中大可不必自己写,opencv已经集成了hough变换的函数,调用它的函数效率高,也很简单。
Opencv中检测直线的函数有cv2.HoughLines(),cv2.HoughLinesP()
函数cv2.HoughLines()返回值有三个(opencv 3.0),实际是个二维矩阵,表述的就是上述的
import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread(‘line.jpg‘) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度图像 #open to see how to use: cv2.Canny#http://blog.csdn.net/on2way/article/details/46851451 edges = cv2.Canny(gray,50,200)plt.subplot(121),plt.imshow(edges,‘gray‘)plt.xticks([]),plt.yticks([])#hough transformlines = cv2.HoughLines(edges,1,np.pi/180,160)lines1 = lines[:,0,:]#提取为为二维for rho,theta in lines1[:]: a = np.cos(theta)b = np.sin(theta)x0 = a*rhoy0 = b*rhox1 = int(x0 + 1000*(-b))y1 = int(y0 + 1000*(a))x2 = int(x0 - 1000*(-b))y2 = int(y0 - 1000*(a)) cv2.line(img,(x1,y1),(x2,y2),(255,0,0),1)plt.subplot(122),plt.imshow(img,)plt.xticks([]),plt.yticks([])
测试一个新的图,不停的改变 cv2.HoughLines最后一个阈值参数到合理的时候如下:
可以看到检测的还可以的。
函数cv2.HoughLinesP()是一种概率直线检测,我们知道,原理上讲hough变换是一个耗时耗力的算法,尤其是每一个点计算,即使经过了canny转换了有的时候点的个数依然是庞大的,这个时候我们采取一种概率挑选机制,不是所有的点都计算,而是随机的选取一些个点来计算,相当于降采样了。这样的话我们的阈值设置上也要降低一些。在参数输入输出上,输入不过多了两个参数:minLineLengh(线的最短长度,比这个短的都被忽略)和MaxLineCap(两条直线之间的最大间隔,小于此值,认为是一条直线)。输出上也变了,不再是直线参数的,这个函数输出的直接就是直线点的坐标位置,这样可以省去一系列for循环中的由参数空间到图像的实际坐标点的转换。
import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread(‘room.jpg‘) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度图像 #open to see how to use: cv2.Canny#http://blog.csdn.net/on2way/article/details/46851451 edges = cv2.Canny(gray,50,200)plt.subplot(121),plt.imshow(edges,‘gray‘)plt.xticks([]),plt.yticks([])#hough transformlines = cv2.HoughLinesP(edges,1,np.pi/180,30,minLineLength=60,maxLineGap=10)lines1 = lines[:,0,:]#提取为二维for x1,y1,x2,y2 in lines1[:]: cv2.line(img,(x1,y1),(x2,y2),(255,0,0),1)plt.subplot(122),plt.imshow(img,)plt.xticks([]),plt.yticks([])
可以看到这个方法似乎更好些,速度还快,调参数得到较好的效果就ok了。
Ok说完了直线的检测,再来说说圆环的检测,我们知道圆的数学表示为:
从而一个圆的确定需要三个参数,那么就需要三层循环来实现(比直线的多一层),从容把图像上的所有点映射到三维参数空间上。其他的就一样了,寻找参数空间累加器的最大(或者大于某一阈值)的值。那么理论上圆的检测将比直线更耗时,然而opencv对其进行了优化,用了一种霍夫梯度法,感兴趣去研究吧,我们只要知道它能优化算法的效率就可以了。关于函数参数输入输出:
cv2.HoughCircles(image, method, dp, minDist, circles, param1, param2, minRadius, maxRadius)
这个时候输入为灰度图像,同时最好规定检测的圆的最大最小半径,不能盲目的检测,否侧浪费时间空间。输出就是三个参数空间矩阵。
来个实际点的人眼图像,把minRadius和maxRadius调到大圆范围检测如下:
import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread(‘eye.jpg‘)gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度图像 plt.subplot(121),plt.imshow(gray,‘gray‘)plt.xticks([]),plt.yticks([])#hough transformcircles1 = cv2.HoughCircles(gray,cv2.HOUGH_GRADIENT,1,100,param1=100,param2=30,minRadius=200,maxRadius=300)circles = circles1[0,:,:]#提取为二维circles = np.uint16(np.around(circles))#四舍五入,取整for i in circles[:]: cv2.circle(img,(i[0],i[1]),i[2],(255,0,0),5)#画圆 cv2.circle(img,(i[0],i[1]),2,(255,0,255),10)#画圆心plt.subplot(122),plt.imshow(img)plt.xticks([]),plt.yticks([])
把半径范围调小点,检测内圆:
至此圆的检测就是这样。
版权声明:本文为博主原创文章,未经博主允许不得转载。
Python下opencv使用笔记(十一)(详解hough变换检测直线与圆)
标签:python opencv 图像处理 霍夫变换 数字图像
原文:http://blog.csdn.net/on2way/article/details/47028969
- python opencv -详解hough变换检测直线与圆
- Python下opencv使用笔记(十一)(详解hough变换检测直线与圆)
- Hough 变换检测直线、圆
- OpenCV自学笔记5:Hough变换检测直线和圆
- OpenCV自学笔记27. Hough变换:检测直线和圆
- OpenCV学习之Hough变换检测直线
- Opencv图像识别从零到精通(22)-----hough变换检测直线与圆
- Hough变换检测直线
- Hough 变换检测直线
- Hough变换检测直线
- Hough变换直线检测
- hough变换检测直线
- Hough变换检测直线
- Hough变换直线检测
- Hough变换-直线检测
- Hough变换直线检测
- Hough变换检测直线
- Hough变换检测直线
- Q94:怎么用ray tracing画部分圆环(Part Tori)
- [Bootkit]开源Bootkit技术(三)vBootkit
- 一个小巧好用的个人知识管理系统-TiddlyWiki.
- Python-内置数据类型
- div和section有什么区别?在加一个article标签
- python opencv -详解hough变换检测直线与圆
- JAVA学习第五天
- 冒泡排序的优化
- Tomcat安装目录下每个文件夹的功能和作用
- 反复器(Iterator)
- 数组中只出现一次的数字(两个)
- fl2440——u-boot的移植
- JSP/Servlet 工作原理
- java实现---杭电2037