这个话题的起因是追求极速的拍图速度。
机器ppm不达标的情况下,往往对视觉的处理速度有变态的要求,为了争取处理时间最短,几十毫秒也要争取。
halcon的接口是通用接口,其速度是比不上相机厂商自己相机配套的SDK的采图速度的。
下面程序运行后,500w的CCD拍图的时间(不算显示时间)达到惊人的32毫秒,如果用halcon接口,最快的我见过是180毫秒。

- using Basler.Pylon;
- using HalconDotNet;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Diagnostics;
- using System.Drawing;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Forms;
-
- namespace WindowsFormsApplication1
- {
- public partial class Form1 : Form
- {
- private PixelDataConverter converter = new PixelDataConverter();
- ///
- /// 相机ID
- ///
- public string UserID { get { return userID; } }
- private string userID = string.Empty;
-
- private Stopwatch sw = new Stopwatch();
- private bool isOkGrab = false;
- private IntPtr latestFrameAddress = IntPtr.Zero;
- public HObject Image { get { return image; } }
- private HObject image = null;
- static Version Sfnc2_0_0 = new Version(2, 0, 0);
- private Camera camera = null;
- HTuple handle;
- public Form1()
- {
- InitializeComponent();
- }
-
- private void button1_Click(object sender, EventArgs e)
- {
- var f1=BaslerCameraInit();
- if(f1)
- {
- MessageBox.Show( Open().ToString());
- }
- }
-
-
- ///
- /// 实例化第一个找到的相机
- ///
- public bool BaslerCameraInit()
- {
- try
- {
- camera = new Camera();
- camera.StreamGrabber.ImageGrabbed -= StreamGrabber_ImageGrabbed;
- camera.StreamGrabber.ImageGrabbed+=StreamGrabber_ImageGrabbed;
- return true;
- }
- catch (Exception ex)
- {
- return false;
- //NotifyG.Error(ex.ToString());
- }
- }
-
-
- ///
- /// 根据相机UserID实例化相机
- ///
- ///
- public bool BaslerCameraInit(string userID)
- {
- try
- {
- // 枚举相机列表
- List
allCameraInfos = CameraFinder.Enumerate(); - foreach (ICameraInfo cameraInfo in allCameraInfos)
- {
- if (userID == cameraInfo[CameraInfoKey.UserDefinedName])
- {
- this.userID = userID;
- camera = new Camera(cameraInfo);
- camera.StreamGrabber.ImageGrabbed -= StreamGrabber_ImageGrabbed;
- camera.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed;
- }
- }
- if (camera == null)
- {
- //NotifyG.Error("未识别到UserID为“" + UserID + "”的相机!");
- return false;
- }
- return true;
- }
- catch (Exception ex)
- {
- return false;
- //NotifyG.Error(ex.ToString());
- }
- }
-
-
- void StreamGrabber_ImageGrabbed(object sender, ImageGrabbedEventArgs e)
- {
- try
- {
- // Acquire the image from the camera. Only show the latest image. The camera may acquire images faster than the images can be displayed.
-
- // Get the grab result.
- IGrabResult grabResult = e.GrabResult;
-
- // Check if the image can be displayed.
- if (grabResult.IsValid)
- {
- //grabTime = sw.ElapsedMilliseconds;
- //if (eventComputeGrabTime != null) eventComputeGrabTime(grabTime);
-
- //Reduce the number of displayed images to a reasonable amount if the camera is acquiring images very fast.
- // **** 降低显示帧率,减少CPU占用率 **** //
- //if (!stopWatch.IsRunning || stopWatch.ElapsedMilliseconds > 33)
- {
- //stopWatch.Restart();
- // 判断是否是黑白图片格式
- if (grabResult.PixelTypeValue == PixelType.Mono8)
- {
- //allocate the m_stream_size amount of bytes in non-managed environment
- if (latestFrameAddress == IntPtr.Zero)
- {
- latestFrameAddress = Marshal.AllocHGlobal((Int32)grabResult.PayloadSize);
- }
- converter.OutputPixelFormat = PixelType.Mono8;
- converter.Convert(latestFrameAddress, grabResult.PayloadSize, grabResult);
- HOperatorSet.GenEmptyObj(out image);
- image.Dispose();
- // 转换为Halcon图像显示
- HOperatorSet.GenImage1(out image, "byte", grabResult.Width, grabResult.Height, latestFrameAddress);
- HOperatorSet.SetPart(handle, 0, 0, grabResult.Height - 1, grabResult.Width - 1);
- }
- else if (grabResult.PixelTypeValue == PixelType.BayerBG8 || grabResult.PixelTypeValue == PixelType.BayerGB8
- || grabResult.PixelTypeValue == PixelType.BayerRG8 || grabResult.PixelTypeValue == PixelType.YUV422packed)
- {
- int imageWidth = grabResult.Width - 1;
- int imageHeight = grabResult.Height - 1;
- HOperatorSet.SetPart(handle, 0, 0, imageHeight, imageWidth);
- int payloadSize = imageWidth * imageHeight;
-
- //allocate the m_stream_size amount of bytes in non-managed environment
- if (latestFrameAddress == IntPtr.Zero)
- {
- latestFrameAddress = Marshal.AllocHGlobal((Int32)(3 * payloadSize));
- }
- converter.OutputPixelFormat = PixelType.RGB8packed; // 根据下面halcon转换的色彩格式bgr
- converter.Parameters[PLPixelDataConverter.InconvertibleEdgeHandling].SetValue("Clip");
- converter.Convert(latestFrameAddress, 3 * payloadSize, grabResult);
-
- HOperatorSet.GenImageInterleaved(out image, latestFrameAddress, "bgr",
- (HTuple)imageWidth, (HTuple)imageHeight, -1, "byte", (HTuple)imageWidth, (HTuple)imageHeight, 0, 0, -1, 0);
- }
- else
- {
- //NotifyG.Error(DeviceName + "拍照失败,相机图像格式设置");
- return;
- }
- isOkGrab = true;
- //MessageBox.Show(isOkGrab.ToString());
- // 抛出图像处理事件
- //if (EventGrab != null) EventGrab(this, new CameraGrabEventArgs(image));
- }
- }
-
- }
- catch (Exception ex)
- {
- //MessageBox.Show(ex.ToString());
- return;
- }
- finally
- {
- // Dispose the grab result if needed for returning it to the grab loop.
- e.DisposeGrabResultIfClone();
- }
- }
-
- ///
- /// 打开相机
- ///
- public bool Open()
- {
- try
- {
- if (camera.IsOpen) camera.Close();
- Thread.Sleep(200);
- camera.Open();
- var imageWidth = camera.Parameters[PLCamera.Width].GetValue(); // 获取图像宽
- var imageHeight = camera.Parameters[PLCamera.Height].GetValue(); // 获取图像高
- GetMinMaxExposureTime();
- GetMinMaxGain();
- camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame);
- //NotifyG.Debug(DeviceName + "打开相机成功:" + userID);
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.ToString());
- return false;
- }
- return true;
- }
-
- ///
- /// 关闭相机,释放相关资源
- ///
- public new bool Close()
- {
- try
- {
- camera.Close();
- camera.Dispose();
- if (Image != null)
- {
- Image.Dispose();
- }
- if (latestFrameAddress != null)
- {
- Marshal.FreeHGlobal(latestFrameAddress);
- latestFrameAddress = IntPtr.Zero;
- }
- //NotifyG.Debug(DeviceName + "关闭相机成功:" + userID);
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.ToString());
- return false;
- }
- return true;
- }
-
- ///
- /// 单张采集
- ///
- public bool GrabImage()
- {
- try
- {
- isOkGrab = false;
- sw.Restart();
- if (camera.StreamGrabber.IsGrabbing)
- {
- //NotifyG.Error("相机当前正处于采集状态!");
- return false;
- }
- else
- {
- camera.StreamGrabber.Start(1, GrabStrategy.LatestImages, GrabLoop.ProvidedByStreamGrabber);
- //while (!isOkGrab)
- //{
- // if (sw.ElapsedMilliseconds > 2000) { isOkGrab = false; return false; }
- // Thread.Sleep(1);
- //}
- //NotifyG.Debug(DeviceName + "拍照成功:" + sw.ElapsedMilliseconds);
- return true;
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.ToString());
- return false;
- }
- return true;
- }
-
- ///
- /// 开始连续采集
- ///
- public bool StartGrabbing()
- {
- try
- {
- if (camera.StreamGrabber.IsGrabbing)
- {
- //NotifyG.Error("相机当前正处于采集状态!");
- return false;
- }
- else
- {
- camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
- camera.StreamGrabber.Start(GrabStrategy.LatestImages, GrabLoop.ProvidedByStreamGrabber);
-
- return true;
- }
- }
- catch (Exception ex)
- {
- //NotifyG.Error(DeviceName + ex.ToString());
- return false;
- }
- }
-
- ///
- /// 停止连续采集
- ///
- public bool StopGrabbing()
- {
- try
- {
- if (camera.StreamGrabber.IsGrabbing)
- {
- camera.StreamGrabber.Stop();
- }
- }
- catch (Exception ex)
- {
- //NotifyG.Error(DeviceName + ex.ToString());
- }
- return true;
- }
-
-
- ///
- /// 获取最小最大曝光时间
- ///
- public void GetMinMaxExposureTime()
- {
- try
- {
- if (camera.GetSfncVersion() < Sfnc2_0_0)
- {
- var minExposureTime = camera.Parameters[PLCamera.ExposureTimeRaw].GetMinimum();
- var maxExposureTime = camera.Parameters[PLCamera.ExposureTimeRaw].GetMaximum();
- }
- else
- {
- var minExposureTime = (long)camera.Parameters[PLUsbCamera.ExposureTime].GetMinimum();
- var maxExposureTime = (long)camera.Parameters[PLUsbCamera.ExposureTime].GetMaximum();
- }
- }
- catch (Exception ex)
- {
-
- }
- }
-
- ///
- /// 获取最小最大增益
- ///
- public void GetMinMaxGain()
- {
- try
- {
- if (camera.GetSfncVersion() < Sfnc2_0_0)
- {
- var minGain = camera.Parameters[PLCamera.GainRaw].GetMinimum();
- var maxGain = camera.Parameters[PLCamera.GainRaw].GetMaximum();
- }
- else
- {
- var minGain = (long)camera.Parameters[PLUsbCamera.Gain].GetMinimum();
- var maxGain = (long)camera.Parameters[PLUsbCamera.Gain].GetMaximum();
- }
- }
- catch (Exception ex)
- {
- //NotifyG.Error(DeviceName + ex.ToString());
- }
- }
-
- private void button2_Click(object sender, EventArgs e)
- {
- Stopwatch sw1 = new Stopwatch();
- sw1.Start();
- var f1 = GrabImage();
- sw1.Stop();
- MessageBox.Show(string.Format("grab time:{0}",sw1.ElapsedMilliseconds));
- //if(f1)
- //{
- // if (null != Image)
- // HOperatorSet.DispObj(Image, hWindowControl1.Handle);
- //}
- }
-
- private void Form1_FormClosing(object sender, FormClosingEventArgs e)
- {
- if (null != camera && camera.IsOpen)
- Close();
- }
-
- private void button6_Click(object sender, EventArgs e)
- {
- try
- {
- if (null != Image && Image.IsInitialized())
- {
- //HOperatorSet.WriteImage(Image, "bmp", 0, "d:\\123.bmp");
- HOperatorSet.DispObj(Image, handle);
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
-
- private void Form1_Load(object sender, EventArgs e)
- {
- handle = hWindowControl1.HalconWindow;
-
- }
-
- private void button3_Click(object sender, EventArgs e)
- {
- timer1.Start();
- StartGrabbing();
- }
-
- private void button4_Click(object sender, EventArgs e)
- {
- timer1.Stop();
- StopGrabbing();
- }
-
- private void timer1_Tick(object sender, EventArgs e)
- {
- button6_Click(null, null);
- }
-
-
- }
- }