【 Halcon 】 仿射定位模板和动态检测区域

 此部分方法,旨在创建模板后,再标注出模板上的感兴趣区域。再查找并仿射模板时,同时对感兴趣区域进行仿射

复制代码后,请自行配置相应的类和全局变量。我写了一个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_查找模板并仿射定位

  • 11
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值