6、Halcon图像边缘提取和轮廓识别

目录

1、图像边缘提取原理

2、边缘提取算子介绍

3、图像的亚像素边缘提取

4、亚像素轮廓的特征分析

5、xld的分割及直线拟合

6、圆及椭圆的拟合

7、中心线的提取


1、图像边缘提取原理

网上搜索图像边缘提取,有很多详细的讲解,就是讲的都太深奥,很难看明白。图像边缘提取原理并不复杂,至于一些大牛提供的复杂变换公式,也没必要深入的去研究,halcon都已经在算子中将其封装好了,我们会用就行。

边缘的定义:边缘是图像中灰度发生明显变化的地方,是不同灰度区域之间的界限。

图像的每个像素点的灰度值用矩阵来表示,那么画竖线的位置就是边缘界限。

那么如何进行图像边缘的提取呢?采用掩模的方式,在图像矩阵上进行移动,然后利用掩模内的掩模值进行计算,进而实现边缘的求取。

举例:假如使用3*3的掩模来求取:

-1    0    1

-1    0    1

-1    0    1

掩模矩阵和红色圈出来的Value1计算:{(-1)*1+0*1+1*1}+{(-1)*1+0*1+1*1}+{(-1)*1+0*1+1*1}=0

掩模矩阵和蓝色圈出来的Value2计算:{(-1)*1+0*1+1*10}+{(-1)*1+0*1+1*10}+{(-1)*1+0*1+1*10}=27

我们可以设置一个边界值Value,则程序中可设置判断,当|Value2-Value1|>Value时就认为当前是图像边缘。

halcon常用的掩模:

Robert边缘

算子:roberts。边缘定位准,但是对噪声敏感;适用于边缘明显且噪声低的图像分割。边缘定位精确度低。

模板1:

1      0

0     -1

模板2:

0       1

-1       0

Prewitte边缘

算子:prewitt_amp。对噪声可以适当抑制,但是会起到边缘平滑,对边缘的平滑不如Robert算子。

x方向:

-1       0       1

-1       0       1

-1       0       1

y方向:

1       1       1

0       0       0

-1      -1     -1

Sobel边缘

算子:sobel_amp。Sobel算子对于像素的位置的影响做了加权,可以降低边缘模糊程度。

x方向:

-1       0       1

-2       0       2

-1       0       1

y方向:

1       2       1

0       0       0

-1      -2     -1

Canny边缘:非极大值抑制与阈值的思想,边缘的提取效果在目前边缘提取中是相对效果最好的。(原理复杂,会用就行)

其它边缘:拉普拉斯边缘等(用的少)。

Canny没有对应的算子,如edges_image (EdgeAmplitude, ImaAmp, ImaDir, 'canny', 1, 'nms', 20, 40),在参数中设置为canny。

2、边缘提取算子使用介绍

弄清了边缘提取原理后,本节讲解边缘提取算子具体使用。

首先,读取图片,并灰度化转换

  1. read_image (Image1, '1.bmp')
  2. rgb1_to_gray (Image1, GrayImage)

roberts边缘算子:

  1. *roberts边缘,边缘定位精准
  2. roberts (GrayImage, ImageRoberts, 'gradient_sum')

prewitt_amp边缘算子,求出来的边缘要清晰很多了:

  1. *prewitt_amp边缘,对噪声可以适当抑制。变换后图像有偏移
  2. prewitt_amp (GrayImage, ImageEdgeAmp)

sobel_amp边缘算子:

  1. *sobel_amp边缘,可以降低边缘模糊程度
  2. sobel_amp (GrayImage, EdgeAmplitude, 'sum_abs', 3)

Canny求边缘(求图像边缘最好的方法)

  1. *图像的边缘,参数7:低阈值,参数8:高阈值。一般高阈值是低阈值的1.5倍-2倍
  2. edges_image (EdgeAmplitude, ImaAmp, ImaDir, 'canny', 1, 'nms', 20, 40)

3、图像的亚像素边缘提取

什么叫图像的亚像素?顾名思义,亚像素就是比普通像素精度更高。由原先的像素单位为1,变为比1小的精度。

亚像素原理:采用插值的方式,精确定位边缘的位置。

        比如:     (最邻近插值)

        1、5         插值后           1       3        5

        1、6         插值后           1       3.5      6

插值方法有:双线性插值、三次样条插值。

亚像素边缘,常用的方法是canny边缘方法,算子是edges_sub_pix(),可以直接得到亚像素边缘。

常用英文单词:

     区域:region            轮廓:XLD

     感兴趣区域:RIO

程序讲解:

读取图片,求取第三个区域的边缘。

  1. read_image (Image1, '1.bmp')
  2. rgb1_to_gray (Image1, GrayImage)

