当前位置:   article > 正文

C# 获取海康相机_mvcameracontrol.dll

mvcameracontrol.dll

一、简介


由于工作关系,本人最近使用到了海康的网口及USB3.0接口的工业相机。现将相关内容进行整理记录。


二、开发环境


64位VS2013 +C#
Halcon12
海康MVS3.0.0

三、项目搭建

1、添加引用

引用海康相机动态库(MvCameraControl.Net.dll)
在VS项目文件中添加添加引用,如下图

引用MVS安装目录下MVS\Development\DotNet\MvCameraControl.Net.dll这个文件。


2、创建相机类


鼠标右键单击工程项目–添加–类,选择“类”,输入类的名称,例如Hikvision,点击右下角的“添加”。
在项目中使用海康相机时,为便于程序编写,可引入如下的命名空间:
using MvCamCtrl.NET;


1.创建需要用到的全局变量
  1. public MyCamera myCamera;//相机对象
  2. private MyCamera.MV_CC_DEVICE_INFO_LIST deviceList;//设备列表
  3. private MyCamera.MV_CC_DEVICE_INFO deviceInfo;//设备对象
  4. private string seriesStr;//接收相机序列号
  5. private MyCamera.MVCC_INTVALUE stParam;//用于接收特定的参数
  6. //为读取、保存图像创建的数组
  7. UInt32 m_nBufSizeForDriver = 4096 * 3000;
  8. byte[] m_pBufForDriver = new byte[4096 * 3000];
  9. UInt32 m_nBufSizeForSaveImage = 4096 * 3000 * 3 + 3000;
  10. byte[] m_pBufForSaveImage = new byte[4096 * 3000 * 3 + 3000];

创建相关函数
1.创建构造函数

  1. //在构造函数中实例化设备列表对象
  2. public Hikvision()
  3. {
  4. deviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
  5. }
2.创建改变相机IP的函数
  1. //成功返回0失败返回-1
  2. //调用函数时可以传入需要改变的目标IP,如过没有传入则将相机IP设置为其所连接的网卡地址+1或-1
  3. public int changeIP(string IP = "")
  4. {
  5. try
  6. {
  7. //获取相机相关信息,例如相机所连接网卡的网址
  8. IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stGigEInfo, 0);
  9. MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
  10. IPAddress cameraIPAddress;
  11. string tempStr = "";
  12. if (IP.Trim().Equals("") || !(IPAddress.TryParse(IP, out cameraIPAddress)))
  13. {
  14. //当前网卡的IP地址
  15. UInt32 nNetIp1 = (gigeInfo.nNetExport & 0xFF000000) >> 24;
  16. UInt32 nNetIp2 = (gigeInfo.nNetExport & 0x00FF0000) >> 16;
  17. UInt32 nNetIp3 = (gigeInfo.nNetExport & 0x0000FF00) >> 8;
  18. UInt32 nNetIp4 = (gigeInfo.nNetExport & 0x000000FF);
  19. //根据网卡IP设定相机IP,如果网卡ip第四位小于252,则相机ip第四位+1,否则相机IP第四位-1
  20. UInt32 cameraIp1 = nNetIp1;
  21. UInt32 cameraIp2 = nNetIp2;
  22. UInt32 cameraIp3 = nNetIp3;
  23. UInt32 cameraIp4 = nNetIp4;
  24. if (nNetIp4 < 252)
  25. {
  26. cameraIp4++;
  27. }
  28. else
  29. {
  30. cameraIp4--;
  31. }
  32. tempStr = cameraIp1 + "." + cameraIp2 + "." + cameraIp3 + "." + cameraIp4;
  33. }
  34. else
  35. {
  36. tempStr = IP;
  37. }
  38. IPAddress.TryParse(tempStr, out cameraIPAddress);
  39. long cameraIP = IPAddress.NetworkToHostOrder(cameraIPAddress.Address);
  40. //设置相机掩码
  41. uint maskIp1 = (gigeInfo.nCurrentSubNetMask & 0xFF000000) >> 24;
  42. uint maskIp2 = (gigeInfo.nCurrentSubNetMask & 0x00FF0000) >> 16;
  43. uint maskIp3 = (gigeInfo.nCurrentSubNetMask & 0x0000FF00) >> 8;
  44. uint maskIp4 = (gigeInfo.nCurrentSubNetMask & 0x000000FF);
  45. IPAddress subMaskAddress;
  46. tempStr = maskIp1 + "." + maskIp2 + "." + maskIp3 + "." + maskIp4;
  47. IPAddress.TryParse(tempStr, out subMaskAddress);
  48. long maskIP = IPAddress.NetworkToHostOrder(subMaskAddress.Address);
  49. //设置网关
  50. uint gateIp1 = (gigeInfo.nDefultGateWay & 0xFF000000) >> 24;
  51. uint gateIp2 = (gigeInfo.nDefultGateWay & 0x00FF0000) >> 16;
  52. uint gateIp3 = (gigeInfo.nDefultGateWay & 0x0000FF00) >> 8;
  53. uint gateIp4 = (gigeInfo.nDefultGateWay & 0x000000FF);
  54. IPAddress gateAddress;
  55. tempStr = gateIp1 + "." + gateIp2 + "." + gateIp3 + "." + gateIp4;
  56. IPAddress.TryParse(tempStr, out gateAddress);
  57. long gateIP = IPAddress.NetworkToHostOrder(gateAddress.Address);
  58. int temp = myCamera.MV_GIGE_ForceIpEx_NET((UInt32)(cameraIP >> 32), (UInt32)(maskIP >> 32), (UInt32)(gateIP >> 32));//执行更改相机IP的命令
  59. if (temp == 0)
  60. //强制IP成功
  61. return 0;
  62. //强制IP失败
  63. return -1;
  64. }
  65. catch
  66. {
  67. return -1;
  68. }
  69. }
