大家好,今天给大家分享下最新学习的知识,C#结合Halcon的模版匹配demo。说个题外话,我认为学习就是自己学习了,学会了再分享给大家,这样才是真正的学会了,那我们现在开始吧~~~
OK,要完成模版匹配案例,我们要知道,模版匹配的流程,还有winform如何调用Halcon,这两个问题我们一一来解决,首先模版匹配的流程:
明白了流程之后我们利用这些逻辑来编写halcon程序 ,具体程序如下图:
halcon的模版匹配程序
**窗口操作
dev_close_window()
dev_get_window(WindowHandle)
dev_set_draw('margin')
dev_set_color('green')
dev_set_line_width(2)
** ①加载模版图像;
read_image(Image, 'D:/HALCONStudy/C#联合halcon编程/匹配图片/board-01.png')
**②绘制匹配区域并锁定;
draw_rectangle1(WindowHandle, Row1, Column1, Row2, Column2)
gen_rectangle1(Rectangle, Row1, Column1, Row2, Column2)
**锁定区域
reduce_domain(Image, Rectangle, ImageReduced)
**③创建模版(参数设置);
create_shape_model(ImageReduced, 'auto', rad(0), rad(360), 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)
**④加载待匹配图像;
read_image(Image2, 'D:/HALCONStudy/C#联合halcon编程/匹配图片/board-02.png')
**⑤使用创建的模版来匹配定位(返回匹配分数,匹配中心坐标,匹配角度);
find_shape_model(Image2, ModelID, rad(0), rad(360), 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
**⑥获取匹配的轮廓,然后使用仿射变换轮廓。
get_shape_model_contours(ModelContours, ModelID, 1)
**创建一个刚性变换矩阵
vector_angle_to_rigid(0, 0, 0, Row, Column, Angle, HomMat2D)
**仿射变换
affine_trans_contour_xld(ModelContours, ContoursAffineTrans, HomMat2D)
dev_display(Image2)
dev_display(ContoursAffineTrans)
halcon程序写完测试完成后,我们可以导出成C#文件,一会在winform编写时可以参考借鉴。
WInform程序设计
我们创建一个简单的Winform程序,先搭建一下环境,导入halcon的dll(halcondotnetxl),接着简单搭建一下界面UI,如下图
接下来就是去编写每个按钮的事件,这边我直接给到大家吧
全局变量
private HImage ho_Image;
private HTuple imageWidth;
private HTuple imageHeight;
private HObject rectangle;
private HTuple hv_ModelID;
加载模板图像
/// <summary>
/// 加载图像
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_LoadImage_Click(object sender, EventArgs e)
{
//清空窗口
mhw.halconWd.ClearWindow();
//创建一个文件资源对话框对象
var dialog = new OpenFileDialog();
//设置打开的资源的后缀
dialog.Filter = "图像|*.png;*.jpg;*.bmp";
//存储最后一次选择的文件夹目录
dialog.RestoreDirectory = true;
if (dialog.ShowDialog() == DialogResult.OK)
{
//获取用户选择的路径
var imgurl = dialog.FileName;
//创建一个halcon图像对象
ho_Image = new HImage();
//显示图像
ho_Image.ReadImage(imgurl);
//获取图像的分辨率
HOperatorSet.GetImageSize(ho_Image, out imageWidth, out imageHeight);
//显示用户加载
//mhw.halconWd.DispObj(ho_Image);
DisplayHObject(mhw.halconWd, ho_Image);
}
}
绘制ROI区域
/// <summary>
/// 在图像上绘制ROI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_PaintROI_Click(object sender, EventArgs e)
{
//设置窗口的颜色
HOperatorSet.SetDraw(mhw.halconWd, "margin");
HOperatorSet.SetColor(mhw.halconWd, "green");
HOperatorSet.SetLineWidth(mhw.halconWd, 3);
//让halcon控件获取焦点
mhw.Focus();
//绘制平行矩形
HOperatorSet.DrawRectangle1(mhw.halconWd, out HTuple row1, out HTuple column1, out HTuple row2, out HTuple column2);
//生成矩形
HOperatorSet.GenRectangle1(out rectangle, row1, column1, row2, column2);
HOperatorSet.DispRectangle1(mhw.halconWd, row1, column1, row2, column2);
}
创建模板
/// <summary>
/// 创建模版
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCreateTem_Click(object sender, EventArgs e)
{
//清空窗口
mhw.halconWd.ClearWindow();
//锁定模版匹配图像
HOperatorSet.ReduceDomain(ho_Image, rectangle, out HObject ho_ImageReduced);
//创建模板(参数设置)
HOperatorSet.CreateShapeModel(ho_ImageReduced, "auto", (new HTuple(0)).TupleRad()
, (new HTuple(360)).TupleRad(), "auto", "auto", "use_polarity", "auto", "auto",
out hv_ModelID);
//保存创建的模板
HOperatorSet.WriteShapeModel(hv_ModelID, "model.shm");
//显示模板区域
mhw.halconWd.DispObj(ho_ImageReduced);
//显示模板
MessageBox.Show("创建模板成功,并保存模板");
}
加载匹配图像
/// <summary>
/// 加载匹配图像
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_LoadMatchImage_Click(object sender, EventArgs e)
{
//清空窗口
mhw.halconWd.ClearWindow();
//创建一个文件资源对话框对象
var dialog = new OpenFileDialog();
//设置打开的资源的后缀
dialog.Filter = "图像|*.png;*.jpg;*.bmp";
//存储最后一次选择的文件夹目录
dialog.RestoreDirectory = true;
if (dialog.ShowDialog() == DialogResult.OK)
{
//获取用户选择的路径
var imgurl = dialog.FileName;
//创建一个halcon图像对象
ho_Image = new HImage();
//显示图像
ho_Image.ReadImage(imgurl);
//获取图像的分辨率
HOperatorSet.GetImageSize(ho_Image, out imageWidth, out imageHeight);
//显示用户加载
//mhw.halconWd.DispObj(ho_Image);
DisplayHObject(mhw.halconWd, ho_Image);
}
//读取模版句柄
HOperatorSet.ReadShapeModel("model.shm", out hv_ModelID);
}
进行模板匹配
/// <summary>
/// 进行模版匹配
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Match_Click(object sender, EventArgs e)
{
//根据创建模版来查找新图像的位置
HOperatorSet.FindShapeModel(ho_Image, hv_ModelID, (new HTuple(0)).TupleRad()
, (new HTuple(360)).TupleRad(), 0.5, 1, 0.5, "least_squares", 0, 0.9, out HTuple hv_Row,
out HTuple hv_Column, out HTuple hv_Angle, out HTuple hv_Score);
//获取匹配的轮廓,然后使用仿射变换
HOperatorSet.GetShapeModelContours(out HObject ho_ModelContours, hv_ModelID, 1);
//创建刚性变换矩阵
HOperatorSet.VectorAngleToRigid(0, 0, 0, hv_Row, hv_Column, hv_Angle, out HTuple hv_HomMat2D);
//仿射变换
HOperatorSet.AffineTransContourXld(ho_ModelContours, out HObject ho_ContoursAffineTrans,
hv_HomMat2D);
HOperatorSet.ClearWindow(mhw.halconWd);
DisplayHObject(mhw.halconWd, ho_Image);
HOperatorSet.DispObj(ho_ContoursAffineTrans, mhw.halconWd);
this.lbl_rate.Text = hv_Score.ToString();
}
运行结果
可见我们的模板匹配还是可以的,人机交互也不错。