点击下方卡片,关注“新机器视觉”公众号
重磅干货,第一时间送达
本文为CSDN博主「小邢同学」的原创文章
原文链接:https://blog.csdn.net/cashmood/java/article/details/1047095
简介
圆环类检测在我们日常的缺陷检测中经常遇到。比如玻璃瓶口的缺陷检测,硬币的缺陷检测,胶垫的缺陷检测…
我们对于圆环检测不像对于矩形等物体的检测,检测区域比较规整,便于我们使用形态学对区域进行筛选,但是圆环物品我们发现会出现一些问题,比如使用矩形形态学会对环形的边界处理产生影响等等。在这种情况下我们可以使用极坐标变换的方法,将环形转换成矩形进而对缺陷进行处理。
极坐标变换
定义
在图像处理中,尤其是在处理环形、圆形图像的过程中,会使用到极坐标变换。将方形图像转换成圆形,即“方转圆”。或者实现圆形转换成方形“圆转方”。
我们把圆形图像转换成方形图像的过程称为图像的极坐标变换;反之则为图像的反极坐标变换
原理
极坐标想必学过高中数学的人都听过,一般的坐标系中用(x, y)值来描述一个点的位置,而在极坐标系中,则使用到原点的距离ρ和夹角θ来描述该点的位置。
首先,正常的图像都是在直角坐标系下的,可以看做一个二维平面。我们要对图像进行坐标变换,首先要把位置转换到新的坐标系,然后将值赋过去。
这里有两个值需要确定:1.位置 2.值。即变换后任一个像素的值与位置。
这里:变幻后的值不变。即求解变幻的位置关系式。
极坐标变换及其反变换的关键在于,根据极坐标变换前的图像确定极坐标变换后的图像上每个像素点的像素值。也即是找到“圆图”和“方图”间几何坐标的对应关系。
证明:
如上图所示,实现极坐标变换的关键即在于找到圆图上任一点P(i,j),在方图上对应的点p(m,n),然后通过插值算法实现圆图上所有像素点的赋值。
方图上,其行列数分别为M、N,方图上的每一列对应为圆图上的每条半径,半径方向存在着一个长度缩放因子delta_r = M/R,圆周方向被分为N等分,即角度因子为delta_t = 2π/N;
圆图上,图像坐标(i,j)和世界坐标(x,y)有着如下变换关系:x = j - R, y = R - i;
那么,图中P点半径长度为r = sqrt(xx + yy),角度theta = arctan(y/x);
圆图上点P在方图上对应行数为r/delta_r;
圆图上点P在方图上对应的列数n = thata/delta_t。
以上就是极坐标变换的基本原理,结合相应的插值算法,即可实现图像的极坐标变换。
Halcon中的极坐标变换
在halcon中极坐标变换算子:
polar_trans_image_ext(针对图像);polar_trans_region(针对区域);polar_trans_contour_xld(针对XLD轮廓)。
在halcon中反极坐标变换算子:
polar_trans_image_inv(针对图像);polar_trans_region_inv(针对区域);polar_trans_contour_xld_inv(针对XLD轮廓)。
1、polar_trans_image_ext算子用法与参数剖析
算子原型:
polar_trans_image_ext(Image : PolarTransImage : Row, Column, AngleStart, AngleEnd, RadiusStart, RadiusEnd, Width, Height, Interpolation : )
参数说明:
Image (input_object)(多通道)图像(-array)→对象(byte * / int2 * / uint2 * / real *)*允许计算设备
输入图像。
PolarTransImage(output_object)(多通道)图像(-array)→对象(字节/ int2 / uint2 /实数)
输出图像。
Row(input_control)编号→(实数/整数)
圆弧中心的行坐标。
默认值:256
建议值:0、16、32、64、128、240、256、480、512
Column(input_control)号→(实数/整数)
圆弧中心的列坐标。
默认值:256
建议值:0、16、32、64、128、256、320、512、640
AngleStart(input_control)数字→(实数)
要映射到输出图像第一列的射线角度。
默认值:0.0
建议值:0.0,0.78539816,1.57079632,3.141592654,6.2831853,12.566370616
AngleEnd(input_control)数字→(实数)
要映射到输出图像最后一列的射线角度。
默认值:6.2831853
建议值:0.0,0.78539816,1.57079632,3.141592654,6.2831853,12.566370616
RadiusStart(input_control)数字→(实数/整数)
要映射到输出图像第一行的圆的半径。
默认值:0
建议值:0、16、32、64、100、128、256、512
典型值范围:0≤RadiusStart
RadiusEnd(input_control)数字→(实数/整数)
要映射到输出图像最后一行的圆的半径。
默认值:100
建议值:0、16、32、64、100、128、256、512
典型值范围:0≤RadiusEnd
Width(input_control)数→(整数)
输出图像的宽度。
默认值:512
建议值:256、320、512、640、800、1024
典型值范围:0≤宽度≤32767
Height(input_control)数→(整数)
输出图像的高度。
默认值:512
建议值:240、256、480、512、600、1024
典型值范围:0≤高度≤32767
Interpolation (input_control)字符串→(string)
内插法进行变换。
默认值:“ nearest_neighbor”
值列表:‘bilinear’,‘nearest_neighbor’
2、polar_trans_region_inv算子用法与参数剖析
算子原型:
polar_trans_image_inv(PolarImage : XYTransImage : Row, Column, AngleStart, AngleEnd, RadiusStart, RadiusEnd, Width, Height, Interpolation : )
参数说明:
PolarImage(input_object)(multichannel-)image(-array)→object(byte * / int2 * / uint2 * / real *)*允许用于计算设备
输入图像。
XYTransImage(output_object)(多通道)图像(-array)→对象(字节/ int2 / uint2 /实数)
输出图像。
Row(input_control)编号→(实数/整数)
圆弧中心的行坐标。
默认值:256
建议值:0、16、32、64、128、240、256、480、512
典型值范围:0≤行≤32767
Column(input_control)号→(实数/整数)
圆弧中心的列坐标。
默认值:256
建议值:0、16、32、64、128、256、320、512、640
典型值范围:0≤列≤32767
AngleStart(input_control)数字→(实数)
将输入图像的第一列映射到的射线角度。
默认值:0.0
建议值:0.0,0.78539816,1.57079632,3.141592654,6.2831853
AngleEnd(input_control)数字→(实数)
将输入图像的最后一列映射到的射线角度。
默认值:6.2831853
建议值:0.0,0.78539816,1.57079632,3.141592654,6.2831853
RadiusStart(input_control)数字→(实数/整数)
要将输入图像的第一行映射到的圆的半径。
默认值:0
建议值:0、16、32、64、100、128、256、512
典型值范围:0≤RadiusStart
RadiusEnd(input_control)数字→(实数/整数)
要将输入图像的最后一行映射到的圆的半径。
默认值:100
建议值:0、16、32、64、100、128、256、512
典型值范围:0≤RadiusEnd
Width(input_control)数→(整数)
输出图像的宽度。
默认值:512
建议值:256、320、512、640、800、1024
典型值范围:0≤宽度≤32767
Height(input_control)数→(整数)
输出图像的高度。
默认值:512
建议值:240、256、480、512、600、1024
典型值范围:0≤高度≤32767
Interpolation (input_control)字符串→(string)
内插法进行变换。
默认值:“ nearest_neighbor”
值列表:‘bilinear’,‘nearest_neighbor’
圆环类缺陷检测思路与步骤
1. 使用Blob分析确定圆心位置与圆环半径、变换起始终止的角度。
2. 使用XLD轮廓拟合对圆心等参数进行精确定位。(此步骤用于精确定位,有的检测不需要)
3. 进行极坐标变换
4. 对极坐标变换后的图像进行处理
5. 进行反极坐标变换
6. 显示缺陷区域
Halcon实例
inspect_bottle_mouth.hdev
实例简介
*此示例检查瓶口是否有缺陷。
思路剖析
*首先,检测瓶子的基本形态,
*边缘检测和圆拟合。
*然后,通过极坐标变换对颈部区域进行变换。
*之后,在变换后的图像中使用动态阈值
*检测缺陷。最后,显示结果。
应用实例1
项目介绍
要求:检测边缘的三个红色圈圈内的缺陷。
原图:
处理程序
read_image (Image, 'C:/Users/Administrator/Desktop/1.png')
rgb3_to_gray (Image, Image, Image, ImageGray)
dev_open_window_fit_image (ImageGray, 0, 0, -1, -1, WindowHandle)
dev_set_draw ('margin')
dev_set_line_width (3)
dev_set_draw ('margin')
* dev_set_draw ('fill')
get_image_size (ImageGray, Width, Height)
binary_threshold (GrayImage, Region, 'max_separability', 'dark', UsedThreshold)
connection (Region, ConnectedRegions)
select_shape_std (ConnectedRegions, SelectedRegions, 'max_area', 70)
smallest_circle (SelectedRegions, Row2, Column2, Radius)
gen_circle (Circle, Row2, Column2, Radius)
reduce_domain (ImageGray, Circle, ImageReduced2)
gray_closing_rect (ImageReduced2, ImageClosing1, 10, 4)
polar_trans_image_ext (ImageClosing1, PolarTransImage1, Row2, Column2, 0, 6.28319, Radius-100, Radius-10, 6.28*Radius, 90, 'nearest_neighbor')
mean_image (PolarTransImage1, ImageMean1, 500, 2)
dyn_threshold (PolarTransImage1, ImageMean1, RegionDynThresh1, 10, 'dark')
connection (RegionDynThresh1, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions1, 'area', 'and',100, 9000000)
union1 (SelectedRegions1, RegionUnion)
closing_rectangle1 (RegionUnion, RegionClosing1, 10, 20)
connection (RegionClosing1, ConnectedRegions3)
opening_rectangle1 (ConnectedRegions3, RegionOpening1, 10, 20)
polar_trans_region_inv (RegionOpening1, XYTransRegion1, Row2, Column2, 0, 6.28319, Radius-100, Radius-10, 6.28*Radius, 90, Width, Height, 'nearest_neighbor')
smallest_circle (XYTransRegion1, Row, Column, Radius1)
gen_circle (Circle1, Row, Column, Radius1)
dev_display (ImageGray)
dev_display (Circle1)
处理效果
应用实例2
项目介绍
要求:如图所示,该图为需要找出红色圆圈内焊点的位置 。
原图:
处理程序
read_image (Image, 'C:/Users/Administrator/Desktop/实际图_副本.bmp')
rgb3_to_gray (Image, Image, Image, ImageGray)
dev_open_window_fit_image (ImageGray, 0, 0, -1, -1, WindowHandle)
dev_set_draw ('margin')
dev_set_line_width (5)
get_image_size (ImageGray, Width, Height)
auto_threshold (ImageGray, Regions, 2)
count_obj (Regions, Number)
select_obj (Regions, ObjectSelected, Number)
fill_up (ObjectSelected, RegionFillUp1)
connection (RegionFillUp1, ConnectedRegions1)
select_shape_std (ConnectedRegions1, SelectedRegions1, 'max_area', 70)
smallest_circle (SelectedRegions1, Row2, Column2, Radius)
gen_circle (Circle, Row2, Column2, Radius)
reduce_domain (ImageGray, Circle, ImageReduced2)
polar_trans_image_ext (ImageReduced2, PolarTransImage1, Row2, Column2, 0, 6.28319, Radius-210, Radius, 6.28*Radius, 210, 'nearest_neighbor')
mean_image (PolarTransImage1, ImageMean1, 200, 5)
dyn_threshold (PolarTransImage1, ImageMean1, RegionDynThresh1, 45, 'dark')
closing_circle (RegionDynThresh1, RegionClosing, 15.5)
connection (RegionClosing, ConnectedRegions2)
select_shape (ConnectedRegions2, SelectedRegions, ['width','height'], 'and', [380,80], [500,160])
polar_trans_region_inv (SelectedRegions, XYTransRegion1, Row2, Column2, 0, 6.28319, Radius-210, Radius, 6.28*Radius, 210, Width, Height, 'nearest_neighbor')
smallest_rectangle2 (XYTransRegion1, Row3, Column3, Phi, Length1, Length2)
gen_rectangle2 (Rectangle, Row3, Column3, Phi, Length1, Length2)
dev_display (ImageGray)
dev_display (Rectangle)
处理效果
本文仅做学术分享,如有侵权,请联系删文。
—THE END—
|