HSmartWindowControl 之 显示图像
概述:使用Halcon在VS中的控件显示一张图片。
要点:使用了图像缩放和图像显示函数,以及鼠标滚轮响应函数。
1、创建WinForm项目
首先在VS中添加Halcon所需的控件HSmartWindowControl,参考上一篇:HSmartWindowControl之安装篇 (Visual Studio 2013 & Halcon 18)https://www.cnblogs.com/oucsheep/p/9563876.html
然后创建新的winForm工程,并向窗体中拖入一个HSmartWindowControl控件和两个按钮控件。

拖入后不添加代码,直接运行,可能会出现如下错误:
HalconDotNet.HHandleBase 的类型初始化值设定项引发异常

Halcon error #2381:License is for wrong edition of Halcon in Operator set_system

原因是halcon运行库是64位的,vs的运行模式也需要设置为64位,默认的debug模式可能是any CPU,需要把这里修改成x64。

或者从解决方案资源管理器(solution Explorer)中双击打开属性(Property)页面,把Build栏的Platform target 改为x64即可。

2、创建Halcon实时显示代码并导出
打开halcon,写一句简单的代码

接着,选择文件->导出,将HDevelop语言导出为C#语言。

3、halcon 导出的C#代码分析
using System;
using HalconDotNet; public partial class HDevelopExport
{
public HTuple hv_ExpDefaultWinHandle; // Main procedure
private void action()
{
// Local iconic variables
HObject ho_Image;
// Local control variables
HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Image);
ho_Image.Dispose();
HOperatorSet.ReadImage(out ho_Image, "printer_chip/printer_chip_01");
hv_Width.Dispose();hv_Height.Dispose();
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
ho_Image.Dispose(); hv_Width.Dispose();
hv_Height.Dispose();
} public void InitHalcon()
{
// Default settings used in HDevelop
HOperatorSet.SetSystem("width", 512);
HOperatorSet.SetSystem("height", 512);
} public void RunHalcon(HTuple Window)
{
hv_ExpDefaultWinHandle = Window;
action();
}
}
实际有用的代码就是action()内的代码,首先声明了图像变量:HObject ho_Image;
需要注意的是,图像类型需要先初始化再使用:HOperatorSet.GenEmptyObj(out ho_Image);
然后调用ReadImage函数读入图像文件,最后调用Dispose函数清空对象。但是没有显示图像的代码,需要自己添加。
4、向VS中插入代码
打开Winform工程窗体关联的cs文件Form1.cs,首先需要在文件头部添加命名空间引用:
using HalconDotNet;
需要在类中定义全局的窗口变量,便于操作窗体:
private static HWindow hwindow; //全局窗口变量
public HTuple hv_ExpDefaultWinHandle; //导出的代码定义的,其实没用到
窗口的初始化函数中添加全局变量的初始化函数:
public Form1()
{
InitializeComponent();
hwindow = hSmartWindowControl1.HalconWindow;//初始化窗口变量
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.my_MouseWheel);
}
然后在按钮的响应函数中添加载入图像的及显示的代码:
private void button2_Click(object sender, EventArgs e)
{
#region 初始化变量
// Local iconic variables
HObject ho_Image;
// Local control variables
HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Image);
ho_Image.Dispose();
HOperatorSet.ReadImage(out ho_Image, "clip.png");
hv_Width.Dispose(); hv_Height.Dispose();
#endregion #region 缩放图像,适应窗口
bool needResizeImage = true;
//获取图像大小及纵横比
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
int im_width = int.Parse(hv_Width.ToString());
int im_height = int.Parse(hv_Height.ToString());
double im_AspectRatio = (double)(im_width)/(double)(im_height);
//获取窗口大小及纵横比
int w_width = hSmartWindowControl1.Size.Width;
int w_height = hSmartWindowControl1.Size.Height;
double w_AspectRatio = (double)(w_width)/(double)(w_height); HOperatorSet.SetSystem("int_zooming", "false");//图像缩放之前最好将此参数设置为false.
HTuple para = new HTuple("constant");
HObject ho_zoomImage;
HOperatorSet.GenEmptyObj(out ho_zoomImage); ho_zoomImage.Dispose();
if(w_width<im_width && im_AspectRatio>w_AspectRatio)
{
//超宽图像
HOperatorSet.ZoomImageSize(ho_Image, out ho_zoomImage, w_width, w_width / im_AspectRatio, para);
}
else if (w_height < im_height && im_AspectRatio < w_AspectRatio)
{
//超高图像
HOperatorSet.ZoomImageSize(ho_Image, out ho_zoomImage, w_height * im_AspectRatio, w_height, para);
}
else
{
needResizeImage = false;
}
#endregion #region 显示图像
hwindow.SetPart(0, 0, -2, -2);
if (needResizeImage)
{
hwindow.DispObj(ho_zoomImage);
}
else
{
hwindow.DispObj(ho_Image);
}
//HOperatorSet.GetImageSize(ho_zoomImage, out hv_Width, out hv_Height);
//im_width = int.Parse(hv_Width.ToString());
//im_height = int.Parse(hv_Height.ToString());
//MessageBox.Show(hv_Width.ToString() + " " + hv_Height.ToString());
#endregion
ho_Image.Dispose();
ho_zoomImage.Dispose();
hv_Width.Dispose();
hv_Height.Dispose();
}
5、图像缩放和显示
这里我对导出的代码做了修改,主要是增加了图像缩放和显示功能。
图像缩放使用了ZoomImageSize函数,在帮助文档中,这个函数有两种用法:
static void HOperatorSet.ZoomImageSize(HObject image, out HObject imageZoom, HTuple width,HTuple height, HTuple interpolation) HImage HImage.ZoomImageSize(int width, int height, string interpolation)
上面的代码中使用了第一种用法,所有的参数必须是Halcon的类型,但是实际使用时width 和height 可以用int类型,interpolation即差值算法参数也可以直接传入string类型,如“constant”。
第二种方法需要将使用HImage类型的变量来操作,所以需要将 HObject 类型定义的图像变量转换一下:
HImage img = new HImage(ho_Image);
ho_zoomImage = img.ZoomImageSize(w_width, w_width, "constant");
图像显示功能:先调用SetPart函数确定要显示图像的区域,然后调用DispObj函数显示图像,DispObj也有三种用法:
static void HOperatorSet.DispObj(HObject objectVal, HTuple windowHandle) void HObject.DispObj(HWindow windowHandle) void HWindow.DispObj(HObject objectVal)
此处我用的第三种:通过Hwindow调用,参数为要显示的图像变量。
hwindow.SetPart(0, 0, -2, -2);
hwindow.DispObj(ho_zoomImage);
6、SmartWindowControl窗口交互
前面实现了图像显示,SmartWindowControl最大的亮点其实是方便的交互功能。
可以用鼠标拖动图像水平移动,利用鼠标滚轮实现图像放大缩小。
另外,在winForm项目中,为了使用SmartWindowControl控件中图像的缩放,还需要添加鼠标滚轮响应的回调函数。详见:C:/Program Files/MVTec/HALCON-18.05-Progress/doc/html/manuals/programmers_guide/programmers_guide_0051.html

