halcon opencv C++环境配置 | halcon opencv |C++互转opencv和Halcon图像变量(非常详细)|(msvc2015/17)(143)

这是本人第一次正儿八经非调侃的态度写C相关的东西;

VS的C++每次环境不好配置就让人望而却步;

而python的优势在于环境几乎只需要pip install xxx;

C# 多数情况下nuget 点点点在添加引用就能愉快的玩耍;

而 py C# 背后 竟然是 xxx; 有一 被分层包养的感觉; 

而C/CPP 头文件 程序 链接文件(动态|静态) 动态链接库 这都啥??

掌握pythonnet  ctypes 咯咯咯嘎嘎嘎  %$#@#$%&^*(&(python?nodejs?Electron??

呃呃呃:python 版的 opencv halcon 图像变量互相转换前面已经讲过了.

作为一个python用户还是要玩C的; 不吹牛开始第一步哈喽沃德吧.

平台:

平台:
	操作系统: Win10 22H2 64 位操作系统, 基于 x64 的处理器
	IDE: Microsoft Visual Studio 2022 (64 位)
	CV: opencv4.9
	HA: HALCON-23.05

环境配置:

1.默认Win10_X64已经安装好了VS2022 且可以正常编译C++工程;

2.已经安装好mvtec-chalcon23.05 ;
	默认安装路径:
		"C:\Program Files\MVTec\HALCON-23.05-Progress";
		"C:\Program Files\MVTec\HALCON-23.05-Progress\bin\x64-win64";
		
3.已经下载好opencv:"opencv-4.9.0-windows.exe":
	运行后自动解压>>:
		"D:\下载\opencv_\opencv4.9";
		"D:\下载\opencv_\opencv4.9\build";	
		"opencv4.9\build\x64\vc16\bin"
		
4.首先新建一个C++工程"控制台应用":
	工程文件夹下会产生:
	xxx.sln
	xxx.vcxproj
	xxx.vcxproj.filters
	xxx.vcxproj.user
	xxx.cpp
	x64
	主要关注:xxx.vcxproj:
		所有工程配置信息以类似xml文本保存到该文件;
		相对路径也是以该文件位置为基准;
		
5.在工程下xxx.vcxproj文件同级目录新建两个文件夹:
	新建HALCON-23.05-Progress:
		将"C:\Program Files\MVTec\HALCON-23.05-Progress"
		,内的 "include" "lib"文件夹复制进来
		
	新建opencv4.9:
		将"D:\下载\opencv_\opencv4.9\build";
		,内的"include" "x64"文件夹复制进来
6.
先在"配置管理器": 
	活动解决方案平台 活动解决方案配置 
		设置好 X64 Release Debug
接下来:
项目>>属性(配置属性):
	VC++目录:
		"包含目录":
			{
				opencv4.9\include
				opencv4.9\include\opencv2
				HALCON-23.05-Progress\include
				HALCON-23.05-Progress\include\halconcpp
			}
		"库目录":
			{
				opencv4.9\x64\vc16\lib
				HALCON-23.05-Progress\lib\x64-win64							
			}
	链接器:
		常规:
			"附加库目录":
				{
					HALCON-23.05-Progress\lib\x64-win64
				}
		输入:
			"附加依赖项":
				{ 
					halconcpp.lib
					opencv_world490.lib
				}
				
7.总结:
项目>>属性(配置属性):
	VC++目录:
		"包含目录":(1)
		"库目录":(2)
	链接器:
		常规:
			"附加库目录":(3)
		输入:
			"附加依赖项":(4)

	程序前面加:
	和 附加依赖项 都行
	没搞明白有啥不一样; 
	两个都搞上也行;
	#pragma comment(lib, "opencv_world490.lib")
	#pragma comment(lib, "opencv_world490d.lib")
	#pragma comment(lib, "halconcpp.lib")

实际上一共四步:

"包含目录":(1)
	opencv4.9\include
	opencv4.9\include\opencv2
	HALCON-23.05-Progress\include\halconcpp
	HALCON-23.05-Progress\include
"库目录":(2)
	opencv4.9\x64\vc16\lib
	HALCON-23.05-Progress\lib\x64-win64
"附加库目录":(3)
	HALCON-23.05-Progress\lib\x64-win64
"附加依赖项":(4)
	halconcpp.lib
	opencv_world490d.lib

接下来:



