Halcon学习之图像采集
Halcon学习之图像采集
1.读取文件夹中的图片
1.1打开Halcon12开发环境
1.2打开“助手”中的“Image Acquistion”
1.3选择“图像文件”选项——“选择路径”——选择存放图片的文件夹
1.4选择“代码生成”选项——点击“插入代码”按钮
1.5 在代码区就是采集代码,可以添加stop()方法后不断点击运行按钮运行代码查看逐一读取图片的效果
2.读取摄像头实时采集
2.1连接Halcon支持的摄像头(无需安装摄像头驱动),这里我用的是大恒的一款摄像头
2.2选择“Image Acquistion”中的“图像获取接口”选项——点击“自动检测接口”按钮
2.2选择“连接”选项卡——点击下方“连接”按钮——点击“实时”按钮摄像头开始采集图像
注:由于我没有连接镜头所以采集到的图像只有灰色的
2.3选择“参数”选项卡——调节对应的摄像头参数——选择“代码生成”选项卡——点击“插入代码”按钮则会导出我们需要的Halcon代码
3.Halcon导出到C#进行图像采集
3.1图像采集的一般方法
使用Halcon导出代码结合C#中Application.Idle事件进行循环采集显示。
使用Halcon导出代码结合C#中的线程进行循环采集显示。
当所选用的摄像头不支持Halcon时,一般选择修改厂商提供的SDK进行采集显示。
3.2这里我介绍第二种方法,因为现代处理器的核在不断增加,采用多线程异步编程才能发挥多核处理的性能提高软件系统的数据处理和吞吐能力
3.2.1首先要解决以下几个问题:
如果希望使用.net的原生控件Picturebox则需要对Halcon导出的C#代码进行修改。
Halcon导出代码采集的图像格式和.net的Image是不兼容的,需要进行转换。
需要将导出代码中的“初始化摄像头”、“启动摄像头”、“关闭摄像头”、“设置摄像头参数”这几块内容进行封装符合面向对象的编程需要。
注:不使用Halcon提供的.net控件的坏处是增加了图像格式转换的开销如果图像像素特别高,系统显示帧率有要求,就需要更高配置的电脑
3.2.2关于实际的代码部分废话不多说直接给Demo
注:根目录下需要放入halcondotnet.dll和halcon.dl,并在开发环境中引用halcondotnet.dll
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using HalconDotNet;
/// <summary>
/// 摄像头类
/// </summary>
public class ImageGraber
{
[DllImport("Kernel32.dll")]
internal static extern void CopyMemory(int dest, int source, int size);
private HObject ho_Image = null; //Halcon中采集的图像对象
private HTuple hv_AcqHandle = null; //Halcon中摄像头操作句柄
private PictureBox picCamera = null; //采集图像显示区
private Thread imageGrabeThread = null; //图像采集异步线程
/// <summary>
/// 摄像头初始化成功标志
/// </summary>
public bool IsInitSuccess { get; set; }
/// <summary>
/// 摄像头处于采集中标志
/// </summary>
public bool IsStart { get; set; }
/// <summary>
/// 摄像头增益参数
/// </summary>
private int gain;
public int Gain
{
get
{
return gain;
}
set
{
try
{
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "gain", value);
gain = value;
}
catch (Exception) { }
}
}
/// <summary>
/// 摄像头快门参数
/// </summary>
private int shutter;
public int Shutter
{
get
{
return shutter;
}
set
{
try
{
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "shutter", value);
shutter = value;
}
catch (Exception) { }
}
}
//其他摄像头参数如法炮制...
/// <summary>
/// 构造函数
/// </summary>
public ImageGraber(PictureBox picCamera)
{
try
{
this.picCamera = picCamera;
IsInitSuccess = false;
IsStart = false;
HOperatorSet.GenEmptyObj(out ho_Image);
HOperatorSet.OpenFramegrabber("DahengCAM", 1, 1, 0, 0, 0, 0, "interlaced", 8,
"gray", -1, "false", "HV-xx51", "1", 1, -1, out hv_AcqHandle);
HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
IsInitSuccess = true;
}
catch (Exception) { IsInitSuccess = false; }
}
/// <summary>
/// 采集一帧图像
/// </summary>
/// <returns></returns>
public Bitmap GrabSingleFrame()
{
try
{
Bitmap GrabBitmap = null;
ho_Image.Dispose();
HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
ConvertHalconGrayByteImageToBitmap(ho_Image, out GrabBitmap);
return GrabBitmap;
}
catch (Exception) { return null; }
}
/// <summary>
/// 关闭摄像头
/// </summary>
/// <returns></returns>
public bool CloseCamera()
{
try
{
HOperatorSet.CloseFramegrabber(hv_AcqHandle);
ho_Image.Dispose();
return true;
}
catch (Exception) { return false; }
}
/// <summary>
/// 图像采集线程函数
/// </summary>
private void ImageGrabThread()
{
while (true)
{
this.picCamera.Image = GrabSingleFrame();
}
}
/// <summary>
/// 开始采集
/// </summary>
public void Start()
{
if (!IsStart && imageGrabeThread == null)
{
imageGrabeThread = new Thread(new ThreadStart(ImageGrabThread));
imageGrabeThread.Start();
IsStart = true;
}
}
/// <summary>
/// 停止采集
/// </summary>
public void Stop()
{
if (IsStart && imageGrabeThread != null)
{
imageGrabeThread.Abort();
imageGrabeThread = null;
IsStart = false;
}
}
/// <summary>
/// 将Halcon中8位灰度图转换为Bitmap图像
/// </summary>
/// <param name="image">Halcon中8位灰度图</param>
/// <param name="res">.net中Bitmap图像</param>
private void ConvertHalconGrayByteImageToBitmap(HObject image, out Bitmap res)
{
HTuple hpoint, type, width, height;
const int Alpha = 255;
int[] ptr = new int[2];
HOperatorSet.GetImagePointer1(image, out hpoint, out type, out width, out height);
res = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
ColorPalette pal = res.Palette;
for (int i = 0; i <= 255; i++)
{
pal.Entries[i] = Color.FromArgb(Alpha, i, i, i);
}
res.Palette = pal;
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bitmapData = res.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
int PixelSize = Bitmap.GetPixelFormatSize(bitmapData.PixelFormat) / 8;
ptr[0] = bitmapData.Scan0.ToInt32();
ptr[1] = hpoint.I;
if (width % 4 == 0)
CopyMemory(ptr[0], ptr[1], width * height * PixelSize);
else
{
for (int i = 0; i < height - 1; i++)
{
ptr[1] += width;
CopyMemory(ptr[0], ptr[1], width * PixelSize);
ptr[0] += bitmapData.Stride;
}
}
res.UnlockBits(bitmapData);
}
/// <summary>
/// 将Halcon中RGB图像转换为Bitmap图像
/// </summary>
/// <param name="image">Halcon中RGB图像</param>
/// <param name="res">.net中Bitmap图像</param>
private void GenertateRGBBitmap(HObject image, out Bitmap res)
{
HTuple hred, hgreen, hblue, type, width, height;
HOperatorSet.GetImagePointer3(image, out hred, out hgreen, out hblue, out type, out width, out height);
res = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bitmapData = res.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
unsafe
{
byte* bptr = (byte*)bitmapData.Scan0;
byte* r = ((byte*)hred.I);
byte* g = ((byte*)hgreen.I);
byte* b = ((byte*)hblue.I);
for (int i = 0; i < width * height; i++)
{
bptr[i * 4] = (b)[i];
bptr[i * 4 + 1] = (g)[i];
bptr[i * 4 + 2] = (r)[i];
bptr[i * 4 + 3] = 255;
}
}
res.UnlockBits(bitmapData);
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using HalconDotNet;
/// <summary>
/// 摄像头类
/// </summary>
public class ImageGraber
{
[DllImport("Kernel32.dll")]
internal static extern void CopyMemory(int dest, int source, int size);
private HObject ho_Image = null; //Halcon中采集的图像对象
private HTuple hv_AcqHandle = null; //Halcon中摄像头操作句柄
private PictureBox picCamera = null; //采集图像显示区
private Thread imageGrabeThread = null; //图像采集异步线程
/// <summary>
/// 摄像头初始化成功标志
/// </summary>
public bool IsInitSuccess { get; set; }
/// <summary>
/// 摄像头处于采集中标志
/// </summary>
public bool IsStart { get; set; }
/// <summary>
/// 摄像头增益参数
/// </summary>
private int gain;
public int Gain
{
get
{
return gain;
}
set
{
try
{
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "gain", value);
gain = value;
}
catch (Exception) { }
}
}
/// <summary>
/// 摄像头快门参数
/// </summary>
private int shutter;
public int Shutter
{
get
{
return shutter;
}
set
{
try
{
HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "shutter", value);
shutter = value;
}
catch (Exception) { }
}
}
//其他摄像头参数如法炮制...
/// <summary>
/// 构造函数
/// </summary>
public ImageGraber(PictureBox picCamera)
{
try
{
this.picCamera = picCamera;
IsInitSuccess = false;
IsStart = false;
HOperatorSet.GenEmptyObj(out ho_Image);
HOperatorSet.OpenFramegrabber("DahengCAM", 1, 1, 0, 0, 0, 0, "interlaced", 8,
"gray", -1, "false", "HV-xx51", "1", 1, -1, out hv_AcqHandle);
HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
IsInitSuccess = true;
}
catch (Exception) { IsInitSuccess = false; }
}
/// <summary>
/// 采集一帧图像
/// </summary>
/// <returns></returns>
public Bitmap GrabSingleFrame()
{
try
{
Bitmap GrabBitmap = null;
ho_Image.Dispose();
HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
ConvertHalconGrayByteImageToBitmap(ho_Image, out GrabBitmap);
return GrabBitmap;
}
catch (Exception) { return null; }
}
/// <summary>
/// 关闭摄像头
/// </summary>
/// <returns></returns>
public bool CloseCamera()
{
try
{
HOperatorSet.CloseFramegrabber(hv_AcqHandle);
ho_Image.Dispose();
return true;
}
catch (Exception) { return false; }
}
/// <summary>
/// 图像采集线程函数
/// </summary>
private void ImageGrabThread()
{
while (true)
{
this.picCamera.Image = GrabSingleFrame();
}
}
/// <summary>
/// 开始采集
/// </summary>
public void Start()
{
if (!IsStart && imageGrabeThread == null)
{
imageGrabeThread = new Thread(new ThreadStart(ImageGrabThread));
imageGrabeThread.Start();
IsStart = true;
}
}
/// <summary>
/// 停止采集
/// </summary>
public void Stop()
{
if (IsStart && imageGrabeThread != null)
{
imageGrabeThread.Abort();
imageGrabeThread = null;
IsStart = false;
}
}
/// <summary>
/// 将Halcon中8位灰度图转换为Bitmap图像
/// </summary>
/// <param name="image">Halcon中8位灰度图</param>
/// <param name="res">.net中Bitmap图像</param>
private void ConvertHalconGrayByteImageToBitmap(HObject image, out Bitmap res)
{
HTuple hpoint, type, width, height;
const int Alpha = 255;
int[] ptr = new int[2];
HOperatorSet.GetImagePointer1(image, out hpoint, out type, out width, out height);
res = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
ColorPalette pal = res.Palette;
for (int i = 0; i <= 255; i++)
{
pal.Entries[i] = Color.FromArgb(Alpha, i, i, i);
}
res.Palette = pal;
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bitmapData = res.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
int PixelSize = Bitmap.GetPixelFormatSize(bitmapData.PixelFormat) / 8;
ptr[0] = bitmapData.Scan0.ToInt32();
ptr[1] = hpoint.I;
if (width % 4 == 0)
CopyMemory(ptr[0], ptr[1], width * height * PixelSize);
else
{
for (int i = 0; i < height - 1; i++)
{
ptr[1] += width;
CopyMemory(ptr[0], ptr[1], width * PixelSize);
ptr[0] += bitmapData.Stride;
}
}
res.UnlockBits(bitmapData);
}
/// <summary>
/// 将Halcon中RGB图像转换为Bitmap图像
/// </summary>
/// <param name="image">Halcon中RGB图像</param>
/// <param name="res">.net中Bitmap图像</param>
private void GenertateRGBBitmap(HObject image, out Bitmap res)
{
HTuple hred, hgreen, hblue, type, width, height;
HOperatorSet.GetImagePointer3(image, out hred, out hgreen, out hblue, out type, out width, out height);
res = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bitmapData = res.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
unsafe
{
byte* bptr = (byte*)bitmapData.Scan0;
byte* r = ((byte*)hred.I);
byte* g = ((byte*)hgreen.I);
byte* b = ((byte*)hblue.I);
for (int i = 0; i < width * height; i++)
{
bptr[i * 4] = (b)[i];
bptr[i * 4 + 1] = (g)[i];
bptr[i * 4 + 2] = (r)[i];
bptr[i * 4 + 3] = 255;
}
}
res.UnlockBits(bitmapData);
}
}