分享

C#与Halcon联合编程 1

 人生入戏ufo 2019-05-14

本人所使用的软件版本为:Windows10 + VS2013 + Halcon 17.12:
参考网址: https://zhidao.baidu.com/question/542376170.html这里写代码片
参考网址: https://blog.csdn.net/u013698770/article/details/52431042

1、Application.EnableVisualStyles()

Application.EnableVisualStyles() 的作用是激活应用程序的显示风格,而显示风格是构成操作系统主题的各种元素,如色彩、字体等。如果控件和OS支持,那么控件的绘制就会根据显示风格来实现。实际上该方法的调用必须早于任何一个控件的创建。通常它位于Main函数的第一行,在集成开发环境下会自动被添加。

2、SetCompatibleTextRenderingDefault()
某些窗体控件在给它们的文本着色时可以使用 TextRenderer类也可以使用 Graphics类。 TextRenderer类是基于 GDI图形库的,而 Graphics类则基于GDI+库。这两种类的并存始于.NET Framework 2.0,部分出于性能原因,部分是由于GDI+的本地化问题。若控件支持UseCompatibleTextRenderingproperty属性,则该方法将此属性设置为默认值。
UseCompatibleTextRendering属性用于兼容使用TextRenderer类的窗体控件和使用 Graphics 类的.NET Framework 1.0和.NET Framework 1.1下的应用程序。如果你到程序不是从1.0或者1.1版本升级来的,那么建议你把该属性设置为false。
除了窗体应用程序,不要调用该方法。
至于为什么出现基于GDI 的TextRenderer类,MSDN上有,我也不想再翻译了。主要是基于性能,美观等考虑,以及多语言字体的兼容问题。

3、SetCompatibleTextRenderingDefault()
对于窗体来说,Run方法在当前线程中启动一个标准的应用程序消息循环,另外它还将你的login窗体显示出来。

4、修改halcon导出的C#程序
修改是将导出的主函数private void action()中的private改为public,这样在其他类中才能有权限去调用HDevelopExport中的函数。
在主程序类中调用Halcon类方法分为两步:
  1是在主程序public partial class Form1 : Form{}中创建一个HDevelopExport类对象

 HDevelopExport HD = new HDevelopExport();//全局的halcon类对象

  2是在需要调用halcon函数的地方使用类对象来调用该函数this.HD.action();,其参数和返回值都是可以根据实际情况而改变的。


例子:参考地址 http://www.cnblogs.com/badguy518/p/5515068.html
这里写图片描述

* 一段 Halcon程序
read_image (Image, 'C:/Users/Administrator/Desktop/298198.jpg')
dev_open_window(0, 0, 512, 512, 'black', WindowHandle)
dev_display(Image)
get_image_size(Image, Width, Height)
rgb3_to_gray(Image, Image, Image, ImageGray)
dev_display(ImageGray)

文件-导出;
这里写图片描述

然后,新建 C#项目
这里写图片描述

设计窗体结构,可以设置一个HWindow窗口,两个button按钮,一个读入,一个处理;
这里写图片描述

如果想让halcon程序在C#里面分开进行处理,就需要将转换的C#代码分割成两部分代码,具体如下;

//定义变量
//初始化halcon
 public void InitHalcon()
  {
   //初始化halcon程序
  }
//读取图片
public void ReadPicture(HTuple Window)
{
//读图程序
}
//处理图片
 public void Process()
{
//处理程序
}

将下面的程序替换到public partial class HDevelopExport 中):

//定义变量
public HTuple hv_ExpDefaultWinHandle;
HObject ho_Image, ho_ImageGray;
HTuple hv_Width, hv_Height;
//初始化halcon
public void InitHalcon()
  {
    // Default settings used in HDevelop 
    HOperatorSet.SetSystem("do_low_error", "false");
  }
public void ReadPicture(HTuple Window)
{
    //读图并显示
   hv_ExpDefaultWinHandle = Window;
   HOperatorSet.GenEmptyObj(out ho_Image);
    ho_Image.Dispose();
    HOperatorSet.ReadImage(out ho_Image, "C:/Users/Administrator/Desktop/298198.jpg");
    HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);
    HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);

}
 public void Process()
{
    //处理程序
   HOperatorSet.GenEmptyObj(out ho_ImageGray);
    ho_ImageGray.Dispose();
    HOperatorSet.Rgb3ToGray(ho_Image, ho_Image, ho_Image, out ho_ImageGray);
    HOperatorSet.DispObj(ho_ImageGray, hv_ExpDefaultWinHandle);
    ho_Image.Dispose();
    ho_ImageGray.Dispose();
}

