目前业内流行的相机除Basler相机以外都有提供给halcon更兼容的动态链接库,虽然说halcon自带的GigE接口能兼容一般GigE接口的相机但是对于较低版本的halcon来说导出来的外部程序可能无法打开相机,就比如我使用的halcon12版本的导出C#程序后出现无法打开相机切卡死的情况。
如果你的halcon版本较高,完全可以使用GigE接口。
如果你的halcon版本较低,可以使用以下步骤(以下举例海康相机的低版本halcon打开方式):
1、进入海康威视的安装目录
2、进入对应版本的halcon文件夹
3、复制hAcqMVision.dll到halcon安装目录下的 bin > x64-win64(对应电脑的操作系统)
4、找到 MVision 接口,连接相机可行后导出代码即可
打开相机报错#8600,解决方法
c#与halcon混合编程调用HOperatorSet.OpenFramegrabber报错#8600的解决
使用halcon的代码导出后运行到
HOperatorSet.OpenFramegrabber("GigEVision", 0, 0, 0, 0, 0, 0, "default", -1,
"default", -1, "false", "default", "cam0", 0, -1, out hv_AcqHandle);
时报如下错误
HALCON error #8600: Dynamic library could not be opened in operator open_framegrabber
分析后发现是某个动态链接库无法打开,debug目录下缺少相应的动态链接库
解决方法:将halcon安装目录下相应的接口动态库和pthreadVC2.dll两个库文件拷贝到程序的debug目录下即可
(此相机需将hAcqGigEVision.dll和pthreadVC2.dll拷贝到debug目录)
以下演示一个C#+Halcon访问相机的2个Demo供你参考:
《一》
窗体设计
先将Halcon中的bin->x64-win64文件中的用到的采集接口动态链接库复制到自己的Debug文件中。否者会出现打开相机卡死现象。
具体代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HalconDotNet;
using System.Threading;
namespace openCamera
{
public partial class FormOpenCamera : Form
{
HObject ho_Image, ho_Regions, ho_image;
HTuple hv_window;//窗体句柄(显示图像)
HTuple hv_AcqHandle = null;//相机句柄(获取图像)
HTuple hv_Width = new HTuple();
HTuple hv_Height = new HTuple();
private bool Acqthread_stop = false;
private Thread thread_Acquire = null;
public FormOpenCamera()
{
InitializeComponent();
}
private void FormOpenCamera_Load(object sender, EventArgs e)
{
thread_Acquire = new Thread(new ThreadStart(Acq_Function));
}
//-------------------------------------------------------------------------------------------------------
//打开相机读取图像
//-------------------------------------------------------------------------------------------------------
private void btnOpen_Click(object sender, EventArgs e)
{
if (this.btnOpen.Text == "打开相机")
{
this.btnOpen.Text = "关闭相机";
HOperatorSet.GenEmptyObj(out ho_image);
//Image Acquisition 01: Code generated by Image Acquisition 01
//DirectShow接口
HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8,
"rgb", -1, "false", "default", "[0] Integrated Camera", 0,
-1, out hv_AcqHandle);
USB3Vision接口
//HOperatorSet.OpenFramegrabber( "USB3Vision", 0, 0, 0, 0, 0, 0, "progressive", -1,
//"default", -1, "false", "default", "26760150FBE8_Basler_acA800510um", 0,
// -1, out hv_AcqHandle);
GigEVision接口
// HOperatorSet.OpenFramegrabber("GigEVision", 0, 0, 0, 0, 0, 0, "default", -1,
// "default", -1, "false", "default", "0030532eeb8f_Basler_acA130060gm", 0,
// -1, out hv_AcqHandle);
HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
UpdateLogMessage("打开相机\r\n");
}
else if (this.btnOpen.Text == "关闭相机")
{
this.btnOpen.Text = "打开相机";
HOperatorSet.CloseFramegrabber(hv_AcqHandle);
ho_image.Dispose();
UpdateLogMessage("关闭相机\r\n");
}
}
private void Acq_Function()
{
// ho_image.Dispose();
// HOperatorSet.GrabImageAsync(out ho_image, hv_AcqHandle, -1);
// HOperatorSet.GetImageSize(ho_image, out hv_Width, out hv_Height);
// HOperatorSet.SetPart(hv_AcqHandle, 0, 0, hv_Height, hv_Width);
// HOperatorSet.DispObj(ho_image, hv_AcqHandle);
}
private void UpdateLogMessage(string Content)
{
string TotalContent = DateTime.Now.ToString("yyyy年MM月dd日HH时mm分ss秒"); //Content
this.Display_tb.AppendText(TotalContent);
}
private void btnStartAcqu_Click(object sender, EventArgs e)
{
//Acqthread_stop = false; //使用线程的情况下
//while (!Acqthread_stop)
//{
// HOperatorSet.OpenWindow(0, 0, hWindowControl2.Width, hWindowControl2.Height, hWindowControl2.HalconWindow, "", "", out hv_AcqHandle);
// HDevWindowStack.Push(hv_AcqHandle);
// if (thread_Acquire.ThreadState == System.Threading.ThreadState.Unstarted)
// {
// thread_Acquire.Start();
// }
// if (thread_Acquire.ThreadState == System.Threading.ThreadState.Stopped || thread_Acquire.ThreadState == System.Threading.ThreadState.Aborted)
// {
// thread_Acquire = new Thread(new ThreadStart(Acq_Function));
// thread_Acquire.Start();
// }
//}
if (this.btnStartAcqu.Text == "开始采集" && this.btnOpen.Text == "关闭相机")
{
timer1.Enabled = true;
this.btnStartAcqu.Text = "停止采集";
HOperatorSet.OpenWindow(0, 0, hWindowControl1.Width, hWindowControl1.Height, hWindowControl1.HalconWindow, "", "", out hv_window);
HDevWindowStack.Push(hv_window); //使用定时器的情况下
UpdateLogMessage("开始采集\r\n");
}
else if (this.btnStartAcqu.Text == "停止采集")
{
timer1.Enabled = false;
this.btnStartAcqu.Text = "开始采集";
HOperatorSet.CloseWindow(hv_window);
UpdateLogMessage("停止采集\r\n");
}
}
private void btnExit_Click(object sender, EventArgs e)
{
System.Environment.Exit(0);
}
private void timer1_Tick(object sender, EventArgs e)
{
ho_image.Dispose();
HOperatorSet.GrabImageAsync(out ho_image, hv_AcqHandle, -1);
HOperatorSet.GetImageSize(ho_image, out hv_Width, out hv_Height);
HOperatorSet.SetPart(hv_window, 0, 0, hv_Height, hv_Width);
HOperatorSet.DispObj(ho_image, hv_window);
ho_image.Dispose();//释放图像变量内存
}
//-------------------------------------------------------------------------------------------------------
//打开文件读取图像
//-------------------------------------------------------------------------------------------------------
//
private void btnImageSelected_Click(object sender, EventArgs e)
{
openFileDialog.Filter = "JEPG文件|*.jpg*|BMP文件|*.bmp*|PNG文件|*.png*";
openFileDialog.RestoreDirectory = true;
HOperatorSet.GenEmptyObj(out ho_Image);
HOperatorSet.GenEmptyObj(out ho_Regions);
ho_Image.Dispose();
string imagepath;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
imagepath = openFileDialog.FileName;
HOperatorSet.ReadImage(out ho_Image, imagepath);
}
}
private void btnDispProceImage_Click(object sender, EventArgs e)
{
HOperatorSet.OpenWindow(0, 0, hWindowControl1.Width, hWindowControl1.Height, hWindowControl1.HalconWindow, "", "", out hv_window);
HDevWindowStack.Push(hv_window);
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
HOperatorSet.SetPart(hv_window, 0, 0, hv_Height, hv_Width);//图像的大小自适应显示窗体
HOperatorSet.DispObj(ho_Image, hv_window);
//ho_Regions.Dispose();
//HOperatorSet.Threshold(ho_Image, out ho_Regions, 81, 141);
//HOperatorSet.SetColor(hv_window, "red");
//HOperatorSet.DispObj(ho_Regions, hv_window);
//ho_Image.Dispose();
//ho_Regions.Dispose();
}
}
}
《二》
窗口设计:
代码:
public partial class Form1 : Form
{
//相机句柄
HTuple hv_AcqHandle = null;
//halcon窗口句柄
HTuple handle;
//单采集的图像
HObject image = null;
//抓取图像的线程
Thread brabT;
//线程开关
bool isRun = true;
public Form1()
{
InitializeComponent();
handle = hWindowControl1.HalconWindow;
}
#region but事件相关
//打开相机
private void button1_Click(object sender, EventArgs e)
{
openCam();
if (hv_AcqHandle == null)
{
return;
}
brabT = new Thread(brabImage);
//开启线程并挂起它
brabT.Start();
brabT.Suspend();
}
//开始采集
private void button2_Click(object sender, EventArgs e)
{
if (brabT != null)
{
//继续执行线程
brabT.Resume();
}
}
//停止采集
private void button3_Click(object sender, EventArgs e)
{
if (brabT != null)
{
//暂停线程
brabT.Suspend();
}
}
//单采集
private void button4_Click(object sender, EventArgs e)
{
HOperatorSet.GrabImage(out image, hv_AcqHandle);
HOperatorSet.DispImage(image, handle);
}
//当窗口关闭时
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (brabT != null)
{
isRun = false;
//brabT.Join();
//继续执行线程
//brabT.Resume();
终止多余线程
brabT.Abort();
}
}
#endregion
#region 相机相关
//抓取图片线程
private void brabImage()
{
HTuple w, h;
HObject ho_Image;
while (isRun)
{
try
{
HOperatorSet.GrabImage(out ho_Image, hv_AcqHandle);
if (ho_Image != null)
{
HOperatorSet.GetImageSize(ho_Image, out w, out h);
HOperatorSet.SetPart(handle, 0, 0, h, w);
HOperatorSet.DispImage(ho_Image, handle);
//显示玩之后释放图片
ho_Image.Dispose();
}
}
catch (Exception)
{
MessageBox.Show("相机已断开,请重新连接!");
Thread.Sleep(3000);
openCam();
}
}
}
private void openCam() {
//释放相机句柄
HOperatorSet.CloseAllFramegrabbers();
try
{
//连接相机
HOperatorSet.OpenFramegrabber("MVision", 1, 1, 0, 0, 0, 0, "progressive", 8,
"default", -1, "false", "auto", "GEV:00D23303857", 0, -1, out hv_AcqHandle);
MessageBox.Show("相机连接成功!");
}
catch (Exception)
{
MessageBox.Show("相机连接失败!");
}
}
#endregion
}