实际测试发现帮助文档中的用法有一些问题,消息相应函数的注册应该在整个窗体的初始化函数中,而不是SmartWindowControl的初始化函数中。
private void hSmartWindowControl1_Load(object sender, EventArgs e)
{
//这句话不起作用
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.my_MouseWheel);
}
public Form1()
{
InitializeComponent();
hwindow = hSmartWindowControl1.HalconWindow;//初始化窗口变量
// 鼠标滚轮的响应函数注册
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.my_MouseWheel);
}
这样修改后,直接使用帮助文档中提供的my_MouseWheel也有一个小bug,就是无论在窗体的任何位置滑动滚轮,图片都会缩放,所以需要对鼠标的位置做一下限制:
private void my_MouseWheel(object sender, MouseEventArgs e)
{
System.Drawing.Point pt = this.Location;
int leftBorder = hSmartWindowControl1.Location.X;
int rightBorder = hSmartWindowControl1.Location.X + hSmartWindowControl1.Size.Width;
int topBorder = hSmartWindowControl1.Location.Y;
int bottomBorder = hSmartWindowControl1.Location.Y + hSmartWindowControl1.Size.Height;
if(e.X > leftBorder && e.X < rightBorder && e.Y > topBorder && e.Y < bottomBorder)
{
MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks,
e.X - pt.X, e.Y - pt.Y, e.Delta);
hSmartWindowControl1.HSmartWindowControl_MouseWheel(sender, newe);
}
}
HSmartWindowControl 之 显示图像的更多相关文章
- HSmartWindowControl 之 摄像头实时显示( 使用 WPF )
1.添加Halcon控件,创建WPF项目 在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见: HSmartWindowControl之安装篇 (Visual Studio ...
- VS2010+Qt+OpenCv(显示图像)
Qt在界面显示窗口中起着越来越重要的作用,从而了解了下如何在Qt中显示一副图像. 该小程序主要注意一下几点: 1.工程属性中设置OpenCV的环境(包含目录和库目录,以及附加依赖项),设置Qt的环境( ...
- LCD如何显示图像
1.LCD显示主要相关概念 (1)像素(pixel) 整个图像是由一个个的像素组成的,像素就是一个显示点.像素就是组成图像的最基本元素,或者说显示中可以被控制的最小单位,整个图像就是由很多个像素组成的 ...
- [原]如何在Android用FFmpeg+SDL2.0解码显示图像
如何在Android上使用FFmpeg解码图像参考文章[原]如何在Android用FFmpeg解码图像 ,如何在Android上使用SDL2.0来显示图像参考[原]零基础学习SDL开发之在Androi ...
- Android 高级UI设计笔记13:Gallery(画廊控件)之 循环显示图像
1. 循环显示图像的原理 循环显示有些类似于循环链表,最后一个结点的下一个结点又是第1个结点.循环显示图像也可以模拟这一点. 也许细心的读者从上一节实现的ImageAdapter类中会发现些什么.对 ...
- GDI+ 学习记录(26): 显示图像 - Image
//显示图像 var g: TGPGraphics; img: TGPImage; begin g := TGPGraphics.Create(Self.Canvas.Handle); ...
- 不使用CvvImage类来在MFC中显示图像
/* * ===================================================================================== * * Filen ...
- Chart图形 [功能帮助类] Assistant创建显示图像的标签和文件 (转载)
点击下载 Assistant.zip /// <summary> /// 类说明:Assistant /// 联系方式:361983679 /// 更新网站:[url=http://www ...
- (原)python中使用plt.show()时显示图像
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6039667.html 参考网址: http://matplotlib.org/users/shell. ...
随机推荐
- python tp_ready函数分析
int PyType_Ready(PyTypeObject *type) { PyObject *dict, *bases; PyTypeObject *base; Py_ssize_t i, n; ...
- 关于 web 页面 占满全屏
页面一般可以分成三部分,头部,底部,中间内容部分. 一般不用考虑中间高度部分,因为可以靠内容撑开,然后让底部到达底部.但是当中间内容太少时,底部就会顶不到底部. 方法1.中间部分给一个最小高度(min ...
- python3之Django基础篇
一.Django基础 Django 是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网站! Django的特点: 强大的数据库功能:拥有强大的数据库操作接口(QueryS ...
- Flask最强攻略 - 跟DragonFire学Flask - 第九篇 Flask 中的蓝图(BluePrint)
蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? 比如说,你有一个客户管理系统,最开始的时候,只有一个查看 ...
- mysql数据库字段内容替换
UPDATE 表名 SET 字段名= replace(字段名, '查找内容', '替换成内容') ; UPDATE car_articles SET article_title = replace(a ...
- 转:centos查看实时网络带宽占用情况方法
Linux中查看网卡流量工具有iptraf.iftop以及nethogs等,iftop可以用来监控网卡的实时流量(可以指定网段).反向解析IP.显示端口信息等. centos安装iftop的命令如下: ...
- FortiGate 5.2/5.4 SSLVPN建立
1.定义源IP池 即用户通过sslvpn拨号成功后获取到的IP地址. 2.定义路由地址 即用户通过sslvpn拨号成功后允许获取到的路由表. 3.建立sslvpn portal 4.定义用户和用户组 ...
- 384. Shuffle an Array数组洗牌
[抄题]: Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. i ...
- kalman滤波(三)---各种滤波的方法汇总+优化的方法
大神解答 一.前提 最一般的状态估计问题,我们会根据系统是否线性,把它们分为线性/非线性系统.同时,对于噪声,根据它们是否为高斯分布,分为高斯/非高斯噪声系统.现实中最常见的,也是最困难的问题,是非线 ...
- dos批处理(bat)运行exe
@echo off SETLOCAL ENABLEDELAYEDEXPANSIONREM 延迟环境变量扩展 color E echo operate:1.start启动 2.stop停止 3.exit ...