然后再主程序Form1的类下对刚才添加的类进行实例化:

HDevelopExport hd = new HDevelopExport();

并在相应按键下添加对应程序

 private void button1_Click(object sender, EventArgs e)
 {
       hd.ReadPicture(hWindowControl1.HalconWindow);
  }
 private void button2_Click(object sender, EventArgs e)
{
      hd.Process();
 }

到此,程序就可以运行了。

附加步骤1:
在以上程序中,已经可以将图片显示出来,并进行处理,但由于窗口与图片的大小不一致,导致在显示窗口中不能适应程序窗口的大小,下面是解决此类问题的方法:
在读图程序中,将获取图片的大小的程序HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);放在显示图片之前,并在显示图片程序之前加入下面程序:
HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, hv_Height - 1, hv_Width - 1);然后图片就可以适应窗口大小。
此步骤也可以在halcon中更改。
附加步骤2:
如果想在程序中能够打开本地文件夹的图片进行处理,则需要改以下程序:
注意:①②是添加的类中③④是主程序中
①将public void ReadPicture(HTuple Window)的括号中加入参数,改为public void ReadPicture(HTuple Window, string ImagePath)
②将 ReadPicture下的程序 HOperatorSet.ReadImage(out ho_Image, "C:/Users/Administrator/Desktop/298198.jpg");改为HOperatorSet.ReadImage(out ho_Image, ImagePath);
③主程序中定义变量string ImagePath
④将button1的程序改成如下:

     private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter ="JPEG文件|*.jpg*|BMP文件|*.bmp*";
            openFileDialog1.RestoreDirectory = true;
            openFileDialog1.FilterIndex = 1;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ImagePath = openFileDialog1.FileName;
                hd.ReadPicture(hWindowControl1.HalconWindow, ImagePath);
            }
        }
接下来可以试试运行程序。

完整代码如下

Program.cs里面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;
namespace WindowsFormsApplication2
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    public partial class HDevelopExport
    {
        public HTuple hv_ExpDefaultWinHandle;
        HObject ho_Image, ho_ImageGray;
        HTuple hv_Width, hv_Height;

        //初始化halcon
        public void InitHalcon()
        {
            // Default settings used in HDevelop 
            HOperatorSet.SetSystem("do_low_error", "false");
        }
        public void ReadPicture(HTuple Window, string ImagePath)
        {
            //读图并显示
            hv_ExpDefaultWinHandle = Window;
            HOperatorSet.GenEmptyObj(out ho_Image);
            ho_Image.Dispose();
            HOperatorSet.ReadImage(out ho_Image, ImagePath);
            HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
            HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, hv_Height - 1, hv_Width - 1);
            HOperatorSet.DispObj(ho_Image, hv_ExpDefaultWinHandle);


        }
        public void Process()
        {
            //处理程序
            HOperatorSet.GenEmptyObj(out ho_ImageGray);
            ho_ImageGray.Dispose();
            HOperatorSet.Rgb3ToGray(ho_Image, ho_Image, ho_Image, out ho_ImageGray);
            HOperatorSet.DispObj(ho_ImageGray, hv_ExpDefaultWinHandle);
            ho_Image.Dispose();
            ho_ImageGray.Dispose();
        }

    }

}

Form1.cs里面的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{

    public partial class Form1 : Form
    {
        HDevelopExport hd = new HDevelopExport();
        string ImagePath;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter ="JPEG文件|*.jpg*|BMP文件|*.bmp*";
            openFileDialog1.RestoreDirectory = true;
            openFileDialog1.FilterIndex = 1;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ImagePath = openFileDialog1.FileName;
                hd.ReadPicture(hWindowControl1.HalconWindow, ImagePath);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            hd.Process();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

    }


}

下面是运行效果:
这里写图片描述

这里写图片描述
这里写图片描述


1、Dispose
一般而言,调用Dispose就会立即执行对象的终结操作(直接关闭非托管资源的句柄),时机是可以掌握的。 但如果你不调用Dispose,转而选择让GC自动执行清理工作,那时机就把握不准:它要判断哪些对象是垃圾(没有被根对象引用),检查是否有终结器,然后执行终结操作,期间会因为“代”的关系,推迟垃圾的清理。
2、HOperatorSet
调用算子。
As you can see, the operator can be called via three classes: HOperatorSet, HImage, and HFramegrabber. The first variant, via HOperatorSet, is mainly used for the export of HDevelop programs

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多