在机器视觉领域,德国MVTec公司出品的视觉开发软件Halcon可谓无人不知,无人不晓,相比与其他轻量级的视觉开发包,Halcon提供了很多具有工业强度的图像识别算法,性能优越,是机器视觉开发首先。最新版为Halcon 12,提供C/C++,.Net等接口,可以非常方便用户将Halcon中的图像算法植入到自己的应用程序中来。
很早以前就打算深入研究一下Halcon机器视觉开发了,利用工作之余,捣鼓了一下,稍微试用了一下,立刻体会到,果真这个软件不是一般的牛逼,对于很多不是计算机图像专业出生的工程师来说,终于可以从晦涩难懂的高等代数与微积分,以及各种矩阵方程中解脱出来,让你不必了解图像处理理论,直接处理业务核心逻辑,极大的缩短了机器视觉的开发周期。本文以微软VS2010中使用MFC开发基于Halcon11的机器视觉应用为例,为很多像我一样的初学者做登堂入室的垫脚石。闲话少说,详见下文所述。
首先,在VS2010中使用MFC配置Halcon11,这一步虽然简单,但有很多初学者在迈出这第一步的时候就碰了一鼻子灰,无论怎么配置,程序就是编译通不过。不要着急,请仔细看好了。以基于对话框的MFC应用程序为例。
第一步,建立MFC应用程序,给工程取个名字叫HalconFirstStep,如下图所示:
第二步,选择基于对话框的应用程序,如下图所示:
第三步:在本例中,我们在对话框中,添加两个按钮,一个按钮用来加载图片,一个用来处理图片,如下所示:
第四步:我们在菜单栏找到”Project“ -> "HalconFirstStep Properties...",在弹出的对话中中,选择左边窗口选择VC++ Directories, 在右边窗口中选择Include Directories,添加Halcon的头文件路径,这个视Halcon的安装路径不同而不同,也许你电脑上的安装路径和下图中显示的有所出入。头文件路径包含两个路径,一个指定Halcon的Include文件夹位置,一个指定Include文件夹下CPP的位置。如下图所示:
第五步:还是在左边窗口选择VC++ Directories, 在右边窗口中选择Library Directories,添加Halcon的lib文件路径,如下图所示:
第六步:在左边窗口中选择C/C++, 在下拉树形列表中选择General,在窗口右边选择Additional Include Directories,配置Halcon头文件所在路径。如下图所示:
第七步:在窗口左边Linker下选择General,在窗口右边选择Addtional Library Directories,配置Halcon库文件所在路径,如下图所示:
第八步: 在左边窗口的Linker下选择Input,在右边窗口中选择Additional Dependencies 输入Halconcpp.lib。如下图所示:
在这一步需要注意的是,如果你安装的是Halcon的版本号是11.0.0.1的话,这里Additional Dependencies 输入的应该是halconcpp10.lib。这是因为11.0.0.1实际上仍然使用的是Halcon10所用的静态链接库。Halcon 11.0.0.1其实并不是真正意义的11.0版本。很多初学者,在安装了Halcon11.0.0.1版本后,参考网上的配置方法,程序编译时死活说找不到符号。多半都是卡在这里。笔者就被这个问题折磨了两天。
经过以上八步,恭喜你,VS 2010配置Halcon 11算是大功告成。接下来就是好戏上演的时刻了,我们要开始编代码来演示我们的例子了。
第九步:在HalconFirstStepDlg.h 文件开始处,添加代码:
#include "halconcpp.h"
using namespace Halcon;
第十步:我们在HalconFirstStepDlg.cpp文件中,添加一个全局变量来存储打开的图片。
Hobject img;
void CHalconFisrtStepDlg::OnBnClickedButton1()
{
//获取图像窗口父窗口句柄
CRect rect;
HWND hwnd = GetDlgItem(IDC_STATIC1)->m_hWnd;
GetDlgItem(IDC_STATIC1)->GetWindowRect(&rect);
//打开图像窗口
Hlong windowId;
open_window(0,0,rect.Width(),rect.Height(),(Hlong)hwnd,"visible","",&windowId);
//将图像读入内存
read_image(&img,"mreut");
//获取图像大小
HTuple width,height;
get_image_size(img,&width,&height);
//按照比例缩放到图像窗口
set_part(windowId,0,0,width,height);
//显示图像
disp_obj(img,windowId);
}
在这幅卫星图片中,我们的目的是,找出公路所在区域,并把它用红色标记出来。从这幅图片的特征我们不难看出,公路与周围草坪的颜色反差很大,草坪和公路颜色泾渭分明,所以,我们对图像进行二值化处理,区域灰度在阈值以下的全部变黑,区域灰度在阈值以上的全部变白,只留下阈值范围内的区域。然后联通所有存在的区域,并选择其中最大的区域。有了这样的思路,我们就可以给按钮“图像处理”单击事件添加下面的代码:
void CHalconFisrtStepDlg::OnBnClickedButton2()
{
//获取图像窗口父窗口句柄
CRect rect;
HWND hwnd = GetDlgItem(IDC_STATIC2)->m_hWnd;
GetDlgItem(IDC_STATIC2)->GetWindowRect(&rect);
//打开图像窗口
Hlong windowId;
open_window(0,0,rect.Width(),rect.Height(),(Hlong)hwnd,"visible","",&windowId);
//获取图像大小
HTuple width,height;
get_image_size(img,&width,&height);
//按照比例缩放到图像窗口
set_part(windowId,0,0,width,height);
//显示图像
disp_obj(img,windowId);
Hobject BrightRegion,ConnectedRegion,SelectedRegion;
//将图像二值化,设定阈值下限为180,上限为255
threshold(img,&BrightRegion,188,255);
//连通阈值范围内明亮区域
connection(BrightRegion,&ConnectedRegion);
//选择连通区域内面积最大的区域
select_shape_std(ConnectedRegion,&SelectedRegion,"max_area",0);
//设定选择区域的颜色为红色
set_color(windowId,"red");
//显示选择区域
disp_obj(SelectedRegion,windowId);
}
要转载本文,请注明出处,尊重知识产权。