3.创建相机连接函数
  1. public int connectCamera(string id)//连接相机,返回-1为失败,0为成功
  2. {
  3. this.seriesStr = id;
  4. string m_SerialNumber = "";//接收设备返回的序列号
  5. int temp;//接收命令执行结果
  6. myCamera = new MyCamera();
  7. try
  8. {
  9. temp = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref deviceList);//更新设备列表
  10. if (temp != 0)
  11. {
  12. //设备更新成功接收命令的返回值为0,返回值不为0则为异常
  13. return -1;
  14. }
  15. //强制相机IP
  16. for (int i = 0; i < deviceList.nDeviceNum; i++)
  17. {
  18. /*******该部分用于获取相机名称、序列号等,从而对指定的相机进行IP更改******/
  19. //更改IP的函数中也有该部分,重叠部分程序可进行相应的简化,本文暂不做处理
  20. deviceInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(deviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));//获取设备信息
  21. IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stGigEInfo, 0);
  22. MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
  23. /*****************************************************************/
  24. m_SerialNumber = gigeInfo.chUserDefinedName;
  25. if(deviceInfo.nTLayerType == MyCamera.MV_GIGE_DEVICE)
  26. {
  27. //判断是否为网口相机
  28. if (seriesStr.Equals(m_SerialNumber))
  29. {
  30. //如果相机用户名正确则修改IP
  31. temp = myCamera.MV_CC_CreateDevice_NET(ref deviceInfo);//更改IP前需要创建设备对象
  32. forceIP();
  33. }
  34. }
  35. }
  36. //更改IP后需要重新刷新设备列表,否则打开相机时会报错
  37. temp = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref deviceList);//更新设备列表
  38. for (int i = 0; i < deviceList.nDeviceNum; i++)
  39. {
  40. deviceInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(deviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));//获取设备
  41. if (deviceInfo.nTLayerType == MyCamera.MV_GIGE_DEVICE)
  42. {
  43. IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stGigEInfo, 0);
  44. MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
  45. //m_SerialNumber = gigeInfo.chSerialNumber;//获取序列号
  46. m_SerialNumber = gigeInfo.chUserDefinedName;//获取用户名
  47. }
  48. else if (deviceInfo.nTLayerType == MyCamera.MV_USB_DEVICE)
  49. {
  50. IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stUsb3VInfo, 0);
  51. MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO));
  52. m_SerialNumber = usbInfo.chUserDefinedName;
  53. }
  54. if (seriesStr.Equals(m_SerialNumber))
  55. {
  56. temp = myCamera.MV_CC_CreateDevice_NET(ref deviceInfo);
  57. if (MyCamera.MV_OK != temp)
  58. {
  59. //创建相机失败
  60. return -1;
  61. }
  62. temp = myCamera.MV_CC_OpenDevice_NET();//
  63. if (MyCamera.MV_OK != temp)
  64. {
  65. //打开相机失败
  66. return -1;
  67. }
  68. return 0;
  69. }
  70. continue;
  71. }
  72. }
  73. catch
  74. {
  75. return -1;
  76. }
  77. return 0;
  78. }
4.创建开始采集、停止采集、关闭相机函数
  1. public int startCamera()//相机开始采集,返回0为成功,-1为失败
  2. {
  3. int temp = myCamera.MV_CC_StartGrabbing_NET();
  4. if (MyCamera.MV_OK != temp)
  5. return -1;
  6. return 0;
  7. }
  8. public int stopCamera()//停止相机采集,返回0为成功,-1为失败
  9. {
  10. int temp = myCamera.MV_CC_StopGrabbing_NET();
  11. if (MyCamera.MV_OK != temp )
  12. return -1;
  13. return 0;
  14. }
  15. public int closeCamera()//关闭相机,返回0为成功,-1为失败
  16. {
  17. int temp = stopCamera();//停止相机采集
  18. if (MyCamera.MV_OK != temp )
  19. return -1;
  20. temp = myCamera.MV_CC_CloseDevice_NET();
  21. if (MyCamera.MV_OK != temp )
  22. return -1;
  23. temp = myCamera.MV_CC_DestroyDevice_NET();
  24. if (MyCamera.MV_OK != temp )
  25. return -1;
  26. return 0;
  27. }
5.创建发送软触发函数
  1. //发送成功返回0,失败返回-1
  2. public int softTrigger()
  3. {
  4. int temp = myCamera.MV_CC_SetCommandValue_NET("TriggerSoftware");
  5. if (MyCamera.MV_OK != temp )
  6. return -1;
  7. return 0;
  8. }
