上次在例程分析中只是简单地介绍如何实现,没有过多地阐述原理,这里我们先来认识一下极坐标转换为直角坐标的原理。
首先,对于极坐标上的所有点可以有参数θ
和ρ
唯一确定,对于一个圆而言,ρ
是确定不变的半径,那么如果转换的到直角坐标系下,就是一条平行于水平坐标轴的直线,当横坐标变换时纵坐标保持不变。
而我们知道
x = ρ * cos(θ)
y = ρ * sin(θ)
根据这个公式我们可以实现从极坐标系转换到直角坐标系。
对于这样一幅图,如何识别圆环那部分?
毫无疑问,我们要用到极坐标转换。
第一步:得到内接圆和外接圆
就像在OCR识别字符排列圆形或字体倾斜的处理办法中的做法一样,做极坐标转换的关键在于找到包围字符区域的外接圆和内接圆。所以我们现在的目的就是分别找出外接圆和内接圆。
首先阈值化,把圆环抠出来
threshold (GrayImage, Regions, 0, 216)
然后形状转换,于是得到外接圆
shape_trans (Regions, RegionOuter, 'outer_circle')
用外接圆与刚刚的圆环区域做差然后用区域选择就得到了我们的内接圆
difference (RegionOuter, Regions, RegionDifference1)
connection (RegionDifference1, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions, 'area', 'and', 516467, 2e+006)
smallest_circle (RegionOuter, RowOut, ColumnOut, RadiusOut)
smallest_circle (SelectedRegions, RowIn, ColumnIn, RadiusIn)
显示如下
dev_set_color ('green')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_display (Image)
dev_display (RegionOuter)
dev_display (SelectedRegions)
第二步:极坐标转换
调用算子
polar_trans_image_ext (GrayImage, PolarTransImage, RowOut, ColumnOut, rad(45), rad(405), RadiusOut-100 , RadiusIn+100 , WidthPolar, HeightPolar, 'nearest_neighbor')
这里的一些参数需要根据实际情况修改,WidthPolar, HeightPolar
参数是设置的极坐标转换之后图像显示的区域,可以根据需求设一个合适的即可,影响的只是显示区域的大小问题,并不影响转换结果和转换区域。
上下镜像一下得到
mirror_image (PolarTransImage, ImageMirror, 'column')
此时我们已经完成了将字符从极坐标转换为直角坐标了,注意这里采用什么样的方式将图像摆正需要结合你实际转换出的图像,这里实际转换出的图像如下
所以采用竖直镜像。
第三步:分割字符
这里就是八仙过海,各显神通了,我们之前分析了很多种方法。
首先我们用invert_image
算子把对比度调一下
然后用缩放工具scale_image
处理一下
再快速阈值化binary_threshold
很遗憾,博主试了很多次,阈值化的结果都只能是这个样子,直接导致后面求交集的时候识别的就是这样的字符,识别准确度不够。
然后把单个字符形成单个连通域
最后识别结果不太理想,其实让我自己看我也分不清0
和O
,贴一下博主的识别结果
如果各位有更高的识别结果,请留言~ 互相学习一下~~~
最后贴一下完整代码以供参考
dev_close_window ()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle1)
*读取图像
read_image (Image, 'F:/1.1.bmp')
*提取内接圆和外接圆
rgb1_to_gray (Image, GrayImage)
threshold (GrayImage, Regions, 0, 216)
shape_trans (Regions, RegionOuter, 'outer_circle')
difference (RegionOuter, Regions, RegionDifference1)
connection (RegionDifference1, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions, 'area', 'and', 516467, 2e+006)
smallest_circle (RegionOuter, RowOut, ColumnOut, RadiusOut)
smallest_circle (SelectedRegions, RowIn, ColumnIn, RadiusIn)
dev_set_color ('green')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_display (Image)
dev_display (RegionOuter)
dev_display (SelectedRegions)
stop ()
*极坐标转换
WidthPolar := 512
HeightPolar := 100
dev_close_window ()
dev_open_window (0, 0, WidthPolar, HeightPolar, 'black', WindowHandle)
polar_trans_image_ext (GrayImage, PolarTransImage, RowOut, ColumnOut, rad(405), rad(45), RadiusOut-100 , RadiusIn+100 , WidthPolar, HeightPolar, 'nearest_neighbor')
*字符分割
invert_image (PolarTransImage, ImageInvert)
scale_image (ImageInvert, ImageScaled1, 6.71053, -1429)
binary_threshold (ImageScaled1, Region, 'max_separability', 'light', UsedThreshold)
connection (Region, ConnectedRegions2)
select_shape (ConnectedRegions2, SelectedRegions1, 'area', 'and', 4.001, 100)
dilation_rectangle1 (SelectedRegions1, RegionDilation, 5, 9)
union1 (RegionDilation, RegionUnion)
connection (RegionUnion, ConnectedRegions)
intersection (ConnectedRegions, Region, RegionIntersection)
sort_region (RegionIntersection, SortedRegions, 'character', 'true', 'row')
*字符识别
read_ocr_class_mlp ('DotPrint_0-9A-Z_NoRej.omc', OCRHandle)
do_ocr_multi_class_mlp (SortedRegions, PolarTransImage, OCRHandle, Class, Confidence)