26、.NET与Halcon混合编程(1)
HWindowXCtrl与HWindowControl都是Haocon提供的用于显示图像的交互式控件,但它们功能上也存在一些明显的差异。它们区别如下:
⑴、引用文件(dll)不同
HWindowXCtrl引用来自:halconx.dll(默认路径C:\Program Files\MVTec\HALCON-10.0\bin\x86sse2-win32\halconx.dll)
HWindowControl引用来自:dotnet35.dll(默认路径C:\Program Files\MVTec\HALCON-10.0\bin\dotnet35)
⑵、功能
HWindowXCtrl控件缺少一些重要有用的事件如HMouseWheel(鼠标中键滚轮滑动,用于缩放图像)
HWindowControl拥有较齐全的事件。
说明:.NET中优先使用HWindowControl,而HWindowXCtrl可用于MFC中(但MFC中也不常用HWindowXCtrl控件,MFC显示图像常用picturebox)下面介绍 HWindowControl控件的使用方法
一、处理图像并准备vb.net代码
- 在HDevelop中处理图像:
read_image (Image12, 'C:/12.jpg')
*把彩色图转换为灰度图
rgb1_to_gray (Image12, GrayImage)
*显式关闭窗口
dev_close_window ()
*显式打开窗口
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
*显式调用显示图像
dev_display (GrayImage)
2、从halcon导出VB.NET代码:
3、导出的代码:
'
' File generated by HDevelop for HALCON/DOTNET (Visual Basic .NET) Version 10.0
'
Option Strict Off
Option Explicit
Imports HalconDotNet
Imports System
Imports Microsoft.VisualBasic
Module Daochu
' Main procedure
Private Sub action()
' Local iconic variables
Dim ho_Image12 As HObject = Nothing, ho_GrayImage As HObject = Nothing
' Local control variables
Dim hv_WindowHandle As HTuple = Nothing
' Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(ho_Image12)
HOperatorSet.GenEmptyObj(ho_GrayImage)
ho_Image12.Dispose()
HOperatorSet.ReadImage(ho_Image12, new HTuple("C:/12.jpg"))
'把彩色图转换为灰度图
ho_GrayImage.Dispose()
HOperatorSet.Rgb1ToGray(ho_Image12, ho_GrayImage)
'显式关闭窗口
If (HDevWindowStack.IsOpen()) Then
HOperatorSet.CloseWindow(HDevWindowStack.Pop())
End If
'显式打开窗口
HOperatorSet.SetWindowAttr("background_color",new HTuple("black"))
HOperatorSet.OpenWindow(new HTuple(0),new HTuple(0),new HTuple(512),new HTuple(512),0,"","",hv_WindowHandle)
HDevWindowStack.Push(hv_WindowHandle)
'显式调用显示图像
If (HDevWindowStack.IsOpen()) Then
HOperatorSet.DispObj(ho_GrayImage, HDevWindowStack.GetActive())
End If
ho_Image12.Dispose()
ho_GrayImage.Dispose()
End Sub
#If Not NO_EXPORT_APP_MAIN Then
Sub InitHalcon()
' Default settings used in HDevelop
Call HOperatorSet.SetSystem(New HTuple("do_low_error"), New HTuple("false"))
End Sub
Sub Main(ByVal args() As String)
Call InitHalcon()
Call action()
End Sub
#End If
End Module
二、把控件添加到界面上
1、从工具箱中添加控件:
选择项---在.NET Framework组件选项卡----浏览---- 添加C:\Program Files\MVTec\HALCON-10.0\bin目录下的dotnet35.dll
2、拖拽控件到界面上:
注:添加该控件后,新增以下选中的引用。
三、根据实际需要把导出代码复制到vb.net工程上
1、在vb.net工程上调用调用action()函数
把导出代码中的action()函数和相应的命名空间复制到vb.net工程中,并在button控件的响应函数
中调用action()函数
Imports HalconDotNet
Imports System
Imports Microsoft.VisualBasic
Public Class Form1
Private Sub action()
' Local iconic variables
Dim ho_Image12 As HObject = Nothing, ho_GrayImage As HObject = Nothing
' Local control variables
Dim hv_WindowHandle As HTuple = Nothing
' Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(ho_Image12)
HOperatorSet.GenEmptyObj(ho_GrayImage)
ho_Image12.Dispose()
HOperatorSet.ReadImage(ho_Image12, New HTuple("C:/12.jpg"))
'把彩色图转换为灰度图
ho_GrayImage.Dispose()
HOperatorSet.Rgb1ToGray(ho_Image12, ho_GrayImage)
'显式关闭窗口
If (HDevWindowStack.IsOpen()) Then
HOperatorSet.CloseWindow(HDevWindowStack.Pop())
End If
'显式打开窗口
HOperatorSet.SetWindowAttr("background_color", New HTuple("black"))
HOperatorSet.OpenWindow(New HTuple(0), New HTuple(0), New HTuple(512), New HTuple(512), 0, "", "", hv_WindowHandle)
HDevWindowStack.Push(hv_WindowHandle)
'显式调用显示图像
If (HDevWindowStack.IsOpen()) Then
HOperatorSet.DispObj(ho_GrayImage, HDevWindowStack.GetActive())
End If
ho_Image12.Dispose()
ho_GrayImage.Dispose()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
action()
End Sub
End Class
- 运行程序:
提示错误:无法加载 DLL"halcon": 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。
- 解决办法:
把halcon安装目录(C:\Program Files\MVTec\HALCON-10.0\bin\x86sse2-win32)下的halcon.dll复制到vb.net工程的目录下(…..\bin\Debug,即跟可执行文件.exe同一个文件夹)或复制到C:\Windows\System32路径下。
- 再次运行效果:
五、改进
从上面的效果看出,这并不是我们想要的结果,因为在程序显示图像的代码为:
HOperatorSet.DispObj(ho_GrayImage, HDevWindowStack.GetActive())
可以看出,它是把ho_Image12图像显示到由
HOperatorSet.OpenWindow(New HTuple(0), New HTuple(0), New HTuple(512), New HTuple(512),
0, "", "", hv_WindowHandle)
HDevWindowStack.Push(hv_WindowHandle)
创建的窗口句柄HDevWindowStack.GetActive()的窗口上。
- 改进方法:把action()函数修改为一下形式
原理:获取HWindowControl1的句柄,并通过句柄把图像显示到该控件上。修改了'********内部分
Imports HalconDotNet
Imports System
Imports Microsoft.VisualBasic
Public Class Form1
Private Sub action()
' Local iconic variables
Dim ho_Image12 As HObject = Nothing, ho_GrayImage As HObject = Nothing
' Local control variables
Dim hv_WindowHandle As HTuple = Nothing
' Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(ho_Image12)
HOperatorSet.GenEmptyObj(ho_GrayImage)
ho_Image12.Dispose()
HOperatorSet.ReadImage(ho_Image12, New HTuple("C:/12.jpg"))
'把彩色图转换为灰度图
ho_GrayImage.Dispose()
HOperatorSet.Rgb1ToGray(ho_Image12, ho_GrayImage)
'*****************************************************************************
'把用于显示图像的句柄设置为HWindowControl1控件的句柄
hv_WindowHandle = HWindowControl1.HalconWindow
'适应控件大小显示图像
Dim hv_Width, hv_Height As HTuple
HOperatorSet.GetImageSize(ho_GrayImage, hv_Width, hv_Height)
HOperatorSet.SetPart(hv_WindowHandle, 0, 0, hv_Height, hv_Width) '适应窗口显示
'显示图像
HOperatorSet.DispObj(ho_GrayImage, hv_WindowHandle)
'*****************************************************************************
ho_Image12.Dispose()
ho_GrayImage.Dispose()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
action()
End Sub
End Class
- 效果:
六、实现交互式绘制
在工程实际需要中,交互绘制一个region或绘制一个圆形、矩形等是非常重要的,如在定位中减少模板定义域就可以用鼠标绘制区域来实现。HWindowControl控件本身就有这个动能,在程序中调用DrawRegion(out HalconDotNet.HObject region, HalconDotNet.HTuple windowHandle)算子即可。
Private Sub Button2_Click(………………..) Handles Button2.Click
HWindowControl1.Focus()
Dim region As HObject = Nothing
Dim out_img As HObject = Nothing
HOperatorSet.SetColor(hv_WindowHandle, New HTuple("yellow"))
HOperatorSet.DrawRegion(region, hv_WindowHandle)
HOperatorSet.ReduceDomain(ho_GrayImage, region, out_img)
HOperatorSet.ClearWindow(hv_WindowHandle)
HOperatorSet.DispObj(out_img, hv_WindowHandle)
End Sub
效果:
鼠标左键绘制区域
右键单击确定: