【机器视觉】Qt联合Halcon编程之显示图片

00. 目录

01. 概述

QT与Halcon联合编程。将Halcon中代码集成到Qt程序中。

开发环境

Qt:Qt5.15.2

Halcon: Halcon 19.11

02. 编写Halcon程序

程序示例

* 从本地磁盘读取一张图片
read_image (Carb, 'E:/CarB.jpg')

* 获取图片大小
get_image_size (Carb, Width, Height)

* 关闭当前窗口
dev_close_window ()

* 打开新窗口
dev_open_window (0, 0, Width / 2, Height / 2, 'black', WindowHandle)

* 显示图片
dev_display (Carb)


Halcon中执行结果
请添加图片描述

03. Halcon程序导出C++文件

3.1选择文件中导出菜单
请添加图片描述

3.2 设置导出文件和格式,然后导出
请添加图片描述

3.3 导出源文件程序如下

///
// File generated by HDevelop for HALCON/C++ Version 19.11.0.0
// Non-ASCII strings in this file are encoded in local-8-bit encoding (cp936).
// Ensure that the interface encoding is set to locale encoding by calling
// SetHcppInterfaceStringEncodingIsUtf8(false) at the beginning of the program.
// 
// Please note that non-ASCII characters in string constants are exported
// as octal codes in order to guarantee that the strings are correctly
// created on all systems, independent on any compiler settings.
// 
// Source files with different encoding should not be mixed in one project.
///



#ifndef __APPLE__
#  include "HalconCpp.h"
#  include "HDevThread.h"
#else
#  ifndef HC_LARGE_IMAGES
#    include <HALCONCpp/HalconCpp.h>
#    include <HALCONCpp/HDevThread.h>
#    include <HALCON/HpThread.h>
#  else
#    include <HALCONCppxl/HalconCpp.h>
#    include <HALCONCppxl/HDevThread.h>
#    include <HALCONxl/HpThread.h>
#  endif
#  include <stdio.h>
#  include <CoreFoundation/CFRunLoop.h>
#endif



using namespace HalconCpp;


#ifndef NO_EXPORT_MAIN
// Main procedure 
void action()
{

  // Local iconic variables
  HObject  ho_Carb;

  // Local control variables
  HTuple  hv_Width, hv_Height, hv_WindowHandle;

  //从本地磁盘读取一张图片
  ReadImage(&ho_Carb, "E:/CarB.jpg");

  //获取图片大小
  GetImageSize(ho_Carb, &hv_Width, &hv_Height);

  //关闭当前窗口
  if (HDevWindowStack::IsOpen())
    CloseWindow(HDevWindowStack::Pop());

  //打开新窗口
  SetWindowAttr("background_color","black");
  OpenWindow(0,0,hv_Width/2,hv_Height/2,0,"visible","",&hv_WindowHandle);
  HDevWindowStack::Push(hv_WindowHandle);

  //显示图片
  if (HDevWindowStack::IsOpen())
    DispObj(ho_Carb, HDevWindowStack::GetActive());



}


#ifndef NO_EXPORT_APP_MAIN

#ifdef __APPLE__
// On OS X systems, we must have a CFRunLoop running on the main thread in
// order for the HALCON graphics operators to work correctly, and run the
// action function in a separate thread. A CFRunLoopTimer is used to make sure
// the action function is not called before the CFRunLoop is running.
// Note that starting with macOS 10.12, the run loop may be stopped when a
// window is closed, so we need to put the call to CFRunLoopRun() into a loop
// of its own.
HTuple      gStartMutex;
H_pthread_t gActionThread;
HBOOL       gTerminate = FALSE;

static void timer_callback(CFRunLoopTimerRef timer, void *info)
{
  UnlockMutex(gStartMutex);
}

static Herror apple_action(void **parameters)
{
  // Wait until the timer has fired to start processing.
  LockMutex(gStartMutex);
  UnlockMutex(gStartMutex);

  try
  {
    action();
  }
  catch (HException &exception)
  {
    fprintf(stderr,"  Error #%u in %s: %s\n", exception.ErrorCode(),
            (const char *)exception.ProcName(),
            (const char *)exception.ErrorMessage());
  }

  // Tell the main thread to terminate itself.
  LockMutex(gStartMutex);
  gTerminate = TRUE;
  UnlockMutex(gStartMutex);
  CFRunLoopStop(CFRunLoopGetMain());
  return H_MSG_OK;
}

