C#与Halcon联合编程 1
本人所使用的软件版本为: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