OpencvHal.h
#include <opencv2/opencv.hpp>
#include <HalconCpp.h>
#include <HalconCDefs.h>
#include <HProto.h>
using namespace HalconCpp;
//Hobject IplImageToHImage(cv::Mat& pImage);
//cv::Mat HImageToIplImage(Hobject &Hobj);
//HObject MatToHImage(cv::Mat pImage, HObject &Hobj);
HImage IplImageToHImage(cv::Mat& pImage);
OpencvHal.cpp
#include "OpencvHal.h"
HImage IplImageToHImage(cv::Mat& pImage)
{
HImage Hobj;
if (3 == pImage.channels())
{
cv::Mat pImageRed, pImageGreen, pImageBlue;
std::vector<cv::Mat> sbgr(3);
cv::split(pImage, sbgr);
int length = pImage.rows * pImage.cols;
uchar *dataBlue = new uchar[length];
uchar *dataGreen = new uchar[length];
uchar *dataRed = new uchar[length];
int height = pImage.rows;
int width = pImage.cols;
for (int row = 0; row <height; row++)
{
uchar* ptr = pImage.ptr<uchar>(row);
for (int col = 0; col < width; col++)
{
dataBlue[row * width + col] = ptr[3 * col];
dataGreen[row * width + col] = ptr[3 * col + 1];
dataRed[row * width + col] = ptr[3 * col + 2];
}
}
HalconCpp::GenImage3(&Hobj, "byte", width, height, (Hlong)(dataRed), (Hlong)(dataGreen), (Hlong)(dataBlue));
delete[] dataRed;
delete[] dataGreen;
delete[] dataBlue;
}
else if (1 == pImage.channels())
{
int height = pImage.rows;
int width = pImage.cols;
uchar *dataGray = new uchar[width * height];
memcpy(dataGray, pImage.data, width * height);
HalconCpp::GenImage1(&Hobj, "byte", width, height, (Hlong)(dataGray));
delete[] dataGray;
}
return Hobj;
}
main.cpp
#include <iostream>
#include <stdio.h>
#include <opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <highgui.h>
//halcon include
#ifndef __APPLE__
# include "HalconCpp.h"
# include "HDevThread.h"
# if defined(__linux__) && !defined(NO_EXPORT_APP_MAIN)
# include <X11/Xlib.h>
# endif
#else
# ifndef HC_LARGE_IMAGES
# include <HALCONCpp/HalconCpp.h>
# include <HALCONCpp/HDevThread.h>
# else
# include <HALCONCppxl/HalconCpp.h>
# include <HALCONCppxl/HDevThread.h>
# endif
# include <stdio.h>
# include <HALCON/HpThread.h>
# include <CoreFoundation/CFRunLoop.h>
#endif
//user include
#include "OpencvHal.h"
using namespace HalconCpp;
Hlong m_WindowRow = 16;
Hlong m_WindowColumn = 630;
Hlong m_WindowWidth = 630;
Hlong m_WindowHeight = 472;
HalconCpp::HWindow m_Window;
int main(int argc, char* argv[])
{
cv::VideoCapture cap;// cap(0, CAP_FFMPEG);
//cap.set(CV_CAP_PROP_FPS, 120);
//cap.set(CV_CAP_PROP_EXPOSURE, -12.0);
cap.open(0);
if (!cap.isOpened()) { return -1; }
//cap.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
//cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
//cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720);//如果相机支持的话这几个设置是可行的。
cv::Mat frame;
cap >> frame;
HTuple WindowHandle;
m_Window.OpenWindow(m_WindowRow, m_WindowColumn,
m_WindowWidth, m_WindowHeight,
NULL, "visible", "");
HImage himg = IplImageToHImage(frame);
Hlong Width, Height;
himg.GetImageSize(&Width, &Height);
m_Window.SetPart(0, 0, Height - 1, Width - 1);
m_Window.SetLineWidth(3);
while (true)
{
cap >> frame;
if (frame.empty())
{
fprintf(stderr, "Can not load the image file.\n");
return -1;
}
cv::Mat gray;
cv::cvtColor(frame, gray, CV_BGR2GRAY);
cv::imshow("Gray",gray);
himg = IplImageToHImage(frame);
m_Window.DispObj(himg);
cv::waitKey(1);
}
}
将上述的一个头文件,两个cpp文件加载到工程中,即可以使用opencv和Halcon窗口显示图像。
但是有些从Halcon直接导出的cpp可能没有窗口的初始化,引导到cpp后无法显示图像。是因为HDevWindowStack::IsOpen()值==0。也就是Window没有压栈。
应该添加一些语句。比如我的一个模板匹配匹配工程中的hdev文件如下
read_image (Filename2025, 'E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/filename2025.bmp')
*
* Matching 01: ************************************************
* Matching 01: BEGIN of generated code for model initialization
* Matching 01: ************************************************
set_system ('border_shape_models', 'false')
*
* Matching 01: Obtain the model image
read_image (Image, '')
*
* Matching 01: Build the ROI from basic regions
gen_rectangle1 (ModelRegion, 72.26, 47.172, 223.22, 685.316)
*
* Matching 01: Reduce the model template
reduce_domain (Image, ModelRegion, TemplateImage)
*
* Matching 01: Create the shape model
create_shape_model (TemplateImage, 5, rad(0), rad(360), rad(1), ['none','no_pregeneration'], 'use_polarity', [30,30,0], 10, ModelID)
*
* Matching 01: Get the model contour for transforming it later into the image
get_shape_model_contours (ModelContours, ModelID, 1)
*
* Matching 01: Get the reference position
area_center (ModelRegion, ModelRegionArea, RefRow, RefColumn)
vector_angle_to_rigid (0, 0, 0, RefRow, RefColumn, 0, HomMat2D)
affine_trans_contour_xld (ModelContours, TransContours, HomMat2D)
*
* Matching 01: Display the model contours
dev_display (Image)
dev_set_color ('green')
dev_set_draw ('margin')
dev_display (ModelRegion)
dev_display (TransContours)
stop ()
*
* Matching 01: END of generated code for model initialization
* Matching 01: * * * * * * * * * * * * * * * * * * * * * * *
* Matching 01: BEGIN of generated code for model application
*
* Matching 01: Loop over all specified test images
TestImages := ['E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/0.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/1.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/10.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/11.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/12.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/13.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/14.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/15.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/16.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/17.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/18.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/19.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/2.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/20.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/21.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/3.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/4.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/5.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/6.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/7.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/8.bmp','E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/9.bmp']
for T := 0 to 21 by 1
*
* Matching 01: Obtain the test image
read_image (Image, TestImages[T])
*
* Matching 01: Find the model
find_shape_model (Image, ModelID, rad(0), rad(360), 0.5, 0, 0.5, 'least_squares', [5,1], 0.75, Row, Column, Angle, Score)
*
* Matching 01: Transform the model contours into the detected positions
dev_display (Image)
for I := 0 to |Score| - 1 by 1
hom_mat2d_identity (HomMat2D)
hom_mat2d_rotate (HomMat2D, Angle[I], 0, 0, HomMat2D)
hom_mat2d_translate (HomMat2D, Row[I], Column[I], HomMat2D)
affine_trans_contour_xld (ModelContours, TransContours, HomMat2D)
dev_set_color ('green')
dev_display (TransContours)
stop ()
endfor
endfor
*
* Matching 01: Clear model when done
stop ()
clear_shape_model (ModelID)
* Matching 01: *******************************************
* Matching 01: END of generated code for model application
* Matching 01: *******************************************
*
将它引导成cpp后,在cpp文件中要添加几个语句才能正常运行,具体添加的语句后面都有注释 //DisplayPart .只要将 注释//DisplayPart的语句加到程序中相应的位置即可显示。
cpp文件如下
///////////////////////////////////////////////////////////////////////////////
// File generated by HDevelop for HALCON/C++ Version 13.0
///////////////////////////////////////////////////////////////////////////////
#ifndef __APPLE__
# include "HalconCpp.h"
# include "HDevThread.h"
# if defined(__linux__) && !defined(NO_EXPORT_APP_MAIN)
# include <X11/Xlib.h>
# endif
#else
# ifndef HC_LARGE_IMAGES
# include <HALCONCpp/HalconCpp.h>
# include <HALCONCpp/HDevThread.h>
# else
# include <HALCONCppxl/HalconCpp.h>
# include <HALCONCppxl/HDevThread.h>
# endif
# include <stdio.h>
# include <HALCON/HpThread.h>
# include <CoreFoundation/CFRunLoop.h>
#endif
using namespace HalconCpp;
Hlong m_WindowRow = 16; //DisplayPart
Hlong m_WindowColumn = 630;//DisplayPart
Hlong m_WindowWidth = 630;//DisplayPart
Hlong m_WindowHeight = 472;//DisplayPart
HalconCpp::HWindow m_Window;//DisplayPart
#ifndef NO_EXPORT_MAIN
// Main procedure
void action()
{
// Local iconic variables
HObject ho_Filename2025, ho_Image, ho_ModelRegion;
HObject ho_TemplateImage, ho_ModelContours, ho_TransContours;
// Local control variables
HTuple hv_ModelID, hv_ModelRegionArea, hv_RefRow;
HTuple hv_RefColumn, hv_HomMat2D, hv_TestImages, hv_T;
HTuple hv_Row, hv_Column, hv_Angle, hv_Score, hv_I;
ReadImage(&ho_Filename2025, "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/filename2025.bmp");
m_Window.OpenWindow(m_WindowRow, m_WindowColumn,
m_WindowWidth, m_WindowHeight,
NULL, "visible", ""); //DisplayPart
HTuple Width, Height;//DisplayPart
GetImageSize(ho_Filename2025, &Width, &Height);//DisplayPart
m_Window.SetPart(0, 0, Height.I() - 1, Width.I() - 1);//DisplayPart
m_Window.SetLineWidth(3);//DisplayPart
HDevWindowStack::Push((m_Window));//DisplayPart
//
//Matching 01: ************************************************
//Matching 01: BEGIN of generated code for model initialization
//Matching 01: ************************************************
SetSystem("border_shape_models", "false");
//
//Matching 01: Obtain the model image
//Matching 01: The image is assumed to be made available in the
//Matching 01: variable last displayed in the graphics window
CopyObj(ho_Filename2025, &ho_Image, 1, 1);
//
//Matching 01: Build the ROI from basic regions
GenRectangle1(&ho_ModelRegion, 64.5703, 44.1127, 224.316, 654.908);
//
//Matching 01: Reduce the model template
ReduceDomain(ho_Image, ho_ModelRegion, &ho_TemplateImage);
//
//Matching 01: Create the shape model
CreateShapeModel(ho_TemplateImage, 6, HTuple(0).TupleRad(), HTuple(360).TupleRad(),
HTuple(0.3898).TupleRad(), (HTuple("none").Append("no_pregeneration")), "use_polarity",
((HTuple(42).Append(71)).Append(13)), 4, &hv_ModelID);
//
//Matching 01: Get the model contour for transforming it later into the image
GetShapeModelContours(&ho_ModelContours, hv_ModelID, 1);
//
//Matching 01: Get the reference position
AreaCenter(ho_ModelRegion, &hv_ModelRegionArea, &hv_RefRow, &hv_RefColumn);
VectorAngleToRigid(0, 0, 0, hv_RefRow, hv_RefColumn, 0, &hv_HomMat2D);
AffineTransContourXld(ho_ModelContours, &ho_TransContours, hv_HomMat2D);
//
//Matching 01: Display the model contours
if (HDevWindowStack::IsOpen())
DispObj(ho_Image, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(), "green");
if (HDevWindowStack::IsOpen())
SetDraw(HDevWindowStack::GetActive(), "margin");
if (HDevWindowStack::IsOpen())
DispObj(ho_ModelRegion, HDevWindowStack::GetActive());
if (HDevWindowStack::IsOpen())
DispObj(ho_TransContours, HDevWindowStack::GetActive());
// stop(...); only in hdevelop
//
//Matching 01: END of generated code for model initialization
//Matching 01: * * * * * * * * * * * * * * * * * * * * * * *
//Matching 01: BEGIN of generated code for model application
//
//Matching 01: Loop over all specified test images
hv_TestImages.Clear();
hv_TestImages[0] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/0.bmp";
hv_TestImages[1] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/1.bmp";
hv_TestImages[2] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/10.bmp";
hv_TestImages[3] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/11.bmp";
hv_TestImages[4] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/12.bmp";
hv_TestImages[5] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/13.bmp";
hv_TestImages[6] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/14.bmp";
hv_TestImages[7] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/15.bmp";
hv_TestImages[8] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/16.bmp";
hv_TestImages[9] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/17.bmp";
hv_TestImages[10] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/18.bmp";
hv_TestImages[11] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/19.bmp";
hv_TestImages[12] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/2.bmp";
hv_TestImages[13] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/20.bmp";
hv_TestImages[14] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/21.bmp";
hv_TestImages[15] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/3.bmp";
hv_TestImages[16] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/4.bmp";
hv_TestImages[17] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/5.bmp";
hv_TestImages[18] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/6.bmp";
hv_TestImages[19] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/7.bmp";
hv_TestImages[20] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/8.bmp";
hv_TestImages[21] = "E:/VisoStidioprojects/win10Opencv31/MystructlineGige/strctlineGigeFor2D/strctlineGige/9.bmp";
for (hv_T = 0; hv_T <= 21; hv_T += 1)
{
//
//Matching 01: Obtain the test image
ReadImage(&ho_Image, HTuple(hv_TestImages[hv_T]));
GetImageSize(ho_Image, &Width, &Height);//DisplayPart
m_Window.SetPart(0, 0, Height.I() - 1, Width.I() - 1);//DisplayPart
//
//Matching 01: Find the model
FindShapeModel(ho_Image, hv_ModelID, HTuple(0).TupleRad(), HTuple(360).TupleRad(),
0.42, 1, 0.5, "least_squares", (HTuple(6).Append(1)), 0.75, &hv_Row, &hv_Column,
&hv_Angle, &hv_Score);
//
//Matching 01: Transform the model contours into the detected positions
std::cout << "HDevWindowStack::IsOpen()" << HDevWindowStack::IsOpen() << std::endl;
if (HDevWindowStack::IsOpen())
DispObj(ho_Image, HDevWindowStack::GetActive());
{
HTuple end_val54 = (hv_Score.TupleLength()) - 1;
HTuple step_val54 = 1;
for (hv_I = 0; hv_I.Continue(end_val54, step_val54); hv_I += step_val54)
{
HomMat2dIdentity(&hv_HomMat2D);
HomMat2dRotate(hv_HomMat2D, HTuple(hv_Angle[hv_I]), 0, 0, &hv_HomMat2D);
HomMat2dTranslate(hv_HomMat2D, HTuple(hv_Row[hv_I]), HTuple(hv_Column[hv_I]),
&hv_HomMat2D);
AffineTransContourXld(ho_ModelContours, &ho_TransContours, hv_HomMat2D);
if (HDevWindowStack::IsOpen())
SetColor(HDevWindowStack::GetActive(), "green");
if (HDevWindowStack::IsOpen())
DispObj(ho_TransContours, HDevWindowStack::GetActive());
// stop(...); only in hdevelop
}
}
}
//
//Matching 01: Clear model when done
// stop(...); only in hdevelop
ClearShapeModel(hv_ModelID);
//Matching 01: *******************************************
//Matching 01: END of generated code for model application
//Matching 01: *******************************************
//
}
#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.
HTuple gStartMutex;
H_pthread_t gActionThread;
static void timer_callback(CFRunLoopTimerRef timer, void *info)
{
UnlockMutex(gStartMutex);
}
static Herror apple_action(void **parameters)
{
LockMutex(gStartMutex);
action();
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);
CFRunLoopRun();
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[])
{
#if defined(_WIN32)
SetSystem("use_window_thread", "true");
#elif defined(__linux__)
XInitThreads();
#endif
// Default settings used in HDevelop (can be omitted)
int ret = 0;
SetSystem("width", 512);
SetSystem("height", 512);
#ifndef __APPLE__
action();
#else
ret = apple_main(argc, argv);
#endif
return ret;
}
#endif
#endif