概述:使用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 之 显示图像的更多相关文章

  1. HSmartWindowControl 之 摄像头实时显示( 使用 WPF )

    1.添加Halcon控件,创建WPF项目 在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见: HSmartWindowControl之安装篇 (Visual Studio ...

  2. VS2010+Qt+OpenCv(显示图像)

    Qt在界面显示窗口中起着越来越重要的作用,从而了解了下如何在Qt中显示一副图像. 该小程序主要注意一下几点: 1.工程属性中设置OpenCV的环境(包含目录和库目录,以及附加依赖项),设置Qt的环境( ...

  3. LCD如何显示图像

    1.LCD显示主要相关概念 (1)像素(pixel) 整个图像是由一个个的像素组成的,像素就是一个显示点.像素就是组成图像的最基本元素,或者说显示中可以被控制的最小单位,整个图像就是由很多个像素组成的 ...

  4. [原]如何在Android用FFmpeg+SDL2.0解码显示图像

    如何在Android上使用FFmpeg解码图像参考文章[原]如何在Android用FFmpeg解码图像 ,如何在Android上使用SDL2.0来显示图像参考[原]零基础学习SDL开发之在Androi ...

  5. Android 高级UI设计笔记13:Gallery(画廊控件)之 循环显示图像

    1. 循环显示图像的原理  循环显示有些类似于循环链表,最后一个结点的下一个结点又是第1个结点.循环显示图像也可以模拟这一点. 也许细心的读者从上一节实现的ImageAdapter类中会发现些什么.对 ...

  6. GDI+ 学习记录(26): 显示图像 - Image

    //显示图像 var   g: TGPGraphics;   img: TGPImage; begin   g := TGPGraphics.Create(Self.Canvas.Handle);   ...

  7. 不使用CvvImage类来在MFC中显示图像

    /* * ===================================================================================== * * Filen ...

  8. Chart图形 [功能帮助类] Assistant创建显示图像的标签和文件 (转载)

    点击下载 Assistant.zip /// <summary> /// 类说明:Assistant /// 联系方式:361983679 /// 更新网站:[url=http://www ...

  9. (原)python中使用plt.show()时显示图像

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6039667.html 参考网址: http://matplotlib.org/users/shell. ...

随机推荐

  1. Kafka自带zookeeper报错INFO Got user-level KeeperException when processing xxx Error Path:/brokers Error:KeeperErrorCode = NodeExists for /brokers (org.apache.zookeeper.server.PrepRequestProcessor)

    问题描述: 按照kafka官方文档的操作步骤,解压kafka压缩包后.依次启动zookeeper,和kafka服务 kafka服务启动后,查看到zookeeper日志里有以下异常 问题原因及解决办法: ...

  2. Swagger注解

    swagger注解说明  1.与模型相关的注解,用在bean上面 @ApiModel:用在bean上,对模型类做注释: @ApiModelProperty:用在属性上,对属性做注释 2.与接口相关的注 ...

  3. java集合: jdk1.8的hashMap原理简单理解

    HashMap的数据结构 HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,他的底层结构是一个数组,而数组的元素是一个单向链表.HashMap默认初始化的是一个长度为16位的数 ...

  4. python的arp扫描

    python的arp扫描 from optparse import *from scapy.all import *parser = OptionParser()parser.add_option(& ...

  5. 9. Palindrome Number (JAVA)

    Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same back ...

  6. 168. Excel Sheet Column Title (Math)

    Given a positive integer, return its corresponding column title as appear in an Excel sheet. For exa ...

  7. object references an unsaved transient instance save the transient instance before flushing

    object references an unsaved transient instance save the transient instance before flushing 对象引用未保存的 ...

  8. Python基础-python简介(一)

    一.简介: python是一种面向对象的解释性计算机程序设计语言,由荷兰人Guido  von  Rossum于1989年的圣诞节发明. Python语言的特色: 1.python是一门解释性语言 解 ...

  9. Spring中,applicationContext.xml 配置文件在web.xml中的配置详解

    一.首先写一下代码结构. 二.再看web.xml中的配置情况. <?xml version="1.0" encoding="UTF-8"?> < ...

  10. <jsp:forward page='/index' />