海康工业相机 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#基础的,可以参考下,直接上代码 BaseResult 来自于Nuget包,搜Rotion可以搜出来 LS.Standard.Data 海康的接口操作,要先引用相应的dll using MvCamCtrl.NET; using PCZD.Commons.Data.CameraModel; using PCZD.Data; using Sys…...
开发技巧,vue 中的动态组件的引用 component + is
在项目中很多时候有切换 tab 的场景,一般来说都是用 v-if 或者 v-show 然后根据各种条件来控制显示隐藏。 其实我们可以使用 vue 中的动态组件,也能实现这个效果 <!-- currentTab 改变时组件也改变 --> <component :is"currentTab"…...
MySQL 二进制安装(正式篇)
Author:Arsen Date:2025/01/24 官方参考文档:点击链接跳转 目录 规划下载安装管理FAQ 规划 OSMySQL Server Version备注CentOS 7.9 or Linux - Generic8.0.33(GNU libc) 2.17 下载 二进制包下载地址:https://downloads.mysql.…...
MongoDB 数据库备份和恢复全攻略
在当今数据驱动的时代,数据库的稳定运行和数据安全至关重要。MongoDB 作为一款流行的 NoSQL 数据库,以其灵活的文档模型和高扩展性备受青睐。然而,无论数据库多么强大,数据丢失的风险始终存在,因此掌握 MongoDB 的备份…...
K8S部署DevOps自动化运维平台
持续集成(CI) 持续集成强调开发人员提交了新代码之后,立刻自动的进行构建、(单元)测试。根据测试结果,我 们可以确定新代码和原有代码能否正确地集成在一起。持续集成过程中很重视自动化测试验证结果&#…...
工业相机 SDK 二次开发-Sherlock插件
本文介绍了 sherlock 连接相机时的插件使用。通过本套插件可连接海康的工业相机。 一.环境配置 1. 拷贝动态库 在用户安装 MVS 目录下按照如下路径 Development\ThirdPartyPlatformAdapter 找到目 录为 DalsaSherlock 的文件夹,根据 Sherlock 版本找到…...
分布式版本控制系统:Git
1 Git概述 Git官网:https://git-scm.com/ Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目Git易于学习,占地面积小,性能极快。它具有廉价的本地库、方便的暂存区域和多个工作流分支等特性…...
页高速缓存与缓冲区缓存的应用差异
页高速缓存(Page Cache)与缓冲区缓存(Buffer Cache)是计算机系统中用于提高数据访问性能的两种不同类型的缓存机制,它们的差异主要体现在以下几个方面: 缓存目的 页高速缓存:主要用于加速对磁…...
C语言编程笔记:文件处理的艺术
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 引言正文一、为什么要用文件二、文件的分…...
如何编写一个MyBatis插件?
大家好,我是锋哥。今天分享关于【Redis为什么这么快?】面试题。希望对大家有帮助; 如何编写一个MyBatis插件? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 编写 MyBatis 插件需要使用 MyBatis 提供的插件接口,MyBa…...
验证二叉搜索树(力扣98)
根据二叉搜索树的特性,我们使用中序遍历,保证节点按从小到大的顺序遍历。既然要验证,就是看在中序遍历的条件下,各个节点的大小关系是否符合二叉搜索树的特性。双指针法和适合解决这个问题,一个指针指向当前节点&#…...
C语言初阶牛客网刷题—— HJ34 图片整理【难度:中等】
1. 题目描述 牛客网在线OJ链接 Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过C语言解决。 输入描述:Lily使用的图片包括 “A…...
Golang Gin系列-7:认证和授权
在本章中,我们将探讨Gin框架中身份验证和授权的基本方面。这包括实现基本的和基于令牌的身份验证,使用基于角色的访问控制,应用中间件进行授权,以及使用HTTPS和漏洞防护保护应用程序。 实现身份认证 Basic 认证 Basic 认证是内置…...
mysql create table的用法
在MySQL中创建表的基本语法如下: CREATE TABLE table_name (column1 datatype,column2 datatype,column3 datatype,... );这里是一个例子,假设我们要创建一个名为employees的表,包含以下字段: id:一个整数类型的主键…...
蓝桥杯算法赛第25场月赛
前言 这些题对于我的难度有点大,大家感兴趣的可以来做一下,看一下,下面给大家展示一下题目 1. 桃花运走向【算法赛】 问题描述 2025 年春节,小明和小红兴致勃勃地去庙会玩耍。庙会上,一个算命先生摆摊算命…...
从介词到状语 (什么都研究一点系列)
契子 英语中介词的使用频率很高, 但在使用时本质上作为状语而成为句子成分, 没错 “本质上” 这三个字就是状语 😃 形式上是这样: 介词 -> 状语 -> 句子 常见的介词: 时间 at, 地点 on, 原因 of, 方式 in, 伴随 with, 比较 than, 条件 if 等等 下面我们开…...
CVE-2025-0411 7-zip 漏洞复现
文章目录 免责申明漏洞描述影响版本漏洞poc漏洞复现修复建议 免责申明 本文章仅供学习与交流,请勿用于非法用途,均由使用者本人负责,文章作者不为此承担任何责任 漏洞描述 此漏洞 (CVSS SCORE 7.0) 允许远程攻击者绕…...
java入门笔记基础语法篇(4)
变量 在Java中,每个变量都有一个类型(type)。在声明变量时,变量的类型位于变量 名之前。例如: int days; double salary; long earthPopulation; boolean done; 在Java中,每个声明以分号结束。变量名必须…...
学习数据结构(1)时间复杂度
1.数据结构和算法 (1)数据结构是计算机存储、组织数据的方式,指相互之间存在⼀种或多种特定关系的数据元素的集合 (2)算法就是定义良好的计算过程,取一个或一组的值为输入,并产生出一个或一组…...
存储基础 -- SCSI命令格式与使用场景
SCSI命令格式与使用场景 1. SCSI命令描述符块(CDB) 1.1 CDB基本概念 SCSI命令通过**命令描述符块(CDB, Command Descriptor Block)**表示。 CDB长度:SCSI命令根据使用场景有不同长度的CDB,常见的有6字节…...
PyTorch广告点击率预测(CTR)利用深度学习提升广告效果
目录 广告点击率预测问题数据集结构广告点击率预测模型的构建1. 数据集准备2. 构建数据加载器3. 构建深度学习模型4. 训练与评估 总结 广告点击率预测(CTR,Click-Through Rate Prediction)是在线广告领域中的重要任务,它帮助广告平…...
算法每日双题精讲 —— 二分查找(寻找旋转排序数组中的最小值,点名)
🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟 别再犹豫了!快来订阅我们的算法每日双题精讲专栏,一起踏上算法学习的精彩之旅吧💪 在算法的…...
Flutter TextPainter 计算文本高度和行数
在开发中有的时候需要去计算文本的高度或者行数,从而控制展示的内容,比如进一步设置展示控件的高度,或者根据行数进行不同的内容展示。 在原生 Android 开发时,View 的绘制流程分为 measure,layout,draw 三…...
STM32-时钟树
STM32-时钟树 时钟 时钟...
算法知识补充2
一部分:Tire树:高效地存储和查找字符串集合的数据结构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开发实践
目录 概要 整体架构流程 (一)用户注册与登录 (二)菜品浏览与点餐 (三)订单管理 (四)后台管理 部分代码展示 1.index.wxml 2.list.wxml 3.checkout.wxml 4.detail.wxml 小结优点 概要…...
WPF基础 | WPF 常用控件实战:Button、TextBox 等的基础应用
WPF基础 | WPF 常用控件实战: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…...
强化学习 - 基于策略搜索和策略优化: 高斯策略
最近在做毕设需要用强化学习来做控制,对强化学习的知识点做一下总结。 高斯策略 高斯策略属于强化学习中的基于策略优化的分支(Policy Optimization),尤其是策略梯度方法(Policy Gradient Methods) 的一部…...
126周日复盘 (166)本周回顾
关键词:帧数测试 1、上午继续各处排查,优化帧数。 中午打包测试。 显卡锁60帧,720p窗口模式,画质3下, 低负载时50-60帧,密集战斗时35-45帧,基本达到预期, 硬件占用,显…...
