当前位置: 首页 > article >正文

海康工业相机 SDK对接 Hikvision

有C#基础的,可以参考下,直接上代码

BaseResult 来自于Nuget包,搜Rotion可以搜出来 LS.Standard.Data

海康的接口操作,要先引用相应的dll

using MvCamCtrl.NET;
using PCZD.Commons.Data.CameraModel;
using PCZD.Data;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Net;
using System.Runtime.InteropServices;
using System.Threading;public class Hikvision{//调用示例//Hikvision camera = new Hikvision();//创建相机对象并实例化//camera.connectCamera("123456");//连接相机,传入相机序列号123456//camera.startCamera();//开启相机采集//camera.setExposureTime(10000);//设置曝光时间为10ms//camera.softTrigger();//发送软触发采集图像//Himage image=camera.readImage();//获取采集到且转换后的图像//camera.stopCamera();//停止相机采集//camera.closeCamera();//关闭相机public Hikvision(){InitCamera();}#region 属性public MyCamera myCamera;//相机对象public MyCamera.MV_CC_DEVICE_INFO_LIST deviceList;//设备列表public MyCamera.MV_CC_DEVICE_INFO deviceInfo;//设备对象public string seriesStr;//接收相机序列号public MyCamera.MVCC_INTVALUE stParam;//用于接收特定的参数//为读取、保存图像创建的数组bool m_bGrabbing = false;Thread m_hReceiveThread;MyCamera.MV_FRAME_OUT_INFO_EX m_stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();UInt32 m_nBufSizeForDriver = 0;IntPtr m_BufForDriver;private static Object BufForDriverLock = new Object();//保存图像使用的参数UInt32 m_nBufSizeForSaveImage = 0;IntPtr m_BufForSaveImage;//图像显示控件IntPtr image_handle;/// <summary>/// 获取实时的图像数据 委托/// </summary>public delegate void DelegateReceiveImage(Bitmap bmp);/// <summary>/// 获取实时的图像数据 委托方法/// </summary>public event DelegateReceiveImage OnReceiveImage;#endregion#region 相机参数//相机参数private float _ExposureTime;/// <summary>/// 曝光时间/// </summary>public float ExposureTime{get => _ExposureTime;}private float _Gain;/// <summary>/// 增益/// </summary>public float Gain{get => _Gain;}private float _ResultingFrameRate;/// <summary>/// 频率/// </summary>public float ResultingFrameRate{get => _ResultingFrameRate;}#endregion#region 公共操作方法/// <summary>/// 初始化相机数据/// </summary>public void InitCamera(){deviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();}/// <summary>/// 相机是否连接/// </summary>/// <returns></returns>public bool IsConnect(){return myCamera.MV_CC_IsDeviceConnected_NET();}/// <summary>/// 设置相机配置/// </summary>/// <param name="config">配置</param>public BaseResult SetCameraConfig(CameraConfig config){try{if (config == null){return new BaseResult(false, "相机参数不能为空");}if (myCamera == null){return new BaseResult(false, "相机未连接");}int Res = 0;if (config.ImageWidth > 0){Res = myCamera.MV_CC_SetIntValue_NET("Width", (uint)config.ImageWidth);if (MyCamera.MV_OK != Res){return new BaseResult(false, $"相机参数-设置相机宽度出错【{config.ImageWidth}】");}}if (config.ImageHeight > 0){Res = myCamera.MV_CC_SetIntValue_NET("Height", (uint)config.ImageHeight);if (MyCamera.MV_OK != Res){return new BaseResult(false, $"相机参数-设置相机高度出错【{config.ImageHeight}】");}}//设置连续自动曝光模式//ExposureAutoMode值为0,表示自动曝光模式关闭;//ExposureAutoMode值为1,表示单次自动曝光模式开启;//ExposureAutoMode值为2,表示连续自动曝光模式开启。uint ExposureAutoMode = config.AutoExposure ? (uint)2 : 0;Res = myCamera.MV_CC_SetExposureAutoMode_NET(ExposureAutoMode);if (MyCamera.MV_OK != Res){return new BaseResult(false, $"相机参数-设置自动 曝光,参数【{ExposureAutoMode}】");}uint GainAutoMode = config.AutoGain ? (uint)2 : (uint)0;Res = myCamera.MV_CC_SetGainMode_NET(GainAutoMode);if (MyCamera.MV_OK != Res){return new BaseResult(false, $"相机参数-设置自动 增益,参数【{GainAutoMode}】");}if (!config.AutoExposure){Res = myCamera.MV_CC_SetFloatValue_NET("ExposureTime", config.ExposureTime);if (MyCamera.MV_OK != Res){return new BaseResult(false, $"相机参数-设置曝光时间出错【{config.ExposureTime}】");}}if (!config.AutoGain){Res = myCamera.MV_CC_SetFloatValue_NET("Gain", config.Gain);if (MyCamera.MV_OK != Res){return new BaseResult(false, $"相机参数-设置增益出错【{config.Gain}】");}}Res = myCamera.MV_CC_SetFloatValue_NET("AcquisitionFrameRate", config.FrameRate);if (MyCamera.MV_OK != Res){return new BaseResult(false, $"相机参数-设置频率错误,参数【{config.FrameRate}】");}//1:触发模式  0:非触发模式Res = myCamera.MV_CC_SetEnumValue_NET("TriggerMode", 1);if (MyCamera.MV_OK != Res){return new BaseResult(false, $"相机参数-设置触发模式失败,参数【{1}】");}//触发源 7:软触发Res = myCamera.MV_CC_SetEnumValue_NET("TriggerSource", 7);if (MyCamera.MV_OK != Res){return new BaseResult(false, $"相机参数-设置触发源失败,参数【{7}】");}myCamera.MV_CC_SetIntValue_NET("GevHeartbeatTimeout", 30 * 1000);return BaseResult.Successed;}catch (Exception ex){return new BaseResult(false, ex.Message);}}/// <summary>/// 绑定显示图象控件/// </summary>/// <param name="handle"></param>public void BindDisplayControl(IntPtr handle){image_handle = handle;}/// <summary>/// 寻找设备/// </summary>public void DeviceListAcq(){deviceList.nDeviceNum = 0;int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref deviceList);if (0 != nRet){return;}}/// <summary>/// 相机修改IP/// 调用函数时可以传入需要改变的目标IP,如过没有传入则将相机IP设置为其所连接的网卡地址+1或-1/// </summary>/// <param name="IP"></param>/// <returns></returns>public BaseResult ChangeIP(string IP = ""){try{//获取相机相关信息,例如相机所连接网卡的网址IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stGigEInfo, 0);MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));IPAddress cameraIPAddress;string tempStr = "";if (IP.Trim().Equals("") || !(IPAddress.TryParse(IP, out cameraIPAddress))){//当前网卡的IP地址UInt32 nNetIp1 = (gigeInfo.nNetExport & 0xFF000000) >> 24;UInt32 nNetIp2 = (gigeInfo.nNetExport & 0x00FF0000) >> 16;UInt32 nNetIp3 = (gigeInfo.nNetExport & 0x0000FF00) >> 8;UInt32 nNetIp4 = (gigeInfo.nNetExport & 0x000000FF);//根据网卡IP设定相机IP,如果网卡ip第四位小于252,则相机ip第四位+1,否则相机IP第四位-1UInt32 cameraIp1 = nNetIp1;UInt32 cameraIp2 = nNetIp2;UInt32 cameraIp3 = nNetIp3;UInt32 cameraIp4 = nNetIp4;if (nNetIp4 < 252){cameraIp4++;}else{cameraIp4--;}tempStr = cameraIp1 + "." + cameraIp2 + "." + cameraIp3 + "." + cameraIp4;}else{tempStr = IP;}IPAddress.TryParse(tempStr, out cameraIPAddress);long cameraIP = IPAddress.NetworkToHostOrder(cameraIPAddress.Address);//设置相机掩码uint maskIp1 = (gigeInfo.nCurrentSubNetMask & 0xFF000000) >> 24;uint maskIp2 = (gigeInfo.nCurrentSubNetMask & 0x00FF0000) >> 16;uint maskIp3 = (gigeInfo.nCurrentSubNetMask & 0x0000FF00) >> 8;uint maskIp4 = (gigeInfo.nCurrentSubNetMask & 0x000000FF);IPAddress subMaskAddress;tempStr = maskIp1 + "." + maskIp2 + "." + maskIp3 + "." + maskIp4;IPAddress.TryParse(tempStr, out subMaskAddress);long maskIP = IPAddress.NetworkToHostOrder(subMaskAddress.Address);//设置网关uint gateIp1 = (gigeInfo.nDefultGateWay & 0xFF000000) >> 24;uint gateIp2 = (gigeInfo.nDefultGateWay & 0x00FF0000) >> 16;uint gateIp3 = (gigeInfo.nDefultGateWay & 0x0000FF00) >> 8;uint gateIp4 = (gigeInfo.nDefultGateWay & 0x000000FF);IPAddress gateAddress;tempStr = gateIp1 + "." + gateIp2 + "." + gateIp3 + "." + gateIp4;IPAddress.TryParse(tempStr, out gateAddress);long gateIP = IPAddress.NetworkToHostOrder(gateAddress.Address);int temp = myCamera.MV_GIGE_ForceIpEx_NET((UInt32)(cameraIP >> 32), (UInt32)(maskIP >> 32), (UInt32)(gateIP >> 32));//执行更改相机IP的命令if (temp == 0)//强制IP成功return BaseResult.Successed;//强制IP失败return BaseResult.Failed;}catch (Exception ex){//PCZDLogHelper.Error("相机修改IP异常", ex);return BaseResult.Failed;}}/// <summary>/// 连接相机/// </summary>/// <param name="id">列表设备索引 0开始</param>/// <returns></returns>public BaseResult ConnectCamera(int id){string m_SerialNumber = "";//接收设备返回的序列号int temp;//接收命令执行结果myCamera = new MyCamera();try{if (deviceList.nDeviceNum <= 0){temp = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref deviceList);//更新设备列表if (temp != 0){//设备更新成功接收命令的返回值为0,返回值不为0则为异常return new BaseResult(false, "刷新设备列表错误");}}if (id >= deviceList.nDeviceNum){return new BaseResult(false, "索引超出设备数量");}int index = id;deviceInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(deviceList.pDeviceInfo[index], typeof(MyCamera.MV_CC_DEVICE_INFO));//获取设备if (deviceInfo.nTLayerType == MyCamera.MV_GIGE_DEVICE){IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stGigEInfo, 0);MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));//m_SerialNumber = gigeInfo.chSerialNumber;//获取序列号m_SerialNumber = gigeInfo.chUserDefinedName;//获取用户名}else if (deviceInfo.nTLayerType == MyCamera.MV_USB_DEVICE){IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stUsb3VInfo, 0);MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO));m_SerialNumber = usbInfo.chUserDefinedName;}this.seriesStr = m_SerialNumber;temp = myCamera.MV_CC_CreateDevice_NET(ref deviceInfo);if (MyCamera.MV_OK != temp){//创建相机失败return new BaseResult(false, "相机创建失败");}temp = myCamera.MV_CC_OpenDevice_NET();//if (MyCamera.MV_OK != temp){//打开相机失败return new BaseResult(false, "打开相机失败");}return BaseResult.Successed;}catch (Exception ex){//PCZDLogHelper.Error("打开相机设备异常", ex);return new BaseResult(false, "打开相机设备发生异常,操作失败");}}/// <summary>/// 连接相机/// </summary>/// <param name="ip">相机IP地址 需要IP转long</param>/// <returns></returns>public BaseResult ConnectCamera(long ip){string m_SerialNumber = "";//接收设备返回的序列号int temp;//接收命令执行结果myCamera = new MyCamera();try{if (deviceList.nDeviceNum <= 0){temp = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref deviceList);//更新设备列表if (temp != 0){//设备更新成功接收命令的返回值为0,返回值不为0则为异常return new BaseResult(false, "刷新设备列表错误");}}bool isFind = false;for (int index = 0; index < deviceList.nDeviceNum; index++){deviceInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(deviceList.pDeviceInfo[index], typeof(MyCamera.MV_CC_DEVICE_INFO));//获取设备if (deviceInfo.nTLayerType == MyCamera.MV_GIGE_DEVICE){//使用IP就只有网口通讯类型了IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stGigEInfo, 0);MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));if (gigeInfo.nCurrentIp == ip){m_SerialNumber = gigeInfo.chUserDefinedName;//获取用户名isFind = true;break;}}}if (!isFind){return new BaseResult(false, $"未找到相应IP的相机设备,IP:[{IPHelper.LongToIp(ip)}]");}this.seriesStr = m_SerialNumber;temp = myCamera.MV_CC_CreateDevice_NET(ref deviceInfo);if (MyCamera.MV_OK != temp){//创建相机失败return new BaseResult(false, "相机创建失败");}temp = myCamera.MV_CC_OpenDevice_NET();//if (MyCamera.MV_OK != temp){//打开相机失败return new BaseResult(false, "打开相机失败");}return BaseResult.Successed;}catch (Exception ex){//PCZDLogHelper.Error("打开相机设备异常", ex);return new BaseResult(false, "打开相机设备发生异常,操作失败");}}/// <summary>/// 相机开始采集/// </summary>/// <returns></returns>public BaseResult StartCamera(){//采集标识m_bGrabbing = true;//收集回调数据的处理线程m_hReceiveThread = new Thread(ReceiveThreadProcess);m_hReceiveThread.Start();m_stFrameInfo.nFrameLen = 0;//取流之前先清除帧长度m_stFrameInfo.enPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined;// ch:开始采集 | en:Start Grabbingint nRet = myCamera.MV_CC_StartGrabbing_NET();if (MyCamera.MV_OK != nRet){m_bGrabbing = false;m_hReceiveThread.Join();return BaseResult.Failed;}return BaseResult.Successed;}/// <summary>/// 停止相机采集/// </summary>/// <returns></returns>public BaseResult StopCamera(){m_bGrabbing = false;m_hReceiveThread?.Join();if (myCamera == null)return BaseResult.Successed;int temp = myCamera.MV_CC_StopGrabbing_NET();if (MyCamera.MV_OK != temp)return BaseResult.Failed;return BaseResult.Successed;}/// <summary>/// 关闭相机/// </summary>/// <returns></returns>public BaseResult CloseCamera(){if (myCamera == null)return BaseResult.Successed;if (m_bGrabbing){var res = StopCamera();//停止相机采集if (!res)return res;}int temp = myCamera.MV_CC_CloseDevice_NET();if (MyCamera.MV_OK != temp)return BaseResult.Failed;temp = myCamera.MV_CC_DestroyDevice_NET();if (MyCamera.MV_OK != temp)return BaseResult.Failed;return BaseResult.Successed;}/// <summary>/// 获取相机参数/// 如:曝光时间 、增益、频率等/// </summary>public void GetCameraParam(){try{if (myCamera == null)return;MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();int nRet = myCamera.MV_CC_GetFloatValue_NET("ExposureTime", ref stParam);if (MyCamera.MV_OK == nRet){_ExposureTime = stParam.fCurValue;}nRet = myCamera.MV_CC_GetFloatValue_NET("Gain", ref stParam);if (MyCamera.MV_OK == nRet){_Gain = stParam.fCurValue;}nRet = myCamera.MV_CC_GetFloatValue_NET("ResultingFrameRate", ref stParam);if (MyCamera.MV_OK == nRet){_ResultingFrameRate = stParam.fCurValue;}}catch (Exception ex){//PCZDLogHelper.Error("获取相机参数发生异常", ex);}}/// <summary>/// 保存参数/// 0-- 成功  1--失败/// </summary>/// <param name="exTime">曝光时间</param>/// <param name="gain">增益</param>/// <param name="fRate">频率</param>/// <returns></returns>public BaseResult SetCameraParam(float exTime, float gain, float fRate){try{myCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);int nRet = myCamera.MV_CC_SetFloatValue_NET("ExposureTime", exTime);if (nRet != MyCamera.MV_OK){return new BaseResult(false, $"设置曝光时间错误,参数【{exTime}】");}myCamera.MV_CC_SetEnumValue_NET("GainAuto", 0);nRet = myCamera.MV_CC_SetFloatValue_NET("Gain", gain);if (nRet != MyCamera.MV_OK){return new BaseResult(false, $"设置增益错误,参数【{gain}】");}nRet = myCamera.MV_CC_SetFloatValue_NET("AcquisitionFrameRate", fRate);if (nRet != MyCamera.MV_OK){return new BaseResult(false, $"设置频率错误,参数【{fRate}】");}return BaseResult.Successed;}catch (Exception ex){//PCZDLogHelper.Error("设置相机参数发生异常", ex);return BaseResult.Failed;}}/// <summary>/// 软触发一次/// 注意:软触发采集图像需要将相机设置为触发模式,并设置触发源为soft。/// </summary>/// <param name="triggerString">TriggerSoftware</param>/// <returns></returns>public BaseResult SoftTrigger(string triggerString = "TriggerSoftware"){int temp = myCamera.MV_CC_SetCommandValue_NET(triggerString);if (MyCamera.MV_OK != temp)return BaseResult.Failed;return BaseResult.Successed;}/// <summary>/// 设置图像宽度/// </summary>/// <param name="width">设置Int型参数</param>/// <returns></returns>public BaseResult SetWidth(uint width){int temp = myCamera.MV_CC_SetIntValue_NET("Width", width);if (MyCamera.MV_OK != temp)return BaseResult.Failed;return BaseResult.Successed;}/// <summary>/// 获取图像宽度/// </summary>/// <returns></returns>public uint GetWidth(){if (myCamera == null)return 0;MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();int temp = myCamera.MV_CC_GetIntValue_NET("Width", ref stParam);if (MyCamera.MV_OK == temp)return stParam.nCurValue;return 0;}/// <summary>/// 设置触发事件/// </summary>/// <param name="TriggerMode"> 1:On 触发模式 0:Off 非触发模式</param>/// <returns></returns>public BaseResult SetTriggerMode(uint TriggerMode){int temp = myCamera.MV_CC_SetEnumValue_NET("TriggerMode", TriggerMode);if (MyCamera.MV_OK != temp)return BaseResult.Failed;return BaseResult.Successed;}/// <summary>/// 设置触发源(方式)/// 0 - Line0;/// 1 - Line1;/// 2 - Line2;/// 3 - Line3;/// 4 - Counter;/// 7 - Software;/// </summary>/// <param name="way">  0 - Line0; 1 - Line1;2 - Line2; 3 - Line3; 4 - Counter;7 - Software;</param>/// <returns></returns>public BaseResult SetTriggerWay(uint way){int temp = myCamera.MV_CC_SetEnumValue_NET("TriggerSource", way);if (MyCamera.MV_OK != temp)return BaseResult.Failed;return BaseResult.Successed;}/// <summary>/// 设置曝光时间(us),成功返回0失败返回-1/// </summary>/// <param name="ExposureTime">曝光时间(us)</param>/// <returns></returns>public BaseResult SetExposureTime(uint ExposureTime){int temp = myCamera.MV_CC_SetFloatValue_NET("ExposureTime", ExposureTime);if (MyCamera.MV_OK != temp)return BaseResult.Failed;return BaseResult.Successed;}/// <summary>/// 设置心跳时间,成功返回0失败返回-1/// </summary>/// <param name="heartBeatTime"></param>/// <returns></returns>public BaseResult SetHeartBeatTime(uint heartBeatTime){//心跳时间最小为500uint tempTime = heartBeatTime > 500 ? heartBeatTime : 500;int temp = myCamera.MV_CC_SetIntValue_NET("GevHeartbeatTimeout", tempTime);if (MyCamera.MV_OK != temp)return BaseResult.Failed;return BaseResult.Successed;}/// <summary>/// 输出一张Bitmap图片/// </summary>/// <param name="bmp"></param>/// <returns></returns>public BaseResult SaveBmp(out Bitmap bmp){bmp = new Bitmap(1, 1);try{if (!m_bGrabbing){return new BaseResult(false, "未开启采集");}if (RemoveCustomPixelFormats(m_stFrameInfo.enPixelType)){return new BaseResult(false, "自定义像素格式");}IntPtr pTemp = IntPtr.Zero;MyCamera.MvGvspPixelType enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined;if (m_stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8 || m_stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed){pTemp = m_BufForDriver;enDstPixelType = m_stFrameInfo.enPixelType;}else{UInt32 nSaveImageNeedSize = 0;MyCamera.MV_PIXEL_CONVERT_PARAM stConverPixelParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();lock (BufForDriverLock){if (m_stFrameInfo.nFrameLen == 0){return new BaseResult(false, "获取bitmap图像失败");}if (IsMonoData(m_stFrameInfo.enPixelType)){enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;nSaveImageNeedSize = (uint)m_stFrameInfo.nWidth * m_stFrameInfo.nHeight;}else if (IsColorData(m_stFrameInfo.enPixelType)){enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed;nSaveImageNeedSize = (uint)m_stFrameInfo.nWidth * m_stFrameInfo.nHeight * 3;}else{return new BaseResult(false, "无效的像素类型");}if (m_nBufSizeForSaveImage < nSaveImageNeedSize){if (m_BufForSaveImage != IntPtr.Zero){Marshal.Release(m_BufForSaveImage);}m_nBufSizeForSaveImage = nSaveImageNeedSize;m_BufForSaveImage = Marshal.AllocHGlobal((Int32)m_nBufSizeForSaveImage);}stConverPixelParam.nWidth = m_stFrameInfo.nWidth;stConverPixelParam.nHeight = m_stFrameInfo.nHeight;stConverPixelParam.pSrcData = m_BufForDriver;stConverPixelParam.nSrcDataLen = m_stFrameInfo.nFrameLen;stConverPixelParam.enSrcPixelType = m_stFrameInfo.enPixelType;stConverPixelParam.enDstPixelType = enDstPixelType;stConverPixelParam.pDstBuffer = m_BufForSaveImage;stConverPixelParam.nDstBufferSize = m_nBufSizeForSaveImage;int nRet = myCamera.MV_CC_ConvertPixelType_NET(ref stConverPixelParam);if (MyCamera.MV_OK != nRet){return new BaseResult(false, "像素类型转换失败");}pTemp = m_BufForSaveImage;}}lock (BufForDriverLock){if (enDstPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8){//Mono8 转 Bitmapbmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 1, PixelFormat.Format8bppIndexed, pTemp);ColorPalette cp = bmp.Palette;for (int i = 0; i < 256; i++){cp.Entries[i] = Color.FromArgb(i, i, i);}bmp.Palette = cp;bmp.Save(OpenCV.bmpFile, ImageFormat.Bmp);}else{//BGR8 转 Bitmaptry{bmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 3, PixelFormat.Format24bppRgb, pTemp);bmp.Save(OpenCV.bmpFile, ImageFormat.Bmp);}catch{return new BaseResult(false, "生成图像失败");}}}return BaseResult.Successed;}catch (Exception ex){//PCZDLogHelper.Error("保存图像发生异常", ex);return new BaseResult(false, "保存图像异常");}}#endregion#region 私有方法/// <summary>/// 获取图像的回调线程/// </summary>private void ReceiveThreadProcess(){MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();int nRet = myCamera.MV_CC_GetIntValue_NET("PayloadSize", ref stParam);if (MyCamera.MV_OK != nRet){return;}UInt32 nPayloadSize = stParam.nCurValue;if (nPayloadSize > m_nBufSizeForDriver){if (m_BufForDriver != IntPtr.Zero){Marshal.Release(m_BufForDriver);}m_nBufSizeForDriver = nPayloadSize;m_BufForDriver = Marshal.AllocHGlobal((Int32)m_nBufSizeForDriver);}if (m_BufForDriver == IntPtr.Zero){return;}MyCamera.MV_FRAME_OUT_INFO_EX stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO();while (m_bGrabbing){try{lock (BufForDriverLock){nRet = myCamera.MV_CC_GetOneFrameTimeout_NET(m_BufForDriver, nPayloadSize, ref stFrameInfo, 1000);if (nRet == MyCamera.MV_OK){m_stFrameInfo = stFrameInfo;}}if (nRet == MyCamera.MV_OK){if (RemoveCustomPixelFormats(stFrameInfo.enPixelType)){continue;}if (image_handle != IntPtr.Zero){stDisplayInfo.hWnd = image_handle;}stDisplayInfo.pData = m_BufForDriver;stDisplayInfo.nDataLen = stFrameInfo.nFrameLen;stDisplayInfo.nWidth = stFrameInfo.nWidth;stDisplayInfo.nHeight = stFrameInfo.nHeight;stDisplayInfo.enPixelType = stFrameInfo.enPixelType;myCamera.MV_CC_DisplayOneFrame_NET(ref stDisplayInfo);Bitmap bmp = null;if (stDisplayInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8){//Mono8 转 Bitmapbmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 1, PixelFormat.Format8bppIndexed, stDisplayInfo.pData);ColorPalette cp = bmp.Palette;for (int i = 0; i < 256; i++){cp.Entries[i] = Color.FromArgb(i, i, i);}bmp.Palette = cp;//bmp.Save("image.bmp", ImageFormat.Bmp);}else{//BGR8 转 Bitmaptry{bmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 3, PixelFormat.Format24bppRgb, stDisplayInfo.pData);//bmp.Save("image.bmp", ImageFormat.Bmp);}catch{bmp = null;}}if (bmp != null)OnReceiveImage?.Invoke(bmp);}else{Thread.Sleep(5);}}catch (Exception ex){}finally{Thread.Sleep(0);}}}/// <summary>/// 去除自定义的像素格式 /// </summary>/// <param name="enPixelFormat"></param>/// <returns></returns>private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat){Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000));if (0x80000000 == nResult){return true;}else{return false;}}/// <summary>/// 判断是否为黑白图像/// </summary>/// <param name="enGvspPixelType"></param>/// <returns></returns>private Boolean IsMonoData(MyCamera.MvGvspPixelType enGvspPixelType){switch (enGvspPixelType){case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:return true;default:return false;}}/// <summary>/// 判断是否彩色照片/// </summary>/// <param name="enGvspPixelType"></param>/// <returns></returns>private Boolean IsColorData(MyCamera.MvGvspPixelType enGvspPixelType){switch (enGvspPixelType){case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed:case MyCamera.MvGvspPixelType.PixelType_Gvsp_YCBCR411_8_CBYYCRYY:return true;default:return false;}}#endregion}

相关文章:

海康工业相机 SDK对接 Hikvision

有C#基础的&#xff0c;可以参考下&#xff0c;直接上代码 BaseResult 来自于Nuget包&#xff0c;搜Rotion可以搜出来 LS.Standard.Data 海康的接口操作&#xff0c;要先引用相应的dll using MvCamCtrl.NET; using PCZD.Commons.Data.CameraModel; using PCZD.Data; using Sys…...

开发技巧,vue 中的动态组件的引用 component + is

在项目中很多时候有切换 tab 的场景&#xff0c;一般来说都是用 v-if 或者 v-show 然后根据各种条件来控制显示隐藏。 其实我们可以使用 vue 中的动态组件&#xff0c;也能实现这个效果 <!-- currentTab 改变时组件也改变 --> <component :is"currentTab"…...

MySQL 二进制安装(正式篇)

Author&#xff1a;Arsen Date&#xff1a;2025/01/24 官方参考文档&#xff1a;点击链接跳转 目录 规划下载安装管理FAQ 规划 OSMySQL Server Version备注CentOS 7.9 or Linux - Generic8.0.33(GNU libc) 2.17 下载 二进制包下载地址&#xff1a;https://downloads.mysql.…...

MongoDB 数据库备份和恢复全攻略

在当今数据驱动的时代&#xff0c;数据库的稳定运行和数据安全至关重要。MongoDB 作为一款流行的 NoSQL 数据库&#xff0c;以其灵活的文档模型和高扩展性备受青睐。然而&#xff0c;无论数据库多么强大&#xff0c;数据丢失的风险始终存在&#xff0c;因此掌握 MongoDB 的备份…...

K8S部署DevOps自动化运维平台

持续集成&#xff08;CI&#xff09; 持续集成强调开发人员提交了新代码之后&#xff0c;立刻自动的进行构建、&#xff08;单元&#xff09;测试。根据测试结果&#xff0c;我 们可以确定新代码和原有代码能否正确地集成在一起。持续集成过程中很重视自动化测试验证结果&#…...

工业相机 SDK 二次开发-Sherlock插件

本文介绍了 sherlock 连接相机时的插件使用。通过本套插件可连接海康的工业相机。 一&#xff0e;环境配置 1. 拷贝动态库 在用户安装 MVS 目录下按照如下路径 Development\ThirdPartyPlatformAdapter 找到目 录为 DalsaSherlock 的文件夹&#xff0c;根据 Sherlock 版本找到…...

分布式版本控制系统:Git

1 Git概述 Git官网&#xff1a;https://git-scm.com/ Git是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目Git易于学习&#xff0c;占地面积小&#xff0c;性能极快。它具有廉价的本地库、方便的暂存区域和多个工作流分支等特性…...

页高速缓存与缓冲区缓存的应用差异

页高速缓存&#xff08;Page Cache&#xff09;与缓冲区缓存&#xff08;Buffer Cache&#xff09;是计算机系统中用于提高数据访问性能的两种不同类型的缓存机制&#xff0c;它们的差异主要体现在以下几个方面&#xff1a; 缓存目的 页高速缓存&#xff1a;主要用于加速对磁…...

C语言编程笔记:文件处理的艺术

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文一、为什么要用文件二、文件的分…...

如何编写一个MyBatis插件?

大家好&#xff0c;我是锋哥。今天分享关于【Redis为什么这么快?】面试题。希望对大家有帮助&#xff1b; 如何编写一个MyBatis插件&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 编写 MyBatis 插件需要使用 MyBatis 提供的插件接口&#xff0c;MyBa…...

验证二叉搜索树(力扣98)

根据二叉搜索树的特性&#xff0c;我们使用中序遍历&#xff0c;保证节点按从小到大的顺序遍历。既然要验证&#xff0c;就是看在中序遍历的条件下&#xff0c;各个节点的大小关系是否符合二叉搜索树的特性。双指针法和适合解决这个问题&#xff0c;一个指针指向当前节点&#…...

C语言初阶牛客网刷题—— HJ34 图片整理【难度:中等】

1. 题目描述 牛客网在线OJ链接 Lily上课时使用字母数字图片教小朋友们学习英语单词&#xff0c;每次都需要把这些图片按照大小&#xff08;ASCII码值从小到大&#xff09;排列收好。请大家给Lily帮忙&#xff0c;通过C语言解决。 输入描述&#xff1a;Lily使用的图片包括 “A…...

Golang Gin系列-7:认证和授权

在本章中&#xff0c;我们将探讨Gin框架中身份验证和授权的基本方面。这包括实现基本的和基于令牌的身份验证&#xff0c;使用基于角色的访问控制&#xff0c;应用中间件进行授权&#xff0c;以及使用HTTPS和漏洞防护保护应用程序。 实现身份认证 Basic 认证 Basic 认证是内置…...

mysql create table的用法

在MySQL中创建表的基本语法如下&#xff1a; CREATE TABLE table_name (column1 datatype,column2 datatype,column3 datatype,... );这里是一个例子&#xff0c;假设我们要创建一个名为employees的表&#xff0c;包含以下字段&#xff1a; id&#xff1a;一个整数类型的主键…...

蓝桥杯算法赛第25场月赛

前言 这些题对于我的难度有点大&#xff0c;大家感兴趣的可以来做一下&#xff0c;看一下&#xff0c;下面给大家展示一下题目 1. 桃花运走向【算法赛】 问题描述 2025 年春节&#xff0c;小明和小红兴致勃勃地去庙会玩耍。庙会上&#xff0c;一个算命先生摆摊算命&#xf…...

从介词到状语 (什么都研究一点系列)

契子 英语中介词的使用频率很高, 但在使用时本质上作为状语而成为句子成分, 没错 “本质上” 这三个字就是状语 &#x1f603; 形式上是这样: 介词 -> 状语 -> 句子 常见的介词: 时间 at, 地点 on, 原因 of, 方式 in, 伴随 with, 比较 than, 条件 if 等等 下面我们开…...

CVE-2025-0411 7-zip 漏洞复现

文章目录 免责申明漏洞描述影响版本漏洞poc漏洞复现修复建议 免责申明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 漏洞描述 此漏洞 &#xff08;CVSS SCORE 7.0&#xff09; 允许远程攻击者绕…...

java入门笔记基础语法篇(4)

变量 在Java中&#xff0c;每个变量都有一个类型&#xff08;type&#xff09;。在声明变量时&#xff0c;变量的类型位于变量 名之前。例如&#xff1a; int days; double salary; long earthPopulation; boolean done; 在Java中&#xff0c;每个声明以分号结束。变量名必须…...

学习数据结构(1)时间复杂度

1.数据结构和算法 &#xff08;1&#xff09;数据结构是计算机存储、组织数据的方式&#xff0c;指相互之间存在⼀种或多种特定关系的数据元素的集合 &#xff08;2&#xff09;算法就是定义良好的计算过程&#xff0c;取一个或一组的值为输入&#xff0c;并产生出一个或一组…...

存储基础 -- SCSI命令格式与使用场景

SCSI命令格式与使用场景 1. SCSI命令描述符块&#xff08;CDB&#xff09; 1.1 CDB基本概念 SCSI命令通过**命令描述符块&#xff08;CDB, Command Descriptor Block&#xff09;**表示。 CDB长度&#xff1a;SCSI命令根据使用场景有不同长度的CDB&#xff0c;常见的有6字节…...

PyTorch广告点击率预测(CTR)利用深度学习提升广告效果

目录 广告点击率预测问题数据集结构广告点击率预测模型的构建1. 数据集准备2. 构建数据加载器3. 构建深度学习模型4. 训练与评估 总结 广告点击率预测&#xff08;CTR&#xff0c;Click-Through Rate Prediction&#xff09;是在线广告领域中的重要任务&#xff0c;它帮助广告平…...

算法每日双题精讲 —— 二分查找(寻找旋转排序数组中的最小值,点名)

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 别再犹豫了&#xff01;快来订阅我们的算法每日双题精讲专栏&#xff0c;一起踏上算法学习的精彩之旅吧&#x1f4aa; 在算法的…...

Flutter TextPainter 计算文本高度和行数

在开发中有的时候需要去计算文本的高度或者行数&#xff0c;从而控制展示的内容&#xff0c;比如进一步设置展示控件的高度&#xff0c;或者根据行数进行不同的内容展示。 在原生 Android 开发时&#xff0c;View 的绘制流程分为 measure&#xff0c;layout&#xff0c;draw 三…...

STM32-时钟树

STM32-时钟树 时钟 时钟...

算法知识补充2

一部分&#xff1a;Tire树&#xff1a;高效地存储和查找字符串集合的数据结构acwing835 #include<iostream> #include<cstring> using namespace std; const int N100010; int son[N][26],cnt[N],idx; char str[N]; void insert(char str[]){int p0;for(int i0;st…...

微信小程序-点餐(美食屋)02开发实践

目录 概要 整体架构流程 &#xff08;一&#xff09;用户注册与登录 &#xff08;二&#xff09;菜品浏览与点餐 &#xff08;三&#xff09;订单管理 &#xff08;四&#xff09;后台管理 部分代码展示 1.index.wxml 2.list.wxml 3.checkout.wxml 4.detail.wxml 小结优点 概要…...

WPF基础 | WPF 常用控件实战:Button、TextBox 等的基础应用

WPF基础 | WPF 常用控件实战&#xff1a;Button、TextBox 等的基础应用 一、前言二、Button 控件基础2.1 Button 的基本定义与显示2.2 按钮样式设置2.3 按钮大小与布局 三、Button 的交互功能3.1 点击事件处理3.2 鼠标悬停与离开效果3.3 按钮禁用与启用 四、TextBox 控件基础4.…...

CentOS7使用源码安装PHP8教程整理

CentOS7使用源码安装PHP8教程整理 下载安装包解压下载的php tar源码包安装所需的一些依赖扩展库安装前的配置修改配置文件1、进入php8的安装包 配置环境变量开机自启启动服务创建软连接常见问题1、checking for icu-uc > 50.1 icu-io icu-i18n... no2、configure: error: Pa…...

强化学习 - 基于策略搜索和策略优化: 高斯策略

最近在做毕设需要用强化学习来做控制&#xff0c;对强化学习的知识点做一下总结。 高斯策略 高斯策略属于强化学习中的基于策略优化的分支&#xff08;Policy Optimization&#xff09;&#xff0c;尤其是策略梯度方法&#xff08;Policy Gradient Methods&#xff09; 的一部…...

126周日复盘 (166)本周回顾

关键词&#xff1a;帧数测试 1、上午继续各处排查&#xff0c;优化帧数。 中午打包测试。 显卡锁60帧&#xff0c;720p窗口模式&#xff0c;画质3下&#xff0c; 低负载时50-60帧&#xff0c;密集战斗时35-45帧&#xff0c;基本达到预期&#xff0c; 硬件占用&#xff0c;显…...