配置完成后:用记事本打开xxx.vcxproj文件:
会发现 这些标签: (反正我看不懂 大概就这意思)
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <IncludePath>
		opencv4.9\include;
		opencv4.9\include\opencv2;
		HALCON-23.05-Progress\include\halconcpp;
		HALCON-23.05-Progress\include;
		$(IncludePath)
	</IncludePath>
    <LibraryPath>
		opencv4.9\x64\vc16\lib;
		HALCON-23.05-Progress\lib\x64-win64;
		$(LibraryPath)
		</LibraryPath>
  </PropertyGroup>
  
8.测试程序是否能正常编译生成:
	"xxx\x64\Release xxx.exe"
	正常生成后还需要运行:
	



从这里:
"C:\Program Files\MVTec\HALCON-23.05-Progress\bin\x64-win64"
	复制
	halcon.dll
	halconc.dll
	halconcpp.dll
	hcanvas.dll 
	halcondl.dll

	halcondlxl.dll
	halconxl.dll
	halconcxl.dll
	halconcppxl.dll

	到xxx.exe同级目录:

从这里:
"opencv4.9\build\x64\vc16\bin"
	复制:
	opencv_world490.dll
	opencv_world490d.dll
	opencv_videoio_msmf490_64.dll
	opencv_videoio_msmf490_64d.dll
	opencv_videoio_ffmpeg490_64.dll
	到xxx.exe同级目录:

就可以运行了:
 不用添加opencv环境变量:
 这个工程可以打包 到只有VS 没有安装opencv halcon的机器;
 
 缺点是opencv dll文件很大

提示 :

 不用添加opencv环境变量:
 这个工程可以打包 到只有VS 没有安装opencv halcon的机器也是没有问题的;

接下来: 上程序: 转换很丝滑;

#include <iostream>
#pragma comment(lib, "opencv_world490.lib")
//#pragma comment(lib, "opencv_world490d.lib")
#pragma comment(lib, "halconcpp.lib")
#include "opencv.hpp"
#include "highgui.hpp"
#include "HalconCpp.h"
#include "HDevThread.h"
using namespace std;
using namespace cv;
using namespace HalconCpp;

cv::Mat HImageToMat(HalconCpp::HObject& H_img)
{
	cv::Mat cv_img, cv_imgr, cv_imgg, cv_imgb;
	HalconCpp::HTuple channels, w, h;

	HalconCpp::ConvertImageType(H_img, &H_img, "byte");
	HalconCpp::CountChannels(H_img, &channels);

	if (channels.I() == 1)
	{
		HalconCpp::HTuple pointer;
		GetImagePointer1(H_img, &pointer, nullptr, &w, &h);
		int width = w.I(), height = h.I();
		int size = width * height;
		cv_img = cv::Mat::zeros(height, width, CV_8UC1);
		memcpy(cv_img.data, (void*)(pointer.L()), size);
	}

	else if (channels.I() == 3)
	{
		HalconCpp::HTuple pointerR, pointerG, pointerB;
		HalconCpp::GetImagePointer3(H_img, &pointerR, &pointerG, &pointerB, nullptr, &w, &h);
		int width = w.I(), height = h.I();
		int size = width * height;
		cv_imgr = cv::Mat::zeros(height, width, CV_8UC1);
		cv_imgg = cv::Mat::zeros(height, width, CV_8UC1);
		cv_imgb = cv::Mat::zeros(height, width, CV_8UC1);
		cv_img = cv::Mat::zeros(height, width, CV_8UC3);

		memcpy(cv_imgr.data, (void*)(pointerR.L()), size);
		memcpy(cv_imgg.data, (void*)(pointerG.L()), size);
		memcpy(cv_imgb.data, (void*)(pointerB.L()), size);
		vector<Mat> imgv;
		imgv.push_back(cv_imgb);
		imgv.push_back(cv_imgg);
		imgv.push_back(cv_imgr);
		cv::merge(imgv, cv_img);
		uchar* R = (uchar*)(pointerR.L());
		uchar* G = (uchar*)(pointerG.L());
		uchar* B = (uchar*)(pointerB.L());
	}
	return cv_img;
}


