Winform之算法模块-形状模板匹配-擦除模板区域
一 初始化参数
二 制作轮廓模板
三 制作橡皮擦
四 开始涂抹:按下鼠标左键涂画,右键结束
五 涂抹结束,显示和保存涂抹区域结果
// 擦除结束标志
bool deleteModelFlag = false;
/// <summary>
/// 擦除模板
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_DeleteModel_Click(object sender, EventArgs e)
{
//一 初始化参数
//二 制作轮廓模板
//三 制作橡皮擦
//四 开始涂抹:按下鼠标左键涂画,右键结束
//五 涂抹结束,显示和保存涂抹区域结果
//一 初始化参数
// 1.获取模板图像
HOperatorSet.ReduceDomain(CurrImage,ModelRegion,out HObject modelImage);
// 裁切出来
HOperatorSet.CropDomain(modelImage,out modelImage);
// 2. 获取窗口的句柄
var hv_WindowHandle = hWindow_Final1.getHWindowControl().HalconWindow;
// 3. 涂抹区域
HObject paint_region = new HRegion();
// 4.涂抹区域取反
HObject paint_region_final = new HObject();
// 5.开启绘制模式(不允许缩放,和右键显示菜单栏)
hWindow_Final1.DrawModel = true;
// 6. 获取焦点
hWindow_Final1.Focus();
// 7 鼠标的状态
HTuple hv_MouseState;
// 8. 鼠标的坐标
HTuple y_Mouse=null, x_Mouse=null;
// 9,橡皮擦。(圆形)(半径小于xy)
HTuple y_Brush=10, x_Brush=10, r_Brush=6;
// 10. 仿射矩阵
HTuple homMat2D;
// 11.仿射变换之后的橡皮擦
HObject brush_region_affine = new HObject();
// 12.模型的轮廓
HObject modelXLD = null;
// 13. 仿射变换之后的模型轮廓
HObject modelXLDAffineTrans = null;
//二 制作轮廓模板,为了明白在哪里进行擦除,仿射变换,和图像进行对应上,(做出了模板,默认位置是 0 0)
// 创建模板
HOperatorSet.CreateShapeModel(modelImage, 0, -3.14, 6.28, "auto", "auto", "use_polarity", 30, "auto", out HTuple ModelId);
// 获取模板的轮廓
HOperatorSet.GetShapeModelContours(out modelXLD, ModelId,1);
HOperatorSet.GetImageSize(modelImage,out HTuple width,out HTuple height);
// 模板轮廓进行仿射变换
HOperatorSet.VectorAngleToRigid(0,0,0, height/2, width/2, 0,out HTuple homMat2D1);
HOperatorSet.AffineTransContourXld(modelXLD,out modelXLDAffineTrans,homMat2D1);
//三 制作橡皮擦
try
{
// 设置橡皮擦的大小和半径
HOperatorSet.GenCircle(out HObject brush_region,y_Brush,x_Brush,r_Brush);
// 显示图像
hWindow_Final1.HobjectToHimage(modelImage);
// 显示颜色
HOperatorSet.SetColor(hv_WindowHandle,"blue");
// 鼠标状态
hv_MouseState = 0;
// 停止涂抹标志位
deleteModelFlag =false;
//四 开始涂抹:按下鼠标左键涂画,右键结束
// 4 右键
while (hv_MouseState != 4 && deleteModelFlag == false)
{
// 跳出循环的时候,会爆发所有积累的事件
System.Windows.Forms.Application.DoEvents();
// 鼠标位置
y_Mouse = -1;
x_Mouse = -1;
// 获取当前的鼠标位置
try
{
HOperatorSet.GetMposition(hv_WindowHandle, out y_Mouse, out x_Mouse, out hv_MouseState);
}
catch (Exception exp)
{
hv_MouseState = 0;
}
// 解决窗口绘制,闪烁问题
HOperatorSet.SetSystem("flush_graphic", "false");
// 显示图像
HOperatorSet.DispObj(modelImage, hv_WindowHandle);
// 显示模板轮廓
HOperatorSet.DispObj(modelXLDAffineTrans, hv_WindowHandle);
// 如果涂抹区域已经被初始化,则直接进行显示
if (paint_region.IsInitialized())
{
HOperatorSet.DispObj(paint_region, hv_WindowHandle);
}
// 核心:绘制涂抹区域
if (y_Mouse >= 0 && x_Mouse >= 0)
{
// 仿射变换(橡皮擦移动到鼠标下面)
// 1.生成仿射矩阵
HOperatorSet.VectorAngleToRigid(y_Brush, x_Brush, 0, y_Mouse, x_Mouse, 0, out homMat2D);
// 2.进行仿射变换
HOperatorSet.AffineTransRegion(brush_region, out brush_region_affine, homMat2D, "nearest_neighbor");
// 显示仿射变换之后的区域
HOperatorSet.DispObj(brush_region_affine, hv_WindowHandle);
// 解决窗口绘制,闪烁问题
HOperatorSet.SetSystem("flush_graphic", "true");
// 按下鼠标右键结束涂抹
ViewROI.HalconTool.set_display_font(hv_WindowHandle, 20, "mono", "true", "false");
ViewROI.HalconTool.disp_message(hv_WindowHandle, "按下鼠标右键结束涂抹", "window", 20, 20, "red", "false");
// 左键,进行区域的合并
// 1 左键
if (hv_MouseState == 1)
{
// 合并显示
if (paint_region.IsInitialized())
{
HOperatorSet.Union2(paint_region, brush_region_affine, out HObject unionRegion);
paint_region = unionRegion;
}
else
{
paint_region = new HObject(brush_region_affine);
}
}
}
}
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
finally
{
/*
* 五 涂抹结束,显示涂抹结果
*/
// 显示图像
hWindow_Final1.HobjectToHimage(modelImage);
// 显示涂抹区域
hWindow_Final1.DispObj(paint_region,"red");
// 关闭绘制模式
hWindow_Final1.DrawModel=false;
// 获取原图区域
HOperatorSet.GetDomain(modelImage,out HObject imageRegion);
// 获取取反的区域
HOperatorSet.Difference(imageRegion, paint_region,out paint_region_final);
// 保存模板区域
HOperatorSet.WriteRegion(paint_region_final, @"D:\\paint_region_final.reg");
}
}