引入
代码
public class MVCamera : InterfaceCamera{#region 属性字段PictureBox pb_ShowImage;//图像框tSdkCameraDevInfo[] tCameraDevInfoList;CameraSdkStatus status;public static CameraHandle[] m_hCamera; // 句柄CAMERA_SNAP_PROC m_CaptureCallback;IntPtr m_iCaptureCallbackCtx; //图像回调函数的上下文参数CAMERA_SNAP_PROC pCaptureCallOld = null;IntPtr[] m_ImageBuffer; // 预览通道RGB图像缓存tSdkCameraCapbility tCameraCapability; // 相机特性描述HTuple hv_Width, hv_Height, hv_WindowHandle;#endregion#region 构造函数public MVCamera(){}public MVCamera(PictureBox pictureBox){this.pb_ShowImage = pictureBox;}#endregion/// <summary>/// 关闭相机/// </summary>/// <param name="index"></param>public void CloseCamera(int index){}/// <summary>/// 查找相机/// </summary>/// <returns></returns>public int EnumCamera(){//查找相机枚举设备int Nums = 0;status = MvApi.CameraEnumerateDevice(out tCameraDevInfoList);if (tCameraDevInfoList?.Length > 0){Nums = tCameraDevInfoList.Length;m_hCamera = new CameraHandle[tCameraDevInfoList.Length];m_ImageBuffer = new IntPtr[tCameraDevInfoList.Length];}if (status == CameraSdkStatus.CAMERA_STATUS_SUCCESS){for (int i = 0; i < Nums; i++){//2初始化相机+status = MvApi.CameraInit(ref tCameraDevInfoList[i], -1, -1, ref m_hCamera[i]);}}return Nums;}/// <summary>/// 采集图像/// </summary>/// <param name="index"></param>/// <param name="image"></param>public void GrabImage(int index, out HObject image){tSdkFrameHead pFrameHead;IntPtr uRawBuffer;//rawbuffer由SDK内部申请。应用层不要调用delete之类的释放函数HObject ho_BImageRGB2;#region 转Halcon变量//采集图像MvApi.CameraGetImageBuffer(m_hCamera[index], out pFrameHead, out uRawBuffer, 500);//图像处理,将原始输出转换为RGB格式的位图数据,同时叠加白平衡、饱和度、LUT等ISP处理。MvApi.CameraImageProcess(m_hCamera[index], uRawBuffer, m_ImageBuffer[index], ref pFrameHead);//图像变量转换两种方式第一种:gen_image_interleaved(多通道)//HOperatorSet.GenImageInterleaved(out ho_BImageRGB2, m_ImageBuffer, "bgr", pFrameHead.iWidth,//pFrameHead.iHeight, -1, "byte", pFrameHead.iWidth, pFrameHead.iHeight, 0, 0, -1, 0);//第二种方式 gen_image3_extern gen_image1_externint bytesPerLineRGB = (pFrameHead.iWidth * 3 + 3) / 4 * 4;//24位彩色图像每行所在字节数 int bytesPerLineGray = (pFrameHead.iWidth + 3) / 4 * 4;//8位灰度图每行所在字节数byte[] bufferRGB = new byte[bytesPerLineRGB * pFrameHead.iHeight]; byte[] bufferB = new byte[bytesPerLineGray * pFrameHead.iHeight];byte[] bufferG = new byte[bytesPerLineGray * pFrameHead.iHeight];byte[] bufferR = new byte[bytesPerLineGray * pFrameHead.iHeight];byte[] bufferGray = new byte[bytesPerLineGray * pFrameHead.iHeight];//将相机中采集的非托管内存数据 Copy到托管内存字节数组中 Marshal.Copy(m_ImageBuffer[index], bufferRGB, 0, bytesPerLineRGB * pFrameHead.iHeight);for (int i = 0; i < pFrameHead.iHeight; i++)//如果是24位才这样拆{for (int j = 0; j < pFrameHead.iWidth; j++){bufferB[i * bytesPerLineGray + j] = bufferRGB[i * bytesPerLineRGB + j * 3 + 0];//B分量bufferG[i * bytesPerLineGray + j] = bufferRGB[i * bytesPerLineRGB + j * 3 + 1];//G分量bufferR[i * bytesPerLineGray + j] = bufferRGB[i * bytesPerLineRGB + j * 3 + 2];//R分量}}unsafe{fixed (byte* pr = bufferR, pg = bufferG, pb = bufferB){HOperatorSet.GenImage3Extern(out ho_BImageRGB2, "byte", pFrameHead.iWidth, pFrameHead.iHeight, new IntPtr(pr), new IntPtr(pg), new IntPtr(pb), 0);}}HOperatorSet.Rgb1ToGray(ho_BImageRGB2, out image);if (index == 0){HOperatorSet.RotateImage(image, out image, 90, "constant");HOperatorSet.MirrorImage(image, out image, "row");}else{HOperatorSet.RotateImage(image, out image, 90, "constant");HOperatorSet.MirrorImage(image, out image, "row");}MvApi.CameraReleaseImageBuffer(m_hCamera[index], uRawBuffer);#endregion}/// <summary>/// 打开相机/// </summary>/// <param name="index"></param>public void OpenCamera(int index){//获取当前相机设备信息MvApi.CameraGetCapability(m_hCamera[index], out tCameraCapability);//申请内存m_ImageBuffer[index] = Marshal.AllocHGlobal(tCameraCapability.sResolutionRange.iWidthMax * tCameraCapability.sResolutionRange.iHeightMax * 3 + 1024);//设置开始采集 MvApi.CameraPlay(m_hCamera[index]);}}