主要就是c#联合Halcon进行几何定位(也可以叫做模型匹配),本程序主要是基于单模板,进行单个模板的匹配以及循环遍历模板的匹配,如果您觉得文章不错,麻烦您关注博主,如有不对的地方,还希望大家提出来,我们共同进步。
一: 程序配置
1: 首先配置在winfom引用程序中引用两个halcon应用程序的库:分别是halcon.dll和halcondotnet.dll,而后把这两个库放在你的应用程序输出路径下面,然后在下边的图片中取消首选32位的勾选。
2:右键点击工具箱,单击选择项,然后点击浏览按钮,引用halcondotnet.dll控件,点击确定就可以显示HWindowControl控件了
二: 程序界面:
用到的控件分别为:
1个图形窗口HWindowControl,2个ListBox控件,5个button控件
程序界面
三:运行效果展示
1:点击读取图片选择一个图片并画ROI区域,在下边可以看到读取图像成功,并且获得模板的基准。
2:点击图片列表载入可以选择多幅图片并且在右上角的listbox控件中显示多幅图片的路径。
3:选中右上角listbox控件的一个项然后单击单步模型匹配会根据不同方向,位置同一个图像进行几何定位
4:点击遍历查找模型可以快速地对右上角listbox控件中的所有图片进行快熟匹配
四:程序代码
读取模型图片按钮代码:
private void button读取图片_Click(object sender, EventArgs e)
{
HTuple width, height;
OpenFileDialog openFile = new OpenFileDialog();
openFile.Filter = "jpg文件(*.jpg)|*.jpg|png文件(*.png)|*.png|bmp文件(*.bmp文件)|*.bmp";
if (openFile.ShowDialog()==DialogResult.OK)
{
hImage.ReadImage(openFile.FileName);
//设置读取的图片的大小,并且刚好设置在窗口中
HOperatorSet.GetImageSize(hImage, out width, out height);
HOperatorSet.SetPart(hw1.HalconWindow, 0, 0, height, width);
//图像显示
hImage.DispObj(hw1.HalconWindow);
listBox信息.Items.Add("读取单个图像成功");
}
}
画ROI按钮:
private void button画ROI_Click(object sender, EventArgs e)
{
try
{
//取消焦点
hw1.Focus();
HOperatorSet.SetColor(hw1.HalconWindow, "red");
HOperatorSet.DrawRectangle2(hw1.HalconID, out row, out column, out phi, out length1, out length);
HOperatorSet.GenRectangle2(out rectangle2, row, column, phi, length1, length);
HOperatorSet.DispObj(rectangle2, hw1.HalconID);
HOperatorSet.ReduceDomain(hImage, rectangle2, out ho_ImageReduced);
HOperatorSet.CreateShapeModel(ho_ImageReduced, "auto", (new HTuple(-180)).TupleRad()
, (new HTuple(360)).TupleRad(), "auto", "auto", "use_polarity", "auto", "auto",
out modelId);
HOperatorSet.FindShapeModel(hImage, modelId, (new HTuple(-180)).TupleRad()
, (new HTuple(360)).TupleRad(), 0.5, 1, 0.5, "least_squares", 0, 0.9, out hv_Row1,
out hv_Column1, out hv_Angle, out hv_Score);
//显示匹配结果
dev_display_shape_matching_results(modelId, "red", hv_Row1, hv_Column1, hv_Angle,
1, 1, 0);
//产生十字交叉点
HOperatorSet.GenCrossContourXld(out ho_Cross, hv_Row1, hv_Column1, 15, (new HTuple(-45)).TupleRad());
HOperatorSet.DispObj(ho_Cross, hw1.HalconWindow);
listBox信息.Items.Add("画模板ROI区域成功");
listBox信息.Items.Add("获得基准模板成功");
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
图片列表载入按钮:
private void button图片载入_Click(object sender, EventArgs e)
{
//多个图片的载入
OpenFileDialog openFile = new OpenFileDialog();
//设置打开属性Multiselect为true表示允许选中多个图片文件
openFile.Multiselect = true;
openFile.Filter = "JPG文件|*.jpg|PNG文件|*.png|BMP文件|*.bmp";
if (openFile.ShowDialog()==DialogResult.OK)
{
foreach (var item in openFile.FileNames)
{
listBox文件.Items.Add(item);
}
}
}
单步查找模型按钮:
private void button单模型查找_Click(object sender, EventArgs e)
{
HImage hImagetwo = new HImage();
string a = Convert.ToString(listBox文件.SelectedItem);
hImagetwo.ReadImage(a);
HTuple Width, Height;
//设置图片以合适的方式显示在图片控件上面
HOperatorSet.GetImageSize(hImagetwo, out Width, out Height);
HOperatorSet.SetPart(hw1.HalconWindow, 0, 0, Height, Width);
HOperatorSet.DispObj(hImagetwo, hw1.HalconWindow);
HOperatorSet.FindShapeModel(hImagetwo, modelId, (new HTuple(-180)).TupleRad()
, (new HTuple(360)).TupleRad(), 0.3, 1, 0.5, "least_squares", 0, 0.7, out hv_Row1,
out hv_Column1, out hv_Angle, out hv_Score);
//显示匹配结果
dev_display_shape_matching_results(modelId, "red", hv_Row1, hv_Column1, hv_Angle,
1, 1, 0);
//产生十字交叉点
HOperatorSet.GenCrossContourXld(out ho_Cross, hv_Row1, hv_Column1, 15, (new HTuple(-45)).TupleRad());
HOperatorSet.DispObj(ho_Cross, hw1.HalconWindow);
listBox信息.Items.Add("单个匹配图像成功");
}
遍历查找模型按钮:
private void button循环遍历查找_Click(object sender, EventArgs e)
{
HImage hImagethree = new HImage();
for (int i = 0; i < listBox文件.Items.Count; i++)
{
int index = listBox文件.FindString(Convert.ToString(listBox文件.Items[i]));
if (index != ListBox.NoMatches)
{
listBox文件.SetSelected(index, true); //表示在listbox文件框中当前循环遍历的是哪一个
string filename = Convert.ToString(listBox文件.SelectedItem);
hImagethree.ReadImage(filename);
HTuple Width, Height;
//设置图片以合适的方式显示在图片控件上面
HOperatorSet.GetImageSize(hImagethree, out Width, out Height);
HOperatorSet.SetPart(hw1.HalconWindow, 0, 0, Height, Width);
HOperatorSet.DispObj(hImagethree, hw1.HalconWindow);
HOperatorSet.FindShapeModel(hImagethree, modelId, (new HTuple(-180)).TupleRad()
, (new HTuple(360)).TupleRad(), 0.3, 1, 0.5, "least_squares", 0, 0.7, out hv_Row1,
out hv_Column1, out hv_Angle, out hv_Score);
//显示匹配结果
if (hv_Row1>0&&hv_Column1>0)
{
//显示匹配结果
dev_display_shape_matching_results(modelId, "red", hv_Row1, hv_Column1, hv_Angle,
1, 1, 0);
//产生十字交叉点
HOperatorSet.GenCrossContourXld(out ho_Cross, hv_Row1, hv_Column1, 15, (new HTuple(-45)).TupleRad());
HOperatorSet.DispObj(ho_Cross, hw1.HalconWindow);
listBox信息.Items.Add("循环遍历中匹配单个图像成功");
}
}
}
}
完整程序代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;
namespace 多模板匹配
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//设置画的模式
HOperatorSet.SetDraw(hw1.HalconWindow, "margin");
}
HImage hImage = new HImage();
private void button读取图片_Click(object sender, EventArgs e)
{
HTuple width, height;
OpenFileDialog openFile = new OpenFileDialog();
openFile.Filter = "jpg文件(*.jpg)|*.jpg|png文件(*.png)|*.png|bmp文件(*.bmp文件)|*.bmp";
if (openFile.ShowDialog()==DialogResult.OK)
{
hImage.ReadImage(openFile.FileName);
//设置读取的图片的大小,并且刚好设置在窗口中
HOperatorSet.GetImageSize(hImage, out width, out height);
HOperatorSet.SetPart(hw1.HalconWindow, 0, 0, height, width);
//图像显示
hImage.DispObj(hw1.HalconWindow);
listBox信息.Items.Add("读取单个图像成功");
}
}
HTuple color;
#region 画ROI区域产生的变量
//创建模板的编号
HTuple modelId;
//查询模板的中间坐标,角度,还有模型实例的分数
HTuple hv_Row1 = null, hv_Column1 = null, hv_Angle = null, hv_Score;
//十字坐标
HObject ho_Cross;
//矩形2
HTuple row, column, phi, length1, length;
HObject rectangle2, ho_ImageReduced;
public void dev_display_shape_matching_results(HTuple hv_ModelID, HTuple hv_Color,
HTuple hv_Row, HTuple hv_Column, HTuple hv_Angle, HTuple hv_ScaleR, HTuple hv_ScaleC,
HTuple hv_Model)
{
// Local iconic variables
HObject ho_ModelContours = null, ho_ContoursAffinTrans = null;
// Local control variables
HTuple hv_NumMatches = null, hv_Index = new HTuple();
HTuple hv_Match = new HTuple(), hv_HomMat2DIdentity = new HTuple();
HTuple hv_HomMat2DScale = new HTuple(), hv_HomMat2DRotate = new HTuple();
HTuple hv_HomMat2DTranslate = new HTuple();
HTuple hv_Model_COPY_INP_TMP = hv_Model.Clone();
HTuple hv_ScaleC_COPY_INP_TMP = hv_ScaleC.Clone();
HTuple hv_ScaleR_COPY_INP_TMP = hv_ScaleR.Clone();
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_ModelContours);
HOperatorSet.GenEmptyObj(out ho_ContoursAffinTrans);
//This procedure displays the results of Shape-Based Matching.
//
hv_NumMatches = new HTuple(hv_Row.TupleLength());
if ((int)(new HTuple(hv_NumMatches.TupleGreater(0))) != 0)
{
if ((int)(new HTuple((new HTuple(hv_ScaleR_COPY_INP_TMP.TupleLength())).TupleEqual(
1))) != 0)
{
HOperatorSet.TupleGenConst(hv_NumMatches, hv_ScaleR_COPY_INP_TMP, out hv_ScaleR_COPY_INP_TMP);
}
if ((int)(new HTuple((new HTuple(hv_ScaleC_COPY_INP_TMP.TupleLength())).TupleEqual(
1))) != 0)
{
HOperatorSet.TupleGenConst(hv_NumMatches, hv_ScaleC_COPY_INP_TMP, out hv_ScaleC_COPY_INP_TMP);
}
if ((int)(new HTuple((new HTuple(hv_Model_COPY_INP_TMP.TupleLength())).TupleEqual(
0))) != 0)
{
HOperatorSet.TupleGenConst(hv_NumMatches, 0, out hv_Model_COPY_INP_TMP);
}
else if ((int)(new HTuple((new HTuple(hv_Model_COPY_INP_TMP.TupleLength()
)).TupleEqual(1))) != 0)
{
HOperatorSet.TupleGenConst(hv_NumMatches, hv_Model_COPY_INP_TMP, out hv_Model_COPY_INP_TMP);
}
for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_ModelID.TupleLength())) - 1); hv_Index = (int)hv_Index + 1)
{
ho_ModelContours.Dispose();
HOperatorSet.GetShapeModelContours(out ho_ModelContours, hv_ModelID.TupleSelect(
hv_Index), 1);
if (HDevWindowStack.IsOpen())
{
HOperatorSet.SetColor(HDevWindowStack.GetActive(), hv_Color.TupleSelect(
hv_Index % (new HTuple(hv_Color.TupleLength()))));
}
HTuple end_val18 = hv_NumMatches - 1;
HTuple step_val18 = 1;
for (hv_Match = 0; hv_Match.Continue(end_val18, step_val18); hv_Match = hv_Match.TupleAdd(step_val18))
{
if ((int)(new HTuple(hv_Index.TupleEqual(hv_Model_COPY_INP_TMP.TupleSelect(
hv_Match)))) != 0)
{
HOperatorSet.HomMat2dIdentity(out hv_HomMat2DIdentity);
HOperatorSet.HomMat2dScale(hv_HomMat2DIdentity, hv_ScaleR_COPY_INP_TMP.TupleSelect(
hv_Match), hv_ScaleC_COPY_INP_TMP.TupleSelect(hv_Match), 0, 0, out hv_HomMat2DScale);
HOperatorSet.HomMat2dRotate(hv_HomMat2DScale, hv_Angle.TupleSelect(hv_Match),
0, 0, out hv_HomMat2DRotate);
HOperatorSet.HomMat2dTranslate(hv_HomMat2DRotate, hv_Row.TupleSelect(
hv_Match), hv_Column.TupleSelect(hv_Match), out hv_HomMat2DTranslate);
ho_ContoursAffinTrans.Dispose();
HOperatorSet.AffineTransContourXld(ho_ModelContours, out ho_ContoursAffinTrans,
hv_HomMat2DTranslate);
//显示
hw1.HalconWindow.DispObj(ho_ContoursAffinTrans);
//
if (HDevWindowStack.IsOpen())
{
HOperatorSet.DispObj(ho_ContoursAffinTrans, HDevWindowStack.GetActive()
);
}
}
}
}
}
ho_ModelContours.Dispose();
ho_ContoursAffinTrans.Dispose();
return;
}
#endregion
private void button画ROI_Click(object sender, EventArgs e)
{
try
{
//取消焦点
hw1.Focus();
HOperatorSet.SetColor(hw1.HalconWindow, "red");
HOperatorSet.DrawRectangle2(hw1.HalconID, out row, out column, out phi, out length1, out length);
HOperatorSet.GenRectangle2(out rectangle2, row, column, phi, length1, length);
HOperatorSet.DispObj(rectangle2, hw1.HalconID);
HOperatorSet.ReduceDomain(hImage, rectangle2, out ho_ImageReduced);
HOperatorSet.CreateShapeModel(ho_ImageReduced, "auto", (new HTuple(-180)).TupleRad()
, (new HTuple(360)).TupleRad(), "auto", "auto", "use_polarity", "auto", "auto",
out modelId);
HOperatorSet.FindShapeModel(hImage, modelId, (new HTuple(-180)).TupleRad()
, (new HTuple(360)).TupleRad(), 0.5, 1, 0.5, "least_squares", 0, 0.9, out hv_Row1,
out hv_Column1, out hv_Angle, out hv_Score);
//显示匹配结果
dev_display_shape_matching_results(modelId, "red", hv_Row1, hv_Column1, hv_Angle,
1, 1, 0);
//产生十字交叉点
HOperatorSet.GenCrossContourXld(out ho_Cross, hv_Row1, hv_Column1, 15, (new HTuple(-45)).TupleRad());
HOperatorSet.DispObj(ho_Cross, hw1.HalconWindow);
listBox信息.Items.Add("画模板ROI区域成功");
listBox信息.Items.Add("获得基准模板成功");
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button图片载入_Click(object sender, EventArgs e)
{
//多个图片的载入
OpenFileDialog openFile = new OpenFileDialog();
//设置打开属性Multiselect为true表示允许选中多个图片文件
openFile.Multiselect = true;
openFile.Filter = "JPG文件|*.jpg|PNG文件|*.png|BMP文件|*.bmp";
if (openFile.ShowDialog()==DialogResult.OK)
{
foreach (var item in openFile.FileNames)
{
listBox文件.Items.Add(item);
}
}
}
private void button单模型查找_Click(object sender, EventArgs e)
{
HImage hImagetwo = new HImage();
string a = Convert.ToString(listBox文件.SelectedItem);
hImagetwo.ReadImage(a);
HTuple Width, Height;
//设置图片以合适的方式显示在图片控件上面
HOperatorSet.GetImageSize(hImagetwo, out Width, out Height);
HOperatorSet.SetPart(hw1.HalconWindow, 0, 0, Height, Width);
HOperatorSet.DispObj(hImagetwo, hw1.HalconWindow);
HOperatorSet.FindShapeModel(hImagetwo, modelId, (new HTuple(-180)).TupleRad()
, (new HTuple(360)).TupleRad(), 0.3, 1, 0.5, "least_squares", 0, 0.7, out hv_Row1,
out hv_Column1, out hv_Angle, out hv_Score);
//显示匹配结果
dev_display_shape_matching_results(modelId, "red", hv_Row1, hv_Column1, hv_Angle,
1, 1, 0);
//产生十字交叉点
HOperatorSet.GenCrossContourXld(out ho_Cross, hv_Row1, hv_Column1, 15, (new HTuple(-45)).TupleRad());
HOperatorSet.DispObj(ho_Cross, hw1.HalconWindow);
listBox信息.Items.Add("单个匹配图像成功");
}
private void button循环遍历查找_Click(object sender, EventArgs e)
{
HImage hImagethree = new HImage();
for (int i = 0; i < listBox文件.Items.Count; i++)
{
int index = listBox文件.FindString(Convert.ToString(listBox文件.Items[i]));
if (index != ListBox.NoMatches)
{
listBox文件.SetSelected(index, true); //表示在listbox文件框中当前循环遍历的是哪一个
string filename = Convert.ToString(listBox文件.SelectedItem);
hImagethree.ReadImage(filename);
HTuple Width, Height;
//设置图片以合适的方式显示在图片控件上面
HOperatorSet.GetImageSize(hImagethree, out Width, out Height);
HOperatorSet.SetPart(hw1.HalconWindow, 0, 0, Height, Width);
HOperatorSet.DispObj(hImagethree, hw1.HalconWindow);
HOperatorSet.FindShapeModel(hImagethree, modelId, (new HTuple(-180)).TupleRad()
, (new HTuple(360)).TupleRad(), 0.3, 1, 0.5, "least_squares", 0, 0.7, out hv_Row1,
out hv_Column1, out hv_Angle, out hv_Score);
//显示匹配结果
if (hv_Row1>0&&hv_Column1>0)
{
//显示匹配结果
dev_display_shape_matching_results(modelId, "red", hv_Row1, hv_Column1, hv_Angle,
1, 1, 0);
//产生十字交叉点
HOperatorSet.GenCrossContourXld(out ho_Cross, hv_Row1, hv_Column1, 15, (new HTuple(-45)).TupleRad());
HOperatorSet.DispObj(ho_Cross, hw1.HalconWindow);
listBox信息.Items.Add("循环遍历中匹配单个图像成功");
}
}
}
}
}
}
如果你觉得文章不错,希望给作者点一个大大的关注,我在这里感谢大家
版权归原作者 SmallTown2 所有, 如有侵权,请联系我们删除。