通过阈值分割、形状筛选,将7个矩形区域从图像中分割出来

  1. *缩小ROI,阈值分割
  2. fast_threshold (GrayImage, Region, 150, 255, 20)
  3. *连通域
  4. connection (Region, ConnectedRegions)
  5. *区域排序
  6. sort_region (ConnectedRegions, SortedRegions, 'first_point', 'true', 'row')
  7. *选择矩形区域-外接矩形
  8. select_shape (SortedRegions, SelectedRegions, ['rect2_len1','rect2_len2'], 'and', [110,50], [160,70])

对筛选出来的7个矩形区域排序,然后选择第三个区域。

  1. *再排一次序:按列排序
  2. sort_region (SelectedRegions, SortedRegions1, 'first_point', 'true', 'column')
  3. *始终选择第三个区域:参数3为要选择的哪一个区域
  4. select_obj (SortedRegions1, ObjectSelected, 3)

区域筛选下来后要求矩形图像边缘,一定要先包含其边缘,只有将整个区域包含了,才能保证求的区域边缘在里面。可以先用膨胀。再将此区域从原图中裁剪下来。

  1. *正常的膨胀需求用dilation_circle,如果想对一个区域进行平滑操作的时候用闭操作closing_circle
  2. dilation_circle (ObjectSelected, RegionDilation, 5)
  3. *将选出来处理好的区域从原灰度图片上裁剪出来
  4. reduce_domain (GrayImage, RegionDilation, ImageReduced)

最后,对其进行求边缘

  1. *边缘检测-canny
  2. edges_sub_pix (ImageReduced, Edges, 'canny', 1, 10, 20)

4、亚像素轮廓的特征分析

为什么要进行特征分析?如下图所示,是求取出来的边缘,周围的线条是真实需要的,而中间的的线条则是引入的干扰线条。需要根据特征来进行筛选,而这个特征就是亚像素的特征。

亚像素轮廓特征:和前面的区域特征一样,亚像素轮廓特征同样具有自己的特征,在亚像素轮廓中使用较多的特征包括:长度、角度、外接矩形的长宽等。还有一些其它使用很少的特征。

亚像素轮廓的长度:轮廓所占的像素数。

亚像素轮廓的角度:轮廓最小外接矩形中,长边所对应的方向。

亚像素轮廓的外接矩形:能包括整个轮廓的最小矩形就是最小外接矩形。

备注:在求取亚像素外接矩形时,算子要加上_xld

求取xld的最小外接矩形1:smallest_rectangle1_xld

求取xld的最小外接矩形2:smallest_rectangle2_xld

筛选xld:select_shape_xld

程序讲解:

接着前面一节的程序进行。

前面一节一节将边缘求取出来了,但是中间有干扰线条。需要将中间的干扰线条去掉,只保留边上需要的线条。可以通过线条周长的长度来进行筛选

  1. *XLD筛选,参数3,周长
  2. select_shape_xld (Edges, SelectedXLD, 'contlength', 'and', 80, 99999)

补充:通过软件工具,获取XLD线条周长

5、xld的分割及直线拟合

为什么要XLD分割和直线拟合,看前面的提取出来的轮廓线,线条有凸起、或者歪歪扭扭的,不是很规整。因此需要将其拟合,拟合前需要将相交的线分割出来,每条线单独拟合。

XLD的分割:根据XLD之间各个节点的连接情况以及设置条件,将一条或多条分割线分割成更多条线的情况,称为xld的分割。一般先的折点的地方称为分割点。

算子:segment_contours_xld

XLD的拟合:根据线条的预先模型,对线条进行重新成成。包括直线的拟合、圆的拟合、以及椭圆拟合等。

         算子:

                     fit_line_contour_xld:直线的拟合

                    fit_circle_contour_xld:圆的拟合

                    fit_ellipse_contour_xld:椭圆的拟合

XLD的拟合原理:基于最小二乘法拟合、考虑权重的拟合方法。如下图所示意。

程序讲解:

接着上节程序,进行讲解,上一节存在的问题。

进行XLD轮廓线分割

  1. *轮廓XLD的分割,参数3:分割方式,参数4:圆滑程度,参数5和参数6:最小和最大线的距离
  2. segment_contours_xld (UnionContours, ContoursSplit, 'lines_circles', 5, 4, 2)

然后再选择矩形下方的横线。

  1. *选择矩形下部没连接到一起的水平线,根据线的角度来选择
  2. select_shape_xld (SelectedXLD, SelectedXLD1, 'phi', 'and', -0.1, 0.1)

对直线进行拟合

  1. *对选出来的直线拟合,参数2,'tukey'是最小2乘拟合、'huber'是考虑权重拟合
  2. fit_line_contour_xld (SelectedXLD1, 'huber', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)

