经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 软件图像 » Visual Studio » 查看文章
HSmartWindowControl 之 显示图像
来源:cnblogs  作者:不锈钢老鼠  时间:2018/9/25 20:48:45  对本文有异议

概述:使用Halcon在VS中的控件显示一张图片。

要点:使用了图像缩放和图像显示函数,以及鼠标滚轮响应函数。

1、创建WinForm项目

首先在VS中添加Halcon所需的控件HSmartWindowControl,参考上一篇:HSmartWindowControl之安装篇 (Visual Studio 2013 & Halcon 18)https://www.cnblogs.com/oucsheep/p/9563876.html

然后创建新的winForm工程,并向窗体中拖入一个HSmartWindowControl控件和两个按钮控件。

image

拖入后不添加代码,直接运行,可能会出现如下错误:

HalconDotNet.HHandleBase 的类型初始化值设定项引发异常

Snipaste_2018-08-30_18-31-30

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

Snipaste_2018-08-27_18-24-24

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

image

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

image

2、创建Halcon实时显示代码并导出

打开halcon,写一句简单的代码

image

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

image

3、halcon 导出的C#代码分析

  1. using System;
  2. using HalconDotNet;
  3. public partial class HDevelopExport
  4. {
  5. public HTuple hv_ExpDefaultWinHandle;
  6. // Main procedure
  7. private void action()
  8. {
  9. // Local iconic variables
  10. HObject ho_Image;
  11. // Local control variables
  12. HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
  13. // Initialize local and output iconic variables
  14. HOperatorSet.GenEmptyObj(out ho_Image);
  15. ho_Image.Dispose();
  16. HOperatorSet.ReadImage(out ho_Image, "printer_chip/printer_chip_01");
  17. hv_Width.Dispose();hv_Height.Dispose();
  18. HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
  19. ho_Image.Dispose();
  20. hv_Width.Dispose();
  21. hv_Height.Dispose();
  22. }
  23. public void InitHalcon()
  24. {
  25. // Default settings used in HDevelop
  26. HOperatorSet.SetSystem("width", 512);
  27. HOperatorSet.SetSystem("height", 512);
  28. }
  29. public void RunHalcon(HTuple Window)
  30. {
  31. hv_ExpDefaultWinHandle = Window;
  32. action();
  33. }
  34. }

实际有用的代码就是action()内的代码,首先声明了图像变量:HObject ho_Image;

需要注意的是,图像类型需要先初始化再使用:HOperatorSet.GenEmptyObj(out ho_Image);

然后调用ReadImage函数读入图像文件,最后调用Dispose函数清空对象。但是没有显示图像的代码,需要自己添加。

4、向VS中插入代码

打开Winform工程窗体关联的cs文件Form1.cs,首先需要在文件头部添加命名空间引用:

  1. using HalconDotNet;

需要在类中定义全局的窗口变量,便于操作窗体:

  1. private static HWindow hwindow; //全局窗口变量
  2. public HTuple hv_ExpDefaultWinHandle; //导出的代码定义的,其实没用到

窗口的初始化函数中添加全局变量的初始化函数:

  1. public Form1()
  2. {
  3. InitializeComponent();
  4. hwindow = hSmartWindowControl1.HalconWindow;//初始化窗口变量
  5. this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.my_MouseWheel);
  6. }

