C#中如何连接海康威视

.NET
547
0
0
2023-04-04
标签   C#
目录
  • C# 连接海康威视
  • C#海康威视无法加载DLL“..\bin\HCNetSDK.dll”
  • 项目场景
  • 问题描述
  • 原因分析
  • 解决方案
  • 总结

C# 连接海康威视

 /// <summary>
/// 海康威视SDK
/// </summary>
public class SDK_Hikvision : SDK_Camera
{
    /// <summary>
    /// 相机名称
    /// </summary>
    private string Cam_name;
    /// <summary>
    /// 相机实例
    /// </summary>
    private MyCamera m_MyCamera;
    /// <summary>
    ///  图像回调 相机名称图源
    /// </summary>
    public override event ImageDelegate Image_Delegate;
   
    IntPtr pBufForSaveImage = IntPtr.Zero;
    //注册图像回调函数
    MyCamera.cbOutputExdelegate ImageCallback;
    /// <summary>
    /// 是否已连接相机
    /// </summary>
    public override bool IsOpen {
        get {
            if (m_MyCamera!=null)
            {
                return m_MyCamera.MV_CC_IsDeviceConnected_NET();
            }
            return false;
        }
    }
    /// <summary>
    /// 
    /// </summary>
    ~SDK_Hikvision()
    {
    }
    /// <summary>
    /// 实时采集
    /// </summary>
    public override void Acquisition()
    {
        if (m_MyCamera == null) return;
        if (GetTriggerMode()==TriggerMode.On)
        {
            SetTriggerMode(TriggerMode.Off);
        }
        m_MyCamera.MV_CC_StartGrabbing_NET();
    }
    /// <summary>
    /// 关闭采集
    /// </summary>
    public override void CloseConsecutive()
    {
        if (m_MyCamera == null) return;
        m_MyCamera.MV_CC_StopGrabbing_NET();
    }
    /// <summary>
    /// 关闭相机
    /// </summary>
    public override void Close_Camera()
    {
        if (m_MyCamera == null) return;
        m_MyCamera.MV_CC_StopGrabbing_NET();
        if (pBufForSaveImage != IntPtr.Zero)
        {
            Marshal.Release(pBufForSaveImage);
        }
        /*   m_MyCamera.MV_CC_StopGrabbing_NET();
           m_MyCamera.MV_CC_ClearImageBuffer_NET();
           m_MyCamera.MV_CC_CloseDevice_NET();
           //销毁设备句柄 
           m_MyCamera.MV_CC_DestroyDevice_NET();*/
 
        m_MyCamera.MV_CC_CloseDevice_NET();
        m_MyCamera.MV_CC_DestroyDevice_NET();
    }
    /// <summary>
    /// 获取曝光
    /// </summary>
    /// <returns></returns>
    public override double GetExposureTime()
    {
        if (m_MyCamera!=null)
        {
            MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
            m_MyCamera.MV_CC_GetFloatValue_NET("ExposureTime", ref stParam);
            return stParam.fCurValue;
        }
      return 0;
    }
    /// <summary>
    /// 获取增益
    /// </summary>
    /// <returns></returns>
    public override double GetGainRaw()
    {
        if (m_MyCamera != null)
        {
            MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
            m_MyCamera.MV_CC_GetFloatValue_NET("Gain", ref stParam);
            return stParam.fCurValue;
        }
      return 0;
    }
    /// <summary>
    /// 获取触发模式
    /// </summary>
    /// <returns></returns>
    public override TriggerMode GetTriggerMode()
    {
        if (m_MyCamera != null)
        {
            MyCamera.MVCC_ENUMVALUE MVCC_SOURCE = new MyCamera.MVCC_ENUMVALUE();
            m_MyCamera.MV_CC_GetEnumValue_NET("TriggerMode", ref MVCC_SOURCE);
            MyCamera.MV_CAM_TRIGGER_MODE Value = (MyCamera.MV_CAM_TRIGGER_MODE)MVCC_SOURCE.nCurValue;
            return (TriggerMode)MVCC_SOURCE.nCurValue;
        }
        return TriggerMode.On;
    }
    /// <summary>
    /// 获取触发源
    /// </summary>
    /// <returns></returns>
    public override TriggerSource GetTriggerSource()
    {
        if (m_MyCamera != null)
        {
            MyCamera.MVCC_ENUMVALUE MVCC_SOURCE = new MyCamera.MVCC_ENUMVALUE();
            m_MyCamera.MV_CC_GetEnumValue_NET("TriggerSource", ref MVCC_SOURCE);
            MyCamera.MV_CAM_TRIGGER_SOURCE Value = (MyCamera.MV_CAM_TRIGGER_SOURCE)MVCC_SOURCE.nCurValue;
            return (TriggerSource)MVCC_SOURCE.nCurValue;
        }
        return TriggerSource.Software;
    }
  