再对线左边延长

  1. *拟合后的线不够长,将起始的列往左移动(减去5个像素点)
  2. gen_contour_polygon_xld (Contour, [RowBegin,RowEnd], [ColBegin-5,ColEnd])

拟合、延长后的

将新生成的线和别的线放到一起

  1. *将其他的线也选择出来
  2. select_shape_xld (SelectedXLD, SelectedXLD2, 'phi', 'and', 0.2, 3.14)
  3. *将两次选出来的线放到一个集合中
  4. concat_obj (SelectedXLD2, Contour, ObjectsConcat)
  5. *将集合中的两个线,合并连接到一起
  6. union_adjacent_contours_xld (ObjectsConcat, UnionContours1, 10, 1, 'attr_keep')

生成新的区域

  1. *将线围起来的区域转换成轮廓
  2. gen_region_contour_xld (UnionContours1, Region1, 'filled')

新生成的区域,边缘很圆滑。先腐蚀,再求边缘。

  1. *使用腐蚀,将多出来的去掉
  2. opening_circle (Region1, RegionOpening, 3.5)
  3. *再求边缘
  4. boundary (RegionOpening, RegionBorder, 'inner')

也不圆滑,再进行膨胀,膨胀后再从前面的区域中中裁剪

  1. *求出来的边缘并不是太好,使用膨胀操作
  2. dilation_circle (RegionBorder, RegionDilation1, 3.5)
  3. *膨胀后再从原图中进行裁剪
  4. reduce_domain (GrayImage, RegionDilation1, ImageReduced1)

然后再使用canny求边缘

  1. *再用刚才的边缘,所求得的边缘就要好多了
  2. edges_sub_pix (ImageReduced1, Edges1, 'canny', 1, 20, 40)

最后再进行连接

  1. *再进行连接
  2. union_adjacent_contours_xld (Edges1, UnionContours2, 10, 1, 'attr_keep')

 

6、圆及椭圆的拟合

圆的拟合与直线的拟合,也包括线条的分割、筛选以及拟合。

直接以程序来讲解。

程序讲解:

打开图片

  1. dev_close_window ()
  2. dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
  3. read_image (Image1, '1.bmp')

然后取图像中一个不规则的圆区域,将其裁剪下来

  1. *画圆
  2. draw_circle (WindowHandle, Row, Column, Radius)
  3. *生成圆
  4. gen_circle (Circle, Row, Column, Radius)
  5. *裁剪
  6. reduce_domain (Image1, Circle, ImageReduced)

进行边缘提取,并选择外部的边缘轮廓

  1. *提取边缘
  2. edges_sub_pix (ImageReduced, Edges, 'canny', 1, 10, 20)
  3. *选择轮廓形状
  4. select_shape_xld (Edges, SelectedXLD, 'contlength', 'and', 80, 99999)

分割、筛选,因为轮廓线就一条,分割后还是一条

  1. *对选出来的轮廓进行分割,然后求出分割最长的那条线
  2. segment_contours_xld (SelectedXLD, ContoursSplit, 'lines_circles', 5, 4, 2)
  3. *分割的xld长度,长度值保存在Length数组中
  4. length_xld (ContoursSplit, Length)
  5. *求数组最大值
  6. tuple_max (Length, Max)
  7. *选出分割最长的线
  8. select_shape_xld (ContoursSplit, SelectedXLD1, 'contlength', 'and', Max-1, 99999)

对分割、筛选后的线,用圆拟合

  1. *对选出来的线,用圆的拟合。参数2:选择拟合方法,回归的形式
  2. fit_circle_contour_xld (SelectedXLD1, 'algebraic', -1, 0, 0, 3, 2, Row1, Column1, Radius1, StartPhi, EndPhi, PointOrder)
  3. *生成圆轮廓-拟合好的分割线
  4. gen_circle_contour_xld (ContCircle, Row1, Column1, Radius1, 0, 6.28, 'positive', 1)

其它的,如椭圆拟合,分割、筛选方法跟圆一样,直接写出算子使用方法了

  1. *椭圆拟合
  2. *fit_ellipse_contour_xld (SelectedXLD1, 'fitzgibbon', -1, 0, 0, 200, 3, 2, Row2, Column2, Phi, Radius11, Radius2, StartPhi1, EndPhi1, PointOrder1)
  3. *生成椭圆轮廓-拟合好的分割线
  4. *gen_ellipse_contour_xld (ContEllipse, Row2, Column2, Phi, Radius11, Radius2, StartPhi1, StartPhi1, 'positive', 1.5)

 

7、中心线的提取

介绍::中心线是出于某区域中心的线,比如图中的道路中心,很多情况下需要求解中心。
求解方法:

方法1:求解区域的边缘,然后进而计算中心。

方法2:先求解区域,然后利用区域骨架求解中心。

方法3:利用lines-gauss算子求解。

