1、应用背景
在实际应用中,程序往往需要既能完成图像的连续抓取显示(监视功能),又需要能实现单帧抓取做图像处理。
实际上连续抓取在实现上就是循环单次抓取,只是需要单独开辟线程来实现。
2、实时刷图线程
1)开启线程:
HANDLE hThreadControl = ::CreateThread(NULL, 0, ThreadControl, (LPVOID)this, 0, 0);
2)线程实现:
while(1)
{
m_Camera.SingleGrab();
set_part(m_hHalconWnd, 0 0, 480-1, 640-1);
disp_obj(m_ImageThreadBuf, m_hHalconWnd);
}
3)变量说明:
m_Camera相机对象,用于封装SingleGrab()单帧抓取函数,后面有描述;
m_hHalconWnd窗口句柄,类型Htuple;
m_ImageThreadBuf图像数据,类型Hobject;
3、单帧抓取原理
1)抓包图像处理回调函数
int WINAPI CCameraDlg::ImageProcess(void *pWebCamera)
{
CCameraDlg* pThis = (CCameraDlg*)pVoid; //回调函数属于静态函数,采用全局变量的方式获取对象指针
gen_image1(&(pThis->m_ImageThread), "byte", 640, 480,
(long)((WebCamera *)pWebCamera)->pFrame->DataBuffer);//获取一幅图片
EnterCriticalSection(&(pThis->m_Camera.m_cCriticalSection));//关键代码段保护
//如果需要单帧抓取,则拷贝一份图片出来
if(TRUE == pThis->m_Camera.m_bIsSingleGrabRequire)
{
pThis->m_Camera.m_bIsSingleGrabRequire = FALSE;
copy_image(pThis->m_ImageThread, &(pThis->m_ImageThreadBuf));
SetEvent(pThis->m_Camera.m_hEvernt); //事件通知拷贝完成
}
LeaveCriticalSection(&(pThis->m_Camera.m_cCriticalSection));
return 1;
}
2)单帧抓取需求函数
void SingleGrab()
{
EnterCriticalSection(&m_cCriticalSection));//关键代码段保护
m_bIsSingleGrabRequire = TRUE;//修改抓图需求标志
LeaveCriticalSection(&m_cCriticalSection));
WaitForSingleObject(m_hEvent, INFINIE);//等待事件通知
return;
}
4、单帧抓取函数冲突
当主线程和子线程同时调用SingleGrab单帧抓取函数时,会存在冲突。
实际上,这种情况经常出现。比如,在子线程中进行连续采图(实时显示)时,
主线程中有单帧抓取需求(图像处理)。
解决这个问题可以采用再开辟一段图像缓存,将连续采图和单帧采图的图像缓冲和
需求标志分离,各自独立,从而解决该冲突。
5、显示窗口绑定
1)halcon显示窗口绑定代码:
CRect rect;
GetDlgItem(IDC_IMAGE_FRAME)->GetWindowRect(rect); //获取窗口大小
open_window(0,0,rect.Width()-1,rect.Height()-1,(Hlong)(GetDlgItem(IDC_IMAGE_FRAME)->mWnd),"visible","",&m_hHalconWnd);
2)参数说明
IDC_IMAGE_FRAME 控件资源号 可以选择picture control控件;
m_hHalconWnd窗口句柄,类型Htuple;