Windows下Qt+Halcon環境的搭建


寫在前面


由於實習的第一個橫向是“傳統視覺+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部署和打包,還需學習,待更新


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM