当前位置:   article > 正文

Qt+opencv+Linux+海康工业相机连接_linux添加相机

linux添加相机

前言

       本人需要在树莓派上部署深度学习推理模型 ,由于本实验室只有海康工业相机,因此通过借鉴博客和自主调试,完成了模型的部署。本文主要讲述如何在基于linux的Qt中成功连接海康工业相机,第一次尝试写博客,练练手感。

一、前期准备

      1、安装海康工业相机自带的MVS

       官方网址:海康机器人-机器视觉-下载中心 (hikrobotics.com),下载自己对应的版本,解压后有适应各种架构计算机的压缩包,其中常用的是:

① 树梅派:armhf架构

② jetson nano: aarch64架构

③ PC: x86_64架构

解压后安装:
里面有一个INSTALL文件可以参考步骤如下:

安装前,需要获取root权限:sudo su 或 su root

tar-xzvf 文件名: 解压压缩包

cd MVS-2.1.0_x86_64_20201228/ : 进入文件根目录

./setup.sh  :运行安装脚本

安装完成在路径下/opt/MVS下会看到:

其中:

Sample:示例程序

lib:封装好的so库

include:头文件

doc:说明文档

最后测试是否安装成功,进入到bin文件夹,即在终端输入命令

  1. cd /opt/MVS/bin
  2. ./MVS

如果成功弹出如下界面,表示安装成功

       2、opencv的编译

        opencv的编译算是一个运气活,如果你是那个天选之子的话可能一次就成功,博主本人在ubuntu上安装基本比较顺利,但是在树莓派上编译经历了一整天的折磨,通过修改各种报错,最后总算是成功了,这里不再具体讲如何编译,直接上链接

          参考博客:linux下编译opencv_opencv linux编译-CSDN博客

        3、Qt的安装

        参考博客: linux环境下安装QT超详细_qt-opensource-linux-CSDN博客

二、qt中.pro文件配置opencv

需要添加的文件路径大概就是这些,具体需要根据自己的opencv编译路径来对应 

  1. QT += core gui
  2. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  3. CONFIG += c++11
  4. # The following define makes your compiler emit warnings if you use
  5. # any Qt feature that has been marked deprecated (the exact warnings
  6. # depend on your compiler). Please consult the documentation of the
  7. # deprecated API in order to know how to port your code away from it.
  8. DEFINES += QT_DEPRECATED_WARNINGS
  9. # You can also make your code fail to compile if it uses deprecated APIs.
  10. # In order to do so, uncomment the following line.
  11. # You can also select to disable deprecated APIs only up to a certain version of Qt.
  12. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
  13. SOURCES += \
  14. MvCamera.cpp \
  15. main.cpp \
  16. mainwidget.cpp \
  17. mythread.cpp \
  18. widget.cpp \
  19. yolov5.cpp
  20. HEADERS += \
  21. MvCamera.h \
  22. mainwidget.h \
  23. mythread.h \
  24. widget.h \
  25. yolov5.h
  26. FORMS += \
  27. mainwidget.ui \
  28. widget.ui
  29. QMAKE_LFLAGS += -no-pie
  30. ###################################对opencv的支持
  31. INCLUDEPATH += /usr/local/include \
  32. /usr/local/include/opencv4 \
  33. /usr/local/include/opencv4/opencv2\
  34. $$PWD/include
  35. LIBS += /usr/local/lib/libopencv_calib3d.so \
  36. /usr/local/lib/libopencv_core.so \
  37. /usr/local/lib/libopencv_features2d.so \
  38. /usr/local/lib/libopencv_flann.so \
  39. /usr/local/lib/libopencv_highgui.so \
  40. /usr/local/lib/libopencv_imgcodecs.so \
  41. /usr/local/lib/libopencv_imgproc.so \
  42. /usr/local/lib/libopencv_ml.so \
  43. /usr/local/lib/libopencv_objdetect.so \
  44. /usr/local/lib/libopencv_photo.so \
  45. #/usr/local/lib/libopencv_shape.so \
  46. /usr/local/lib/libopencv_stitching.so \
  47. #/usr/local/lib/libopencv_superres.so \
  48. /usr/local/lib/libopencv_videoio.so \
  49. /usr/local/lib/libopencv_video.so\
  50. /usr/local/lib/libopencv_dnn.so \
  51. -L$$PWD/64/ -lMvCameraControl
  52. /usr/local/lib/libopencv_videostab.so
  53. ###################################
  54. # Default rules for deployment.
  55. qnx: target.path = /tmp/$${TARGET}/bin
  56. else: unix:!android: target.path = /opt/$${TARGET}/bin
  57. !isEmpty(target.path): INSTALLS += target
  58. DISTFILES += \
  59. test2.pro.user
  60. RESOURCES += \
  61. res.qrc

 

三、程序运行

1、相机依赖的h文件和c文件

 ①  .h文件

  1. #ifndef MVCAMERA_H
  2. #define MVCAMERA_H
  3. #include "MvCameraControl.h"
  4. #include <string.h>
  5. #include <QDebug>
  6. #include <stdio.h>
  7. #ifndef MV_NULL
  8. #define MV_NULL 0
  9. #endif
  10. #include "opencv2/opencv.hpp"
  11. #include "opencv2/imgproc/types_c.h"
  12. class CMvCamera
  13. {
  14. public:
  15. CMvCamera();
  16. ~CMvCamera();
  17. // ch:获取SDK版本号 | en:Get SDK Version
  18. static int GetSDKVersion();
  19. // ch:枚举设备 | en:Enumerate Device
  20. static int EnumDevices(unsigned int nTLayerType,
  21. MV_CC_DEVICE_INFO_LIST *pstDevList);
  22. // ch:判断设备是否可达 | en:Is the device accessible
  23. static bool IsDeviceAccessible(MV_CC_DEVICE_INFO *pstDevInfo,
  24. unsigned int nAccessMode);
  25. // ch:打开设备 | en:Open Device
  26. int Open(MV_CC_DEVICE_INFO *pstDeviceInfo);
  27. // ch:关闭设备 | en:Close Device
  28. int Close();
  29. // ch:判断相机是否处于连接状态 | en:Is The Device Connected
  30. bool IsDeviceConnected();
  31. // ch:注册图像数据回调 | en:Register Image Data CallBack
  32. int RegisterImageCallBack(
  33. void(__stdcall *cbOutput)(unsigned char *pData,
  34. MV_FRAME_OUT_INFO_EX *pFrameInfo,
  35. void *pUser),
  36. void *pUser);
  37. // ch:开启抓图 | en:Start Grabbing
  38. int StartGrabbing();
  39. // ch:停止抓图 | en:Stop Grabbing
  40. int StopGrabbing();
  41. // ch:主动获取一帧图像数据 | en:Get one frame initiatively
  42. int GetImageBuffer(MV_FRAME_OUT *pFrame, int nMsec);
  43. // ch:释放图像缓存 | en:Free image buffer
  44. int FreeImageBuffer(MV_FRAME_OUT *pFrame);
  45. // ch:主动获取一帧图像数据 | en:Get one frame initiatively
  46. int GetOneFrameTimeout(unsigned char *pData, unsigned int *pnDataLen,
  47. unsigned int nDataSize,
  48. MV_FRAME_OUT_INFO_EX *pFrameInfo, int nMsec);
  49. // ch:显示一帧图像 | en:Display one frame image
  50. int DisplayOneFrame(MV_DISPLAY_FRAME_INFO *pDisplayInfo);
  51. // ch:设置SDK内部图像缓存节点个数 | en:Set the number of the internal image
  52. // cache nodes in SDK
  53. int SetImageNodeNum(unsigned int nNum);
  54. // ch:获取设备信息 | en:Get device information
  55. int GetDeviceInfo(MV_CC_DEVICE_INFO *pstDevInfo);
  56. // ch:获取GEV相机的统计信息 | en:Get detect info of GEV camera
  57. int GetGevAllMatchInfo(MV_MATCH_INFO_NET_DETECT *pMatchInfoNetDetect);
  58. // ch:获取U3V相机的统计信息 | en:Get detect info of U3V camera
  59. int GetU3VAllMatchInfo(MV_MATCH_INFO_USB_DETECT *pMatchInfoUSBDetect);
  60. // ch:获取和设置Int型参数,如 Width和Height,详细内容参考SDK安装目录下的
  61. // MvCameraNode.xlsx 文件 en:Get Int type parameters, such as Width and
  62. // Height, for details please refer to MvCameraNode.xlsx file under SDK
  63. // installation directory
  64. // int GetIntValue(IN const char* strKey, OUT MVCC_INTVALUE_EX* pIntValue);
  65. int GetIntValue(IN const char *strKey, OUT unsigned int *pnValue);
  66. int SetIntValue(IN const char *strKey, IN int64_t nValue);
  67. // ch:获取和设置Enum型参数,如 PixelFormat,详细内容参考SDK安装目录下的
  68. // MvCameraNode.xlsx 文件 en:Get Enum type parameters, such as PixelFormat,
  69. // for details please refer to MvCameraNode.xlsx file under SDK installation
  70. // directory
  71. int GetEnumValue(IN const char *strKey, OUT MVCC_ENUMVALUE *pEnumValue);
  72. int SetEnumValue(IN const char *strKey, IN unsigned int nValue);
  73. int SetEnumValueByString(IN const char *strKey, IN const char *sValue);
  74. // ch:获取和设置Float型参数,如
  75. // ExposureTime和Gain,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
  76. // en:Get Float type parameters, such as ExposureTime and Gain, for details
  77. // please refer to MvCameraNode.xlsx file under SDK installation directory
  78. int GetFloatValue(IN const char *strKey, OUT MVCC_FLOATVALUE *pFloatValue);
  79. int SetFloatValue(IN const char *strKey, IN float fValue);
  80. // ch:获取和设置Bool型参数,如 ReverseX,详细内容参考SDK安装目录下的
  81. // MvCameraNode.xlsx 文件 en:Get Bool type parameters, such as ReverseX, for
  82. // details please refer to MvCameraNode.xlsx file under SDK installation
  83. // directory
  84. int GetBoolValue(IN const char *strKey, OUT bool *pbValue);
  85. int SetBoolValue(IN const char *strKey, IN bool bValue);
  86. // ch:获取和设置String型参数,如 DeviceUserID,详细内容参考SDK安装目录下的
  87. // MvCameraNode.xlsx 文件UserSetSave en:Get String type parameters, such as
  88. // DeviceUserID, for details please refer to MvCameraNode.xlsx file under
  89. // SDK installation directory
  90. int GetStringValue(IN const char *strKey, MVCC_STRINGVALUE *pStringValue);
  91. int SetStringValue(IN const char *strKey, IN const char *strValue);
  92. // ch:执行一次Command型命令,如 UserSetSave,详细内容参考SDK安装目录下的
  93. // MvCameraNode.xlsx 文件 en:Execute Command once, such as UserSetSave, for
  94. // details please refer to MvCameraNode.xlsx file under SDK installation
  95. // directory
  96. int CommandExecute(IN const char *strKey);
  97. // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal
  98. // package size(It only works for the GigE camera)
  99. int GetOptimalPacketSize(unsigned int *pOptimalPacketSize);
  100. // ch:注册消息异常回调 | en:Register Message Exception CallBack
  101. int RegisterExceptionCallBack(
  102. void(__stdcall *cbException)(unsigned int nMsgType, void *pUser),
  103. void *pUser);
  104. // ch:注册单个事件回调 | en:Register Event CallBack
  105. int RegisterEventCallBack(
  106. const char *pEventName,
  107. void(__stdcall *cbEvent)(MV_EVENT_OUT_INFO *pEventInfo, void *pUser),
  108. void *pUser);
  109. // ch:强制IP | en:Force IP
  110. int ForceIp(unsigned int nIP, unsigned int nSubNetMask,
  111. unsigned int nDefaultGateWay);
  112. // ch:配置IP方式 | en:IP configuration method
  113. int SetIpConfig(unsigned int nType);
  114. // ch:设置网络传输模式 | en:Set Net Transfer Mode
  115. int SetNetTransMode(unsigned int nType);
  116. // ch:像素格式转换 | en:Pixel format conversion
  117. int ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM *pstCvtParam);
  118. // ch:保存图片 | en:save image
  119. int SaveImage(MV_SAVE_IMAGE_PARAM_EX *pstParam);
  120. // ch:保存图片为文件 | en:Save the image as a file
  121. //int SaveImageToFile(MV_SAVE_IMG_TO_FILE_PARAM *pstParam);
  122. //设置是否为触发模式
  123. int setTriggerMode(unsigned int TriggerModeNum);
  124. //设置触发源
  125. int setTriggerSource(unsigned int TriggerSourceNum);
  126. //软触发
  127. int softTrigger();
  128. //读取buffer
  129. int ReadBuffer(cv::Mat &image);
  130. //读取buffer
  131. int ReadBuffer2(cv::Mat &image,bool saveFlag,QByteArray imageName);
  132. //设置曝光时间
  133. int setExposureTime(float ExposureTimeNum);
  134. public:
  135. void *m_hDevHandle;
  136. unsigned int m_nTLayerType;
  137. public:
  138. unsigned char *m_pBufForSaveImage; // 用于保存图像的缓存
  139. unsigned int m_nBufSizeForSaveImage;
  140. unsigned char *m_pBufForDriver; // 用于从驱动获取图像的缓存
  141. unsigned int m_nBufSizeForDriver;
  142. };
  143. #endif // MVCAMERA_H

