VS2015 + Halcon18 - (一) MFC加载图片&打开相机

一个正经的目录

  • 前言
    • 1、加载图片
      • 1.1、代码片段
    • 2、加载相机
      • 2.1、代码片段

前言

写在前面:关于使用halcon和C++联合编程,并不是什么新鲜事情,但对于新手来说还是会遇到各种各样的问题,归根结底还是对C++的掌握不够熟练,在此记录下学习的过程,水平有限,还请多多指教。

1、加载图片

使用MFC的picture control控件以及halcon加载一个图片,开发过程中遇到的一个最大的问题:

1.编译成功且图片资源成功加载,但是无法显示

1.1、代码片段

对话框准备(不需要绑定变量,使用默认的ID和设置即可):
VS2015 + Halcon18 - (一) MFC加载图片&打开相机_第1张图片
直接上代码:
补充:必须要在类内定义窗口变量HWindowID和m_HWindowID否则后续无法加载窗口

//类内定义窗口变量
HTuple m_HWindowID, HWindowID;

在OnInitDialog()中定义并初始化窗口
起初尝试在按钮时间函数中定义窗口,编译成功而且图片也可以加载,但是却看不到图片,后来经过搜索发现在窗口初始化时加载一个空的窗口即可

//在OnInitDialog()中定义并初始化窗口
	CRect Rect;
	CWnd* pWnd = GetDlgItem(IDC_STATIC);
	HWindowID = (Hlong)pWnd->m_hWnd;//获取父窗口句柄
	pWnd->GetWindowRect(&Rect);
	OpenWindow(0, 0, Rect.Width(), Rect.Height(), HWindowID, "visible", "", &m_HWindowID);
	int w = Rect.Width();

初始化一个新的空窗口:
VS2015 + Halcon18 - (一) MFC加载图片&打开相机_第2张图片

//下面是按钮事件的相应函数
bool clicked = false;
void CDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	HObject m_hImage;
	HTuple m_hWidth, m_hHeight;
	//显示静态图片
	ReadImage(&m_hImage, "Lena.png");//程序根目录下的图片Lena.png
	GetImagePointer1(m_hImage, NULL, NULL, &m_hWidth, &m_hHeight);//获取图片大小
	int imw = m_hWidth[0], imh = m_hHeight[0];//通过这种方式实现halcon变量和C++变量的转换
	SetPart(m_HWindowID, 0, 0, m_hHeight - 1, m_hWidth - 1);//设置图片窗口
	DispObj(m_hImage, m_HWindowID);//显示图片
	//判定窗口按钮是否点击过,重复点击使窗口在加载图片和清除之间切换
	if (clicked){ 
		OnInitDialog();
		clicked = false;
		SetDlgItemText(IDC_BUTTON1, _T("加载图片"));
	}else{
		clicked = true;
		SetDlgItemText(IDC_BUTTON1, _T("清除图片"));
	}
}

通过按钮回调函数打开图片:
VS2015 + Halcon18 - (一) MFC加载图片&打开相机_第3张图片
至此,图片的加载显示完成。
小结,理一下思路:
1、MFC和Halcon使用Picture Control显示图片
2、添加Picture Control控件
3、定义类内窗口句柄ID变量
4、在OnInitDialog()中加载空窗口
5、ReadImage加载图片,并获取图片的大小
6、通过窗口ID绑定图片,显示窗口并显示图片

2、加载相机

使用MFC(Picture Control)+Halcon打开相机并实时显示。
核心思路:
在halcon中导出一个新的相机Acquisition程序.cpp文件;
在新线程中加载相机并通过同一个按钮打开和关闭;
图形窗口显示承接静态图片,保留第一部分的窗口,用于显示相机画面。

2.1、代码片段

在对话框类内新建一些用于获取图像和相机的变量

volatile BOOL m_CamFlag = false;//相机打开或关闭的标志,初始值设为false
HObject ho_Image;//接收相机stream帧图片的变量
HTuple hv_AcqHandle;//相机句柄
HTuple m_FGHandle, m_ImageWidth, m_ImageHeight;

新建一个UINT型的线程函数,将相机的运行放在里面,线程函数需要在头文件中定义

static UINT ThreadFunc(LPVOID lpParam);//对话框头文件中声明
// 线程函数,对话框类中定义
 UINT CDlg::ThreadFunc(LPVOID lpParam)
{
	//acquisition中导出的语句,用于打开笔记本自带的相机,并设置一些参数。
	OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb", -1, "false",
		"default", "[0] ", 0, -1, &hv_AcqHandle);
	GrabImageStart(hv_AcqHandle, -1);
	ClearWindow(m_HWindowID);
	GrabImage(&ho_Image, hv_AcqHandle);
	GetImagePointer1(ho_Image, NULL,NULL,&m_ImageWidth, &m_ImageHeight);//和加载静态图像相同
	SetPart(m_HWindowID, 0, 0, m_ImageHeight - 1, m_ImageWidth - 1);//同上
	//当按钮点击时,m_CamFlag为TRUE,循环获取并显示帧
	while (m_CamFlag){
		GrabImageAsync(&ho_Image, hv_AcqHandle, -1);
		DispObj(ho_Image,m_HWindowID);
		Sleep(50);//休眠,控制获取帧的频率
		}
	ClearWindow(m_HWindowID);
	CloseFramegrabber(hv_AcqHandle);
	ExitThread(0);
}

设置按钮回调事件,控制相机的开与关

void CDlg::OnBnClickedbtncam()
{
	//判定相机是否运行,并更改标签
	if (m_CamFlag) {
		OnInitDialog();
		m_CamFlag = FALSE;
		SetDlgItemText(IDC_btncam, _T("打开相机"));
	}else{
		SetDlgItemText(IDC_btncam, _T("关闭相机"));
		m_CamFlag = TRUE;
		AfxBeginThread(ThreadFunc, this);//使用AfxBeginThread函数开始新的线程
	}
}

VS2015 + Halcon18 - (一) MFC加载图片&打开相机_第4张图片
至此,相机打开成功
小结,思路整理:
1、同静态窗口的显示一样,在OnInitDialog中新建窗口
2、在halcon中导出acquisition的C++工程文件.cpp
3、新建UINT类型线程函数,在此函数中调用相机,AfxBeginThread函数开始新线程
4、按钮回调函数中设置相机打开/关闭状态

参考:
https://www.cnblogs.com/oucsheep/p/5911839.html
https://www.cnblogs.com/oucsheep/p/5911852.html
https://www.cnblogs.com/renyuan/archive/2012/12/12/2814340.html

你可能感兴趣的:(Halcon学习笔记)