halcon与c#联合编程实现相机控制+图像平移缩放+日志记录+缺陷检测+路径规划

halcon与c#联合编程实现相机控制+图像平移缩放+日志记录+缺陷检测+路径规划


前言

本人近期在工作中遇到需要对某场景下利用海康相机进行图像缺陷检测与对应路径规划。通过对海康相机示例代码进行吸收与借鉴,最终实现了对海康相机的控制,并增加HSmartWindowControl控件,实现图像的实时显示与平移缩放功能;通过listview+toolstrip实现日志显示与类型(提示、警告、错误)分类;同时自行编制算法实现对缺陷的识别以及缺陷外扩矩形范围内的路径规划。
在这里插入图片描述


1.日志记录

代码如下(示例):

try
{
    lock(obj)
    {
        if (msg == string.Empty)
        {
            listView1.BeginUpdate();   //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度  

            ListViewItem item1 = new ListViewItem();
            item1.Text = DateTime.Now.ToString("yyyy:MM:dd,HH:mm:ss");
            item1.SubItems.Add(msg);
            item1.ForeColor = color;
            listView1.Items.Add(item1);

            this.listView1.EndUpdate();  //结束数据处理,UI界面一次性绘制。
        }
        else
        {
            if (color == Color.Yellow)
                numYellow++;
            else if (color == Color.Red)
            {
                numRed++;
           }
            else
                numGreen++;

            string time = DateTime.Now.ToString("yyyy:MM:dd,HH:mm:ss");
            OutputItem outputItem = new OutputItem();
            outputItem.msg = msg;
            outputItem.color = color;
            outputItem.time = time;

            L_outputItem.Add(outputItem);
            if (L_outputItem.Count > 1000)
            {
                if (L_outputItem[0].color == Color.Yellow)
                    numYellow--;
                else if (L_outputItem[0].color == Color.Red)
                    numRed--;
                else
                    numGreen--;
                L_outputItem.RemoveAt(0);
            }
            UpdateCount();


            listView1.BeginUpdate();   //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度  
            ListViewItem item1 = new ListViewItem();
            item1.Text = time;
            item1.SubItems.Add(msg);
            item1.ForeColor = color;
            listView1.Items.Add(item1);

            this.listView1.EndUpdate();  //结束数据处理,UI界面一次性绘制。

            log.SaveLog(LogType.Operate, msg);
        }
    }
}
catch (Exception ex)
{
    log.SaveError(ex);
}

在这里插入图片描述

2.图像平移缩放

代码如下(示例):

private void my_MouseWheel(object sender, MouseEventArgs e)
        {
            System.Drawing.Point pt = this.Location;
            int leftBorder = hSmartWindowControl1.Location.X;
            int rightBorder = hSmartWindowControl1.Location.X + hSmartWindowControl1.Size.Width;
            int topBorder = hSmartWindowControl1.Location.Y;
            int bottomBorder = hSmartWindowControl1.Location.Y + hSmartWindowControl1.Size.Height;
            if (e.X > leftBorder && e.X < rightBorder && e.Y > topBorder && e.Y < bottomBorder)
            {
                MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks,
                                                     e.X - pt.X, e.Y - pt.Y, e.Delta);
                hSmartWindowControl1.HSmartWindowControl_MouseWheel(sender, newe);
            }
        }

在这里插入图片描述
在这里插入图片描述

3.特征识别与路径规划

代码如下(示例):