HalconCpp::HImage MatToHImage(const cv::Mat& mat)
{
	HalconCpp::HImage hImg;
	int hgt = mat.rows;
	int wid = mat.cols;
	int channels = mat.channels();

	switch (channels)
	{
	case 1:
	{
		// Assuming the image is single channel (grayscale)
		HalconCpp::GenImage1(&hImg, "byte", wid, hgt, (Hlong)mat.data);
		break;
	}
	case 3:
	{
		// Assuming the image is 3 channel (BGR in OpenCV)
		cv::Mat rgbMat;
		cv::cvtColor(mat, rgbMat, cv::COLOR_BGR2RGB);
		hImg.GenImageInterleaved(rgbMat.data, "rgb", wid, hgt, 0, "byte", wid, hgt, 0, 0, -1, 0);
		break;
	}
	// Add more cases as needed for different number of channels
	}
	return hImg;
}


void action()
{
	SetSystem("use_window_thread", "true");
	SetHcppInterfaceStringEncodingIsUtf8(false);
	SetSystem("width", 512);
	SetSystem("height", 512);
	HObject  ho_Image;
	HTuple  hv_WindowHandle;
	ReadImage(&ho_Image, "printer_chip/printer_chip_01");
	SetWindowAttr("background_color", "black");
	OpenWindow(0, 0, 512, 512, 0, "visible", "", &hv_WindowHandle);
	DispObj(ho_Image, hv_WindowHandle);

	ClearWindow(hv_WindowHandle);
}

void opcv()
{
	Mat img = imread("C://Users//Administrator//Desktop//opencv_C++_halcon_转换//ha_ft_cv_conv//x64//Release//012.jpg");
	namedWindow("窗口", WINDOW_AUTOSIZE | WINDOW_NORMAL);
	cv::imshow("窗口", img);
	//while (char(waitKey(1)) != 'q') {}
	waitKey(2000);
}

void convtt() 
{
	Mat img = imread("C:/lena4.jpg");
	Mat M1(600, 600, CV_8UC3, cv::Scalar(255, 0, 0));
	//Mat M1(600, 600, CV_8UC4, cv::Scalar(255, 0, 0,255));// 4通道
	namedWindow("kl", 1);cv::imshow("kl", M1);waitKey(2000);

	//halcon 转CV mat
	HalconCpp::HImage H_img("C:/LenaNO.jpg"); //
	HalconCpp::HImage H_gray;
	HalconCpp::Rgb1ToGray(H_img, &H_gray);  //
	cv::Mat cv_imgHgray = HImageToMat(H_gray);//1通道
	namedWindow("kl", 1);cv::imshow("kl", cv_imgHgray);waitKey(2000);
	cv::Mat cv_imgH = HImageToMat(H_img); // 3通道
	namedWindow("kl", 1); cv::imshow("kl", cv_imgH); waitKey(2000);

	//CV mat 转 halcon 
/****************************************************************************************/
	cv::Mat mat = cv::imread("C:/lena1.png");
	HalconCpp::HImage hImg = MatToHImage(mat);//3通道
	Mat img_gray = imread("C:/lena1.png", 0);
	HalconCpp::HImage hImg_gray = MatToHImage(img_gray);//灰度1通道
	HTuple  hv_WindowHandle, hv_WindowHandle1;

	SetSystem("use_window_thread", "true");
	SetHcppInterfaceStringEncodingIsUtf8(false);
	SetSystem("width", 512);
	SetSystem("height", 512);
	SetWindowAttr("background_color", "black");
	OpenWindow(0, 0, 512, 512, 0, "visible", "", &hv_WindowHandle);
	OpenWindow(0, 512, 512, 512, 0, "visible", "", &hv_WindowHandle1);
	DispObj(hImg, hv_WindowHandle);
	DispObj(hImg_gray, hv_WindowHandle1);
	Sleep(3000);
}
int main(int argc, char* argv[], char** env)
{    
	cout << argc <<  argv[0];
	action();//单独试试halcon行不行
	opcv(); //单独试试cv行不行
	convtt();//测试单通道三通道互相转换 
	return 0;
}

本来到这里已经结束了,突然想比较一下python版本和C++的速度;来开始:

先上python:

import os,cv2,time
import halcon as ha
import numpy as np
from ctypes import *
def cmd(s="pause"):
    os.system(s)
def open_window(width, height,row=0,column=0,father_window=0):
    if os.name == 'nt':
        ha.set_system('use_window_thread', 'true')
    return ha.open_window(
        row=row,
        column=column,
        width=width,
        height=height,
        father_window=0,
        mode='visible',
        machine=''
    )
