Halcon实例之hough变换检测圆
1. 问题描述
在工业检测中,我们有时需要找到图像中的圆,如下图所示,可能是需要对图中的目标进行计数,也可能是需要定位到这些目标进行后续的检测. 该图像来自OpenCV的示例图像smarties.png 在本文中,因为主要任务是目标定位,所以把这张图的颜色细节忽略掉,转换成灰度图来进行处理.
2. hough_circles算子解析
Halcon中用来进行hough圆检测的算子为hough_circles 算子原型为 hough_circles(RegionIn:RegionOut:Radius, Percent, Mode) 其中,
RegionIn: 输入的Object,必须为Region,相当于对原图进行二值化 RegionOut: 检测得到的可能的圆心位置,单个圆检测的结果区域可能是若干个像素区域,不一定是单个像素 Radius: 程序设计者需要预先知道像素半径值Radius Percent: 待检测圆的完整度,对于完整的圆一般使用90%即可 Mode: 取值为0 1 2,其中,
0模式下,设定的Radius半径针对圆区域(往往是圆环)的外边缘, 1模式下,设定的半径Radius针对圆环的中间线, 2模式下,设定的半径Radius针对圆环的内边缘
3. 检测圆实例
回到我们初始的那个问题,对这幅图像进行处理. 以下是Halcon的实例代码:
read_image (Smarties, './smarties.png')
rgb1_to_gray (Smarties, GrayImage)
edges_sub_pix (GrayImage, Edges, 'canny', 1, 40, 80)
select_contours_xld (Edges, SelectedContours, 'contour_length', 140, 220, -0.5, 0.5)
gen_region_contour_xld (SelectedContours, Region, 'filled')
opening_circle (Region, RegionOpening, 13.5)
union1 (RegionOpening, RegionUnion)
hough_circles (RegionUnion, RegionOut, 25, 90, 0)
connection (RegionOut, ConnectedRegions)
area_center (ConnectedRegions, Area, Row, Column)
gen_cross_contour_xld (Cross, Row, Column, 6, 0.785398)
tuple_gen_const (|Area|, 26, Radiuses)
gen_circle (Circle, Row, Column, Radiuses)
gen_contour_region_xld (Circle, Contours, 'border')
dev_set_line_width (2)
dev_set_color ('green')
dev_clear_window ()
dev_display (GrayImage)
dev_display (Cross)
dev_display (Contours)
代码的整体思路整理如下:
- 读取原图;
- 将原图转换为灰度图;
- 在灰度图中应用边缘检测,这里用的是canny边缘检测算子,针对这张图,阈值选的是40和80之间;
- 对得到的边缘进行筛选,去除长度不符的边缘;
- 由筛选得到的边缘生成Region;
- 对Region进行一次形态学处理,分离不同的目标个体,然后再合并Region;
- 应用hough_circles算子,这里选择的半径为25,因为检测的是完整圆弧,百分比设90,这样就能得到检测所得的圆心位置(但并不是很精确,可以看到每个圆心都是若干个像素);
- 对每一“团”圆心Region计算质心,这样计算不是很精确,但是对于本例足够使用;
- 通过圆心和半径画出结果
4. 结果讨论
A. 从结果可以看出,我们找到了所有完整的目标,图像左下角的两个不完整目标则没有找到.
B. 图像中的目标并不是非常圆,而通过算法找到的圆的圆心则基本上位于目标的中心.
C. 了解hough检测原理的同学应该知道,如果不对Radius加以指定,那么算子需要在三维空间中求解圆锥面截面圆的交点,计算量过大,所以我们看到Halcon在实现这个算子的过程中也是通过限定Radius,将求解限定在二维空间.
D. Halcon中还有一个hough_circle_trans 算子,可以看一下得分图(极坐标空间图):
hough_circle_trans (RegionUnion, HoughImage, 25)
图中越亮的点得分越高,也即目标圆心点.
E. 本文中代码不需要进行边缘提取也能得到结果:
read_image (Smarties, './smarties.png')
rgb1_to_gray (Smarties, GrayImage)
threshold(GrayImage, RegionThresh, 0, 200)
hough_circles (RegionThresh, RegionOut, 25, 90, 0)
connection (RegionOut, ConnectedRegions)
area_center (ConnectedRegions, Area, Row, Column)
gen_cross_contour_xld (Cross, Row, Column, 6, 0.785398)
tuple_gen_const (|Area|, 25, Radiuses)
gen_circle (Circle, Row, Column, Radiuses)
gen_contour_region_xld (Circle, Contours, 'border')
dev_set_line_width (2)
dev_set_color ('green')
dev_clear_window ()
dev_display (GrayImage)
dev_display (Cross)
dev_display (Contours)
注意对比一下以上结果和做了边缘提取+形态学处理之后的结果,很明显的是,在左侧第二个目标的检测效果上,前者不如后者.这是由于图像中的阴影对找圆的结果造成了影响.
→
\rightarrow
→本文对hough圆检测的原理未作阐述,因为网上解释这部分原理的博客很多,下面也贴一两个链接,有兴趣的话可以去阅读一下:
- 已故大神浅墨(毛星云)关于opencv霍夫检测原理的博客文章
- LancerHarries关于霍夫变换的博客文章
- Hough变换检测原理
作者水平有限,若有错漏,欢迎指正,轻喷勿骂
|