机器视觉Qt联合Halcon编程之显示多图片
Posted 沧海一笑-dj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器视觉Qt联合Halcon编程之显示多图片相关的知识,希望对你有一定的参考价值。
00. 目录
01. 概述
QT与Halcon联合编程。将Halcon中代码集成到Qt程序中。
开发环境
Qt:Qt5.15.2
Halcon: Halcon 19.11
02. 编写Halcon程序
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++文件
将上述Halcon程序导出为C++源程序
导出内容如下:
///
// 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;
// Procedure declarations
// Local procedures
void blobImage (HObject *ho_Image, HObject *ho_Region);
// Procedures
// Local procedures
void blobImage (HObject *ho_Image, HObject *ho_Region)
{
ReadImage(&(*ho_Image), "E:/test.jpg.tif");
Threshold((*ho_Image), &(*ho_Region), 128, 255);
if (HDevWindowStack::IsOpen())
DispObj((*ho_Image), HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
DispObj((*ho_Region), HDevWindowStack::GetActive());
return;
}
#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设计如下
集成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相关头文件
#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;
5.3 在MainWindow添加halcon相关的变量
源程序如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#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;
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();
void on_pushButton_3_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()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("打开图片"), "E://", tr("Image Files (*.png *.jpg *.bmp)"));
qDebug() << fileName;
//从本地磁盘读取一张图片
//QString转HTuple要通过String
ReadImage(&ho_Carb, fileName.toStdString().c_str());
//获取图片大小
GetImageSize(ho_Carb, &hv_Width, &hv_Height);
}
友情提示
//QString转HTuple要通过String
ReadImage(&ho_Carb, fileName.toStdString().c_str());
5.5 实现显示图像槽函数
//显示图像
void MainWindow::on_pushButton_3_clicked()
{
//关闭当前窗口
if (HDevWindowStack::IsOpen())
CloseWindow(HDevWindowStack::Pop());
//打开新窗口
SetWindowAttr("background_color","black");
OpenWindow(0,0,hv_Width/2,hv_Height/2, (Hlong)ui->label->winId(),"visible","",&hv_WindowHandle);
HDevWindowStack::Push(hv_WindowHandle);
//显示图片
if (HDevWindowStack::IsOpen())
DispObj(ho_Carb, HDevWindowStack::GetActive());
}
友情提示
Qt中winId()和Halcon中窗口句柄转换
OpenWindow(0,0,hv_Width/2,hv_Height/2, (Hlong)ui->label->winId(),“visible”,"",&hv_WindowHandle);
5.6 编译程序
运行结果如下:
06. 附录
6.1 测试程序下载
以上是关于机器视觉Qt联合Halcon编程之显示多图片的主要内容,如果未能解决你的问题,请参考以下文章