1.使用向导创建基于对话框的应用程序。
2.环境变量设置,这步只要配置一次就可以。具体可以参加相关文章。
3.添加附加库halconcpp.lib,project->properties->configuration
properties->linker->Input->Additional
dependecies后面添加。
4.添加头文件和命名空间
在***Dlg.h头文件中添加如下的头文件和命名空间:
#include
"halconcpp.h"
using
namespace
Halcon;
5.创建halcon显示窗口
5.1定义窗口句柄(在***Dlg.h头文件中添加):HTuple
m_HWindowID
5.2添加初始化窗口函数(在***Dlg.h头文件中添加):public:void
InitHalconWindow();
5.3在对话框窗口添加一Picture控件,ID为:IDC_PIC_HWINDOW,用于显示图像。
5.4实例化初始化窗口函数(在***Dlg.cpp文件中添加),如下所示:
void C***Dlg::InitHalconWindow()
{
//定义显示的起点和长宽高
HTuple
HWindowRow,HWindowColumn,HWindowWidth,HWindowHeight;
//定义窗口ID
HTuple
HWindowID;
//定义一个CRect类的对象,用于获取图像框的尺寸和位置
CRect
Rect;
CWnd
*pWnd =
GetDlgItem(IDC_PIC_HWINDOW);
CDC
*pDC =
pWnd->GetDC();
pWnd->GetWindowRect(&Rect);
//设置显示窗口的起点和宽高
HWindowRow
= 0;
HWindowColumn
= 0;
HWindowWidth
= Rect.Width();
HWindowHeight
= Rect.Height();
//设定固定的窗口大小,而不是根据控件大小设定
//GetDlgItem(IDC_PIC_HWINDOW)->SetWindowPos(NULL,0,0,322,242,SWP_NOZORDER
| SWP_NOMOVE);
try
{
set_window_attr("border_width",0);
//获取当前窗口指针
HWindowID
= (Hlong)pWnd->m_hWnd;
set_check("~father");
open_window(HWindowRow,HWindowColumn,HWindowWidth,HWindowHeight,HWindowID,"visible","",&m_HWindowID);
set_check("father");
//设置显示模式是margin(边缘)
set_draw(m_HWindowID,"margin");
}
catch
(HException&
except)
{
TRACE(except.message);
}
}
然后把此函数放到程序的初始化函数中(即放到OnInitDialog()函数中),之后程序运行就可以打开窗口,窗口句柄为m_HWindowID。
6添加打开相机的函数
6.1定义相机句柄和图像的宽高(在***Dlg.h头文件中添加):HTuple
m_FGHandle,m_ImageWidth, m_ImageHeight;
6.2定义打开相机函数(在***Dlg.h头文件中添加):void
OpenCam(CString strCamDrv);
6.3打开相机的函数实例化(在***Dlg.cpp文件中添加),如下所示:
void C***Dlg::OpenCam()
{
try
{
//根据使用的相机,选择合适的参数
open_framegrabber("DirectShow",
1, 1,
0, 0,
0, 0,
"default", 8, "rgb",
-1,
"false", "default", "USB
视频设备", 0, -1, &m_FGHandle);
//设置相机参数的一些算子
//……
//打开异步采集
grab_image_start(m_FGHandle,
-1);
//采集一副图像
grab_image_async(&m_LiveImage,
m_FGHandle, -1);
//得到图像的宽高和指针
get_image_pointer1(m_LiveImage,
NULL, NULL, &m_ImageWidth, &m_ImageHeight);
//使图像显示适应窗口大小
set_part(m_HWindowID,
0, 0,
m_ImageHeight - 1, m_ImageWidth -1);
}
catch
(HException&
except)
{
TRACE(except.message);
}
}
然后把此函数放到程序的初始化函数中(即放到OnInitDialog()函数中),之后程序运行就可以打开相机,相机句柄为m_FGHandle。当然也可以放到其他合适的地方。
7添加线程函数,用于实时采集图像和处理
7.1定义:添加线程布尔变量、线程句柄、事件和ID
//是否采集布尔变量
BOOL
m_bStartSnap;
//线程句柄和事件
HANDLE
m_hSnapHandle, m_hEvent;
//线程ID
DWORD
m_dwThreadID;
//定义采集到的图像对象
Hobject
m_LiveImage;
//定义线程函数
Static
DWORD CALLBACK SnapThread(LPVOID lpParam);
7.2添加线程体函数如下:
DWORD WINAPI C***Dlg::SnapThread(LPVOID lpParam)
{
CGrabberDlg
*pDlg =
(C***Dlg *)AfxGetApp()->m_pMainWnd;
Hobject
SymbolRegions;
try
{
while
(pDlg->m_bStartSnap)
{
//抓取图像
grab_image(&pDlg->m_LiveImage,pDlg->m_FGHandle);
//窗口中显示图像
disp_obj(pDlg->m_LiveImage,
pDlg->m_HWindowID);
if
(pDlg->m_bStartInc)
{
//处理采集的图像
{
pDlg->BarCodeInc(pDlg->m_LiveImage);
}
}
}
}
catch
(HException&
except)
{
TRACE(except.message);
}
return
0;
}
7.3添加按钮创建线程,在.2中描述了创建线程体函数的过程,这一段主要描述怎样创建线程,上.2中的线程体函数开始运行。
在OnInitDialog()初始化函数中初始化采集图像的布尔变量,m_bStartSnap =
FALSE;
在对画框中添加一个按钮,ID为:IDC_BUTTON_STARTSNAP,名称为开始采集。为此按钮添加事件如下:
void C***Dlg::OnBnClickedButtonStartsnap()
{
//
TODO: Add your control notification handler code here
DWORD
dwExit = 0;
MSG
msg;
if
(!m_bStartSnap)
{
//采集图像的布尔变量为TRUE
m_bStartSnap
= TRUE;
m_hEvent
=
CreateEvent(NULL,TRUE,FALSE,NULL);
//创建线程
m_hSnapHandle=CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)SnapThread, m_hEvent, 0, &m_dwThreadID);
SetEvent(m_hEvent);
}
else
{
m_bStartSnap
= FALSE;
do
{
Sleep(1);
GetExitCodeThread(m_hSnapHandle,
&dwExit);
if
(::PeekMessage(&msg, NULL, 0, 0,
PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}while(dwExit
== STILL_ACTIVE);
//关闭线程和事件
CloseHandle(m_hEvent);
CloseHandle(m_hSnapHandle);
}
}
完成以上七步以后,运行程序,点击开始采集按钮,如果连接上相机的话此时在窗口中会实时显示采集到的图像。
8添加烟盒一维条码识别程序。
把编写好的Hdev程序导出CPP文件,从cpp文件中找出我们需要部分,添加到程序中。
8.1定义条码识别的各种变量,包括条码句柄、条码类型和识别的条码结果。
HTuple
m_BarCodeHandle, m_CodeTypes,
m_DecodedDataStrings;
8.2在OnInitDialog()初始化函数中创建条码句柄和设置条码类型,如下所示:
create_bar_code_model(HTuple(),
HTuple(), &m_BarCodeHandle);
m_CodeTypes
= "auto";
8.3添加条码识别函数
定义://条码识别函数
void BarCodeInc(Hobject
Image);
实例化该函数的代码如下:
void C***Dlg::BarCodeInc(Hobject Image)
{
Hobject
SymbolRegions;
try
{
//在图像中找到条码并进行识别
//find_bar_code(Image,
&SymbolRegions, m_BarCodeHandle, m_CodeTypes,
&m_DecodedDataStrings);
//设置条码的显示位置
//set_tposition(m_HWindowID2,
24, 12);
//在窗口的相应位置显示是别的条码数据
//write_string(m_HWindowID,
"条码:"+m_DecodedDataStrings);
//用于测试
threshold(Image,&SymbolRegions,0,125);
disp_obj(SymbolRegions,m_HWindowID);
}
catch
(HException&
except)
{
TRACE(except.message);
}
}
8.4在对话框界面中添加一个按钮控件,ID为:
IDC_BUTTON_STARTINC,名称为:开始检测
双击此按钮控件添加一个消息响应函数:void
C***Dlg::OnBnClickedButtonStartinc()
定义:在***Dlg.h中添加一个是否开始检测的布尔变量:BOOL
m_bStartInc,并在OnInitDialog()初始化函数中把布尔变量设置为: bStartInc =
FALSE;
在OnBnClickedButtonStartinc()函数中添加如下内容:
void CGrabberDlg::OnBnClickedButtonStartinc()
{
//
TODO: Add your control notification handler code here
if
(!m_bStartInc)
{
m_bStartInc
= TRUE;
}
else
{
m_bStartInc
= FALSE;
}
}
8.5在SnapThread(LPVOID
lpParam)函数中添加如下内容:
if
(pDlg->m_bStartInc)
{
//处理采集的图像
{
pDlg->BarCodeInc(pDlg->m_LiveImage);
}
}nbsp;//定义窗口ID
&//定义一个CRect类的对象,用于获取图像框的尺寸和位置
&
&*pWnd = GetDlgItem(IDC_PIC_HWINDOW);
&*pDC = pWnd-&GetDC();
|