6.创建读取图像函数
函数返回Halcon图像库可以处理的Himage格式。
如何添加halcon图像库请自行百度,网上教程非常多
  1. //读取成功返回Himage图像,失败返回NULL
  2. public HImage readImage()
  3. {
  4. UInt32 nPayloadSize = 0;
  5. int temp = myCamera.MV_CC_GetIntValue_NET("PayloadSize", ref stParam);
  6. if (MyCamera.MV_OK != temp)
  7. {
  8. return null;
  9. }
  10. nPayloadSize = stParam.nCurValue;
  11. if (nPayloadSize > m_nBufSizeForDriver)
  12. {
  13. m_nBufSizeForDriver = nPayloadSize;
  14. m_pBufForDriver = new byte[m_nBufSizeForDriver];
  15. m_nBufSizeForSaveImage = m_nBufSizeForDriver * 3 + 2048;
  16. m_pBufForSaveImage = new byte[m_nBufSizeForSaveImage];
  17. }
  18. IntPtr pData = Marshal.UnsafeAddrOfPinnedArrayElement(m_pBufForDriver, 0);
  19. MyCamera.MV_FRAME_OUT_INFO_EX stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
  20. temp = myCamera.MV_CC_GetOneFrameTimeout_NET(pData, m_nBufSizeForDriver, ref stFrameInfo, 1000);//获取一帧图像,超时时间设置为1000
  21. if (MyCamera.MV_OK != temp)
  22. {
  23. return null;
  24. }
  25. HImage image = new HImage();
  26. if (IsMonoData(stFrameInfo.enPixelType))//判断是否为黑白图像
  27. {
  28. //如果是黑白图像,则利用Halcon图像库中的GenImage1算子来构建图像
  29. image .GenImage1("byte", (int)stFrameInfo.nWidth, (int)stFrameInfo.nHeight, pData);
  30. }
  31. else
  32. {
  33. if (stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
  34. {
  35. //如果彩色图像是RGB8格式,则可以直接利用GenImageInterleaved算子来构建图像
  36. image .GenImageInterleaved(pData, "rgb", (int)stFrameInfo.nWidth, (int)stFrameInfo.nHeight, 0, "byte", (int)stFrameInfo.nWidth, (int)stFrameInfo.nHeight, 0, 0, -1, 0);
  37. }
  38. else
  39. {
  40. //如果彩色图像不是RGB8格式,则需要将图像格式转换为RGB8。
  41. IntPtr pBufForSaveImage = IntPtr.Zero;
  42. if (pBufForSaveImage == IntPtr.Zero)
  43. {
  44. pBufForSaveImage = Marshal.AllocHGlobal((int)(stFrameInfo.nWidth * stFrameInfo.nHeight * 3 + 2048));
  45. }
  46. MyCamera.MV_PIXEL_CONVERT_PARAM stConverPixelParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();
  47. stConverPixelParam.nWidth = stFrameInfo.nWidth;
  48. stConverPixelParam.nHeight = stFrameInfo.nHeight;
  49. stConverPixelParam.pSrcData = pData;
  50. stConverPixelParam.nSrcDataLen = stFrameInfo.nFrameLen;
  51. stConverPixelParam.enSrcPixelType = stFrameInfo.enPixelType;
  52. stConverPixelParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;//在此处选择需要转换的目标类型
  53. stConverPixelParam.pDstBuffer = pBufForSaveImage;
  54. stConverPixelParam.nDstBufferSize = (uint)(stFrameInfo.nWidth * stFrameInfo.nHeight * 3 + 2048);
  55. myCamera.MV_CC_ConvertPixelType_NET(ref stConverPixelParam);
  56. image .GenImageInterleaved(pBufForSaveImage, "rgb", (int)stFrameInfo.nWidth, (int)stFrameInfo.nHeight, 0, "byte", (int)stFrameInfo.nWidth, (int)stFrameInfo.nHeight, 0, 0, -1, 0);
  57. //释放指针
  58. Marshal.FreeHGlobal(pBufForSaveImage);
  59. }
  60. }
  61. return image ;
  62. }
7.在海康MVS安装目录下MVS\Development\Documentations\MvCameraNode.xlsx是一个关于参数设置的文档,可以参考MVS并结合该文档进行相应参数的设置,非常方便。

8.实例化相机对象,并通过软触发采集图像
  1. Hikvision camera = new Hikvision();//创建相机对象并实例化
  2. camera.connectCamera("123456");//连接相机,传入相机序列号123456
  3. camera.startCamera();//开启相机采集
  4. camera.setExposureTime(10000);//设置曝光时间为10ms
  5. camera.softTrigger();//发送软触发采集图像
  6. Himage image=camera.readImage();//获取采集到且转换后的图像
  7. camera.stopCamera();//停止相机采集
  8. camera.closeCamera();//关闭相机


————————————————
版权声明:本文为CSDN博主「大_樱_桃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/biggestcherry/article/details/87011094

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/883364
推荐阅读
相关标签
  

闽ICP备14008679号