此部分方法,旨在创建模板后,再标注出模板上的感兴趣区域。再查找并仿射模板时,同时对感兴趣区域进行仿射。
复制代码后,请自行配置相应的类和全局变量。我写了一个Helper类,都是方法封装。实例化类时hwindowcontrol1作为参数传入,返回的窗口句柄直接被Helper类自调用。
public class Helper
{
private HTuple h_hWindowHandle; //halcon图形窗口句柄
private HWindowControl h_hWindow; //用于窗口Focus
public Helper(HWindowControl hWindow)
{
this.h_hWindow = hWindow;
h_hWindowHandle = hWindow.HalconWindow;
//实例化一个窗口并获得该窗口的句柄
}
}
Halcon封装方法
1.创建模板方法
private HTuple RowModel, ColModel;//模板的中心点参数
public void CreateShapeModel()
{
HTuple Homate2D;
HObject ImageReduced, ModelXld, ModelXld_T;
HOperatorSet.GenEmptyObj(out ImageReduced);
try
{
//判断图像是否为空
if (!ObjectValided(h_Image))
{
return;
}
h_hWindow.Focus();
HOperatorSet.GenEmptyObj(out ImageReduced);
HOperatorSet.GenEmptyObj(out ModelXld);
HOperatorSet.DispObj(h_Image, h_hWindowHandle);
HTuple Angle, Length1, Length2;
//提示信息
disp_message(h_hWindowHandle, "画模板区域,点击鼠标右键确认", "window", 20, 20, "red", "false");
//画并产生模板区域
HOperatorSet.DrawRectangle2(h_hWindowHandle, out RowModel, out ColModel, out Angle, out Length1,
out Length2);
h_Match.m_ModelRegion.Dispose();
HOperatorSet.GenRectangle2(out h_Match.m_ModelRegion, RowModel, ColModel, Angle, Length1, Length2);
ImageReduced.Dispose();
HOperatorSet.ReduceDomain(h_Image, h_Match.m_ModelRegion, out ImageReduced);
//创建模板
if (h_Match.m_ModelID != null)
{
HOperatorSet.ClearShapeModel(h_Match.m_ModelID);
h_Match.m_ModelID = null;
}
HOperatorSet.CreateShapeModel(ImageReduced, "auto", new HTuple(-h_Match.m_dAngle).TupleRad(),
new HTuple(h_Match.m_dAngle * 2).TupleRad(), "auto", "auto", "use_polarity", "auto", "auto",
out h_Match.m_ModelID);
HOperatorSet.VectorAngleToRigid(0, 0, 0, RowModel, ColModel, 0, out Homate2D);
//获取模板轮廓
ModelXld.Dispose();
HOperatorSet.GetShapeModelContours(out ModelXld, h_Match.m_ModelID, 1);
HOperatorSet.AffineTransContourXld(ModelXld, out ModelXld_T, Homate2D);
//对模板进行仿射变换
HOperatorSet.DispObj(h_Image, h_hWindowHandle);
HOperatorSet.DispObj(ModelXld_T, h_hWindowHandle);
//提示信息
if (h_Match.m_ModelID != null)
{
disp_message(h_hWindowHandle, "创建模板成功!", "window", 20, 20, "green", "false");
}
else
{
disp_message(h_hWindowHandle, "创建模板失败!", "window", 20, 20, "red", "false");
}
}
catch
{
disp_message(h_hWindowHandle, "创建模板过程失败!", "window", 20, 20, "red", "false");
}
ImageReduced.Dispose();
}
2.标注感兴趣区域方法(此处我用点生成圆形区域)
public void CreatePoint()
{
HTuple RowPoint, ColPoint;
if (!ObjectValided(h_Image))
{
return;
}
h_hWindow.Focus();
HOperatorSet.DrawPoint(h_hWindowHandle, out RowPoint, out ColPoint);
HOperatorSet.GenCircle(out h_Match.m_CatchXld, RowPoint, ColPoint, 10);
HOperatorSet.DispObj(h_Match.m_CatchXld, h_hWindowHandle);
}
3.查找模板方法
public void FindShapeModel(int num, out double[] Rows, out double[] Cols, out double[] Angles)
{
h_Match.m_nNumMatchs = num; //模板查找指定个数
Rows = new double[h_Match.m_nNumMatchs];
Cols = new double[h_Match.m_nNumMatchs];
Angles = new double[h_Match.m_nNumMatchs];
//判断图像是否为空
if (!ObjectValided(h_Image))
{
Rows = Cols = Angles = null;
return;
}
h_HomMat2D = 0;
HTuple Row = new HTuple();
HTuple Column = new HTuple();
HTuple Angle = new HTuple();
HTuple Score = new HTuple();
HObject Contour, ContourCatch;
HOperatorSet.GenEmptyObj(out Contour);
HOperatorSet.GenEmptyObj(out ContourCatch);
try
{
//判断模板是否为空
if (h_Match.m_ModelID == null)
{
HOperatorSet.DispObj(h_Image, h_hWindowHandle);
disp_message(h_hWindowHandle, "定位模板为空!", "window", 20, 20, "red", "false");
Rows = Cols = Angles = null;
return;
}
//几何定位
HOperatorSet.FindShapeModel(h_Image, h_Match.m_ModelID, (new HTuple(-h_Match.m_dAngle)).TupleRad(),
(new HTuple(h_Match.m_dAngle * 2)).TupleRad(), h_Match.m_dScore, h_Match.m_nNumMatchs,
h_Match.m_dOverlap,
"least_squares", 0, 0.9, out Row, out Column, out Angle, out Score);
//如果定位到有物体,跳转到if里面。注:定位后,一定要进行此判断
if (Row.Length > 0)
{
HOperatorSet.DispObj(h_Image, h_hWindowHandle);
for (int i = 0; i < Row.Length; i++)
{
Rows[i] = Convert.ToDouble(Row[i].D);
Cols[i] = Convert.ToDouble(Column[i].D);
Angles[i] = Convert.ToDouble(Angle[i].D);
//显示模板轮廓和模板中心
//产生模板轮廓仿射变换矩阵
HOperatorSet.VectorAngleToRigid(0, 0, 0, Row[i], Column[i], Angle[i], out h_HomMat2D);
//获取模板轮廓
Contour.Dispose();
HOperatorSet.GetShapeModelContours(out Contour, h_Match.m_ModelID, 1);
//对模板进行仿射变换
HOperatorSet.AffineTransContourXld(Contour, out Contour, h_HomMat2D);
HOperatorSet.DispObj(Contour, h_hWindowHandle);
//判断,如果有抓取点设置
if (h_Match.m_CatchXld != null)
{
//产生模板从原位置到现位置的仿射变换矩阵
HOperatorSet.VectorAngleToRigid(RowModel, ColModel, 0, Row[i], Column[i], Angle[i],
out h_HomMat2D_T);
//利用该矩阵对抓取点进行仿射
HOperatorSet.AffineTransRegion(h_Match.m_CatchXld, out ContourCatch, h_HomMat2D_T,
"nearest_neighbor");
HOperatorSet.DispObj(ContourCatch, h_hWindowHandle);
}
}
}
else
{
Rows = Cols = Angles = null;
HOperatorSet.DispObj(h_Image, h_hWindowHandle);
disp_message(h_hWindowHandle, "定位失败!", "window", 20, 20, "red", "false");
return;
}
}
catch (Exception)
{
Rows = Cols = Angles = null;
HOperatorSet.DispObj(h_Image, h_hWindowHandle);
disp_message(h_hWindowHandle, "定位过程失败!", "window", 20, 20, "red", "false");
return;
}
Contour.Dispose();
return;
}
Form界面和方法调用
private void btnCreateModel_Click(object sender, EventArgs e)
{
try
{
m_Help.CreateShapeModel();
}
catch (Exception)
{
MessageBox.Show("创建失败!");
}
}
private void btnFindModel_Click(object sender, EventArgs e)
{
try
{
m_Help.FindShapeModel(10, out m_Rows, out m_Cols, out m_Angles);
}
catch (Exception)
{
MessageBox.Show("查找失败!");
}
}
private void btnCatchPoint_Click(object sender, EventArgs e)
{
m_Help.CreatePoint();
}
操作流程
1_创建模板
2_创建抓取点(感兴趣区域)
3_查找模板并仿射定位