```csharp
  HObject ho_ROI_0, ho_ImageTmp, ho_Rectangle = null;
            HObject ho_ImageR, ho_ImageG, ho_ImageB, ho_ImageReduced;
            HObject ho_ImageGauss, ho_EdgeAmplitude, ho_Basins, ho_Region;
            HObject ho_RegionDilation, ho_RegionUnion, ho_ConnectedRegions;
            HObject ho_SelectedRegions, ho_Contours, ho_Contours_fit = null;
            HObject ho_Contour_fit = null, ho_Cross_tuple = null;

            // Local control variables 

            HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
            HTuple hv_WindowHandle = new HTuple(), hv_ModelID = new HTuple();
            HTuple hv_Area = new HTuple(), hv_Row0 = new HTuple();
            HTuple hv_Column0 = new HTuple();
            HTuple hv_Row = new HTuple(), hv_Column = new HTuple();
            HTuple hv_Angle = new HTuple(), hv_Scale = new HTuple();
            HTuple hv_Score = new HTuple(), hv_I = new HTuple(), hv_A = new HTuple();
            HTuple hv_Row1 = new HTuple(), hv_Column1 = new HTuple();
            HTuple hv_Phi = new HTuple(), hv_Length1 = new HTuple();
            HTuple hv_Length2 = new HTuple(), hv_PointOrder = new HTuple();
            HTuple hv_Row2 = new HTuple(), hv_Column2 = new HTuple();
            HTuple hv_Radius = new HTuple(), hv_StartPhi = new HTuple();
            HTuple hv_EndPhi = new HTuple(), hv_PointOrder1 = new HTuple();
            HTuple hv_Number = new HTuple(), hv_Row_fit = new HTuple();
            HTuple hv_Col_fit = new HTuple(), hv_ZigzagPath_row = new HTuple();
            HTuple hv_ZigzagPath_column = new HTuple();
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_ROI_0);
            HOperatorSet.GenEmptyObj(out ho_ImageTmp);
            HOperatorSet.GenEmptyObj(out ho_Rectangle);
            HOperatorSet.GenEmptyObj(out ho_ImageR);
            HOperatorSet.GenEmptyObj(out ho_ImageG);
            HOperatorSet.GenEmptyObj(out ho_ImageB);
            HOperatorSet.GenEmptyObj(out ho_ImageReduced);
            HOperatorSet.GenEmptyObj(out ho_ImageGauss);
            HOperatorSet.GenEmptyObj(out ho_EdgeAmplitude);
            HOperatorSet.GenEmptyObj(out ho_Basins);
            HOperatorSet.GenEmptyObj(out ho_Region);
            HOperatorSet.GenEmptyObj(out ho_RegionDilation);
            HOperatorSet.GenEmptyObj(out ho_RegionUnion);
            HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);
            HOperatorSet.GenEmptyObj(out ho_SelectedRegions);
            HOperatorSet.GenEmptyObj(out ho_Contours);
            HOperatorSet.GenEmptyObj(out ho_Contours_fit);
            HOperatorSet.GenEmptyObj(out ho_Contour_fit);
            HOperatorSet.GenEmptyObj(out ho_Cross_tuple);


            Int32 nEquivalenceNum = (int)numericUpDown_Param1.Value;
            if(nEquivalenceNum <= 0)
            {
                MessageBox.Show("路径等分点数值设置错误", "参数设置", MessageBoxButtons.OK, MessageBoxIcon.Error);
                OutputMsg("特征分析error:路径等分点数值设置错误!", Color.Red);
                return;
            }

            try
            {
                //对窗口进行模板匹配并将该区域以黑色覆盖(后面提取白色区域)
                hv_ModelID.Dispose();
                HOperatorSet.ReadShapeModel("D:/00-工作/00-工作-0中车四方所/00-项目/2021年项目/04-西安车体机器人自动化打磨/02-项目代码/01-Code/Window.shm",
                    out hv_ModelID);
                hv_Row0.Dispose();
                HOperatorSet.ReadTuple("D:/00-工作/00-工作-0中车四方所/00-项目/2021年项目/04-西安车体机器人自动化打磨/02-项目代码/01-Code/row.tup",
                    out hv_Row0);
                hv_Column0.Dispose();
                HOperatorSet.ReadTuple("D:/00-工作/00-工作-0中车四方所/00-项目/2021年项目/04-西安车体机器人自动化打磨/02-项目代码/01-Code/column.tup",
                    out hv_Column0);

                //HObject ho_Null = new HObject();
                //HTuple hv_N = new HTuple();
                //ho_Null.Dispose();
                //hv_N.Dispose();


                HOperatorSet.GenEmptyObj(out ho_Null);
                HOperatorSet.TestEqualRegion(ho_Image, ho_Null, out hv_N);
                if ((int)(new HTuple(hv_N.TupleEqual(1))) != 0)
                {
                    MessageBox.Show("图像为空", "图像采集", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }


                using (HDevDisposeHelper dh = new HDevDisposeHelper())
                {
                    hv_Row.Dispose();
                    hv_Column.Dispose();
                    hv_Angle.Dispose();
                    hv_Scale.Dispose();
                    hv_Score.Dispose();
                    HOperatorSet.FindScaledShapeModel(ho_Image, hv_ModelID, -((new HTuple(90)).TupleRad()
                        ), (new HTuple(90)).TupleRad(), 0.9, 1.1, 0.5, 0, 0.5, "least_squares",
                        0, 0.9, out hv_Row, out hv_Column, out hv_Angle, out hv_Scale, out hv_Score);
                }
                ho_ImageTmp.Dispose();
                HOperatorSet.CopyImage(ho_Image, out ho_ImageTmp);

                for (hv_I = 0; (int)hv_I <= (int)((new HTuple(hv_Score.TupleLength())) - 1); hv_I = (int)hv_I + 1)
                {
                    //重画车窗位置为黑色
                    using (HDevDisposeHelper dh = new HDevDisposeHelper())
                    {
                        ho_Rectangle.Dispose();
                        HOperatorSet.GenRectangle2(out ho_Rectangle, hv_Row.TupleSelect(hv_I), hv_Column.TupleSelect(
                            hv_I), 0, 190, 180);
                    }
                    HOperatorSet.OverpaintRegion(ho_ImageTmp, ho_Rectangle, ((new HTuple(0)).TupleConcat(
                        0)).TupleConcat(0), "fill");
                }


                //对图像进行处理获取打腻子区域
                ho_ImageR.Dispose();
                ho_ImageG.Dispose();
                ho_ImageB.Dispose();
                HOperatorSet.Decompose3(ho_ImageTmp, out ho_ImageR, out ho_ImageG, out ho_ImageB);

                HalconDisplay(m_Window, ho_ImageB, ImageHeight, ImageWidth);

                ho_ROI_0.Dispose();
                HOperatorSet.GenRectangle1(out ho_ROI_0, 195, 5, 1000, 1440);
                ho_ImageReduced.Dispose();
                HOperatorSet.ReduceDomain(ho_ImageB, ho_ROI_0, out ho_ImageReduced);

                ho_ImageGauss.Dispose();
                HOperatorSet.GaussFilter(ho_ImageReduced, out ho_ImageGauss, 11);
                ho_EdgeAmplitude.Dispose();
                HOperatorSet.SobelAmp(ho_ImageGauss, out ho_EdgeAmplitude, "sum_abs", 5);
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.SetDraw(HDevWindowStack.GetActive(), "margin");
                }
                ho_Basins.Dispose();
                HOperatorSet.WatershedsThreshold(ho_EdgeAmplitude, out ho_Basins, 10);

                ho_Region.Dispose();
                HOperatorSet.Threshold(ho_ImageReduced, out ho_Region, 180, 255);
                ho_RegionDilation.Dispose();
                HOperatorSet.DilationCircle(ho_Region, out ho_RegionDilation, 3.5);
                ho_RegionUnion.Dispose();
                HOperatorSet.Union1(ho_RegionDilation, out ho_RegionUnion);
                ho_ConnectedRegions.Dispose();
                HOperatorSet.Connection(ho_RegionUnion, out ho_ConnectedRegions);
                ho_SelectedRegions.Dispose();
                HOperatorSet.SelectShape(ho_ConnectedRegions, out ho_SelectedRegions, (new HTuple("area")).TupleConcat(
                    "roundness"), "and", (new HTuple(100)).TupleConcat(0.2), (new HTuple(1000000)).TupleConcat(1));
                ho_Contours.Dispose();
                HOperatorSet.GenContourRegionXld(ho_SelectedRegions, out ho_Contours, "border");
                HalconDisplay(m_Window, ho_Image, ImageHeight, ImageWidth);
                HalconDisplay(m_Window, ho_Contours, ImageHeight, ImageWidth);


                hv_A.Dispose();
                hv_A = "矩形";
                if ((int)(new HTuple(hv_A.TupleEqual("矩形"))) != 0)
                {
                    hv_Row1.Dispose(); hv_Column1.Dispose(); hv_Phi.Dispose(); hv_Length1.Dispose(); hv_Length2.Dispose(); hv_PointOrder.Dispose();
                    HOperatorSet.FitRectangle2ContourXld(ho_Contours, "tukey", -1, 0, 0, 3, 2,
                        out hv_Row1, out hv_Column1, out hv_Phi, out hv_Length1, out hv_Length2,
                        out hv_PointOrder);
                    ho_Contours_fit.Dispose();
                    HOperatorSet.GenRectangle2ContourXld(out ho_Contours_fit, hv_Row1, hv_Column1,
                        hv_Phi, hv_Length1, hv_Length2);
                }
                else
                {
                    hv_Row2.Dispose();
                    hv_Column2.Dispose();
                    hv_Radius.Dispose();
                    hv_StartPhi.Dispose();
                    hv_EndPhi.Dispose();
                    hv_PointOrder1.Dispose();
                    HOperatorSet.FitCircleContourXld(ho_Contours, "algebraic", -1, 0, 0, 3, 2,
                        out hv_Row2, out hv_Column2, out hv_Radius, out hv_StartPhi, out hv_EndPhi, out hv_PointOrder1);
                    ho_Contours_fit.Dispose();
                    HOperatorSet.GenCircleContourXld(out ho_Contours_fit, hv_Row2, hv_Column2,
                        hv_Radius, hv_StartPhi, hv_EndPhi, "positive", 1);
                }

                HOperatorSet.SetColor(m_Window, "red");
                HalconDisplay(m_Window, ho_Contours_fit, ImageHeight, ImageWidth);


                hv_Number.Dispose();
                HOperatorSet.CountObj(ho_Contours_fit, out hv_Number);
                HTuple end_val71 = hv_Number;
                HTuple step_val71 = 1;
                for (hv_I = 1; hv_I.Continue(end_val71, step_val71); hv_I = hv_I.TupleAdd(step_val71))
                {
                    ho_Contour_fit.Dispose();
                    HOperatorSet.SelectObj(ho_Contours_fit, out ho_Contour_fit, hv_I);
                    hv_Row_fit.Dispose();
                    hv_Col_fit.Dispose();
                    HOperatorSet.GetContourXld(ho_Contour_fit, out hv_Row_fit, out hv_Col_fit);
                    hv_ZigzagPath_row.Dispose(); hv_ZigzagPath_column.Dispose();
                    Gen_ZigzagPath_by_rectangle2(hv_Row_fit, hv_Col_fit, 8, out hv_ZigzagPath_row,out hv_ZigzagPath_column);

                    //“之”字型路线标记
                    ho_Cross_tuple.Dispose();
                    HOperatorSet.GenCrossContourXld(out ho_Cross_tuple, hv_ZigzagPath_row, hv_ZigzagPath_column, 10, 0.785398);
                    HOperatorSet.SetColor(m_Window, "blue");
                    HalconDisplay(m_Window, ho_Cross_tuple, ImageHeight, ImageWidth);
                    HOperatorSet.SetColor(m_Window, "red");
                }
            }

在这里插入图片描述

halcon与c#联合编程

总结

以上是针对该项目做的关键功能部分代码展示,比较适合新手初学者进行学习。
源码

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的叮小当

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值