在别的网站看到一个案例:需要识别环状物体上的字符(OCR),要用到极坐标变换。

按照最简单的模式,原始检测方案如下:
read_image (Image, 'H:/学习笔记/halcon笔记/1.jpg')
*获取图片尺寸,极坐标变换成原始图片大小
get_image_size (Image, Width, Height)
*获取圆环物体区域(包含字符),抠图
threshold (Image, Region, 0, 100)
connection (Region, ConnectedRegions)
select_shape_std (ConnectedRegions, SelectedRegions, 'max_area', 70)
fill_up_shape (SelectedRegions, RegionFillUp, 'area', 1, 10000)
reduce_domain (Image, RegionFillUp, ImageReduced)
*求外圆圆心,半径
gen_contour_region_xld (RegionFillUp, OuterCont, 'border')
fit_circle_contour_xld (OuterCont, 'algebraic', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
*求内圆圆心,半径
fill_up (RegionFillUp, RegionFillUp1)
difference (RegionFillUp1, RegionFillUp, RegionDifference)
gen_contour_region_xld (RegionDifference, InnerCont, 'border')
fit_circle_contour_xld (InnerCont, 'algebraic', -1, 0, 0, 3, 2, Row1, Column1, Radius1, StartPhi1, EndPhi1, PointOrder1)
*极坐标变换
polar_trans_image_ext (ImageReduced, PolarTransImage, Row, Column, 0, rad(360), Radius, Radius1, Width, Height, 'nearest_neighbor')
*
mirror_image (PolarTransImage, ImageMirror1, 'column')
*下一步:OCR字符识别
但是这个方案有一个问题:变换的初始角度默认为0,最终角度默认为360度;如果不特别设置角度,变换后的图片中,字符可能不是连续的(被切割为两部分);如果想完整识别字符,则需要字符不被切割分开。
最终呈现的效果如下:

优化方案:
重新设置极坐标变换的起始、终止角度:01、求字符区域的外接旋转矩形,求矩形的四个顶点。02、矩形同一边的2个顶点与物体外接圆圆心连线,计算线线之间夹角。03、以夹角作为起始角度,360+夹角作为终止角度。
以下为优化后的代码:
read_image (Image, 'H:/BEGINNER/学习笔记1.jpg')
*获取图片尺寸,极坐标变换成原始图片大小
get_image_size (Image, Width, Height)
*获取圆环物体区域(包含字符),抠图
threshold (Image, Region, 0, 100)
connection (Region, ConnectedRegions)
select_shape_std (ConnectedRegions, SelectedRegions, 'max_area', 70)
fill_up_shape (SelectedRegions, RegionFillUp, 'area', 1, 10000)
reduce_domain (Image, RegionFillUp, ImageReduced)
*求外圆圆心,半径
gen_contour_region_xld (RegionFillUp, OuterCont, 'border')
fit_circle_contour_xld (OuterCont, 'algebraic', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
*求内圆圆心,半径
fill_up (RegionFillUp, RegionFillUp1)
difference (RegionFillUp1, RegionFillUp, RegionDifference)
gen_contour_region_xld (RegionDifference, InnerCont, 'border')
fit_circle_contour_xld (InnerCont, 'algebraic', -1, 0, 0, 3, 2, Row1, Column1, Radius1, StartPhi1, EndPhi1, PointOrder1)
*抠出字符区域,求此区域的角度
threshold (ImageReduced, Region1, 100, 255)
connection (Region1, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions1, 'width', 'and', 6, 12)
select_shape (SelectedRegions1, SelectedRegions2, 'area', 'and', 16, 99999)
closing_rectangle1 (SelectedRegions2, RegionClosing, 100,100)
union1 (RegionClosing, RegionUnion)
*区域转化为旋转矩形
shape_trans (RegionUnion, RegionTrans, 'rectangle2')
*得到外接旋转矩形的坐标,半边长
smallest_rectangle2 (RegionTrans, Row2, Column2, Phi, Length1, Length2)
dev_set_draw ('margin')
*求矩形的四个顶点坐标
if(abs(deg(Phi))>45)
Phi:=rad(deg(Phi)-90*(Phi/abs(Phi)))
Tmp:=Length1
Length1:=Length2
Length2:=Tmp
endif
tuple_sin (Phi, Sin)
tuple_cos (Phi, Cos)
*左上角
TopLeft_X := -Length1*Cos - Length2*Sin
TopLeft_Y := -Length1*Sin + Length2*Cos
TopLeft_Row := Row2 - TopLeft_Y
TopLeft_Col := Column2 + TopLeft_X
gen_cross_contour_xld (Cross1, TopLeft_Row, TopLeft_Col, 30, 0.785398)
*右上角
TopRight_X := Length1*Cos - Length2*Sin
TopRight_Y := Length1*Sin + Length2*Cos
TopRight_Row := Row2 - TopRight_Y
TopRight_Col := Column2 + TopRight_X
gen_cross_contour_xld (Cross2, TopRight_Row, TopRight_Col, 30, 0.785398)
*右下角
LowerRight_X := Length1*Cos + Length2*Sin
LowerRight_Y := Length1*Sin - Length2*Cos
LowerRight_Row := Row2 - LowerRight_Y
LowerRight_Col := Column2 + LowerRight_X
gen_cross_contour_xld (Cross3, LowerRight_Row, LowerRight_Col, 30, 0.785398)
*左下角
LowerLeft_X := -Length1*Cos + Length2*Sin
LowerLeft_Y := -Length1*Sin - Length2*Cos
LowerLeft_Row := Row2 - LowerLeft_Y
LowerLeft_Col := Column2 + LowerLeft_X
gen_cross_contour_xld (Cross4, LowerLeft_Row, LowerLeft_Col, 30, 0.785398)
*查看夹角效果
*dev_set_color ('blue')
*gen_region_line (RegionLine1, Row, Column, TopRight_Row, TopRight_Col)
*gen_region_line (RegionLine2, Row, Column, LowerRight_Row, LowerRight_Col)
*得到四个顶点坐标后,取左(右)上左(右)下点,分别与大圆的圆心连线,求线线夹角
angle_ll (Row, Column, TopRight_Row, TopRight_Col, Row, Column, LowerRight_Row, LowerRight_Col, Angle)
tuple_deg (Angle, Deg)
*极坐标变换
polar_trans_image_ext (ImageReduced, PolarTransImage, Row, Column, rad(Deg), rad(360+Deg), Radius, Radius1, Width, Height, 'nearest_neighbor')
*
mirror_image (PolarTransImage, ImageMirror1, 'column')
*下一步:OCR字符识别
最终效果如下图:

下面附上另外3张图片,感兴趣的可以测试一下



1万+



被折叠的 条评论
为什么被折叠?