def ha_ha_2_np(image):
    before = time.time()
    img=ha.himage_as_numpy_array(image)
    img_bgr=cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
    after = time.time()
    time_consuming=after-before    
    return time_consuming,img_bgr
def hanp__2_ha(img):
    before = time.time() 
    img_bgr=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    image=ha.himage_from_numpy_array(img_bgr) 
    after = time.time()
    time_consuming=after-before    
    return time_consuming,image
if __name__ == "__main__":  
    Image = ha.read_image('Lena1')
    ty,img=ha_ha_2_np(Image)
    #img_bgr=cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
    print(f"python:halcon转numpy耗时:{ty}")
    ty,h_img=hanp__2_ha(img)
    print(f"python:numpy转halcon耗时:{ty}")
    Width, Height = ha.get_image_size(Image)
    print(Width[0], Height[0])
    WindowHandle =open_window(Width[0]/2, Height[0]/2)
    gray = ha.rgb1_to_gray(Image)
    thres = ha.threshold(gray, 100, 200)
    ha.disp_obj(Image, WindowHandle);cmd()
    ha.clear_window(WindowHandle)
    ha.disp_obj(thres, WindowHandle);cmd()

运行结果:

python:halcon转numpy耗时:0.00398707389831543
python:numpy转halcon耗时:0.001956939697265625
512 512
请按任意键继续. . .

请出C:

//记得#include <iostream> #include <chrono>
void convtttime()
{
	//halcon 转CV mat
	HalconCpp::HImage H_img("C://Lena1.png"); // 拿图
	auto start = std::chrono::high_resolution_clock::now();
	cv::Mat cv_imgH = HImageToMat(H_img); // 3通道 转换
	auto end = std::chrono::high_resolution_clock::now();
	std::chrono::duration<double> elapsed = end - start;
	printf("\n");
	std::cout << "halcon 转CV mat: " << elapsed.count() << "s\n";
	namedWindow("kl", 1); cv::imshow("kl", cv_imgH); waitKey(1);//显示
	//CV mat 转 halcon 
/**********************************************************************************/
	cv::Mat mat = cv::imread("C://Lena1.png");
	auto start1 = std::chrono::high_resolution_clock::now();
	HalconCpp::HImage hImg = MatToHImage(mat);//3通道
	auto end1 = std::chrono::high_resolution_clock::now();
	std::chrono::duration<double> elapsed1 = end1 - start1;
	printf("\n");
	std::cout << "CV mat 转 halcon: " << elapsed1.count() << "s\n";

	HTuple  hv_WindowHandle, hv_WindowHandle1;
	SetSystem("use_window_thread", "true");
	SetHcppInterfaceStringEncodingIsUtf8(false);
	SetSystem("width", 512);
	SetSystem("height", 512);
	SetWindowAttr("background_color", "black");
	OpenWindow(0, 0, 512, 512, 0, "visible", "", &hv_WindowHandle);
	DispObj(hImg, hv_WindowHandle);                                     //显示
	Sleep(30000);
}
int main(int argc, char* argv[], char** env)
{    
	cout << argc <<  argv[0];
	convtttime();
	return 0;
}

最后看运行结果:

1C:\Users\Administrator\Desktop\opencv_C++_halcon_转换\ha_ft_cv_conv\x64\Release\ha_ft_cv_conv.exe
halcon 转CV mat: 0.001906s

CV mat 转 halcon: 0.0005785s

对比不明显:把两个结果放在一起来看:

C++:
1C:\Users\Administrator\Desktop\opencv_C++_halcon_转换\ha_ft_cv_conv\x64\Release\ha_ft_cv_conv.exe
halcon 转CV mat: 0.001906s

CV mat 转 halcon: 0.0005785s


python:
python:halcon转numpy耗时:0.0049591064453125
python:numpy转halcon耗时:0.000993490219116211
512 512

同样一张图: 
halcon 转 CV 前者比后者快了2.6倍;
CV 转 halcon 前者比后者快 几乎2倍
然而 不是说python出了名的慢,比C慢几十倍上百倍么;
你会发现py竟然比C#的halconnet >>互转<<opencvsharp快??
这就是争吵的原因;

当然脱离实际情况的争吵属于耍无赖;具体问题具体分析;

纯cli:
如果是QT那么你得把C:\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin
150多个dll共计600M的依赖文件拿过来 图转成RGB888 这不得拖慢多少倍

 

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值