《HALCON机器视觉与算法原理编程实践》第10章 边缘检测
文章目录
- 10.1 像素级边缘提取
- 10.1.1 经典的边缘检测算子
- 10.1.2 边缘检测的一般流程
- 10.1.3 sobel_amp算子
- 10.1.4 edges_image算子
- 10.1.5 其它滤波器
- 10.2 亚像素级边缘提取
- 10.2.1 edges_sub_pix 算子
- 10.2.2 edges_color_sub_pix 算子
- 10.2.3 lines_gauss 算子
- 10.3 轮廓处理
10.1 像素级边缘提取
像素级边缘提取,直观点说,也就是颜色的边缘提取。
10.1.1 经典的边缘检测算子
Sobel算子
Sobel 算子是一个主要用作边缘检测的离散微分算子 (discrete differentiation operator)。 它Sobel算子结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。Laplce算子
Laplacian 算子是n维欧几里德空间中的一个二阶微分算子,定义为梯度grad()的散度div()。Canny算子
Canny边缘检测算子是John F.Canny于 1986 年开发出来的一个多级边缘检测算法。更为重要的是 Canny 创立了边缘检测计算理论(Computational theory ofedge detection),解释了这项技术是如何工作的。Canny边缘检测算法以Canny的名字命名,被很多人推崇为当今最优的边缘检测的算法。
(1)Sobel算子在边缘检测的同事尽量减少了噪声的影响,比较容易实现。效果比较好,是很常用的边缘检测方法。
(2)Laplace算子是一种各向同性算子,比较适用于只关心边缘的位置而不考虑其周围像素的灰度差值的情况。只适用于无噪声图像。存在噪声的情况下,要先对图像进行低通滤波处理。
(3)Canny算子是目前理论相对最完善的一种边缘检测算法,但也存在不足之处:为了得到较好的边缘检测结果,通常需要使用较大的滤波尺度,这样容易丢失一些细节。
10.1.2 边缘检测的一般流程
- 获取图像
- 选择感兴趣的区域
- 图像滤波
- 提取边缘
- 边缘处理
- 显示结果
10.1.3 sobel_amp算子
sobel_amp - 使用Sobel算子检测边缘(幅度)。
sobel_amp(图片:边缘图像:滤波器方式,掩膜大小:)
read_image(Image,'data/flower')rgb1_to_gray (Image, GrayImage)sobel_amp(GrayImage,Amp,'sum_abs',3)threshold(Amp,Edg,100,255)skeleton (Edg, Skeleton)dev_clear_window ()dev_display (Skeleton)
10.1.4 edges_image算子
edges_image(Image : ImaAmp, ImaDir : Filter, Alpha, NMS, Low, High : )
ImaAmp: 输出变量,说的是edges的amplitude,其实就是梯度的大小(因为边缘检测最重要的几种方法中一种就是基于灰度值梯度的计算,这个算子中用的那些滤波器就是这样的)。
ImaDir: 输出变量,这个呢,说的是edges的方向,其实就是看灰度值变化的方向了,计算出灰度值是从小变大了还是从大变小了。
Alpha: 这个值在使用的时候要注意,小一些的值会导致比较强的平滑,从而图像中的细节就会变得更少。(和Canny算子正好相反,因为Canny算子用的是Gauss原理,所以那个值越大越平滑
NMS: 这个变量是用来控制我们是否使用非极大值抑制技术(这个技术主要是在Canny检测中提出来的)
Low, High: 就是指定一个双阈值了。
dev_close_window ()read_image(Image,'data/flower')rgb1_to_gray (Image, GrayImage)gen_image_proto (Image, ImageCleared, 1)dev_open_window (0, 0, 256, 256, 'black', WindowHandle1)dev_open_window (0, 256, 256, 256, 'black', WindowHandle2)dev_open_window (0, 512, 256, 256, 'black', WindowHandle3)edges_image (GrayImage, ImaAmpGray, ImaDirGray, 'canny', 1, 'none', -1, -1)edges_image (GrayImage, ImaAmpGrayNMS, ImaDirGrayHyst, 'canny', 1, 'nms',20, 40) *对非极大值抑制后的边缘梯度图像进行了阈值处理threshold (ImaAmpGrayNMS, RegionGray, 1, 255) *提取边缘轮廓skeleton (RegionGray, EdgesGray) *用于结果显示和对比dev_set_window (WindowHandle1)dev_display (ImageCleared) dev_display (ImaAmpGray) dev_set_window (WindowHandle2)dev_display (ImageCleared) dev_display (ImaAmpGrayNMS) dev_set_window (WindowHandle3)dev_display (ImageCleared) dev_display (EdgesGray)
10.1.5 其它滤波器
- derivate_gauss(Image : DerivGauss : Sigma, Component : )
- laplace(Image : ImageLaplace : ResultType, MaskSize, FilterMask : )
read_image (Image, 'data/flower')laplace (Image, ImageLaplace, 'signed', 11, 'n_8_isotropic')zero_crossing (ImageLaplace, RegionCrossing)
3.laplace_of_gauss(Image : ImageLaplace : Sigma : )
10.2 亚像素级边缘提取
面阵摄像机的成像面以像素为最小单位。例如某CMOS摄像芯片,其像素间距为5.2微米。摄像机拍摄时,将物理世界中连续的图像进行了离散化处理。到成像面上每一个像素点只代表其附近的颜色。至于“附近”到什么程度,就很难解释。两个像素之间有5.2微米的距离,在宏观上可以看作是连在一起的。但是在微观上,它们之间还有无限的更小的东西存在。这个更小的东西我们称它为“亚像素”。实际上“亚像素”是存在的,只是硬件上没有个细微的传感器把它检测出来,于是软件上把它近似地计算出来。
Halcon中用XLD表示亚像素的轮廓和多边形。
10.2.1 edges_sub_pix 算子
edges_sub_pix(Image : Edges : Filter, Alpha, Low, High : )
https://www.mvtec.com/doc/halcon/13/en/edges_sub_pix.html
read_image (Image, 'data/flower') *转换为单通道灰色图像rgb1_to_gray (Image, GrayImage)*进行亚像素边缘提取。分别使用了不同的滞后阈值以便进行对比edges_sub_pix (GrayImage, Edges1, 'lanser2', 0.5, 5, 50) edges_sub_pix (GrayImage, Edges2, 'lanser2', 0.5, 25, 50) edges_sub_pix (GrayImage, Edges3, 'lanser2', 0.5, 5, 25) *将提取结果显示在窗口中dev_display (Edges1) stop()dev_display (Edges2)stop()dev_display (Edges3)
10.2.2 edges_color_sub_pix 算子
edges_color_sub_pix(Image : Edges : Filter, Alpha, Low, High : )
https://www.mvtec.com/doc/halcon/13/en/edges_color_sub_pix.html
read_image (Image, 'data/flower') *使用canny算子进行亚像素边缘提取edges_color_sub_pix (Image, Edges1, 'canny', 0.5, 5, 50)*使用canny算子进行亚像素边缘提取edges_color_sub_pix (Image, Edges2, 'sobel_fast', 0.5, 40, 70)dev_clear_window ()dev_display (Edges1) dev_display (Edges2)
10.2.3 lines_gauss 算子
lines_gauss(Image : Lines : Sigma, Low, High, LightDark, ExtractWidth, LineModel, CompleteJunctions : )
https://www.mvtec.com/doc/halcon/13/en/lines_gauss.html
read_image (Image, 'data/flower') rgb1_to_gray (Image, GrayImage)dev_open_window (0, 512, 512, 512, 'black', WindowHandle1)*进行边缘检测lines_gauss(GrayImage,Lines,1.5,1,8,'light','true','bar-shaped','true')*在窗口将轮廓线条绘制出来dev_set_color ('red')dev_clear_window()dev_display (Lines)
10.3 轮廓处理
dev_close_window ()read_image (Image, 'data/shapes')rgb1_to_gray (Image, GrayImage)get_image_size (Image, Width, Height)dev_open_window (0, 0, Width , Height, 'black', WindowHandle)*提取出的亚像素边缘edge的图像,得到了一个初始的轮廓edges_sub_pix (GrayImage, Edges, 'canny', 2.5, 15, 40)*对上一步的轮廓进行分割segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 2)*提取出轮廓中较长的部分线段select_contours_xld (ContoursSplit, SelectedContours, 'contour_length', 20, Width / 2, -0.5, 0.5)*对相邻的轮廓段进行连接union_adjacent_contours_xld (SelectedContours, UnionContours, 20, 1, 'attr_keep')
dev_close_window ()*读取了图像并创建显示窗口read_image (Image, 'data/flower')rgb1_to_gray (Image, GrayImage)get_image_size (Image, Width, Height)dev_open_window (0, 0, Width , Height, 'black', WindowHandle)dev_set_color ('white')*对图像进行阈值处理threshold (GrayImage, Region, 130, 255)*使用闭运算进行填充closing_circle (Region, Region, 20.5)*获取前景目标的初始轮廓gen_contour_region_xld (Region, Contour, 'border')*拟合圆形轮廓fit_circle_contour_xld (Contour, 'atukey', -1, 2, 0, 10, 1, Row, Column, Radius, StartPhi, EndPhi, PointOrder)*生成该拟合的圆形轮廓gen_circle_contour_xld (ContCircle, Row, Column, Radius, 0, 4 * acos(0), 'positive', 1)