    /// <summary>
    /// 打开相机
    /// </summary>
    /// <param name="Cam_Name">相机名称</param>
    /// <returns></returns>
    public override bool Open_Camera(string Cam_Name)
    {
        System.GC.Collect();
        MyCamera.MV_CC_DEVICE_INFO_LIST m_stDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
        int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_stDeviceList);
        if (0 != nRet)
        {
            return false;
        }
        for (int i = 0; i < m_stDeviceList.nDeviceNum; i++)
        {
            MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_stDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
            if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
            {
                IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);
                //MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
                MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
                this.Cam_name = gigeInfo.chUserDefinedName;
            }
            else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
            {
                IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stUsb3VInfo, 0);
                MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO));
                //MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stUsb3VInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO));
                this.Cam_name = usbInfo.chUserDefinedName;
            }
            if (Cam_Name == this.Cam_name)
            {
                //打开设备
                if (null == m_MyCamera)
                {
                    m_MyCamera = new MyCamera();
                }                   
                //创建设备 
                nRet = m_MyCamera.MV_CC_CreateDevice_NET(ref device);
                if (MyCamera.MV_OK != nRet)
                {
                    return false;
                }
                //打开设备 
                nRet = m_MyCamera.MV_CC_OpenDevice_NET();
                if (MyCamera.MV_OK != nRet)
                {
                    //打开设备失败 销毁设备句柄 
                    m_MyCamera.MV_CC_DestroyDevice_NET();
                    return false;
                }
                // 探测网络最佳包大小(只对GigE相机有效)
                if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
                {
                    int nPacketSize = m_MyCamera.MV_CC_GetOptimalPacketSize_NET();
                    if (nPacketSize > 0)
                    {
                        m_MyCamera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);                            
                    }
                }
                //设置相机模式
                //连续采集
                m_MyCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS);
                //触发模式
                m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
                //设置图像缓存节点个数
                m_MyCamera.MV_CC_SetImageNodeNum_NET(8);
                //注册图像回调函数
                ImageCallback = new MyCamera.cbOutputExdelegate(GrabImage);
                //来设置数据回调函数。
                nRet =m_MyCamera.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);
                if (MyCamera.MV_OK != nRet)
                {
                    return false;
                }
                //开启采集
                m_MyCamera.MV_CC_StartGrabbing_NET();
                return true;
            }
        }
        return false;
    }     
    /// <summary>
    /// 图像注册事件
    /// </summary>
    /// <param name="pData"></param>
    /// <param name="pFrameInfo"></param>
    /// <param name="pUser"></param>
    private void GrabImage(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
    {
        byte[] SrcData = new byte[pFrameInfo.nHeight * pFrameInfo.nWidth];//图像数据
      //  Marshal.Copy(pData, SrcData, 0, (int)pFrameInfo.nFrameLen);
        HObject Hobj;
        HOperatorSet.GenEmptyObj(out Hobj);
        byte[] imageData = IntPtr2Bytes(pData, (int)(pFrameInfo.nFrameLen));
        uint imageLen = pFrameInfo.nFrameLen;
        uint imageWidth = pFrameInfo.nWidth;
        uint imageHight = pFrameInfo.nHeight;
        if (IsMonoPixelFormat(pFrameInfo.enPixelType))//黑白
        {
            Hobj.Dispose();
            HOperatorSet.GenImage1(out Hobj, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, pData);
        }
        else
        {
            if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)//RGB
            {
                Hobj.Dispose();
                HOperatorSet.GenImageInterleaved(out  Hobj, pData, "rgb", (int)pFrameInfo.nWidth, (int)pFrameInfo.nHeight, 0, "byte", (int)pFrameInfo.nWidth, (int)pFrameInfo.nHeight, 0, 0, -1, 0);
            }
            else
            {                   
                if (pBufForSaveImage == IntPtr.Zero)
                {
                    pBufForSaveImage = Marshal.AllocHGlobal((int)(pFrameInfo.nWidth * pFrameInfo.nHeight * 3 + 2048));
                }
                MyCamera.MV_PIXEL_CONVERT_PARAM stConverPixelParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();
                stConverPixelParam.nWidth = pFrameInfo.nWidth; 
                stConverPixelParam.nHeight = pFrameInfo.nHeight;
                stConverPixelParam.pSrcData = pData;
                stConverPixelParam.nSrcDataLen = pFrameInfo.nFrameLen;
                stConverPixelParam.enSrcPixelType = pFrameInfo.enPixelType;
                stConverPixelParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;//在此处选择需要转换的目标类型
                stConverPixelParam.pDstBuffer = pBufForSaveImage;
                stConverPixelParam.nDstBufferSize = (uint)(pFrameInfo.nWidth * pFrameInfo.nHeight * 3 + 2048);
                m_MyCamera.MV_CC_ConvertPixelType_NET(ref stConverPixelParam);
                Hobj.Dispose();
                HOperatorSet.GenImageInterleaved(out  Hobj, pBufForSaveImage, "rgb", (int)pFrameInfo.nWidth, (int)pFrameInfo.nHeight, 0, "byte", (int)pFrameInfo.nWidth, (int)pFrameInfo.nHeight, 0, 0, -1, 0);
            }               
        }
        if (Hobj.CountObj() > 0)
        {
            Image_Delegate?.Invoke(Cam_name, Hobj?.Clone());
        }           
        Hobj?.Dispose();            
        System.GC.Collect();
    }
    public static byte[] IntPtr2Bytes(IntPtr ptr, int size)
    {
 
        if (ptr == IntPtr.Zero)
        {
            return null;
        }
 
        byte[] bytes = new byte[size];
        Marshal.Copy(ptr, bytes, 0, size);
        return bytes;
    }
    /// <summary>
    /// 黑白图像
    /// </summary>
    /// <param name="enType"></param>
    /// <returns></returns>
    private bool IsMonoPixelFormat(MyCamera.MvGvspPixelType enType)
    {
        switch (enType)
        {
            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="enType"></param>
    /// <returns></returns>
    private bool IsColorPixelFormat(MyCamera.MvGvspPixelType enType)
    {
        switch (enType)
        {
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGBA8_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGRA8_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed:
            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_BayerGB10:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12:
            case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed:
                return true;
            default:
                return false;
        }
    }
    /// <summary>
    /// 设置曝光
    /// </summary>
    /// <param name="Value"></param>
    /// <returns></returns>
    public override double SetExposureTime(double Value)
    {
        m_MyCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
        MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
        m_MyCamera.MV_CC_GetFloatValue_NET("ExposureTime", ref stParam);
        if (Value <= stParam.fMax && Value >= stParam.fMin)
        {
            m_MyCamera.MV_CC_SetFloatValue_NET("ExposureTime", (float)Value);
        }
        return stParam.fCurValue;
    }
    /// <summary>
    /// 设置增益
    /// </summary>
    /// <param name="Value"></param>
    /// <returns></returns>
    public override double SetGainRaw(double Value)
    {
        m_MyCamera.MV_CC_SetEnumValue_NET("GainAuto", 0);
        MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
        m_MyCamera.MV_CC_GetFloatValue_NET("Gain", ref stParam);
        if (Value <= stParam.fMax && Value >= stParam.fMin)
        {
            m_MyCamera.MV_CC_SetFloatValue_NET("Gain", (float)Value);
        }
        return stParam.fCurValue;
    }
    /// <summary>
    /// 获取触发模式
    /// </summary>
    /// <param name="mode"></param>
    public override void SetTriggerMode(TriggerMode mode)
    {
        if (mode == TriggerMode.Off)
        {
            m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
        }
        else
        {
            m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
        }
    }
    /// <summary>
    /// 设置触发源
    /// </summary>
    /// <param name="source"></param>
    public override void SetTriggerSource(TriggerSource source)
    {
        m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
        switch (source)
        {
            case TriggerSource.Line1:
                m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
                break;
            case TriggerSource.Line2:
                m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE1);
                break;
            case TriggerSource.Software:
                m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
                break;
            default:
                break;
        }
    }
    /// <summary>
    /// 软触发一次
    /// </summary>
    public override bool TriggerSoftware()
    {
        if (m_MyCamera == null) return false;
        if (GetTriggerMode()==TriggerMode.Off)
        {
            m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
            m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
        }           
        m_MyCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
        return true;
    }
}

C#海康威视无法加载DLL“..\bin\HCNetSDK.dll”

项目场景

c#海康威视:System.DllNotFoundException:“无法加载 DLL“…\bin\HCNetSDK.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。”

问题描述

将海康威视的SDK直接复制到我的项目中时,使用到SDK中的方法就出现这个异常。

将demo里的dll放在bin文件夹和bin\Debug文件夹里时也会出错。

在这里插入图片描述

原因分析

这个肯定是路径出错了,不然不会报这个找不到指定模块的异常。

解决方案

在代码中选中方法函数,右键转到定义:

在这里插入图片描述

将\bin\HCNetSDK.dll改成\Debug\HCNetSDK,这样就不会报错了。