0


基于halcon与c#联合的视觉处理软件

1、视觉软件

  当我们拿到一个视觉项目,如果有一个拖拽式视觉软件去帮我们完成这样一个项目,既省时又省力,学什么halcon、opencv、visionpro,甚至头疼的C++、C#,统统不需要,也能快速成为一名视觉工程师,哈哈哈,这样一想门槛也太低了吧。下图海康的视觉软件vision master想必各位视觉大佬都不陌生吧,每个公司都有自己研发的视觉软件,市场上五花八门的软件,不过框架都差不多,学一个其他的也差不多了吧。这些视觉软件究竟为什么框选出一个区域,就能找到一个圆、一条线、识别出数字、或者其他特征呢,这个问题也困扰了我很久,奈何自己读书少,一直困惑于此,前几天闲来无事,工地搬完砖下班回到宿舍,打开才上手不久的halcon,和在工地上自学的C#,用底层代码去编写这样一个小视觉软件。

vision master

2、图像处理

  利用halcon软件进行图像处理,这里用一个下班在路上捡的一个药品盖做一个模板匹配。图像处理上的细节不过多阐述,主要就是创造模板(create_shape_model)、寻找模板(create_shape_model)、点和角度刚性仿射变换,XLD轮廓任意仿射2D变换,相信各位大神对这些都不陌生,我就不在关公面前耍大刀,代码仅供跟我一样的小白参考,哈哈哈。

3、halcon导出c#

   用halcon菜单栏文件,将算子代码转为c#代码,因为我们待会做界面要用winform来做,到时候直接用导出的代码,大神也可以用MFC编界面。

