MFC调用HALCON实现相机采图和图像显示

一、相机采图

1、查询设备信息

HTuple Information, Values;

info_framegrabber("GigEVision", "device", &Information, &Values);

Information用来获取相机信息

Values用来获取相机名称


2、打开相机

HTuple m_hFrameGrabber; //相机句柄

open_framegrabber("GigEVision",0,0,0,0,0,0,"progressive",-1,"default",

-1,"false","default",Values[0],0,-1,&m_hFrameGrabber);

打开第二个相机

open_framegrabber("GigEVision",0,0,0,0,0,0,"progressive",-1,"default",

-1,"false","default",Values[1],0,-1,&m_hFrameGrabber);

注意相机名的调用方法。


3、获取相机参数

HTuple m_ImageWidth;

get_framegrabber_param(m_hFrameGrabber,"m_ImageWidth",&m_ImageWidth);


4、单帧抓取

Hobject * pImage; //图片指针

grab_image(pImage,m_hFrameGrabber);

由于grab_image函数不能中断执行,因此在多线程中调用时,需要注意对它的原子保护。


5、关闭相机

close_framegrabber(m_hFrameGrabber);



二、图像显示

1、抓取单帧图像

m_Camera.SingleGrab(GetImage());

2、显示图片

CHalconBase::uShowImageOrSize(GetMyHalconWnd(),GetImage());

注:

1)获取显示窗口句柄GetMyHalconWnd()

2)获取图片指针GetImage()

3)显示函数原型

void CHalconBase::uShowImageOrSize(HTuple* WindowsHandle,Hobject* obj)

{

if(NULL == WindowsHandle || NULL ==obj)return;

else

{

if((long*)1 == obj->Id())return;

Hlong Width,Height;

get_image_size(*obj,&Width,&Height);

set_part(*WindowHandle,0,0,Height-1,Width-1);

disp_obj(*obj,*WindowsHandle);

}

}


三、模板选取
1)图像选取操作
stDoubleRect CHalconBase::uDrawRectangle(HTuple* WindowHandle,char* strColor)
{
uSetColor(WindowHandle,strColor); //颜色选取
stDoubleRect m_stTempRect;
//画矩形
Halcon::draw_rectangle1(*WindowHandle,&(m_stTempRect.Row1),&(m_stTempRect.Col1),
&(m_stTempRect.Row2 ),&(m_stTempRect.Col2 ));
return m_stTempRect;
}
//生成矩形框
gen_rectangle1();
//颜色变更并显示
set_color(*WinowHandle,strColorObj);
disp_opj(*obj,*WinowHandle);

出现问题:
矩形框不能正常画出。

问题原因:
图像拷贝出现问题,图片不能简单赋值,需要调用copy_image。

2)相机实时采图显示
相机采图和相机显示可以采用两个独立的线程来分别处理,可以提高执行效率。
但是需要注意,图像缓存,如果两个线程同时去处理共享存储区,会出现不一些
不可预知的问题,比如halcon图像显示函数disp_obj()会卡死,或者disp_obj操作
会报存储空间不够的错误。

问题解决:
可以采用采图线程主动询问的方式,当采图线程才到一幅图后,去查询如果需要
显示采图线程可以主动拷贝一份图片到显示线程的图片操作缓冲(即图片拷贝),这样
就避免了两个线程同时同一片共享存储区的问题。

3)实时刷图线程
实时刷图线程需要做的工作就是抓取一幅图和显示一幅图。但是抓图要考虑对图像缓冲区
的多线程操作保护,实际在处理方式上是设置标志位,被动获取。

遇到问题:
刷图线程如果在显示图片即调用disp_obj(),如果主线程也进如刷图函数段disp_obj()或者
窗口绑定函数段open_window(),会发生卡死的情况。

问题解决:
1、降低刷图线程刷图频率,比如抓10次图才显示一次。
2、停掉实时刷图线程,注意停掉的方式,不能采用挂起的方式,这样线程中断的位置不确定,
可能在不允许中断的位置中断了,比如正在写图像缓冲的时候;可以采用线程状态标识判断的
方式,每天线程执行完一遍都会判断线程状态,如果是空闲态,改线程将空跑,不去执行实际
内容。采用这种方式将刷图线程停掉。
3、采图线程不采用被动等待标志查寻的方式,可以采用等待事件通知的方式。因为前者容易
造成共享标志位频繁访问。


你可能感兴趣的:(MFC调用HALCON实现相机采图和图像显示)