②  cpp文件

  1. #include "MvCamera.h"
  2. #include <stdio.h>
  3. CMvCamera::CMvCamera()
  4. {
  5. m_hDevHandle = MV_NULL;
  6. }
  7. CMvCamera::~CMvCamera()
  8. {
  9. if (m_hDevHandle) {
  10. MV_CC_DestroyHandle(m_hDevHandle);
  11. m_hDevHandle = MV_NULL;
  12. }
  13. }
  14. // ch:获取SDK版本号 | en:Get SDK Version
  15. int CMvCamera::GetSDKVersion()
  16. {
  17. return MV_CC_GetSDKVersion();
  18. }
  19. // ch:枚举设备 | en:Enumerate Device
  20. int CMvCamera::EnumDevices(unsigned int nTLayerType,
  21. MV_CC_DEVICE_INFO_LIST *pstDevList)
  22. {
  23. return MV_CC_EnumDevices(nTLayerType, pstDevList);
  24. }
  25. // ch:判断设备是否可达 | en:Is the device accessible
  26. bool CMvCamera::IsDeviceAccessible(MV_CC_DEVICE_INFO *pstDevInfo,
  27. unsigned int nAccessMode)
  28. {
  29. return MV_CC_IsDeviceAccessible(pstDevInfo, nAccessMode);
  30. }
  31. // ch:打开设备 | en:Open Device
  32. int CMvCamera::Open(MV_CC_DEVICE_INFO *pstDeviceInfo)
  33. {
  34. if (MV_NULL == pstDeviceInfo) {
  35. return MV_E_PARAMETER;
  36. }
  37. if (m_hDevHandle) {
  38. return MV_E_CALLORDER;
  39. }
  40. int nRet = MV_CC_CreateHandle(&m_hDevHandle, pstDeviceInfo);
  41. if (MV_OK != nRet) {
  42. return nRet;
  43. }
  44. nRet = MV_CC_OpenDevice(m_hDevHandle);
  45. if (MV_OK != nRet) {
  46. MV_CC_DestroyHandle(m_hDevHandle);
  47. m_hDevHandle = MV_NULL;
  48. }
  49. return nRet;
  50. }
  51. // ch:关闭设备 | en:Close Device
  52. int CMvCamera::Close()
  53. {
  54. if (MV_NULL == m_hDevHandle) {
  55. return MV_E_HANDLE;
  56. }
  57. MV_CC_CloseDevice(m_hDevHandle);
  58. int nRet = MV_CC_DestroyHandle(m_hDevHandle);
  59. m_hDevHandle = MV_NULL;
  60. return nRet;
  61. }
  62. // ch:判断相机是否处于连接状态 | en:Is The Device Connected
  63. bool CMvCamera::IsDeviceConnected()
  64. {
  65. return MV_CC_IsDeviceConnected(m_hDevHandle);
  66. }
  67. // ch:注册图像数据回调 | en:Register Image Data CallBack
  68. int CMvCamera::RegisterImageCallBack(
  69. void(__stdcall *cbOutput)(unsigned char *pData,
  70. MV_FRAME_OUT_INFO_EX *pFrameInfo, void *pUser),
  71. void *pUser)
  72. {
  73. return MV_CC_RegisterImageCallBackEx(m_hDevHandle, cbOutput, pUser);
  74. }
  75. // ch:开启抓图 | en:Start Grabbing
  76. int CMvCamera::StartGrabbing()
  77. {
  78. return MV_CC_StartGrabbing(m_hDevHandle);
  79. }
  80. // ch:停止抓图 | en:Stop Grabbing
  81. int CMvCamera::StopGrabbing()
  82. {
  83. return MV_CC_StopGrabbing(m_hDevHandle);
  84. }
  85. // ch:主动获取一帧图像数据 | en:Get one frame initiatively
  86. int CMvCamera::GetImageBuffer(MV_FRAME_OUT *pFrame, int nMsec)
  87. {
  88. return MV_CC_GetImageBuffer(m_hDevHandle, pFrame, nMsec);
  89. }
  90. // ch:释放图像缓存 | en:Free image buffer
  91. int CMvCamera::FreeImageBuffer(MV_FRAME_OUT *pFrame)
  92. {
  93. return MV_CC_FreeImageBuffer(m_hDevHandle, pFrame);
  94. }
  95. // ch:主动获取一帧图像数据 | en:Get one frame initiatively
  96. int CMvCamera::GetOneFrameTimeout(unsigned char *pData, unsigned int *pnDataLen,
  97. unsigned int nDataSize,
  98. MV_FRAME_OUT_INFO_EX *pFrameInfo, int nMsec)
  99. {
  100. if (NULL == pnDataLen) {
  101. return MV_E_PARAMETER;
  102. }
  103. int nRet = MV_OK;
  104. *pnDataLen = 0;
  105. nRet = MV_CC_GetOneFrameTimeout(m_hDevHandle, pData, nDataSize, pFrameInfo,
  106. nMsec);
  107. if (MV_OK != nRet) {
  108. return nRet;
  109. }
  110. *pnDataLen = pFrameInfo->nFrameLen;
  111. return nRet;
  112. }
  113. // ch:设置显示窗口句柄 | en:Set Display Window Handle
  114. int CMvCamera::DisplayOneFrame(MV_DISPLAY_FRAME_INFO *pDisplayInfo)
  115. {
  116. return MV_CC_DisplayOneFrame(m_hDevHandle, pDisplayInfo);
  117. }
  118. // ch:设置SDK内部图像缓存节点个数 | en:Set the number of the internal image
  119. // cache nodes in SDK
  120. int CMvCamera::SetImageNodeNum(unsigned int nNum)
  121. {
  122. return MV_CC_SetImageNodeNum(m_hDevHandle, nNum);
  123. }
  124. // ch:获取设备信息 | en:Get device information
  125. int CMvCamera::GetDeviceInfo(MV_CC_DEVICE_INFO *pstDevInfo)
  126. {
  127. return MV_CC_GetDeviceInfo(m_hDevHandle, pstDevInfo);
  128. }
  129. // ch:获取GEV相机的统计信息 | en:Get detect info of GEV camera
  130. int CMvCamera::GetGevAllMatchInfo(MV_MATCH_INFO_NET_DETECT *pMatchInfoNetDetect)
  131. {
  132. if (MV_NULL == pMatchInfoNetDetect) {
  133. return MV_E_PARAMETER;
  134. }
  135. MV_CC_DEVICE_INFO stDevInfo = { 0 };
  136. GetDeviceInfo(&stDevInfo);
  137. if (stDevInfo.nTLayerType != MV_GIGE_DEVICE) {
  138. return MV_E_SUPPORT;
  139. }
  140. MV_ALL_MATCH_INFO struMatchInfo = { 0 };
  141. struMatchInfo.nType = MV_MATCH_TYPE_NET_DETECT;
  142. struMatchInfo.pInfo = pMatchInfoNetDetect;
  143. struMatchInfo.nInfoSize = sizeof(MV_MATCH_INFO_NET_DETECT);
  144. memset(struMatchInfo.pInfo, 0, sizeof(MV_MATCH_INFO_NET_DETECT));
  145. return MV_CC_GetAllMatchInfo(m_hDevHandle, &struMatchInfo);
  146. }
  147. // ch:获取U3V相机的统计信息 | en:Get detect info of U3V camera
  148. int CMvCamera::GetU3VAllMatchInfo(MV_MATCH_INFO_USB_DETECT *pMatchInfoUSBDetect)
  149. {
  150. if (MV_NULL == pMatchInfoUSBDetect) {
  151. return MV_E_PARAMETER;
  152. }
  153. MV_CC_DEVICE_INFO stDevInfo = { 0 };
  154. GetDeviceInfo(&stDevInfo);
  155. if (stDevInfo.nTLayerType != MV_USB_DEVICE) {
  156. return MV_E_SUPPORT;
  157. }
  158. MV_ALL_MATCH_INFO struMatchInfo = { 0 };
  159. struMatchInfo.nType = MV_MATCH_TYPE_USB_DETECT;
  160. struMatchInfo.pInfo = pMatchInfoUSBDetect;
  161. struMatchInfo.nInfoSize = sizeof(MV_MATCH_INFO_USB_DETECT);
  162. memset(struMatchInfo.pInfo, 0, sizeof(MV_MATCH_INFO_USB_DETECT));
  163. return MV_CC_GetAllMatchInfo(m_hDevHandle, &struMatchInfo);
  164. }
  165. // ch:获取和设置Int型参数,如 Width和Height,详细内容参考SDK安装目录下的
  166. // MvCameraNode.xlsx 文件 en:Get Int type parameters, such as Width and Height,
  167. // for details please refer to MvCameraNode.xlsx file under SDK installation
  168. // directory
  169. int CMvCamera::GetIntValue(IN const char *strKey, OUT unsigned int *pnValue)
  170. {
  171. if (NULL == strKey || NULL == pnValue) {
  172. return MV_E_PARAMETER;
  173. }
  174. MVCC_INTVALUE stParam;
  175. memset(&stParam, 0, sizeof(MVCC_INTVALUE));
  176. int nRet = MV_CC_GetIntValue(m_hDevHandle, strKey, &stParam);
  177. if (MV_OK != nRet) {
  178. return nRet;
  179. }
  180. *pnValue = stParam.nCurValue;
  181. return MV_OK;
  182. }
  183. int CMvCamera::SetIntValue(IN const char *strKey, IN int64_t nValue)
  184. {
  185. return MV_CC_SetIntValueEx(m_hDevHandle, strKey, nValue);
  186. }
  187. // ch:获取和设置Enum型参数,如 PixelFormat,详细内容参考SDK安装目录下的
  188. // MvCameraNode.xlsx 文件 en:Get Enum type parameters, such as PixelFormat, for
  189. // details please refer to MvCameraNode.xlsx file under SDK installation
  190. // directory
  191. int CMvCamera::GetEnumValue(IN const char *strKey,
  192. OUT MVCC_ENUMVALUE *pEnumValue)
  193. {
  194. return MV_CC_GetEnumValue(m_hDevHandle, strKey, pEnumValue);
  195. }
  196. int CMvCamera::SetEnumValue(IN const char *strKey, IN unsigned int nValue)
  197. {
  198. return MV_CC_SetEnumValue(m_hDevHandle, strKey, nValue);
  199. }
  200. int CMvCamera::SetEnumValueByString(IN const char *strKey,
  201. IN const char *sValue)
  202. {
  203. return MV_CC_SetEnumValueByString(m_hDevHandle, strKey, sValue);
  204. }
  205. // ch:获取和设置Float型参数,如 ExposureTime和Gain,详细内容参考SDK安装目录下的
  206. // MvCameraNode.xlsx 文件 en:Get Float type parameters, such as ExposureTime and
  207. // Gain, for details please refer to MvCameraNode.xlsx file under SDK
  208. // installation directory
  209. int CMvCamera::GetFloatValue(IN const char *strKey,
  210. OUT MVCC_FLOATVALUE *pFloatValue)
  211. {
  212. return MV_CC_GetFloatValue(m_hDevHandle, strKey, pFloatValue);
  213. }
  214. int CMvCamera::SetFloatValue(IN const char *strKey, IN float fValue)
  215. {
  216. return MV_CC_SetFloatValue(m_hDevHandle, strKey, fValue);
  217. }
  218. // ch:获取和设置Bool型参数,如 ReverseX,详细内容参考SDK安装目录下的
  219. // MvCameraNode.xlsx 文件 en:Get Bool type parameters, such as ReverseX, for
  220. // details please refer to MvCameraNode.xlsx file under SDK installation
  221. // directory
  222. int CMvCamera::GetBoolValue(IN const char *strKey, OUT bool *pbValue)
  223. {
  224. return MV_CC_GetBoolValue(m_hDevHandle, strKey, pbValue);
  225. }
  226. int CMvCamera::SetBoolValue(IN const char *strKey, IN bool bValue)
  227. {
  228. return MV_CC_SetBoolValue(m_hDevHandle, strKey, bValue);
  229. }
  230. // ch:获取和设置String型参数,如 DeviceUserID,详细内容参考SDK安装目录下的
  231. // MvCameraNode.xlsx 文件UserSetSave en:Get String type parameters, such as
  232. // DeviceUserID, for details please refer to MvCameraNode.xlsx file under SDK
  233. // installation directory
  234. int CMvCamera::GetStringValue(IN const char *strKey,
  235. MVCC_STRINGVALUE *pStringValue)
  236. {
  237. return MV_CC_GetStringValue(m_hDevHandle, strKey, pStringValue);
  238. }
  239. int CMvCamera::SetStringValue(IN const char *strKey, IN const char *strValue)
  240. {
  241. return MV_CC_SetStringValue(m_hDevHandle, strKey, strValue);
  242. }
  243. // ch:执行一次Command型命令,如 UserSetSave,详细内容参考SDK安装目录下的
  244. // MvCameraNode.xlsx 文件 en:Execute Command once, such as UserSetSave, for
  245. // details please refer to MvCameraNode.xlsx file under SDK installation
  246. // directory
  247. int CMvCamera::CommandExecute(IN const char *strKey)
  248. {
  249. return MV_CC_SetCommandValue(m_hDevHandle, strKey);
  250. }
  251. // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal
  252. // package size(It only works for the GigE camera)
  253. int CMvCamera::GetOptimalPacketSize(unsigned int *pOptimalPacketSize)
  254. {
  255. if (MV_NULL == pOptimalPacketSize) {
  256. return MV_E_PARAMETER;
  257. }
  258. int nRet = MV_CC_GetOptimalPacketSize(m_hDevHandle);
  259. if (nRet < MV_OK) {
  260. return nRet;
  261. }
  262. *pOptimalPacketSize = (unsigned int)nRet;
  263. return MV_OK;
  264. }
  265. // ch:注册消息异常回调 | en:Register Message Exception CallBack
  266. int CMvCamera::RegisterExceptionCallBack(
  267. void(__stdcall *cbException)(unsigned int nMsgType, void *pUser),
  268. void *pUser)
  269. {
  270. return MV_CC_RegisterExceptionCallBack(m_hDevHandle, cbException, pUser);
  271. }
  272. // ch:注册单个事件回调 | en:Register Event CallBack
  273. int CMvCamera::RegisterEventCallBack(
  274. const char *pEventName,
  275. void(__stdcall *cbEvent)(MV_EVENT_OUT_INFO *pEventInfo, void *pUser),
  276. void *pUser)
  277. {
  278. return MV_CC_RegisterEventCallBackEx(m_hDevHandle, pEventName, cbEvent,
  279. pUser);
  280. }
  281. // ch:强制IP | en:Force IP
  282. int CMvCamera::ForceIp(unsigned int nIP, unsigned int nSubNetMask,
  283. unsigned int nDefaultGateWay)
  284. {
  285. return MV_GIGE_ForceIpEx(m_hDevHandle, nIP, nSubNetMask, nDefaultGateWay);
  286. }
  287. // ch:配置IP方式 | en:IP configuration method
  288. int CMvCamera::SetIpConfig(unsigned int nType)
  289. {
  290. return MV_GIGE_SetIpConfig(m_hDevHandle, nType);
  291. }
  292. // ch:设置网络传输模式 | en:Set Net Transfer Mode
  293. int CMvCamera::SetNetTransMode(unsigned int nType)
  294. {
  295. return MV_GIGE_SetNetTransMode(m_hDevHandle, nType);
  296. }
  297. // ch:像素格式转换 | en:Pixel format conversion
  298. int CMvCamera::ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM *pstCvtParam)
  299. {
  300. return MV_CC_ConvertPixelType(m_hDevHandle, pstCvtParam);
  301. }
  302. // ch:保存图片 | en:save image
  303. int CMvCamera::SaveImage(MV_SAVE_IMAGE_PARAM_EX *pstParam)
  304. {
  305. return MV_CC_SaveImageEx2(m_hDevHandle, pstParam);
  306. }
  307. //ch:保存图片为文件 | en:Save the image as a file
  308. // int CMvCamera::SaveImageToFile(MV_SAVE_IMG_TO_FILE_PARAM *pstSaveFileParam)
  309. //{
  310. // return MV_CC_SaveImageToFile(m_hDevHandle, pstSaveFileParam);
  311. //}
  312. //设置是否为触发模式
  313. int CMvCamera::setTriggerMode(unsigned int TriggerModeNum)
  314. {
  315. // 0:Off 1:On
  316. int tempValue =
  317. MV_CC_SetEnumValue(m_hDevHandle, "TriggerMode", TriggerModeNum);
  318. if (tempValue != 0) {
  319. return -1;
  320. } else {
  321. return 0;
  322. }
  323. }
  324. //设置触发源
  325. int CMvCamera::setTriggerSource(unsigned int TriggerSourceNum)
  326. {
  327. // 0:Line0 1:Line1 7:Software
  328. int tempValue =
  329. MV_CC_SetEnumValue(m_hDevHandle, "TriggerSource", TriggerSourceNum);
  330. if (tempValue != 0) {
  331. return -1;
  332. } else {
  333. return 0;
  334. }
  335. }
  336. //发送软触发
  337. int CMvCamera::softTrigger()
  338. {
  339. int tempValue = MV_CC_SetCommandValue(m_hDevHandle, "TriggerSoftware");
  340. if (tempValue != 0) {
  341. return -1;
  342. } else {
  343. return 0;
  344. }
  345. }
  346. //读取相机中的图像
  347. // int ReadBuffer(cv::Mat &image);
  348. int CMvCamera::ReadBuffer(cv::Mat &image)
  349. {
  350. cv::Mat *getImage = new cv::Mat();
  351. unsigned int nRecvBufSize = 0;
  352. MVCC_INTVALUE stParam;
  353. memset(&stParam, 0, sizeof(MVCC_INTVALUE));
  354. int tempValue = MV_CC_GetIntValue(m_hDevHandle, "PayloadSize", &stParam);
  355. if (tempValue != 0) {
  356. return -1;
  357. }
  358. nRecvBufSize = stParam.nCurValue;
  359. unsigned char *pDate;
  360. pDate = (unsigned char *)malloc(nRecvBufSize);
  361. MV_FRAME_OUT_INFO_EX stImageInfo = { 0 };
  362. tempValue = MV_CC_GetOneFrameTimeout(m_hDevHandle, pDate, nRecvBufSize,
  363. &stImageInfo, 500);
  364. if (tempValue != 0) {
  365. return -1;
  366. }
  367. m_nBufSizeForSaveImage =
  368. stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
  369. unsigned char *m_pBufForSaveImage;
  370. m_pBufForSaveImage = (unsigned char *)malloc(m_nBufSizeForSaveImage);
  371. bool isMono;
  372. switch (stImageInfo.enPixelType) {
  373. case PixelType_Gvsp_Mono8:
  374. case PixelType_Gvsp_Mono10:
  375. case PixelType_Gvsp_Mono10_Packed:
  376. case PixelType_Gvsp_Mono12:
  377. case PixelType_Gvsp_Mono12_Packed:
  378. isMono = true;
  379. break;
  380. default:
  381. isMono = false;
  382. break;
  383. }
  384. if (isMono) {
  385. *getImage =
  386. cv::Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC1, pDate);
  387. // imwrite("d:\\测试opencv_Mono.tif", image);
  388. } else {
  389. //转换图像格式为BGR8
  390. MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 };
  391. memset(&stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));
  392. stConvertParam.nWidth = stImageInfo.nWidth; // ch:图像宽 | en:image
  393. // width
  394. stConvertParam.nHeight =
  395. stImageInfo.nHeight; // ch:图像高 | en:image height
  396. // stConvertParam.pSrcData = m_pBufForDriver; //ch:输入数据缓存 |
  397. // en:input data buffer
  398. stConvertParam.pSrcData =
  399. pDate; // ch:输入数据缓存 | en:input data buffer
  400. stConvertParam.nSrcDataLen =
  401. stImageInfo.nFrameLen; // ch:输入数据大小 | en:input data size
  402. stConvertParam.enSrcPixelType =
  403. stImageInfo.enPixelType; // ch:输入像素格式 | en:input pixel format
  404. stConvertParam.enDstPixelType =
  405. PixelType_Gvsp_BGR8_Packed; // ch:输出像素格式 | en:output pixel
  406. // format 适用于OPENCV的图像格式
  407. // stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed;
  408. //输出像素格式 | en:output pixel format
  409. stConvertParam.pDstBuffer =
  410. m_pBufForSaveImage; // ch:输出数据缓存 | en:output data buffer
  411. stConvertParam.nDstBufferSize =
  412. m_nBufSizeForSaveImage; // ch:输出缓存大小 | en:output buffer size
  413. MV_CC_ConvertPixelType(m_hDevHandle, &stConvertParam);
  414. *getImage = cv::Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC3,
  415. m_pBufForSaveImage);
  416. }
  417. (*getImage).copyTo(image);
  418. (*getImage).release();
  419. free(pDate);
  420. free(m_pBufForSaveImage);
  421. return 0;
  422. }
  423. //设置曝光时间
  424. int CMvCamera::setExposureTime(float ExposureTimeNum)
  425. {
  426. int tempValue =
  427. MV_CC_SetFloatValue(m_hDevHandle, "ExposureTime", ExposureTimeNum);
  428. if (tempValue != 0) {
  429. return -1;
  430. } else {
  431. return 0;
  432. }
  433. }

 2、主界面的相关代码

       ①  h文件

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include <QMessageBox>
  5. #include <QCloseEvent>
  6. #include <QSettings>
  7. #include <QDate>
  8. #include <QDir>
  9. #include "MvCamera.h"
  10. #include "mythread.h"
  11. #include "mainwidget.h"
  12. #define MAX_DEVICE_NUM 2
  13. #define TRIGGER_SOURCE 7
  14. #define EXPOSURE_TIME 40000
  15. #define FRAME 30
  16. #define TRIGGER_ON 1
  17. #define TRIGGER_OFF 0
  18. #define START_GRABBING_ON 1
  19. #define START_GRABBING_OFF 0
  20. #define IMAGE_NAME_LEN 64
  21. QT_BEGIN_NAMESPACE
  22. namespace Ui {
  23. class Widget;
  24. }
  25. QT_END_NAMESPACE
  26. class MainWidget;
  27. class Widget : public QWidget
  28. {
  29. Q_OBJECT
  30. public:
  31. Widget(QWidget *parent = nullptr);
  32. ~Widget();
  33. signals:
  34. void closedWid();
  35. void back();
  36. public:
  37. CMvCamera *m_pcMyCamera[MAX_DEVICE_NUM]; // 相机指针对象
  38. MV_CC_DEVICE_INFO_LIST m_stDevList; // 存储设备列表
  39. cv::Mat *myImage_L = new cv::Mat(); //保存左相机图像的图像指针对象
  40. cv::Mat *myImage_R = new cv::Mat(); //保存右相机有图像的图像指针对象
  41. int devices_num; // 设备数量
  42. MainWidget *mainWid = NULL; //创建一个存储主界面窗体的指针
  43. public:
  44. MyThread *myThread_Camera_show = NULL; //相机实时显示线程对象
  45. private slots:
  46. void on_pbn_enum_camera_clicked();
  47. void on_pbn_open_camera_clicked();
  48. void on_rdo_continue_mode_clicked();
  49. void on_rdo_softigger_mode_clicked();
  50. void on_pbn_start_grabbing_clicked();
  51. void on_pbn_stop_grabbing_clicked();
  52. void on_pbn_software_once_clicked();
  53. void display_myImage_L(const Mat *imagePrt);
  54. void display_myImage_Main(const Mat *imagePrt);
  55. void on_pbn_close_camera_clicked();
  56. void on_pbn_save_BMP_clicked();
  57. void on_pbn_save_JPG_clicked();
  58. void on_le_set_exposure_textChanged(const QString &arg1);
  59. void on_le_set_gain_textChanged(const QString &arg1);
  60. void on_pbn_return_main_clicked();
  61. public:
  62. // 状态
  63. bool m_bOpenDevice; // 是否打开设备
  64. bool m_bStartGrabbing; // 是否开始抓图
  65. int m_nTriggerMode; // 触发模式
  66. int m_bContinueStarted; // 开启过连续采集图像
  67. MV_SAVE_IAMGE_TYPE m_nSaveImageType; // 保存图像格式
  68. private:
  69. QString PrintDeviceInfo(MV_CC_DEVICE_INFO *pstMVDevInfo, int num_index);
  70. QString m_SaveImagePath;
  71. void OpenDevices();
  72. void CloseDevices();
  73. void SaveImage();
  74. void saveImage(QString format,int index);
  75. private:
  76. Ui::Widget *ui;
  77. protected:
  78. void closeEvent(QCloseEvent *event) override; //重写关闭事件处理函数
  79. };
  80. #endif // WIDGET_H

    ②  cpp文件

  1. #include "widget.h"
  2. #include "./ui_widget.h"
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <stdlib.h>
  7. #include <fstream>
  8. #include <iostream>
  9. #include <QDebug>
  10. Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
  11. {
  12. ui->setupUi(this);
  13. ui->lbl_camera_L->setPixmap(QPixmap(":/icon/MVS.png"));
  14. ui->lbl_camera_L->setScaledContents(true);
  15. //ui->lbl_camera_R->setPixmap(QPixmap("back_img.jpg"));
  16. //ui->lbl_camera_R->setScaledContents(true);
  17. // 相机初始化控件
  18. ui->pbn_enum_camera->setEnabled(true);
  19. ui->pbn_open_camera->setEnabled(false);
  20. ui->pbn_close_camera->setEnabled(false);
  21. ui->cmb_camera_index->setEnabled(false);
  22. // 图像采集控件
  23. ui->rdo_continue_mode->setEnabled(false);
  24. ui->rdo_softigger_mode->setEnabled(false);
  25. ui->pbn_start_grabbing->setEnabled(false);
  26. ui->pbn_stop_grabbing->setEnabled(false);
  27. ui->pbn_software_once->setEnabled(false);
  28. // 参数控件
  29. ui->le_set_exposure->setEnabled(false);
  30. ui->le_set_gain->setEnabled(false);
  31. // 保存图像控件
  32. ui->pbn_save_BMP->setEnabled(false);
  33. ui->pbn_save_JPG->setEnabled(false);
  34. // 线程对象实例化
  35. myThread_Camera_show = new MyThread; //相机线程对象
  36. //发送信号实现页面切换
  37. connect(ui->pbn_return_main,SIGNAL(clicked()),this,SIGNAL(back()));
  38. connect(myThread_Camera_show, SIGNAL(Display(const Mat *)), this,
  39. SLOT(display_myImage_L(const Mat *)));
  40. // 曝光和增益的输入控件限制值
  41. QRegExp int_rx("100000|([0-9]{0,5})");
  42. ui->le_set_exposure->setValidator(new QRegExpValidator(int_rx, this));
  43. QRegExp double_rx("15|([0-9]{0,1}[0-5]{1,2}[\.][0-9]{0,1})");
  44. ui->le_set_gain->setValidator(new QRegExpValidator(double_rx, this));
  45. }
  46. Widget::~Widget()
  47. {
  48. delete ui;
  49. delete mainWid;
  50. delete myThread_Camera_show;
  51. delete myImage_L;
  52. }
  53. //创建关闭子窗体事件,显示主窗体
  54. void Widget::closeEvent(QCloseEvent *event)
  55. {
  56. emit closedWid(); //发射closed信号
  57. event->accept();
  58. }
  59. void Widget::on_pbn_enum_camera_clicked()
  60. {
  61. memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
  62. int nRet = MV_OK;
  63. nRet = CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList);
  64. devices_num = m_stDevList.nDeviceNum;
  65. if (devices_num == 0) {
  66. QString cameraInfo;
  67. cameraInfo =
  68. QString::fromLocal8Bit("暂无设备可连接,请检查设备是否连接正确!");
  69. ui->lbl_camera_messagee->setText(cameraInfo);
  70. }
  71. if (devices_num > 0) {
  72. QString cameraInfo;
  73. for (int i = 0; i < devices_num; i++) {
  74. MV_CC_DEVICE_INFO *pDeviceInfo = m_stDevList.pDeviceInfo[i];
  75. QString cameraInfo_i = PrintDeviceInfo(pDeviceInfo, i);
  76. cameraInfo.append(cameraInfo_i);
  77. cameraInfo.append("\n");
  78. ui->cmb_camera_index->addItem(QString::number(i+1));
  79. }
  80. ui->lbl_camera_messagee->setText(cameraInfo);
  81. ui->pbn_open_camera->setEnabled(true);
  82. ui->cmb_camera_index->setEnabled(true);
  83. }
  84. }
  85. //打印相机的型号、ip等信息
  86. QString Widget::PrintDeviceInfo(MV_CC_DEVICE_INFO *pstMVDevInfo, int num_index)
  87. {
  88. QString cameraInfo_index;
  89. cameraInfo_index = QString::fromLocal8Bit("相机序号:");
  90. cameraInfo_index.append(QString::number(num_index+1));
  91. cameraInfo_index.append("\t\t");
  92. // 海康GIGE协议的相机
  93. if (pstMVDevInfo->nTLayerType == MV_GIGE_DEVICE) {
  94. int nIp1 =
  95. ((pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >>
  96. 24);
  97. int nIp2 =
  98. ((pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >>
  99. 16);
  100. int nIp3 =
  101. ((pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >>
  102. 8);
  103. int nIp4 =
  104. (pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff);
  105. cameraInfo_index.append(QString::fromLocal8Bit("相机型号:"));
  106. std::string str_name =
  107. (char *)pstMVDevInfo->SpecialInfo.stGigEInfo.chModelName;
  108. cameraInfo_index.append(QString::fromStdString(str_name));
  109. cameraInfo_index.append("\n");
  110. cameraInfo_index.append(QString::fromLocal8Bit("当前相机IP地址:"));
  111. cameraInfo_index.append(QString::number(nIp1));
  112. cameraInfo_index.append(".");
  113. cameraInfo_index.append(QString::number(nIp2));
  114. cameraInfo_index.append(".");
  115. cameraInfo_index.append(QString::number(nIp3));
  116. cameraInfo_index.append(".");
  117. cameraInfo_index.append(QString::number(nIp4));
  118. cameraInfo_index.append("\t");
  119. } else if (pstMVDevInfo->nTLayerType == MV_USB_DEVICE) {
  120. cameraInfo_index.append(QString::fromLocal8Bit("相机型号:"));
  121. std::string str_name =
  122. (char *)pstMVDevInfo->SpecialInfo.stUsb3VInfo.chModelName;
  123. cameraInfo_index.append(QString::fromStdString(str_name));
  124. cameraInfo_index.append("\n");
  125. } else {
  126. cameraInfo_index.append(QString::fromLocal8Bit("相机型号:未知"));
  127. }
  128. cameraInfo_index.append(QString::fromLocal8Bit("相机品牌:海康威视"));
  129. return cameraInfo_index;
  130. }
  131. void Widget::on_pbn_open_camera_clicked()
  132. {
  133. ui->pbn_open_camera->setEnabled(false);
  134. ui->pbn_close_camera->setEnabled(true);
  135. ui->rdo_continue_mode->setEnabled(true);
  136. ui->rdo_softigger_mode->setEnabled(true);
  137. ui->rdo_continue_mode->setCheckable(true);
  138. // 参数据控件
  139. ui->le_set_exposure->setEnabled(true);
  140. ui->le_set_gain->setEnabled(true);
  141. OpenDevices();
  142. }
  143. void Widget::OpenDevices()
  144. {
  145. int nRet = MV_OK;
  146. // 创建相机指针对象
  147. for (unsigned int i = 0, j = 0; j < m_stDevList.nDeviceNum; j++, i++) {
  148. m_pcMyCamera[i] = new CMvCamera;
  149. // 相机对象初始化
  150. m_pcMyCamera[i]->m_pBufForDriver = NULL;
  151. m_pcMyCamera[i]->m_pBufForSaveImage = NULL;
  152. m_pcMyCamera[i]->m_nBufSizeForDriver = 0;
  153. m_pcMyCamera[i]->m_nBufSizeForSaveImage = 0;
  154. m_pcMyCamera[i]->m_nTLayerType =
  155. m_stDevList.pDeviceInfo[j]->nTLayerType;
  156. nRet = m_pcMyCamera[i]->Open(m_stDevList.pDeviceInfo[j]); //打开相机
  157. //设置触发模式
  158. m_pcMyCamera[i]->setTriggerMode(TRIGGER_ON);
  159. //设置触发源为软触发
  160. m_pcMyCamera[i]->setTriggerSource(TRIGGER_SOURCE);
  161. //设置曝光时间,初始为40000,并关闭自动曝光模式
  162. m_pcMyCamera[i]->setExposureTime(EXPOSURE_TIME);
  163. m_pcMyCamera[i]->SetEnumValue("ExposureAuto",
  164. MV_EXPOSURE_AUTO_MODE_OFF);
  165. }
  166. }
  167. void Widget::on_rdo_continue_mode_clicked()
  168. {
  169. ui->pbn_start_grabbing->setEnabled(true);
  170. m_nTriggerMode = TRIGGER_ON;
  171. }
  172. void Widget::on_rdo_softigger_mode_clicked()
  173. {
  174. // 如果开始选择的连续模式,切换到触发模式之前,需要先停止采集
  175. if (m_bContinueStarted == 1) {
  176. on_pbn_stop_grabbing_clicked(); //先执行停止采集
  177. }
  178. ui->pbn_start_grabbing->setEnabled(false);
  179. ui->pbn_software_once->setEnabled(true);
  180. m_nTriggerMode = TRIGGER_OFF;
  181. for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
  182. m_pcMyCamera[i]->setTriggerMode(m_nTriggerMode);
  183. }
  184. }
  185. void Widget::on_pbn_start_grabbing_clicked()
  186. {
  187. // 触发模式标记一下,切换触发模式时先执行停止采集图像函数
  188. m_bContinueStarted = 1;
  189. ui->pbn_start_grabbing->setEnabled(false);
  190. ui->pbn_stop_grabbing->setEnabled(true);
  191. // 保存图像控件
  192. ui->pbn_save_BMP->setEnabled(true);
  193. // 图像采集控件
  194. ui->pbn_save_JPG->setEnabled(true);
  195. int camera_Index = 0;
  196. // 先判断什么模式,再判断是否正在采集
  197. if (m_nTriggerMode == TRIGGER_ON) {
  198. // 开始采集之后才创建workthread线程
  199. for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
  200. //开启相机采集
  201. m_pcMyCamera[i]->StartGrabbing();
  202. camera_Index = i;
  203. if (camera_Index == 0) {
  204. myThread_Camera_show->getCameraPtr(
  205. m_pcMyCamera[0]); //线程获取左相机指针
  206. myThread_Camera_show->getImagePtr(
  207. myImage_L); //线程获取图像指针
  208. myThread_Camera_show->getCameraIndex(0); //相机 Index==0
  209. if (!myThread_Camera_show->isRunning()) {
  210. myThread_Camera_show->start();
  211. m_pcMyCamera[0]->softTrigger();
  212. m_pcMyCamera[0]->ReadBuffer(*myImage_L); //读取Mat格式的图像
  213. }
  214. }
  215. }
  216. }
  217. }
  218. void Widget::on_pbn_stop_grabbing_clicked()
  219. {
  220. ui->pbn_start_grabbing->setEnabled(true);
  221. ui->pbn_stop_grabbing->setEnabled(false);
  222. for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
  223. //关闭相机
  224. if (myThread_Camera_show->isRunning()) {
  225. m_pcMyCamera[0]->StopGrabbing();
  226. myThread_Camera_show->requestInterruption();
  227. myThread_Camera_show->wait();
  228. }
  229. }
  230. }
  231. void Widget::on_pbn_software_once_clicked()
  232. {
  233. // 保存图像控件
  234. ui->pbn_save_BMP->setEnabled(true);
  235. ui->pbn_save_JPG->setEnabled(true);
  236. if (m_nTriggerMode == TRIGGER_OFF) {
  237. int nRet = MV_OK;
  238. for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
  239. //开启相机采集
  240. m_pcMyCamera[i]->StartGrabbing();
  241. if (i == 0) {
  242. nRet = m_pcMyCamera[i]->CommandExecute("TriggerSoftware");
  243. m_pcMyCamera[i]->ReadBuffer(*myImage_L);
  244. display_myImage_L(myImage_L); //左相机图像
  245. display_myImage_Main(myImage_L); //主界面显示
  246. }
  247. }
  248. }
  249. }
  250. //在相机配置界面显示
  251. void Widget::display_myImage_L(const Mat *imagePrt)
  252. {
  253. cv::Mat rgb;
  254. //判断是黑白、彩色图像
  255. QImage QmyImage_L;
  256. if (myImage_L->channels() > 1) {
  257. cv::cvtColor(*imagePrt, rgb, CV_BGR2RGB);
  258. QmyImage_L = QImage((const unsigned char *)(rgb.data), rgb.cols,
  259. rgb.rows, QImage::Format_RGB888);
  260. } else {
  261. cv::cvtColor(*imagePrt, rgb, CV_GRAY2RGB);
  262. QmyImage_L = QImage((const unsigned char *)(rgb.data), rgb.cols,
  263. rgb.rows, QImage::Format_RGB888);
  264. }
  265. QmyImage_L = (QmyImage_L)
  266. .scaled(ui->lbl_camera_L->size(), Qt::IgnoreAspectRatio,
  267. Qt::SmoothTransformation); //饱满填充
  268. ui->lbl_camera_L->setPixmap(QPixmap::fromImage(QmyImage_L));
  269. }
  270. //在主界面显示
  271. void Widget::display_myImage_Main(const Mat *imagePrt)
  272. {
  273. cv::Mat rgb;
  274. cv::cvtColor(*imagePrt, rgb, CV_BGR2RGB);
  275. QImage QmyImage_L;
  276. QmyImage_L = QImage((const unsigned char *)(rgb.data), rgb.cols,
  277. rgb.rows, QImage::Format_RGB888);
  278. QmyImage_L = (QmyImage_L)
  279. .scaled(ui->lbl_camera_L->size(), Qt::IgnoreAspectRatio,
  280. Qt::SmoothTransformation); //饱满填充
  281. //显示图像
  282. this->mainWid=new MainWidget();
  283. //ui->lbl_camera_L->setPixmap(QPixmap::fromImage(QmyImage_L));
  284. mainWid->ui->lbl_res_pic->setPixmap(QPixmap::fromImage(QmyImage_L));
  285. }
  286. void Widget::CloseDevices()
  287. {
  288. for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
  289. // 关闭线程、相机
  290. if (myThread_Camera_show->isRunning()) {
  291. myThread_Camera_show->requestInterruption();
  292. myThread_Camera_show->wait();
  293. m_pcMyCamera[0]->StopGrabbing();
  294. }
  295. m_pcMyCamera[i]->Close();
  296. }
  297. // 关闭之后再枚举一遍
  298. memset(&m_stDevList, 0,
  299. sizeof(MV_CC_DEVICE_INFO_LIST)); // 初始化设备信息列表
  300. int devices_num = MV_OK;
  301. devices_num =
  302. CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE,
  303. &m_stDevList); // 枚举子网内所有设备,相机设备数量
  304. }
  305. void Widget::on_pbn_close_camera_clicked()
  306. {
  307. ui->pbn_open_camera->setEnabled(true);
  308. ui->pbn_close_camera->setEnabled(false);
  309. // 图像采集控件
  310. ui->rdo_continue_mode->setEnabled(false);
  311. ui->rdo_softigger_mode->setEnabled(false);
  312. ui->pbn_start_grabbing->setEnabled(false);
  313. ui->pbn_stop_grabbing->setEnabled(false);
  314. ui->pbn_software_once->setEnabled(false);
  315. // 参数控件
  316. ui->le_set_exposure->setEnabled(false);
  317. ui->le_set_gain->setEnabled(false);
  318. // 保存图像控件
  319. ui->pbn_save_BMP->setEnabled(false);
  320. ui->pbn_save_JPG->setEnabled(false);
  321. // 关闭设备,销毁线程
  322. CloseDevices();
  323. ui->lbl_camera_messagee->clear();
  324. ui->lbl_camera_L->clear();
  325. ui->lbl_camera_L->setPixmap(QPixmap(":/icon/MVS.png"));
  326. //ui->lbl_camera_R->clear();
  327. }
  328. void Widget::on_pbn_save_BMP_clicked()
  329. {
  330. m_nSaveImageType = MV_Image_Bmp;
  331. SaveImage();
  332. }
  333. void Widget::on_pbn_save_JPG_clicked()
  334. {
  335. m_nSaveImageType = MV_Image_Jpeg;
  336. SaveImage();
  337. }
  338. void Widget::SaveImage()
  339. {
  340. // 获取1张图
  341. MV_FRAME_OUT_INFO_EX stImageInfo = { 0 };
  342. memset(&stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));
  343. unsigned int nDataLen = 0;
  344. int nRet = MV_OK;
  345. //保存图片的路径
  346. QString saveDirPath="/home/joe/program/VersionDetect/test2/image/1.jpg";
  347. for (int i = 0; i < devices_num; i++) {
  348. //保存图像的缓存类指针
  349. const char *imageName_c_str=NULL;
  350. // 仅在第一次保存图像时申请缓存,在CloseDevice时释放
  351. if (NULL == m_pcMyCamera[i]->m_pBufForDriver) {
  352. unsigned int nRecvBufSize = 0;
  353. m_pcMyCamera[i]->GetIntValue("PayloadSize", &nRecvBufSize);
  354. m_pcMyCamera[i]->m_nBufSizeForDriver = nRecvBufSize; // 一帧数据大小
  355. m_pcMyCamera[i]->m_pBufForDriver =
  356. (unsigned char *)malloc(m_pcMyCamera[i]->m_nBufSizeForDriver);
  357. }
  358. nRet = m_pcMyCamera[i]->GetOneFrameTimeout(
  359. m_pcMyCamera[i]->m_pBufForDriver, &nDataLen,
  360. m_pcMyCamera[i]->m_nBufSizeForDriver, &stImageInfo, 1000);
  361. if (MV_OK == nRet) {
  362. // 仅在第一次保存图像时申请缓存,在 CloseDevice 时释放
  363. if (NULL == m_pcMyCamera[i]->m_pBufForSaveImage) {
  364. // BMP图片大小:width * height * 3 + 2048(预留BMP头大小)
  365. m_pcMyCamera[i]->m_nBufSizeForSaveImage =
  366. stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
  367. m_pcMyCamera[i]->m_pBufForSaveImage = (unsigned char *)malloc(
  368. m_pcMyCamera[i]->m_nBufSizeForSaveImage);
  369. }
  370. // 设置对应的相机参数
  371. MV_SAVE_IMAGE_PARAM_EX stParam = { 0 };
  372. stParam.enImageType = m_nSaveImageType; // 需要保存的图像类型
  373. stParam.enPixelType = stImageInfo.enPixelType; // 相机对应的像素格式
  374. stParam.nBufferSize =
  375. m_pcMyCamera[i]->m_nBufSizeForSaveImage; // 存储节点的大小
  376. stParam.nWidth = stImageInfo.nWidth; // 相机对应的宽
  377. stParam.nHeight = stImageInfo.nHeight; // 相机对应的高
  378. stParam.nDataLen = stImageInfo.nFrameLen;
  379. stParam.pData = m_pcMyCamera[i]->m_pBufForDriver;
  380. stParam.pImageBuffer = m_pcMyCamera[i]->m_pBufForSaveImage;
  381. stParam.nJpgQuality = 90; // jpg编码,仅在保存Jpg图像时有效
  382. nRet = m_pcMyCamera[i]->SaveImage(&stParam);
  383. QString image_name;
  384. //图像名称
  385. char chImageName[IMAGE_NAME_LEN] = {0};
  386. if (MV_Image_Bmp == stParam.enImageType) {
  387. if (i == 0) {
  388. snprintf(chImageName, IMAGE_NAME_LEN,
  389. "Image_w%d_h%d_fn%d_L.bmp", stImageInfo.nWidth,
  390. stImageInfo.nHeight, stImageInfo.nFrameNum);
  391. image_name = "Image_w";
  392. image_name.append(QString::number(stImageInfo.nWidth));
  393. image_name.append("_h");
  394. image_name.append(QString::number(stImageInfo.nHeight));
  395. image_name.append("_fn");
  396. image_name.append(QString::number(stImageInfo.nFrameNum));
  397. image_name.append("_L.bmp");
  398. }
  399. if (i == 1) {
  400. snprintf(chImageName, IMAGE_NAME_LEN,
  401. "Image_w%d_h%d_fn%03d_R.bmp", stImageInfo.nWidth,
  402. stImageInfo.nHeight, stImageInfo.nFrameNum);
  403. }
  404. } else if (MV_Image_Jpeg == stParam.enImageType) {
  405. if (i == 0) {
  406. snprintf(chImageName, IMAGE_NAME_LEN,
  407. "Image_w%d_h%d_fn%d_L.jpg", stImageInfo.nWidth,
  408. stImageInfo.nHeight, stImageInfo.nFrameNum);
  409. image_name = "Image_w";
  410. image_name.append(QString::number(stImageInfo.nWidth));
  411. image_name.append("_h");
  412. image_name.append(QString::number(stImageInfo.nHeight));
  413. image_name.append("_fn");
  414. image_name.append(QString::number(stImageInfo.nFrameNum));
  415. image_name.append("_L.jpg");
  416. }
  417. if (i == 1) {
  418. snprintf(chImageName, IMAGE_NAME_LEN,
  419. "Image_w%d_h%d_fn%03d_R.jpg", stImageInfo.nWidth,
  420. stImageInfo.nHeight, stImageInfo.nFrameNum);
  421. }
  422. }
  423. QString imagePath = saveDirPath + image_name;
  424. QByteArray ba = imagePath.toLatin1();
  425. imageName_c_str = ba.data();
  426. FILE *fp = fopen(imageName_c_str, "wb");
  427. fwrite(m_pcMyCamera[i]->m_pBufForSaveImage, 1, stParam.nImageLen,
  428. fp);
  429. fclose(fp);
  430. // ui->lbl_camera_R->setPixmap(QPixmap(image_name));
  431. // ui->lbl_camera_R->setScaledContents(true);
  432. }
  433. }
  434. }
  435. void Widget::on_le_set_exposure_textChanged(const QString &arg1)
  436. {
  437. //设置曝光时间
  438. QString str = ui->le_set_exposure->text(); // 读取
  439. int exposure_Time = str.toInt();
  440. for (int i = 0; i < devices_num; i++) {
  441. m_pcMyCamera[i]->SetEnumValue("ExposureAuto",
  442. MV_EXPOSURE_AUTO_MODE_OFF);
  443. m_pcMyCamera[i]->SetFloatValue("ExposureTime", exposure_Time);
  444. }
  445. }
  446. void Widget::on_le_set_gain_textChanged(const QString &arg1)
  447. {
  448. QString str = ui->le_set_gain->text(); // 读取
  449. float gain = str.toFloat();
  450. for (int i = 0; i < devices_num; i++) {
  451. m_pcMyCamera[i]->SetEnumValue("GainAuto", 0);
  452. m_pcMyCamera[i]->SetFloatValue("Gain", gain);
  453. }
  454. }
  455. void Widget::on_pbn_return_main_clicked()
  456. {
  457. //发送信号实现页面切换
  458. //connect(ui->pbn_return_main,SIGNAL(clicked()),this,SIGNAL(back()));
  459. }

3、界面效果

其中返回主界面的button是在部署深度学习模型中要用的,与相机连接无关 ,整体就是:

枚举相机->打开相机->连续模式->连续采集or软触发一次


参考博客:海康威视在linux下使用笔记——ros驱动相机_hikrobot工业相机ros驱动-CSDN博客

        

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

闽ICP备14008679号