程序讲解:

先去读取图片,然后灰度转换

  1. read_image (Image1, '1.bmp')
  2. rgb1_to_gray (Image1, GrayImage)

示例1:中心线提取-亮的区域。

  1. *中心线提取,亮的区域。
  2. *参数3:提取的中心线光滑程度,通常取1.2-1.5。参数4参数5:边缘高低阈值,类似于canny。参数6:中心线是dark还是light
  3. lines_gauss (GrayImage, Lines, 1.5, 3, 8, 'light', 'true', 'bar-shaped', 'true')

示例2:中心线提取-暗的区域。

  1. *提取黑色的中心线
  2. lines_gauss (GrayImage, Lines1, 1.5, 3, 8, 'dark', 'true', 'bar-shaped', 'true')

 

区域边缘提取和轮廓识别,案例应用见下一节:7、Halcon图像中识别多个矩形区域并对平均宽度测量。

https://blog.csdn.net/panjinliang066333/article/details/104431979

(0)

相关推荐

  • 【OpenCV读取标记点坐标】管道测速

    文章目录 一.项目简介 二.思考步骤 1. 图像二值化 2. 滤波去噪 3. Canny算法检测边缘 4. 查找轮廓并计算 5. 绘制轮廓并表示质心 三.测试结果 四.工程代码 一.项目简介 昨天一个 ...

  • 图像特征提取(颜色,纹理,形状)

    来源:新机器视觉 来自:小白学视觉公众号 编辑:王萌(深度学习冲鸭公众号) 著作权归作者所有,本文仅作学术分享,若侵权,请联系后台删文处理 后台回复西瓜手推获得西瓜书手推笔记 后台回复CV入坑必备获得 ...

  • 图像处理知多少?准大厂算法工程师30+场秋招后总结的面经问题详解

    作者丨灯会 来源丨极市平台 编辑丨极市平台 极市导读 本篇主要包含了图像滤波.边缘检测相关常考内容等相关面试经验. >>加入极市CV技术交流群,走在计算机视觉的最前沿 系列文章: 深度学习 ...

  • 10、Halcon图像条形码和二维码识别

    10、Halcon图像条形码和二维码识别

  • 7、Halcon图像中识别多个矩形区域并对平均宽度测量

    一.需求:计算图片7个白色矩形的平均宽度. 二.分析: 首先求出七个矩形区域总得范围,然后再求每个矩形的范围. 求出每个矩形区域的边缘. 对每个矩形区域边缘处理:连接.拟合. 然后再求出每个线之间的间 ...

  • 查缺补漏 | 3.1 细胞分裂过程图像和坐标曲线的识别

    提纲 核心点拨 1.理清细胞分裂过程中细胞分裂图像.坐标曲线和柱状坐标图之间的对应关系图 2.细胞分裂中相关物质或结构变化规律及成因 3.抓住关键点,快速判断细胞分裂图像的分裂方式 4.在坐标曲线中, ...

  • halcon图像灰度操作

    *生成灰度为0的图像 gen_image_const (Image, 'byte', 512, 512) *计算尺寸 get_image_size (Image, Width, Height) *设置 ...

  • Halcon 图像截取

    在Halcon中进行截图有很多坑,比如reduce_domain.get_domain.crop_part等等,每个算子都有不同的功能,经过多次试验验证,crop_part才是名副其实用来截取感兴趣区 ...

  • Matlab图像处理(五)——图像边缘提取

    上一讲小白为小伙伴们带来了如何使用自编函数和自带函数对图像进行滤波,去除图像的噪声.这次小白为大家带来滤波的新用处--边缘提取. 什么是图像边缘 所谓图像边缘(Edlge)是指图像局部特性的不连续性, ...

  • CVPR2019| 04-16更新48篇论文及代码(9篇oral、含行人检测、图像生成、步态识别等)

    前段时间,计算机视觉顶会CVPR 2019 公布了接收结果,极市也对此做了相关报道:1300篇!CVPR2019接收结果公布,你中了吗?.目前官方只公布了接收论文ID列表,极市已汇总目前公开的所有论文 ...

  • 3、halcon图像预处理:基本变换、滤波和人脸祛斑

    目录 1.图像灰度化 2.图像的滤波 3.图像仿射变换 4.图像的极坐标变换 5.图像的傅里叶变换 6. 案例-人脸去斑 1.图像灰度化 ① 灰度变化的主要目的,是提高图像的对比度.对比度就是图像的清 ...

  • Halcon图像、区域缩放

     无法停止的时间,并不仅仅是为了让人珍惜缅怀,也是为了让人能不断地体验到每一个美妙瞬间,所以才流泻不止吧! ---摘自:吉本芭娜娜<身体全知道>  最近在做一个项目的时候,需要对算法时间进 ...