导出来之后,我们只需要关注action这个方法里面的代码,前面的都是定义变量,halcon的变量一般只有三个变量类型, HTuple数据变量(宽度,大小,数量),Hobject图像变量,HWindow 窗口句柄。

  private void action()
  {

    // Local iconic variables 

    HObject ho_Qq20211015161226, ho_GrayImage;
    HObject ho_Rectangle, ho_ImageReduced, ho_ModelContours;
    HObject ho_ContoursAffineTrans, ho_RegionAffineTrans=null;
    HObject ho_ContoursAffineTrans1=null, ho_Rectangle1=null;

    // Local control variables 

    HTuple hv_WindowHandle = null, hv_Row1 = null;
    HTuple hv_Column1 = null, hv_ModelID = null, hv_Area = null;
    HTuple hv_Row = null, hv_Column = null, hv_HomMat2D = null;
    HTuple hv_Angle = null, hv_Score = null, hv_i = null, hv_HomMat2DIdentity = new HTuple();
    HTuple hv_HomMat2DTranslate = new HTuple(), hv_HomMat2DRotate = new HTuple();
    HTuple hv_HomMat2D1 = new HTuple();
    // Initialize local and output iconic variables 
    HOperatorSet.GenEmptyObj(out ho_Qq20211015161226);
    HOperatorSet.GenEmptyObj(out ho_GrayImage);
    HOperatorSet.GenEmptyObj(out ho_Rectangle);
    HOperatorSet.GenEmptyObj(out ho_ImageReduced);
    HOperatorSet.GenEmptyObj(out ho_ModelContours);
    HOperatorSet.GenEmptyObj(out ho_ContoursAffineTrans);
    HOperatorSet.GenEmptyObj(out ho_RegionAffineTrans);
    HOperatorSet.GenEmptyObj(out ho_ContoursAffineTrans1);
    HOperatorSet.GenEmptyObj(out ho_Rectangle1);
    if (HDevWindowStack.IsOpen())
    {
      HOperatorSet.CloseWindow(HDevWindowStack.Pop());
    }
    HOperatorSet.SetWindowAttr("background_color","black");
    HOperatorSet.OpenWindow(0,0,512,512,0,"visible","",out hv_WindowHandle);
    HDevWindowStack.Push(hv_WindowHandle);
    ho_Qq20211015161226.Dispose();
    HOperatorSet.ReadImage(out ho_Qq20211015161226, "G:/实验/药瓶盖检测1.bmp");
    ho_GrayImage.Dispose();
    HOperatorSet.Rgb1ToGray(ho_Qq20211015161226, out ho_GrayImage);
    //draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
    ho_Rectangle.Dispose();
    HOperatorSet.GenRectangle1(out ho_Rectangle, 328, 456, 676, 797);
    ho_ImageReduced.Dispose();
    HOperatorSet.ReduceDomain(ho_GrayImage, ho_Rectangle, out ho_ImageReduced);
    HOperatorSet.CreateShapeModel(ho_ImageReduced, "auto", (new HTuple(-180)).TupleRad()
        , (new HTuple(180)).TupleRad(), "auto", "auto", "use_polarity", "auto", "auto", 
        out hv_ModelID);
    ho_ModelContours.Dispose();
    HOperatorSet.GetShapeModelContours(out ho_ModelContours, hv_ModelID, 1);
    HOperatorSet.AreaCenter(ho_Rectangle, out hv_Area, out hv_Row, out hv_Column);
    HOperatorSet.VectorAngleToRigid(0, 0, 0, hv_Row, hv_Column, 0, out hv_HomMat2D);
    ho_ContoursAffineTrans.Dispose();
    HOperatorSet.AffineTransContourXld(ho_ModelContours, out ho_ContoursAffineTrans, 
        hv_HomMat2D);
    if (HDevWindowStack.IsOpen())
    {
      HOperatorSet.DispObj(ho_Qq20211015161226, HDevWindowStack.GetActive());
    }
    if (HDevWindowStack.IsOpen())
    {
      HOperatorSet.DispObj(ho_ContoursAffineTrans, HDevWindowStack.GetActive());
    }
    if (HDevWindowStack.IsOpen())
    {
      HOperatorSet.SetDraw(HDevWindowStack.GetActive(), "margin");
    }
    if (HDevWindowStack.IsOpen())
    {
      HOperatorSet.DispObj(ho_Rectangle, HDevWindowStack.GetActive());
    }
    //关闭
    ho_ContoursAffineTrans.Dispose();
    if (HDevWindowStack.IsOpen())
    {
      HOperatorSet.ClearWindow(HDevWindowStack.GetActive());
    }

    ho_Qq20211015161226.Dispose();
    HOperatorSet.ReadImage(out ho_Qq20211015161226, "G:/实验/药瓶盖检测2.bmp");
    HOperatorSet.FindShapeModel(ho_Qq20211015161226, hv_ModelID, (new HTuple(-180)).TupleRad()
        , (new HTuple(180)).TupleRad(), 0.6, 0, 0.5, "least_squares", 0, 0.9, out hv_Row1, 
        out hv_Column1, out hv_Angle, out hv_Score);

    for (hv_i=0; (int)hv_i<=(int)((new HTuple(hv_Score.TupleLength()))-1); hv_i = (int)hv_i + 1)
    {
      HOperatorSet.HomMat2dIdentity(out hv_HomMat2DIdentity);
      HOperatorSet.HomMat2dTranslate(hv_HomMat2DIdentity, hv_Row1.TupleSelect(hv_i), 
          hv_Column1.TupleSelect(hv_i), out hv_HomMat2DTranslate);
      HOperatorSet.HomMat2dRotate(hv_HomMat2DTranslate, hv_Angle.TupleSelect(hv_i), 
          hv_Row1.TupleSelect(hv_i), hv_Column1.TupleSelect(hv_i), out hv_HomMat2DRotate);

      HOperatorSet.VectorAngleToRigid(hv_Row1, hv_Column1, hv_Angle, hv_Row1, hv_Column1, 
          hv_Angle, out hv_HomMat2D1);
      ho_RegionAffineTrans.Dispose();
      HOperatorSet.AffineTransRegion(ho_Rectangle, out ho_RegionAffineTrans, hv_HomMat2D1, 
          "nearest_neighbor");

      ho_ContoursAffineTrans1.Dispose();
      HOperatorSet.AffineTransContourXld(ho_ModelContours, out ho_ContoursAffineTrans1, 
          hv_HomMat2DRotate);

      ho_Rectangle1.Dispose();
      HOperatorSet.GenRectangle2(out ho_Rectangle1, hv_Row1.TupleSelect(hv_i), hv_Column1.TupleSelect(
          hv_i), hv_Angle.TupleSelect(hv_i), 170, 170);
      if (HDevWindowStack.IsOpen())
      {
        HOperatorSet.DispObj(ho_Qq20211015161226, HDevWindowStack.GetActive());
      }
      if (HDevWindowStack.IsOpen())
      {
        HOperatorSet.DispObj(ho_ContoursAffineTrans1, HDevWindowStack.GetActive()
            );
      }
      if (HDevWindowStack.IsOpen())
      {
        HOperatorSet.SetDraw(HDevWindowStack.GetActive(), "margin");
      }
      if (HDevWindowStack.IsOpen())
      {
        HOperatorSet.DispObj(ho_Rectangle1, HDevWindowStack.GetActive());
      }

    }
    ho_Qq20211015161226.Dispose();
    ho_GrayImage.Dispose();
    ho_Rectangle.Dispose();
    ho_ImageReduced.Dispose();
    ho_ModelContours.Dispose();
    ho_ContoursAffineTrans.Dispose();
    ho_RegionAffineTrans.Dispose();
    ho_ContoursAffineTrans1.Dispose();
    ho_Rectangle1.Dispose();

  }