static int apple_main(int argc, char *argv[])
{
  Herror                error;
  CFRunLoopTimerRef     Timer;
  CFRunLoopTimerContext TimerContext = { 0, 0, 0, 0, 0 };

  CreateMutex("type","sleep",&gStartMutex);
  LockMutex(gStartMutex);

  error = HpThreadHandleAlloc(&gActionThread);
  if (H_MSG_OK != error)
  {
    fprintf(stderr,"HpThreadHandleAlloc failed: %d\n", error);
    exit(1);
  }

  error = HpThreadCreate(gActionThread,0,apple_action);
  if (H_MSG_OK != error)
  {
    fprintf(stderr,"HpThreadCreate failed: %d\n", error);
    exit(1);
  }

  Timer = CFRunLoopTimerCreate(kCFAllocatorDefault,
                               CFAbsoluteTimeGetCurrent(),0,0,0,
                               timer_callback,&TimerContext);
  if (!Timer)
  {
    fprintf(stderr,"CFRunLoopTimerCreate failed\n");
    exit(1);
  }
  CFRunLoopAddTimer(CFRunLoopGetCurrent(),Timer,kCFRunLoopCommonModes);

  for (;;)
  {
    HBOOL terminate;

    CFRunLoopRun();

    LockMutex(gStartMutex);
    terminate = gTerminate;
    UnlockMutex(gStartMutex);

    if (terminate)
      break;
  }

  CFRunLoopRemoveTimer(CFRunLoopGetCurrent(),Timer,kCFRunLoopCommonModes);
  CFRelease(Timer);

  error = HpThreadHandleFree(gActionThread);
  if (H_MSG_OK != error)
  {
    fprintf(stderr,"HpThreadHandleFree failed: %d\n", error);
    exit(1);
  }

  ClearMutex(gStartMutex);
  return 0;
}
#endif

int main(int argc, char *argv[])
{
  int ret = 0;

  try
  {
#if defined(_WIN32)
    SetSystem("use_window_thread", "true");
#endif

    // file was stored with local-8-bit encoding
    //   -> set the interface encoding accordingly
    SetHcppInterfaceStringEncodingIsUtf8(false);

    // Default settings used in HDevelop (can be omitted)
    SetSystem("width", 512);
    SetSystem("height", 512);

#ifndef __APPLE__
    action();
#else
    ret = apple_main(argc,argv);
#endif
  }
  catch (HException &exception)
  {
    fprintf(stderr,"  Error #%u in %s: %s\n", exception.ErrorCode(),
            (const char *)exception.ProcName(),
            (const char *)exception.ErrorMessage());
    ret = 1;
  }
  return ret;
}

#endif


#endif

04. 创建Qt图形界面项目

4.1 简单的GUI设计如下
请添加图片描述

4.2 选择MSVC2019编译器或者其它版本的编译器
请添加图片描述

集成halcon编译需要用msvc,如果用minGW,会出错,等有时间在去研究minGW编译情形。

05. Qt集成Halcon程序

5.1 在pro项目配置文件中添加一下Halcon相关配置

# 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"
}

5.2 在mainwindow.h文件中添加Halcon相关头文件

#  include "HalconCpp.h"
#  include "HDevThread.h"

using namespace HalconCpp;

5.3 在MainWindow添加halcon相关的变量
请添加图片描述

源文件如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>



#  include "HalconCpp.h"
#  include "HDevThread.h"

using namespace HalconCpp;


QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;

    // Local iconic variables
    HObject  ho_Carb;

    // Local control variables
    HTuple  hv_Width, hv_Height, hv_WindowHandle;


};
#endif // MAINWINDOW_H

5.4 实现采集图像槽函数

//采集图像按钮槽函数
void MainWindow::on_pushButton_clicked()
{
    //从本地磁盘读取一张图片
      ReadImage(&ho_Carb, "E:/CarB.jpg");

      //获取图片大小
      GetImageSize(ho_Carb, &hv_Width, &hv_Height);

      //关闭当前窗口
      if (HDevWindowStack::IsOpen())
        CloseWindow(HDevWindowStack::Pop());

      //打开新窗口
      SetWindowAttr("background_color","black");
      //Halcon图像窗口与QT窗口是独立的窗口
      //OpenWindow(0,0,hv_Width/2,hv_Height/2,0,"visible","",&hv_WindowHandle);

      //获取Label空间的WinId
      Hlong winId = (Hlong)ui->label->winId();
      //将Label和Halcon窗口进行绑定
      OpenWindow(0,0,hv_Width/2,hv_Height/2,winId,"visible","",&hv_WindowHandle);
      HDevWindowStack::Push(hv_WindowHandle);

      //显示图片
      if (HDevWindowStack::IsOpen())
        DispObj(ho_Carb, HDevWindowStack::GetActive());

}

5.5 编译运行,执行结果
请添加图片描述

06. 附录

6.1 测试程序下载

下载:【机器视觉】Qt联合Halcon编程之显示图片.rar

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值