然后在按钮的响应函数中添加载入图像的及显示的代码:

  1. private void button2_Click(object sender, EventArgs e)
  2. {
  3. #region 初始化变量
  4. // Local iconic variables
  5. HObject ho_Image;
  6. // Local control variables
  7. HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
  8. // Initialize local and output iconic variables
  9. HOperatorSet.GenEmptyObj(out ho_Image);
  10. ho_Image.Dispose();
  11. HOperatorSet.ReadImage(out ho_Image, "clip.png");
  12. hv_Width.Dispose(); hv_Height.Dispose();
  13. #endregion
  14.  
  15. #region 缩放图像,适应窗口
  1. bool needResizeImage = true;
  2. //获取图像大小及纵横比
  3. HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
  4. int im_width = int.Parse(hv_Width.ToString());
  5. int im_height = int.Parse(hv_Height.ToString());
  6. double im_AspectRatio = (double)(im_width)/(double)(im_height);
  7. //获取窗口大小及纵横比
  8. int w_width = hSmartWindowControl1.Size.Width;
  9. int w_height = hSmartWindowControl1.Size.Height;
  10. double w_AspectRatio = (double)(w_width)/(double)(w_height);
  11. HOperatorSet.SetSystem("int_zooming", "false");//图像缩放之前最好将此参数设置为false.
  12. HTuple para = new HTuple("constant");
  13. HObject ho_zoomImage;
  14. HOperatorSet.GenEmptyObj(out ho_zoomImage);
  15. ho_zoomImage.Dispose();
  16. if(w_width<im_width && im_AspectRatio>w_AspectRatio)
  17. {
  18. //超宽图像
  19. HOperatorSet.ZoomImageSize(ho_Image, out ho_zoomImage, w_width, w_width / im_AspectRatio, para);
  20. }
  21. else if (w_height < im_height && im_AspectRatio < w_AspectRatio)
  22. {
  23. //超高图像
  24. HOperatorSet.ZoomImageSize(ho_Image, out ho_zoomImage, w_height * im_AspectRatio, w_height, para);
  25. }
  1. else
  1. {
  1. needResizeImage = false;
  1. }
  2. #endregion
  3.  
  4. #region 显示图像
  5. hwindow.SetPart(0, 0, -2, -2);

            if (needResizeImage)
             {
                 hwindow.DispObj(ho_zoomImage);
             }
             else
             {
                 hwindow.DispObj(ho_Image);
             }

  1. //HOperatorSet.GetImageSize(ho_zoomImage, out hv_Width, out hv_Height);
  2. //im_width = int.Parse(hv_Width.ToString());
  3. //im_height = int.Parse(hv_Height.ToString());
  4. //MessageBox.Show(hv_Width.ToString() + " " + hv_Height.ToString());
  5. #endregion
  6. ho_Image.Dispose();
  7. ho_zoomImage.Dispose();
  8. hv_Width.Dispose();
  9. hv_Height.Dispose();
  10. }

5、图像缩放和显示

这里我对导出的代码做了修改,主要是增加了图像缩放和显示功能。

图像缩放使用了ZoomImageSize函数,在帮助文档中,这个函数有两种用法:

  1. static void HOperatorSet.ZoomImageSize(HObject image, out HObject imageZoom, HTuple width,HTuple height, HTuple interpolation)
  2. HImage HImage.ZoomImageSize(int width, int height, string interpolation)

上面的代码中使用了第一种用法,所有的参数必须是Halcon的类型,但是实际使用时width 和height 可以用int类型,interpolation即差值算法参数也可以直接传入string类型,如“constant”。

第二种方法需要将使用HImage类型的变量来操作,所以需要将 HObject 类型定义的图像变量转换一下:

  1. HImage img = new HImage(ho_Image);
  2. ho_zoomImage = img.ZoomImageSize(w_width, w_width, "constant");

图像显示功能:先调用SetPart函数确定要显示图像的区域,然后调用DispObj函数显示图像,DispObj也有三种用法:

  1. static void HOperatorSet.DispObj(HObject objectVal, HTuple windowHandle)
  2. void HObject.DispObj(HWindow windowHandle)
  3. void HWindow.DispObj(HObject objectVal)

此处我用的第三种:通过Hwindow调用,参数为要显示的图像变量。

  1. hwindow.SetPart(0, 0, -2, -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

image

实际测试发现帮助文档中的用法有一些问题,消息相应函数的注册应该在整个窗体的初始化函数中,而不是SmartWindowControl的初始化函数中。

  1. private void hSmartWindowControl1_Load(object sender, EventArgs e)
  2. {
  3. //这句话不起作用
  4. this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.my_MouseWheel);
  5. }
  1. public Form1()
  2. {
  3. InitializeComponent();
  4. hwindow = hSmartWindowControl1.HalconWindow;//初始化窗口变量
  5. // 鼠标滚轮的响应函数注册
  6. this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.my_MouseWheel);
  7. }

这样修改后,直接使用帮助文档中提供的my_MouseWheel也有一个小bug,就是无论在窗体的任何位置滑动滚轮,图片都会缩放,所以需要对鼠标的位置做一下限制:

  1. private void my_MouseWheel(object sender, MouseEventArgs e)
  2. {
  3. System.Drawing.Point pt = this.Location;
  4. int leftBorder = hSmartWindowControl1.Location.X;
  5. int rightBorder = hSmartWindowControl1.Location.X + hSmartWindowControl1.Size.Width;
  6. int topBorder = hSmartWindowControl1.Location.Y;
  7. int bottomBorder = hSmartWindowControl1.Location.Y + hSmartWindowControl1.Size.Height;
  8. if(e.X > leftBorder && e.X < rightBorder && e.Y > topBorder && e.Y < bottomBorder)
  9. {
  10. MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks,
  11. e.X - pt.X, e.Y - pt.Y, e.Delta);
  12. hSmartWindowControl1.HSmartWindowControl_MouseWheel(sender, newe);
  13. }
  14. }
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号