4、界面编写

  下面就是激动人心的代码时刻了,本界面使用c#下winform编写的。首先配置halcon与vs环境,一共就只有两步,不像MFC配置那么复杂,到现在我也忘了,反正自认为很难搞,会的可以教教我,第一步添加应用,第二步添加命名空间using HalconDotNet。如果配置成功但总是报错,可以改以下生成平台

                                                              第一步 

                                                                         第二步

    环境配置好后,进行界面的设计,大家在界面上添加hWindowControl1窗口,这里也是需要在工具箱添加halcon窗体控件的,工具箱里面控件,右键点击选择项,找到halcon安装路径,添加halcondotnet.dll文件,因为图像处理都基于halcon窗口来做的,picturebox是没法做。这里我们只需要注意模板匹配里面的控件,采集图片和清除功能。我们的理清楚我们模板匹配的思路,一、读入图像,二、画出ROI,找到所需要的模板区域,三、创建模板,将你所框选区域的模板物体进行显示、四、再读取一张图片,在这张图中进行模板搜索,识别出该图中的目标予以框出,显示目标坐标,五,清除界面。

4.1、读入图像

   双击采集图片按钮,我们以选取文件夹里面的图片为例,按钮中添加以下代码。

            ![](https://img-blog.csdnimg.cn/57849994e9944fc89308da4ac8182015.png)

4.2、画出ROI

   双击画矩形按钮,设置框选的颜色,样式(一般margin),线宽,画出区域,将区域图片进行裁剪显示。

4.3、创建模板

4.4、读取图片,寻找模板

   将匹配分数设置为0.5,这里需要注意的是,halcon处理得到的中心坐标是HTuple类型,textBox显示出来得用string类型,进行类型转换,我用了如下方法,其他也没找到比较好的方法。

4.5,清除界面

                         ![](https://img-blog.csdnimg.cn/fb5da45091444e5cb81afb4899518db4.png)

5、结果展示

    该模板匹配,检测,适用于常规目标识别,只需要模板图片和测试图片。

6、还做了一些以相机实时采集的形式、查找圆、查找线、拟合、测量的一些小控件。框选出目标区域,自动找圆、找线,如下图,下次再分享,明天还得上工地,第一次写,写的不好,望各位大神提出意见,相互学习,晚安!


本文转载自: https://blog.csdn.net/qq_55834632/article/details/124673278
版权归原作者 ️169 所有, 如有侵权,请联系我们删除。

“基于halcon与c#联合的视觉处理软件”的评论:

还没有评论