OCR实战篇第一篇:点状喷码数字的识别
Halcon的程序:
read_image (Image, 'D:/shijue/学习笔记/OCR识别1.png')
get_image_size (Image, Width, Height)
gen_rectangle1 (ROI_0, 18.0852, 220.975, 649.983, 1158.32)
text_line_slant (Image, Image, 70, -0.4, 0.4, SlantAngle)
vector_angle_to_rigid (Height/2, Width/2, SlantAngle,Height/2, Width/2, 0, HomMat2D)
affine_trans_image (Image, ImageAffineTrans, HomMat2D, 'constant', 'false')
*定位矫正
dots_image (ImageAffineTrans, DotImage, 5, 'dark', 0)
*对点状直接提取
reduce_domain (DotImage, ROI_0, ImageReduced)
invert_image (ImageReduced, ImageInvert)
binary_threshold (ImageReduced, Region, 'max_separability', 'light', UsedThreshold)
dilation_rectangle1 (Region, RegionDilation, 12,12)
connection (RegionDilation, ConnectedRegions)
shape_trans (ConnectedRegions, RegionTrans,'rectangle1')
select_shape (RegionTrans, SelectedRegions, ['height','width'], 'and', [36.394,15.48], [100,161.44])
partition_rectangle (SelectedRegions, Partitioned, 50, 100)
intersection (Partitioned, Region, RegionIntersection)
sort_region (RegionIntersection, SortedRegions, 'character', 'true', 'row')
read_ocr_class_mlp ('D:/shijue/halcon1/ocr/DotPrint_0-9A-Z_NoRej.omc', OCRHandle)
do_ocr_multi_class_mlp (SortedRegions, ImageInvert, OCRHandle, Class, Confidence)
dev_display (ImageAffineTrans)
smallest_rectangle1 (SortedRegions, Row1, Column1, Row2, Column2)
count_obj (SortedRegions, Number1)
dev_get_window (WindowHandle)
disp_message (WindowHandle, Class, 'window', Row1, Column1-80, 'black', 'true')
stop ()
实现效果
单步具体讲解:
read_image (Image, ‘D:/shijue/学习笔记/OCR识别1.png’)
//直接调用image助手,直接访问我们的图片。
get_image_size (Image, Width, Height)
//选取我们的图片的宽高方便后续提取图片的中心点
gen_rectangle1 (ROI_0, 18.0852, 220.975, 649.983, 1158.32)
//绘制我们所需要的空间,方便后续直接提取。绘制范围可以根据多张图片绘制大小都可以。
//绘制ROI工具助手
text_line_slant (Image, Image, 70, -0.4, 0.4, SlantAngle)
//对图像中的字符进行识别,并将识别到的字符相对于窗口的的角度存放在SlantAngle,函数中//的70,-0.4,0.4均不影响后续的处理,但是第四与第五个变量必须为相反关系。具体可直接查
//询halcon算子详细
vector_angle_to_rigid (Height/2, Width/2, SlantAngle,Height/2, Width/2, 0, HomMat2D)
//对图像进行一定角度的翻转。Height/2, Width/2,选取高与宽的二份之一位旋转的中心点。然后旋转角度为SlantAngle。第四与第五的变量均为第一与第二个变量相一致。第六的变量置为0。HomMat2D为旋转后的图像存放变量,但是不能直接调用显示函数直接显示
affine_trans_image (Image, ImageAffineTrans, HomMat2D, ‘constant’, ‘false’)
//对旋转的图像进行仿射变换。实际的效果为显示旋转后的图像。
//上述就3条函数就可以实现对图像的矫正变化。为通用模板。
//
dots_image (ImageAffineTrans, DotImage, 5, ‘dark’, 0)
//由于halcon中包含对点状的图像进行直接读取的功能。所以掉用点状读取算子。DotImage为输出的图像变量存放位置。5为点状的最大直径。如果不想选取过大的点,可以调小,可以使用默认直径。‘dark’,最重要的变量。你提取的点状区域是提取暗色还是亮色(light)还是所有(all)。
reduce_domain (DotImage, ROI_0, ImageReduced)
//裁剪图像。DotImage被裁剪图像,ROI_0裁剪剩余区域。ImageReduced裁剪后的图像存放变量。
invert_image (ImageReduced, ImageInvert)
//对图像进行亮暗翻转。对于halcon的程序来说。Halcon默认识别字符是暗色字符,亮色背景。
binary_threshold (ImageReduced, Region, ‘max_separability’, ‘light’, UsedThreshold)
//快速二值化函数。当图像中只包含2种或者灰度值差别特别大时,可以直接使用快速二值化函数。ImageReduced输入图像。Region输出图像。'max_separability’处理方式(最大方差),'light’提取亮色部分,暗色为(dark)。UsedThreshold默认二值化参数。
dilation_rectangle1 (Region, RegionDilation, 12,12)
//进行膨胀处理,将字符连接在一起。在入门篇中为必须处理步骤,如果不进行膨胀则会使得例如1,i等字符会被识别成2个区域。还有就是膨胀数值太小也会导致字符不能连接在一起,肉眼可能不能观察到,但是进行connection就会有问题。这时候直接调大膨胀量就行了。
connection (RegionDilation, ConnectedRegions)
//拆分区域。RegionDilation输入图像。ConnectedRegions输出图像。
shape_trans (ConnectedRegions, RegionTrans,‘rectangle1’)
//将区域进行选择,‘rectangle1’选择部分为矩形区域
select_shape (RegionTrans, SelectedRegions, [‘height’,‘width’], ‘and’, [36.394,15.48], [100,161.44])
//对多余的区域进行去除。由于我们的字符是具有一定的宽高的区域。我们在进行特征选择的时候可以直接采用对一定高的区域,对一定宽的区域进行筛选。如果不行可以在膨胀后进行开运算或者继续调大膨胀量。
partition_rectangle (SelectedRegions, Partitioned, 50, 100)
//OCR核心识别函数。对于我们已经选择好的区域我们发现一个区域中包含多个字符。那么我们直接继续切割区域。可以点击键盘的ctal键和移动鼠标可以大致看到字符的宽高。然后输入变量固定值。50,为切割宽度。100为切割高度。Partitioned输出图像的变量。
intersection (Partitioned, Region, RegionIntersection)
//然后进行取交集。这一步最容易出现错误。我们要与什么取交集。我们需要的是与我们快速二值化的函数输出进行取交集。我们Partitioned这个变量是我们处理到的字符所在的区域,Region这个变量是我们提取到的字符的形态的。当2个去交集的时候才可以实现。
sort_region (RegionIntersection, SortedRegions, ‘character’, ‘true’, ‘row’)
//对区域输出进行优先排序。主要需要注意排序方式。由于halcon的默认排序方式为从上到逐一排序,所以我们需要修改变量。排序方式为算子的第三个变量’character’。'character’已经我修改好为从左到右排序。更多排序方式可以查看halcon的算子助手。
read_ocr_class_mlp (‘D:/shijue/halcon1/ocr/DotPrint_0-9A-Z_NoRej.omc’, OCRHandle)
//读取halcon的字符识别分类器。Halcon对字符的分类器有非常多种。这次我们的是点状字符。所以选择的是DotPrint【点印】开头的文件,且我们包含有0-9和大写字母等多种字符,所以调用为0-9A-Z类型。对于我们正常输出应调用NoRej类型而不是调用Rej类型,OCRHandle为OCR句柄。Halcon分类器的路径在我们自己的安装程序目录halcon/ocr中
do_ocr_multi_class_mlp (SortedRegions, ImageInvert, OCRHandle, Class, Confidence)
//使用分类器进行区分输出。SortedRegions我们取完交集后的输出图像。ImageInvert我们识别的区域,因为我前面说过halcon只支持暗色字体,亮色背景,所以如果我们的字体为亮色应该将字体进行亮暗翻转,亮暗翻转的算子为invert_image。OCRHandle,OCR句柄,就是我们上面读取分类器的时候进行的输出OCR句柄,Class输出数组,halcon会把所有识别到的数组存放在这个变量中,如果你没有进行排序或者排序错误则输出的数组循序也会是错误的。Confidence调用类型。这个算子是对所有字体进行同步一起识别。也有逐一识别。当我们所要的字符在一定区域,我们可以通过排序然后循环一定个数输出我们需要的字符。
dev_display (ImageAffineTrans)
//显示修正角度后图像。
smallest_rectangle1 (SortedRegions, Row1, Column1, Row2, Column2)
//对图像继续求取最小矩形,方便后面存放输出到图像上
dev_get_window (WindowHandle)
//获取窗口句柄,用于输出在窗口中。
disp_message (WindowHandle, Class, ‘window’, Row1, Column1-80, ‘black’, ‘true’)
//输出字符在窗口中
输出效果
总结实战:
第一:读图。
第二:无论任何情况都需要修正字符角度,除非已经保证字符是平行与图像的。
固定的套路程序,可以直接调用万能。
get_image_size (Image, Width, Height)
gen_rectangle1 (ROI_0, 18.0852, 220.975, 649.983, 1158.32)
//可以不用画ROI区域,其他代码可以直接使用
text_line_slant (Image, Image, 70, -0.4, 0.4, SlantAngle)
vector_angle_to_rigid (Height/2, Width/2, SlantAngle,Height/2, Width/2, 0, HomMat2D)
affine_trans_image (Image, ImageAffineTrans, HomMat2D, ‘constant’, ‘false’)
第三:对字符提取,对于点状字符而言我们可以直接使用
dots_image (ImageAffineTrans, DotImage, 5, ‘dark’, 0)
点状字符提取函数。如果不是点状字符则可以用通过思路解决,在入门篇halcon案例中均是非点状字符的。
第四:使得图像为一个连通域,防止i,1等字符无法识别成功
固定程序:
dilation_rectangle1 (Region, RegionDilation, 12,12)
connection (RegionDilation, ConnectedRegions)
如果字符为亮字符则需要进行亮暗转化,算子为:invert_image (ImageReduced, ImageInvert)
当图像只有黑白2种颜色或者,灰度值差别特别大时,可以直接调用快速二值化函数进行输出。相关算子:binary_threshold (ImageReduced, Region, ‘max_separability’, ‘light’, UsedThreshold)
第五:进行区域拆分
固定程序:
shape_trans (ConnectedRegions, RegionTrans,‘rectangle1’)
select_shape (RegionTrans, SelectedRegions, [‘height’,‘width’], ‘and’, [36.394,15.48], [100,161.44])
partition_rectangle (SelectedRegions, Partitioned, 50, 100)
intersection (Partitioned, Region, RegionIntersection)
sort_region (RegionIntersection, SortedRegions, ‘character’, ‘true’, ‘row’)
进行区域选择然后去除多余部分,对字符区域切割,与二值化的图像取交集,进行排序
第六:进行读取halcon分类器输出
固定程序:
read_ocr_class_mlp (‘D:/shijue/halcon1/ocr/DotPrint_0-9A-Z_NoRej.omc’, OCRHandle)
do_ocr_multi_class_mlp (SortedRegions, ImageInvert, OCRHandle, Class, Confidence)
dev_display (ImageAffineTrans)
smallest_rectangle1 (SortedRegions, Row1, Column1, Row2, Column2)
count_obj (SortedRegions, Number1)
dev_get_window (WindowHandle)
disp_message (WindowHandle, Class, ‘window’, Row1, Column1-80, ‘black’, ‘true’)
当然调用的分类器可能不会相同,但是思路都是一样的。
//
最后如果我们要对汉字进行识别了,这个需要我们自己训练分类器,需要的训练量会非常大,通常不需要。
/*********************************************/
有问题可以直接叫我。