车牌或OCR识别套路:
1、读取/采集图像(read_image)
2、对于RGB图像一般可以考虑转换颜色空间(关于RGB、HSV、HSL:https://zhuanlan.zhihu.com/p/67930839)
(1)先分离RGB通道(decompose3)
(2)将RGB转换颜色空间,如转换到HSV:trans_from_rgb(Red, Green, Blue, Hue, Saturation, Intensity, 'hsv'),一般使用H(颜色,如果你需要的目标颜色非常鲜明,比如都是红色,那就一般用这个分量)、S(饱和度)分量做处理
3、定位、校正(可选)
定位套路:
(1)阈值化(threshold)
(2)断开形成不同连通域(connection)
》注意如果我们需要的目标比如车牌,出现断开(即看起来不完整比如有字符看起来缺了),需要先使用膨胀dilation_*/联合union1,将像素连起来
(3)特征选择shape_select,提取目标区域即车牌。(获取区域特征的函数region_features)
》同理如果出现目标没有连一起,也可以使用联合或膨胀连接起来
》填充目标区中的孔洞fill_up
》求目标区域的角度(区域的极轴方向一般偏向于尖角方向)orientation
校正位置:
(1)根据目标区域角度(正表示逆时针方向需将其旋转到180才回正、负表示顺时针方向需将其旋转到0度位置)转正图像
》求区域的中心位置(area_center)
》根据角度求旋转矩阵vector_angle_to_rigid
》仿射变换转正图像(注意这里转正的是图像即读取的Image)affine_trans_image
(2)抠图(即扣取定位校正后的车牌)
》affine_trans_region 转正目标区域(目的说白了就是求车牌转正之后在图像中的位置)
》reduce_domain(根据转正车牌区域位置从已转正的图像中抠出车牌图像)
4、字符分割
》对上面抠出来的车牌进行灰度化rgb1_to_gray(可以做一个翻转图像给inert_image给下面的字符识别使用)
》阈值化threshold(如果阈值化之后发现字符和其他没用的地方连起来了,可以做个腐蚀/开运算)
》断开connection
》特征选择select_shape,提取字符
》对字符区域排序sort_region
5、ocr字符识别
》read_ocr_class_mlp从文件中获取OCR的分类器,一般用印刷字体分类器Industrial_0-9A-Z_NoRej.omc
》do_ocr_multi_class_mlp 使用分类器对多个字符分类,第一个参数是上一步提取的字符,第二个参数需要注意它需要一张翻转后的灰度图像
6、显示
汉字识别:
1、读取/采集图像(read_image)
2、预处理(可选)
》灰度变换:如线性变换scale_image
3、字符分割
》阈值化threshold
》断开connection
》特征检测选择select_shape
》可能需要定位、校正
4、形成trf文件(即将字符图像和字符关联)
5、训练
》创建分类器
》训练分类器
》保存分类器到omc文件(不保存,直接拿来识别文字也可以)
》识别文字
Blob分析:阈值化+形状选择+形态学
图像处理基本框架:
1、采集
2、预处理
增加对比度:sacle_image(特征直方图里面选择缩放工具)、emphasize、gray_range_rect、equhis...(直方图均衡化)
去噪:中值滤波、均值滤波、高斯滤波
3、图像分割
手画提取ROI
Blob逼近提取ROI(阈值化+形态学+形状选择)
4、特征识别、计算
5、显示或通信(与运动板卡通信)
图像处理十大领域:
1、图像基础理论
2、灰度变换
3、图像增强
4、图像的几何变换(如仿射变换、极坐标变换)
5、图像分割(ROI提取, Blob就是图像团块提取)
6、图像频域处理(傅里叶变换,通常用于轻微的划痕检测)
7、形态学
8、图像复原(一般用于刑侦学,了解)
9、运动图像(差分)
10、图像配准(如模板匹配)
颜色识别:(查看Halcon颜色检测例程)
方法1:HSV转换提取,缺点不稳定受光照影响很严重 Sort fuses by color例程
方法2:训练学习。color_pieces MLP例程
特征向量:说白了就是一个物品的各种特征集合如:[纹理,周长,面积]。训练器通过特征向量将物品进行分类
所谓机器学习不过就是先给一些标准模板给它提取特征、训练、并将模型分类保存起来,后续到了真实环境能正确识别同类物品
VC++联合:
程序三层:UI、业务、数据
Halcon写好导出cpp,找到void action()函数就相当于在halcon里面写的代码逻辑
环境配置:(即配置Halcon)
1.include目录配置:项目属性 -- C/C++ -- 常规 -- 附加包含目录 -- 添加 例如:
C:\Program Files\MVTec\HALCON-12.0\include
C:\Program Files\MVTec\HALCON-12.0\include\halconcpp
2.lib配置:
》项目属性 -- 链接器 -- 常规 -- 附加库目录 -- 添加注意编译器位数和库位数要对应,如下为32位
C:\Program Files\MVTec\HALCON-12.0\lib\x86sse2-win32
》项目属性 -- 链接器 -- 输入 -- 附加依赖项 -- 添加halconcpp.lib
3.DLL拷贝到exe所在目录或配置
C:\Program Files\MVTec\HALCON-12.0\bin\x86sse2-win32
4.项目代码#include对应头文件,命名空间如using namespace HalconCpp;
5.Picture Control控件可以用来显示图像
显示图像的Demo:
HObject ho_image; // Halcon中只有图像、区域、xld轮廓是HObject类型,其他都是HTuple类型
HTuple hv_width, hv_height, hv_windowHandle;ReadImage(&ho_image, "wer.bmp"); // 读取图像
GetImageSize(ho_image, &hv_width, &hv_height); // 获取图像宽高
SetWindowAttr("background_color", "black");// 设置Halcon窗口属性// 获取Picture Control控件的窗口句柄
HWND hPic = GetDlgItem(IDC_PIC)->m_hWnd;
// 获取控件的尺寸
CRect rectPic;
GetDlgItem(IDC_PIC)->GetWindowRect(&rectPic);
// 转换到Halcon中的类型
HTuple width, height;
width[0] = rect.Width();
height[0] = rect.Height();// 将Halcon窗口嵌套到控件
OpenWindow(0, 0, width, height, (LONG)hPic, "", "", &hv_windowHandle);
HDevWindowStack::Push(hv_windowHandle);
if (HDevWindowStack::IsOpen())
DispObj(ho_image, HDevWindowStack::GetActive());
工业视觉常见需求分类:
二维
识别定位
OCR光学字符识别、一维码、二维码
测量
缺陷检测
运动控制-手眼标定-手眼抓取
三维
双目视觉
点云
特征识别/纹理识别套路:
1、特征提取,提取多个特征生成特征向量,特征还可以通过共生矩阵来提取cooc_feather_image
2、创建分类器
3、添加(特征)样本
4、训练
5、训练完成就可以用分类器来识别
手眼标定:(机械手+相机联合)
像素坐标 变换矩阵 机械手坐标
1、九点标定Demo:(eye-to-hand即相机和机械手分别固定,eye-in-hand模式是指将相机固定在机械手上,跟着移动但是每次在固定位置抓图)
area_center(SortedRegions, Area, Row, Column); # 像素点坐标,即相机获取的标定板的9个点的坐标
# 下面的假设是从机械手中读取的9个点的坐标
Row1 := [55,50,45,5,0,-5,-50,-50,-50]
Column1 := [375,325,270,380,280,395,340,290]
# 求变换矩阵HomMat2D
vector_to_hom_mat2d(Row, Column, Row1, Column1, HomMat2D)
# 求出变换矩阵之后就可以根据像素坐标转换到机械手的坐标
affine_trans_point_2d(HomMat2D, Row2, Column2, Qx, Qy) # (Row2,Column2)为相机识别的坐标,转换的结果为机械手坐标(Qx, Qy)
2、标定法
平移:
1 0 a x1 x2
0 1 b * y1 = y2
0 0 1 1 1
官方案例:手眼标定系统下的handeye-movingcam_calibration.hdev
相机标定demo:摄像机标定