首页 > 技术文章 > Windows下Qt+Halcon环境的搭建

tzbubble 2020-05-30 03:38 原文

写在前面


由于实习的第一个横向是“传统视觉+GUI”

于是实习方向也基本往这个方向进行

虽然自己使用的是Mac,要考虑客户使用,只好在Windows虚拟机环境下进行环境搭建


传统视觉有两大图像处理库:OpenCV和Halcon

  • OpenCV直接基于C++,主要是底层的算法,性能好,比较难

  • Halcon更注重应用,简单而适合快速开发,有自己的一套语言,但能自动转换成C++/C#进行部署嵌入


此文介绍Windows下Qt Creator中进行Halcon的联合环境搭建

关于OpenCV的环境搭建,见Windows下Qt+OpenCV环境的搭建

新建一个Widget例程


默认读者具备基本的C++,Qt,halcon知识,某些内容不多余说明,以保持简洁

Qt添加外部库(两种方法,建议使用方法2):


方法1:类似OpenCV环境搭建那篇博文中

  1. 右键pro文件添加库 -> 外部库



    如图选择,要将lib\x64-win64路径下的7个lib文件全部添加

    每一次添加后,“为debug版本添加d作为后缀”会自动勾选,取消一下

  2. 注意整理冗余

    添加完7个lib后:

    以下两条应该会重复添加7次

    INCLUDEPATH += 路径
    DEPENDPATH += 路径

    而以下语句,每次添加应该都是不同的

    win32: LIBS += -路径

    最后去除重复,整理后效果大概是:

    PS:由于本人的halcon安装路径中有一个文件名内有一个',导致新建工程打开会出错,OpenCV使用转义字符是可以的,但是添加halcon库却不行,所以采用另一个方法

方法2:参考例程配置环境变量(更简单通用,可移植)

  1. 原理:由于安装halcon的时候相关库已经导入环境变量,所以有更简单通用的方法

    其实halcon的参考例程中有一个Qt+halcon的例程(默认路径为C:\Users\Public\Documents)

    不出意外的话,Qt例程位置在:C:\Users\Public\Documents\MVTec\HALCON-17.12-Progress\examples\cpp\qt文件夹下的Matching工程文件夹

    Qt的MSVC的kit搭建好之后可以直接打开测试(MSVC搭建见OpenCV环境搭建博文)

  2. 将以下代码添加到pro文件末尾即可

    # MacOS specific settings. Note that while dyld will search under
    # /Library/Frameworks by default, the preprocessor/compiler/linker will not
    # and need to be told explicitly.
    macx {
    QMAKE_CXXFLAGS += -F/Library/Frameworks
    QMAKE_LFLAGS   += -F/Library/Frameworks
    LIBS           += -framework HALCONCpp
    }
    else {
    #defines
    win32:DEFINES += WIN32
    
    #includes
    INCLUDEPATH   += "$$(HALCONROOT)/include"
    INCLUDEPATH   += "$$(HALCONROOT)/include/halconcpp"
    
    #libs
    QMAKE_LIBDIR  += "$$(HALCONROOT)/lib/$$(HALCONARCH)"
    unix:LIBS     += -lhalconcpp -lhalcon -lXext -lX11 -ldl -lpthread
    win32:LIBS    += "$$(HALCONROOT)/lib/$$(HALCONARCH)/halconcpp.lib" \
                   "$$(HALCONROOT)/lib/$$(HALCONARCH)/halcon.lib"
    }
    

对halcon程序进行导出


  1. 按下图设置进行导出,选择C++UTF-8编码

  2. 原halcon代码如下:

    read_image (image, 'C:/Panyp\'s/Code/Halcon/coin.png') //读取图片
    dev_open_window (0, 0, Width/2, Height/2, 'black', WindowID)	//打开图形窗口,返回WindowID
    dev_display (image)	//显示图片
    
    rgb1_to_gray(image,coin)
    threshold (coin, Regions, 153, 248)
    
    closing_circle (Regions, RegionClosing, 20)
    opening_circle (RegionClosing, RegionOpening, 20)
    
    connection (RegionOpening, ConnectedRegions)
    select_shape (ConnectedRegions, SelectedRegions, 'circularity', 'and', 0.81549, 2)
    
    dev_display (SelectedRegions) //显示硬币提取后的区域
    

    转换成C++代码后,我们只关心void action(){代码块}中的内容

    void action()
    {
    
      // Local iconic variables								//变量定义部分
      HObject  ho_image, ho_coin, ho_Regions, ho_RegionClosing;
      HObject  ho_RegionOpening, ho_ConnectedRegions, ho_SelectedRegions;
    
      // Local control variables								//变量定义部分
      HTuple  hv_WindowID, hv_Row, hv_Column, hv_Radius;
    
      ReadImage(&ho_image, "C:/Panyp's/Code/Halcon/coin.png");
      SetWindowAttr("background_color","black");
      OpenWindow(0,0,hv_Width/2,hv_Height/2,0,"","",&hv_WindowID);	//修改部分
      HDevWindowStack::Push(hv_WindowID);
      if (HDevWindowStack::IsOpen())
        DispObj(ho_image, HDevWindowStack::GetActive());
    
      Rgb1ToGray(ho_image, &ho_coin);
      Threshold(ho_coin, &ho_Regions, 153, 248);
    
      ClosingCircle(ho_Regions, &ho_RegionClosing, 20);
      OpeningCircle(ho_RegionClosing, &ho_RegionOpening, 20);
    
      Connection(ho_RegionOpening, &ho_ConnectedRegions);
      SelectShape(ho_ConnectedRegions, &ho_SelectedRegions, "circularity", "and", 0.81549, 2);
    
      SmallestCircle(ho_SelectedRegions, &hv_Row, &hv_Column, &hv_Radius);
      if (HDevWindowStack::IsOpen())
        DispObj(ho_SelectedRegions, HDevWindowStack::GetActive());
    
    }
    
  3. 使用方法:

    • Local iconic variables内定义的HObject和HTuple变量,我们把他粘贴到控件的.h文件的public中

      同时注意在该头文件中添加

      #include "HalconCpp.h"
      #include "HDevThread.h"
      
    • 其余代码我们大略阅读明白其大意,自行进行分割

      选择需要的部分放入对应控件的响应槽中

      注意添加以下命名空间说明(或一直使用HalconCpp::前缀代替)

      using namespace HalconCpp;
      
    • 注意“修改部分”(代码中已标出)

      该代码前需要添加

      Hlong MainWndID = (Hlong)this->ui->label->winId();

      再将

      OpenWindow(0,0,hv_Width/2,hv_Height/2,0,"","",&hv_WindowID);

      修改为

      - OpenWindow(0, 0, ui->label->width(), ui->label->height(), MainWndID, "visible", "", &hv_WindowID); 
       //其中ui->label为自己定义的控件,根据需求改
      
      

      修改代码的目的在于使WindowID作为子控件依附于父窗口上,而不是成为独立窗口跳出

效果图


  • 点击read时,读取硬币图

  • 点击process时,提取硬币region

完成

已基本实现功能,但是后期的dll部署和打包,还需学习,待更新

推荐阅读