前言
本人需要在树莓派上部署深度学习推理模型 ,由于本实验室只有海康工业相机,因此通过借鉴博客和自主调试,完成了模型的部署。本文主要讲述如何在基于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文件夹,即在终端输入命令
cd /opt/MVS/bin
./MVS
如果成功弹出如下界面,表示安装成功
2、opencv的编译
opencv的编译算是一个运气活,如果你是那个天选之子的话可能一次就成功,博主本人在ubuntu上安装基本比较顺利,但是在树莓派上编译经历了一整天的折磨,通过修改各种报错,最后总算是成功了,这里不再具体讲如何编译,直接上链接
参考博客:linux下编译opencv_opencv linux编译-CSDN博客
3、Qt的安装
参考博客: linux环境下安装QT超详细_qt-opensource-linux-CSDN博客
二、qt中.pro文件配置opencv
需要添加的文件路径大概就是这些,具体需要根据自己的opencv编译路径来对应
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
MvCamera.cpp \
main.cpp \
mainwidget.cpp \
mythread.cpp \
widget.cpp \
yolov5.cpp
HEADERS += \
MvCamera.h \
mainwidget.h \
mythread.h \
widget.h \
yolov5.h
FORMS += \
mainwidget.ui \
widget.ui
QMAKE_LFLAGS += -no-pie
###################################对opencv的支持
INCLUDEPATH += /usr/local/include \
/usr/local/include/opencv4 \
/usr/local/include/opencv4/opencv2\
$$PWD/include
LIBS += /usr/local/lib/libopencv_calib3d.so \
/usr/local/lib/libopencv_core.so \
/usr/local/lib/libopencv_features2d.so \
/usr/local/lib/libopencv_flann.so \
/usr/local/lib/libopencv_highgui.so \
/usr/local/lib/libopencv_imgcodecs.so \
/usr/local/lib/libopencv_imgproc.so \
/usr/local/lib/libopencv_ml.so \
/usr/local/lib/libopencv_objdetect.so \
/usr/local/lib/libopencv_photo.so \
#/usr/local/lib/libopencv_shape.so \
/usr/local/lib/libopencv_stitching.so \
#/usr/local/lib/libopencv_superres.so \
/usr/local/lib/libopencv_videoio.so \
/usr/local/lib/libopencv_video.so\
/usr/local/lib/libopencv_dnn.so \
-L$$PWD/64/ -lMvCameraControl
/usr/local/lib/libopencv_videostab.so
###################################
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
test2.pro.user
RESOURCES += \
res.qrc
三、程序运行
1、相机依赖的h文件和c文件
① .h文件
#ifndef MVCAMERA_H
#define MVCAMERA_H
#include "MvCameraControl.h"
#include <string.h>
#include <QDebug>
#include <stdio.h>
#ifndef MV_NULL
#define MV_NULL 0
#endif
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/types_c.h"
class CMvCamera
{
public:
CMvCamera();
~CMvCamera();
// ch:获取SDK版本号 | en:Get SDK Version
static int GetSDKVersion();
// ch:枚举设备 | en:Enumerate Device
static int EnumDevices(unsigned int nTLayerType,
MV_CC_DEVICE_INFO_LIST *pstDevList);
// ch:判断设备是否可达 | en:Is the device accessible
static bool IsDeviceAccessible(MV_CC_DEVICE_INFO *pstDevInfo,
unsigned int nAccessMode);
// ch:打开设备 | en:Open Device
int Open(MV_CC_DEVICE_INFO *pstDeviceInfo);
// ch:关闭设备 | en:Close Device
int Close();
// ch:判断相机是否处于连接状态 | en:Is The Device Connected
bool IsDeviceConnected();
// ch:注册图像数据回调 | en:Register Image Data CallBack
int RegisterImageCallBack(
void(__stdcall *cbOutput)(unsigned char *pData,
MV_FRAME_OUT_INFO_EX *pFrameInfo,
void *pUser),
void *pUser);
// ch:开启抓图 | en:Start Grabbing
int StartGrabbing();
// ch:停止抓图 | en:Stop Grabbing
int StopGrabbing();
// ch:主动获取一帧图像数据 | en:Get one frame initiatively
int GetImageBuffer(MV_FRAME_OUT *pFrame, int nMsec);
// ch:释放图像缓存 | en:Free image buffer
int FreeImageBuffer(MV_FRAME_OUT *pFrame);
// ch:主动获取一帧图像数据 | en:Get one frame initiatively
int GetOneFrameTimeout(unsigned char *pData, unsigned int *pnDataLen,
unsigned int nDataSize,
MV_FRAME_OUT_INFO_EX *pFrameInfo, int nMsec);
// ch:显示一帧图像 | en:Display one frame image
int DisplayOneFrame(MV_DISPLAY_FRAME_INFO *pDisplayInfo);
// ch:设置SDK内部图像缓存节点个数 | en:Set the number of the internal image
// cache nodes in SDK
int SetImageNodeNum(unsigned int nNum);
// ch:获取设备信息 | en:Get device information
int GetDeviceInfo(MV_CC_DEVICE_INFO *pstDevInfo);
// ch:获取GEV相机的统计信息 | en:Get detect info of GEV camera
int GetGevAllMatchInfo(MV_MATCH_INFO_NET_DETECT *pMatchInfoNetDetect);
// ch:获取U3V相机的统计信息 | en:Get detect info of U3V camera
int GetU3VAllMatchInfo(MV_MATCH_INFO_USB_DETECT *pMatchInfoUSBDetect);
// ch:获取和设置Int型参数,如 Width和Height,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件 en:Get Int type parameters, such as Width and
// Height, for details please refer to MvCameraNode.xlsx file under SDK
// installation directory
// int GetIntValue(IN const char* strKey, OUT MVCC_INTVALUE_EX* pIntValue);
int GetIntValue(IN const char *strKey, OUT unsigned int *pnValue);
int SetIntValue(IN const char *strKey, IN int64_t nValue);
// ch:获取和设置Enum型参数,如 PixelFormat,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件 en:Get Enum type parameters, such as PixelFormat,
// for details please refer to MvCameraNode.xlsx file under SDK installation
// directory
int GetEnumValue(IN const char *strKey, OUT MVCC_ENUMVALUE *pEnumValue);
int SetEnumValue(IN const char *strKey, IN unsigned int nValue);
int SetEnumValueByString(IN const char *strKey, IN const char *sValue);
// ch:获取和设置Float型参数,如
// ExposureTime和Gain,详细内容参考SDK安装目录下的 MvCameraNode.xlsx 文件
// en:Get Float type parameters, such as ExposureTime and Gain, for details
// please refer to MvCameraNode.xlsx file under SDK installation directory
int GetFloatValue(IN const char *strKey, OUT MVCC_FLOATVALUE *pFloatValue);
int SetFloatValue(IN const char *strKey, IN float fValue);
// ch:获取和设置Bool型参数,如 ReverseX,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件 en:Get Bool type parameters, such as ReverseX, for
// details please refer to MvCameraNode.xlsx file under SDK installation
// directory
int GetBoolValue(IN const char *strKey, OUT bool *pbValue);
int SetBoolValue(IN const char *strKey, IN bool bValue);
// ch:获取和设置String型参数,如 DeviceUserID,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件UserSetSave en:Get String type parameters, such as
// DeviceUserID, for details please refer to MvCameraNode.xlsx file under
// SDK installation directory
int GetStringValue(IN const char *strKey, MVCC_STRINGVALUE *pStringValue);
int SetStringValue(IN const char *strKey, IN const char *strValue);
// ch:执行一次Command型命令,如 UserSetSave,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件 en:Execute Command once, such as UserSetSave, for
// details please refer to MvCameraNode.xlsx file under SDK installation
// directory
int CommandExecute(IN const char *strKey);
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal
// package size(It only works for the GigE camera)
int GetOptimalPacketSize(unsigned int *pOptimalPacketSize);
// ch:注册消息异常回调 | en:Register Message Exception CallBack
int RegisterExceptionCallBack(
void(__stdcall *cbException)(unsigned int nMsgType, void *pUser),
void *pUser);
// ch:注册单个事件回调 | en:Register Event CallBack
int RegisterEventCallBack(
const char *pEventName,
void(__stdcall *cbEvent)(MV_EVENT_OUT_INFO *pEventInfo, void *pUser),
void *pUser);
// ch:强制IP | en:Force IP
int ForceIp(unsigned int nIP, unsigned int nSubNetMask,
unsigned int nDefaultGateWay);
// ch:配置IP方式 | en:IP configuration method
int SetIpConfig(unsigned int nType);
// ch:设置网络传输模式 | en:Set Net Transfer Mode
int SetNetTransMode(unsigned int nType);
// ch:像素格式转换 | en:Pixel format conversion
int ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM *pstCvtParam);
// ch:保存图片 | en:save image
int SaveImage(MV_SAVE_IMAGE_PARAM_EX *pstParam);
// ch:保存图片为文件 | en:Save the image as a file
//int SaveImageToFile(MV_SAVE_IMG_TO_FILE_PARAM *pstParam);
//设置是否为触发模式
int setTriggerMode(unsigned int TriggerModeNum);
//设置触发源
int setTriggerSource(unsigned int TriggerSourceNum);
//软触发
int softTrigger();
//读取buffer
int ReadBuffer(cv::Mat &image);
//读取buffer
int ReadBuffer2(cv::Mat &image,bool saveFlag,QByteArray imageName);
//设置曝光时间
int setExposureTime(float ExposureTimeNum);
public:
void *m_hDevHandle;
unsigned int m_nTLayerType;
public:
unsigned char *m_pBufForSaveImage; // 用于保存图像的缓存
unsigned int m_nBufSizeForSaveImage;
unsigned char *m_pBufForDriver; // 用于从驱动获取图像的缓存
unsigned int m_nBufSizeForDriver;
};
#endif // MVCAMERA_H
② cpp文件
#include "MvCamera.h"
#include <stdio.h>
CMvCamera::CMvCamera()
{
m_hDevHandle = MV_NULL;
}
CMvCamera::~CMvCamera()
{
if (m_hDevHandle) {
MV_CC_DestroyHandle(m_hDevHandle);
m_hDevHandle = MV_NULL;
}
}
// ch:获取SDK版本号 | en:Get SDK Version
int CMvCamera::GetSDKVersion()
{
return MV_CC_GetSDKVersion();
}
// ch:枚举设备 | en:Enumerate Device
int CMvCamera::EnumDevices(unsigned int nTLayerType,
MV_CC_DEVICE_INFO_LIST *pstDevList)
{
return MV_CC_EnumDevices(nTLayerType, pstDevList);
}
// ch:判断设备是否可达 | en:Is the device accessible
bool CMvCamera::IsDeviceAccessible(MV_CC_DEVICE_INFO *pstDevInfo,
unsigned int nAccessMode)
{
return MV_CC_IsDeviceAccessible(pstDevInfo, nAccessMode);
}
// ch:打开设备 | en:Open Device
int CMvCamera::Open(MV_CC_DEVICE_INFO *pstDeviceInfo)
{
if (MV_NULL == pstDeviceInfo) {
return MV_E_PARAMETER;
}
if (m_hDevHandle) {
return MV_E_CALLORDER;
}
int nRet = MV_CC_CreateHandle(&m_hDevHandle, pstDeviceInfo);
if (MV_OK != nRet) {
return nRet;
}
nRet = MV_CC_OpenDevice(m_hDevHandle);
if (MV_OK != nRet) {
MV_CC_DestroyHandle(m_hDevHandle);
m_hDevHandle = MV_NULL;
}
return nRet;
}
// ch:关闭设备 | en:Close Device
int CMvCamera::Close()
{
if (MV_NULL == m_hDevHandle) {
return MV_E_HANDLE;
}
MV_CC_CloseDevice(m_hDevHandle);
int nRet = MV_CC_DestroyHandle(m_hDevHandle);
m_hDevHandle = MV_NULL;
return nRet;
}
// ch:判断相机是否处于连接状态 | en:Is The Device Connected
bool CMvCamera::IsDeviceConnected()
{
return MV_CC_IsDeviceConnected(m_hDevHandle);
}
// ch:注册图像数据回调 | en:Register Image Data CallBack
int CMvCamera::RegisterImageCallBack(
void(__stdcall *cbOutput)(unsigned char *pData,
MV_FRAME_OUT_INFO_EX *pFrameInfo, void *pUser),
void *pUser)
{
return MV_CC_RegisterImageCallBackEx(m_hDevHandle, cbOutput, pUser);
}
// ch:开启抓图 | en:Start Grabbing
int CMvCamera::StartGrabbing()
{
return MV_CC_StartGrabbing(m_hDevHandle);
}
// ch:停止抓图 | en:Stop Grabbing
int CMvCamera::StopGrabbing()
{
return MV_CC_StopGrabbing(m_hDevHandle);
}
// ch:主动获取一帧图像数据 | en:Get one frame initiatively
int CMvCamera::GetImageBuffer(MV_FRAME_OUT *pFrame, int nMsec)
{
return MV_CC_GetImageBuffer(m_hDevHandle, pFrame, nMsec);
}
// ch:释放图像缓存 | en:Free image buffer
int CMvCamera::FreeImageBuffer(MV_FRAME_OUT *pFrame)
{
return MV_CC_FreeImageBuffer(m_hDevHandle, pFrame);
}
// ch:主动获取一帧图像数据 | en:Get one frame initiatively
int CMvCamera::GetOneFrameTimeout(unsigned char *pData, unsigned int *pnDataLen,
unsigned int nDataSize,
MV_FRAME_OUT_INFO_EX *pFrameInfo, int nMsec)
{
if (NULL == pnDataLen) {
return MV_E_PARAMETER;
}
int nRet = MV_OK;
*pnDataLen = 0;
nRet = MV_CC_GetOneFrameTimeout(m_hDevHandle, pData, nDataSize, pFrameInfo,
nMsec);
if (MV_OK != nRet) {
return nRet;
}
*pnDataLen = pFrameInfo->nFrameLen;
return nRet;
}
// ch:设置显示窗口句柄 | en:Set Display Window Handle
int CMvCamera::DisplayOneFrame(MV_DISPLAY_FRAME_INFO *pDisplayInfo)
{
return MV_CC_DisplayOneFrame(m_hDevHandle, pDisplayInfo);
}
// ch:设置SDK内部图像缓存节点个数 | en:Set the number of the internal image
// cache nodes in SDK
int CMvCamera::SetImageNodeNum(unsigned int nNum)
{
return MV_CC_SetImageNodeNum(m_hDevHandle, nNum);
}
// ch:获取设备信息 | en:Get device information
int CMvCamera::GetDeviceInfo(MV_CC_DEVICE_INFO *pstDevInfo)
{
return MV_CC_GetDeviceInfo(m_hDevHandle, pstDevInfo);
}
// ch:获取GEV相机的统计信息 | en:Get detect info of GEV camera
int CMvCamera::GetGevAllMatchInfo(MV_MATCH_INFO_NET_DETECT *pMatchInfoNetDetect)
{
if (MV_NULL == pMatchInfoNetDetect) {
return MV_E_PARAMETER;
}
MV_CC_DEVICE_INFO stDevInfo = { 0 };
GetDeviceInfo(&stDevInfo);
if (stDevInfo.nTLayerType != MV_GIGE_DEVICE) {
return MV_E_SUPPORT;
}
MV_ALL_MATCH_INFO struMatchInfo = { 0 };
struMatchInfo.nType = MV_MATCH_TYPE_NET_DETECT;
struMatchInfo.pInfo = pMatchInfoNetDetect;
struMatchInfo.nInfoSize = sizeof(MV_MATCH_INFO_NET_DETECT);
memset(struMatchInfo.pInfo, 0, sizeof(MV_MATCH_INFO_NET_DETECT));
return MV_CC_GetAllMatchInfo(m_hDevHandle, &struMatchInfo);
}
// ch:获取U3V相机的统计信息 | en:Get detect info of U3V camera
int CMvCamera::GetU3VAllMatchInfo(MV_MATCH_INFO_USB_DETECT *pMatchInfoUSBDetect)
{
if (MV_NULL == pMatchInfoUSBDetect) {
return MV_E_PARAMETER;
}
MV_CC_DEVICE_INFO stDevInfo = { 0 };
GetDeviceInfo(&stDevInfo);
if (stDevInfo.nTLayerType != MV_USB_DEVICE) {
return MV_E_SUPPORT;
}
MV_ALL_MATCH_INFO struMatchInfo = { 0 };
struMatchInfo.nType = MV_MATCH_TYPE_USB_DETECT;
struMatchInfo.pInfo = pMatchInfoUSBDetect;
struMatchInfo.nInfoSize = sizeof(MV_MATCH_INFO_USB_DETECT);
memset(struMatchInfo.pInfo, 0, sizeof(MV_MATCH_INFO_USB_DETECT));
return MV_CC_GetAllMatchInfo(m_hDevHandle, &struMatchInfo);
}
// ch:获取和设置Int型参数,如 Width和Height,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件 en:Get Int type parameters, such as Width and Height,
// for details please refer to MvCameraNode.xlsx file under SDK installation
// directory
int CMvCamera::GetIntValue(IN const char *strKey, OUT unsigned int *pnValue)
{
if (NULL == strKey || NULL == pnValue) {
return MV_E_PARAMETER;
}
MVCC_INTVALUE stParam;
memset(&stParam, 0, sizeof(MVCC_INTVALUE));
int nRet = MV_CC_GetIntValue(m_hDevHandle, strKey, &stParam);
if (MV_OK != nRet) {
return nRet;
}
*pnValue = stParam.nCurValue;
return MV_OK;
}
int CMvCamera::SetIntValue(IN const char *strKey, IN int64_t nValue)
{
return MV_CC_SetIntValueEx(m_hDevHandle, strKey, nValue);
}
// ch:获取和设置Enum型参数,如 PixelFormat,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件 en:Get Enum type parameters, such as PixelFormat, for
// details please refer to MvCameraNode.xlsx file under SDK installation
// directory
int CMvCamera::GetEnumValue(IN const char *strKey,
OUT MVCC_ENUMVALUE *pEnumValue)
{
return MV_CC_GetEnumValue(m_hDevHandle, strKey, pEnumValue);
}
int CMvCamera::SetEnumValue(IN const char *strKey, IN unsigned int nValue)
{
return MV_CC_SetEnumValue(m_hDevHandle, strKey, nValue);
}
int CMvCamera::SetEnumValueByString(IN const char *strKey,
IN const char *sValue)
{
return MV_CC_SetEnumValueByString(m_hDevHandle, strKey, sValue);
}
// ch:获取和设置Float型参数,如 ExposureTime和Gain,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件 en:Get Float type parameters, such as ExposureTime and
// Gain, for details please refer to MvCameraNode.xlsx file under SDK
// installation directory
int CMvCamera::GetFloatValue(IN const char *strKey,
OUT MVCC_FLOATVALUE *pFloatValue)
{
return MV_CC_GetFloatValue(m_hDevHandle, strKey, pFloatValue);
}
int CMvCamera::SetFloatValue(IN const char *strKey, IN float fValue)
{
return MV_CC_SetFloatValue(m_hDevHandle, strKey, fValue);
}
// ch:获取和设置Bool型参数,如 ReverseX,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件 en:Get Bool type parameters, such as ReverseX, for
// details please refer to MvCameraNode.xlsx file under SDK installation
// directory
int CMvCamera::GetBoolValue(IN const char *strKey, OUT bool *pbValue)
{
return MV_CC_GetBoolValue(m_hDevHandle, strKey, pbValue);
}
int CMvCamera::SetBoolValue(IN const char *strKey, IN bool bValue)
{
return MV_CC_SetBoolValue(m_hDevHandle, strKey, bValue);
}
// ch:获取和设置String型参数,如 DeviceUserID,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件UserSetSave en:Get String type parameters, such as
// DeviceUserID, for details please refer to MvCameraNode.xlsx file under SDK
// installation directory
int CMvCamera::GetStringValue(IN const char *strKey,
MVCC_STRINGVALUE *pStringValue)
{
return MV_CC_GetStringValue(m_hDevHandle, strKey, pStringValue);
}
int CMvCamera::SetStringValue(IN const char *strKey, IN const char *strValue)
{
return MV_CC_SetStringValue(m_hDevHandle, strKey, strValue);
}
// ch:执行一次Command型命令,如 UserSetSave,详细内容参考SDK安装目录下的
// MvCameraNode.xlsx 文件 en:Execute Command once, such as UserSetSave, for
// details please refer to MvCameraNode.xlsx file under SDK installation
// directory
int CMvCamera::CommandExecute(IN const char *strKey)
{
return MV_CC_SetCommandValue(m_hDevHandle, strKey);
}
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal
// package size(It only works for the GigE camera)
int CMvCamera::GetOptimalPacketSize(unsigned int *pOptimalPacketSize)
{
if (MV_NULL == pOptimalPacketSize) {
return MV_E_PARAMETER;
}
int nRet = MV_CC_GetOptimalPacketSize(m_hDevHandle);
if (nRet < MV_OK) {
return nRet;
}
*pOptimalPacketSize = (unsigned int)nRet;
return MV_OK;
}
// ch:注册消息异常回调 | en:Register Message Exception CallBack
int CMvCamera::RegisterExceptionCallBack(
void(__stdcall *cbException)(unsigned int nMsgType, void *pUser),
void *pUser)
{
return MV_CC_RegisterExceptionCallBack(m_hDevHandle, cbException, pUser);
}
// ch:注册单个事件回调 | en:Register Event CallBack
int CMvCamera::RegisterEventCallBack(
const char *pEventName,
void(__stdcall *cbEvent)(MV_EVENT_OUT_INFO *pEventInfo, void *pUser),
void *pUser)
{
return MV_CC_RegisterEventCallBackEx(m_hDevHandle, pEventName, cbEvent,
pUser);
}
// ch:强制IP | en:Force IP
int CMvCamera::ForceIp(unsigned int nIP, unsigned int nSubNetMask,
unsigned int nDefaultGateWay)
{
return MV_GIGE_ForceIpEx(m_hDevHandle, nIP, nSubNetMask, nDefaultGateWay);
}
// ch:配置IP方式 | en:IP configuration method
int CMvCamera::SetIpConfig(unsigned int nType)
{
return MV_GIGE_SetIpConfig(m_hDevHandle, nType);
}
// ch:设置网络传输模式 | en:Set Net Transfer Mode
int CMvCamera::SetNetTransMode(unsigned int nType)
{
return MV_GIGE_SetNetTransMode(m_hDevHandle, nType);
}
// ch:像素格式转换 | en:Pixel format conversion
int CMvCamera::ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM *pstCvtParam)
{
return MV_CC_ConvertPixelType(m_hDevHandle, pstCvtParam);
}
// ch:保存图片 | en:save image
int CMvCamera::SaveImage(MV_SAVE_IMAGE_PARAM_EX *pstParam)
{
return MV_CC_SaveImageEx2(m_hDevHandle, pstParam);
}
//ch:保存图片为文件 | en:Save the image as a file
// int CMvCamera::SaveImageToFile(MV_SAVE_IMG_TO_FILE_PARAM *pstSaveFileParam)
//{
// return MV_CC_SaveImageToFile(m_hDevHandle, pstSaveFileParam);
//}
//设置是否为触发模式
int CMvCamera::setTriggerMode(unsigned int TriggerModeNum)
{
// 0:Off 1:On
int tempValue =
MV_CC_SetEnumValue(m_hDevHandle, "TriggerMode", TriggerModeNum);
if (tempValue != 0) {
return -1;
} else {
return 0;
}
}
//设置触发源
int CMvCamera::setTriggerSource(unsigned int TriggerSourceNum)
{
// 0:Line0 1:Line1 7:Software
int tempValue =
MV_CC_SetEnumValue(m_hDevHandle, "TriggerSource", TriggerSourceNum);
if (tempValue != 0) {
return -1;
} else {
return 0;
}
}
//发送软触发
int CMvCamera::softTrigger()
{
int tempValue = MV_CC_SetCommandValue(m_hDevHandle, "TriggerSoftware");
if (tempValue != 0) {
return -1;
} else {
return 0;
}
}
//读取相机中的图像
// int ReadBuffer(cv::Mat &image);
int CMvCamera::ReadBuffer(cv::Mat &image)
{
cv::Mat *getImage = new cv::Mat();
unsigned int nRecvBufSize = 0;
MVCC_INTVALUE stParam;
memset(&stParam, 0, sizeof(MVCC_INTVALUE));
int tempValue = MV_CC_GetIntValue(m_hDevHandle, "PayloadSize", &stParam);
if (tempValue != 0) {
return -1;
}
nRecvBufSize = stParam.nCurValue;
unsigned char *pDate;
pDate = (unsigned char *)malloc(nRecvBufSize);
MV_FRAME_OUT_INFO_EX stImageInfo = { 0 };
tempValue = MV_CC_GetOneFrameTimeout(m_hDevHandle, pDate, nRecvBufSize,
&stImageInfo, 500);
if (tempValue != 0) {
return -1;
}
m_nBufSizeForSaveImage =
stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
unsigned char *m_pBufForSaveImage;
m_pBufForSaveImage = (unsigned char *)malloc(m_nBufSizeForSaveImage);
bool isMono;
switch (stImageInfo.enPixelType) {
case PixelType_Gvsp_Mono8:
case PixelType_Gvsp_Mono10:
case PixelType_Gvsp_Mono10_Packed:
case PixelType_Gvsp_Mono12:
case PixelType_Gvsp_Mono12_Packed:
isMono = true;
break;
default:
isMono = false;
break;
}
if (isMono) {
*getImage =
cv::Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC1, pDate);
// imwrite("d:\\测试opencv_Mono.tif", image);
} else {
//转换图像格式为BGR8
MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 };
memset(&stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));
stConvertParam.nWidth = stImageInfo.nWidth; // ch:图像宽 | en:image
// width
stConvertParam.nHeight =
stImageInfo.nHeight; // ch:图像高 | en:image height
// stConvertParam.pSrcData = m_pBufForDriver; //ch:输入数据缓存 |
// en:input data buffer
stConvertParam.pSrcData =
pDate; // ch:输入数据缓存 | en:input data buffer
stConvertParam.nSrcDataLen =
stImageInfo.nFrameLen; // ch:输入数据大小 | en:input data size
stConvertParam.enSrcPixelType =
stImageInfo.enPixelType; // ch:输入像素格式 | en:input pixel format
stConvertParam.enDstPixelType =
PixelType_Gvsp_BGR8_Packed; // ch:输出像素格式 | en:output pixel
// format 适用于OPENCV的图像格式
// stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed;
//输出像素格式 | en:output pixel format
stConvertParam.pDstBuffer =
m_pBufForSaveImage; // ch:输出数据缓存 | en:output data buffer
stConvertParam.nDstBufferSize =
m_nBufSizeForSaveImage; // ch:输出缓存大小 | en:output buffer size
MV_CC_ConvertPixelType(m_hDevHandle, &stConvertParam);
*getImage = cv::Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC3,
m_pBufForSaveImage);
}
(*getImage).copyTo(image);
(*getImage).release();
free(pDate);
free(m_pBufForSaveImage);
return 0;
}
//设置曝光时间
int CMvCamera::setExposureTime(float ExposureTimeNum)
{
int tempValue =
MV_CC_SetFloatValue(m_hDevHandle, "ExposureTime", ExposureTimeNum);
if (tempValue != 0) {
return -1;
} else {
return 0;
}
}
2、主界面的相关代码
① h文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMessageBox>
#include <QCloseEvent>
#include <QSettings>
#include <QDate>
#include <QDir>
#include "MvCamera.h"
#include "mythread.h"
#include "mainwidget.h"
#define MAX_DEVICE_NUM 2
#define TRIGGER_SOURCE 7
#define EXPOSURE_TIME 40000
#define FRAME 30
#define TRIGGER_ON 1
#define TRIGGER_OFF 0
#define START_GRABBING_ON 1
#define START_GRABBING_OFF 0
#define IMAGE_NAME_LEN 64
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class MainWidget;
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
signals:
void closedWid();
void back();
public:
CMvCamera *m_pcMyCamera[MAX_DEVICE_NUM]; // 相机指针对象
MV_CC_DEVICE_INFO_LIST m_stDevList; // 存储设备列表
cv::Mat *myImage_L = new cv::Mat(); //保存左相机图像的图像指针对象
cv::Mat *myImage_R = new cv::Mat(); //保存右相机有图像的图像指针对象
int devices_num; // 设备数量
MainWidget *mainWid = NULL; //创建一个存储主界面窗体的指针
public:
MyThread *myThread_Camera_show = NULL; //相机实时显示线程对象
private slots:
void on_pbn_enum_camera_clicked();
void on_pbn_open_camera_clicked();
void on_rdo_continue_mode_clicked();
void on_rdo_softigger_mode_clicked();
void on_pbn_start_grabbing_clicked();
void on_pbn_stop_grabbing_clicked();
void on_pbn_software_once_clicked();
void display_myImage_L(const Mat *imagePrt);
void display_myImage_Main(const Mat *imagePrt);
void on_pbn_close_camera_clicked();
void on_pbn_save_BMP_clicked();
void on_pbn_save_JPG_clicked();
void on_le_set_exposure_textChanged(const QString &arg1);
void on_le_set_gain_textChanged(const QString &arg1);
void on_pbn_return_main_clicked();
public:
// 状态
bool m_bOpenDevice; // 是否打开设备
bool m_bStartGrabbing; // 是否开始抓图
int m_nTriggerMode; // 触发模式
int m_bContinueStarted; // 开启过连续采集图像
MV_SAVE_IAMGE_TYPE m_nSaveImageType; // 保存图像格式
private:
QString PrintDeviceInfo(MV_CC_DEVICE_INFO *pstMVDevInfo, int num_index);
QString m_SaveImagePath;
void OpenDevices();
void CloseDevices();
void SaveImage();
void saveImage(QString format,int index);
private:
Ui::Widget *ui;
protected:
void closeEvent(QCloseEvent *event) override; //重写关闭事件处理函数
};
#endif // WIDGET_H
② cpp文件
#include "widget.h"
#include "./ui_widget.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <QDebug>
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
ui->lbl_camera_L->setPixmap(QPixmap(":/icon/MVS.png"));
ui->lbl_camera_L->setScaledContents(true);
//ui->lbl_camera_R->setPixmap(QPixmap("back_img.jpg"));
//ui->lbl_camera_R->setScaledContents(true);
// 相机初始化控件
ui->pbn_enum_camera->setEnabled(true);
ui->pbn_open_camera->setEnabled(false);
ui->pbn_close_camera->setEnabled(false);
ui->cmb_camera_index->setEnabled(false);
// 图像采集控件
ui->rdo_continue_mode->setEnabled(false);
ui->rdo_softigger_mode->setEnabled(false);
ui->pbn_start_grabbing->setEnabled(false);
ui->pbn_stop_grabbing->setEnabled(false);
ui->pbn_software_once->setEnabled(false);
// 参数控件
ui->le_set_exposure->setEnabled(false);
ui->le_set_gain->setEnabled(false);
// 保存图像控件
ui->pbn_save_BMP->setEnabled(false);
ui->pbn_save_JPG->setEnabled(false);
// 线程对象实例化
myThread_Camera_show = new MyThread; //相机线程对象
//发送信号实现页面切换
connect(ui->pbn_return_main,SIGNAL(clicked()),this,SIGNAL(back()));
connect(myThread_Camera_show, SIGNAL(Display(const Mat *)), this,
SLOT(display_myImage_L(const Mat *)));
// 曝光和增益的输入控件限制值
QRegExp int_rx("100000|([0-9]{0,5})");
ui->le_set_exposure->setValidator(new QRegExpValidator(int_rx, this));
QRegExp double_rx("15|([0-9]{0,1}[0-5]{1,2}[\.][0-9]{0,1})");
ui->le_set_gain->setValidator(new QRegExpValidator(double_rx, this));
}
Widget::~Widget()
{
delete ui;
delete mainWid;
delete myThread_Camera_show;
delete myImage_L;
}
//创建关闭子窗体事件,显示主窗体
void Widget::closeEvent(QCloseEvent *event)
{
emit closedWid(); //发射closed信号
event->accept();
}
void Widget::on_pbn_enum_camera_clicked()
{
memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
int nRet = MV_OK;
nRet = CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList);
devices_num = m_stDevList.nDeviceNum;
if (devices_num == 0) {
QString cameraInfo;
cameraInfo =
QString::fromLocal8Bit("暂无设备可连接,请检查设备是否连接正确!");
ui->lbl_camera_messagee->setText(cameraInfo);
}
if (devices_num > 0) {
QString cameraInfo;
for (int i = 0; i < devices_num; i++) {
MV_CC_DEVICE_INFO *pDeviceInfo = m_stDevList.pDeviceInfo[i];
QString cameraInfo_i = PrintDeviceInfo(pDeviceInfo, i);
cameraInfo.append(cameraInfo_i);
cameraInfo.append("\n");
ui->cmb_camera_index->addItem(QString::number(i+1));
}
ui->lbl_camera_messagee->setText(cameraInfo);
ui->pbn_open_camera->setEnabled(true);
ui->cmb_camera_index->setEnabled(true);
}
}
//打印相机的型号、ip等信息
QString Widget::PrintDeviceInfo(MV_CC_DEVICE_INFO *pstMVDevInfo, int num_index)
{
QString cameraInfo_index;
cameraInfo_index = QString::fromLocal8Bit("相机序号:");
cameraInfo_index.append(QString::number(num_index+1));
cameraInfo_index.append("\t\t");
// 海康GIGE协议的相机
if (pstMVDevInfo->nTLayerType == MV_GIGE_DEVICE) {
int nIp1 =
((pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >>
24);
int nIp2 =
((pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >>
16);
int nIp3 =
((pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >>
8);
int nIp4 =
(pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff);
cameraInfo_index.append(QString::fromLocal8Bit("相机型号:"));
std::string str_name =
(char *)pstMVDevInfo->SpecialInfo.stGigEInfo.chModelName;
cameraInfo_index.append(QString::fromStdString(str_name));
cameraInfo_index.append("\n");
cameraInfo_index.append(QString::fromLocal8Bit("当前相机IP地址:"));
cameraInfo_index.append(QString::number(nIp1));
cameraInfo_index.append(".");
cameraInfo_index.append(QString::number(nIp2));
cameraInfo_index.append(".");
cameraInfo_index.append(QString::number(nIp3));
cameraInfo_index.append(".");
cameraInfo_index.append(QString::number(nIp4));
cameraInfo_index.append("\t");
} else if (pstMVDevInfo->nTLayerType == MV_USB_DEVICE) {
cameraInfo_index.append(QString::fromLocal8Bit("相机型号:"));
std::string str_name =
(char *)pstMVDevInfo->SpecialInfo.stUsb3VInfo.chModelName;
cameraInfo_index.append(QString::fromStdString(str_name));
cameraInfo_index.append("\n");
} else {
cameraInfo_index.append(QString::fromLocal8Bit("相机型号:未知"));
}
cameraInfo_index.append(QString::fromLocal8Bit("相机品牌:海康威视"));
return cameraInfo_index;
}
void Widget::on_pbn_open_camera_clicked()
{
ui->pbn_open_camera->setEnabled(false);
ui->pbn_close_camera->setEnabled(true);
ui->rdo_continue_mode->setEnabled(true);
ui->rdo_softigger_mode->setEnabled(true);
ui->rdo_continue_mode->setCheckable(true);
// 参数据控件
ui->le_set_exposure->setEnabled(true);
ui->le_set_gain->setEnabled(true);
OpenDevices();
}
void Widget::OpenDevices()
{
int nRet = MV_OK;
// 创建相机指针对象
for (unsigned int i = 0, j = 0; j < m_stDevList.nDeviceNum; j++, i++) {
m_pcMyCamera[i] = new CMvCamera;
// 相机对象初始化
m_pcMyCamera[i]->m_pBufForDriver = NULL;
m_pcMyCamera[i]->m_pBufForSaveImage = NULL;
m_pcMyCamera[i]->m_nBufSizeForDriver = 0;
m_pcMyCamera[i]->m_nBufSizeForSaveImage = 0;
m_pcMyCamera[i]->m_nTLayerType =
m_stDevList.pDeviceInfo[j]->nTLayerType;
nRet = m_pcMyCamera[i]->Open(m_stDevList.pDeviceInfo[j]); //打开相机
//设置触发模式
m_pcMyCamera[i]->setTriggerMode(TRIGGER_ON);
//设置触发源为软触发
m_pcMyCamera[i]->setTriggerSource(TRIGGER_SOURCE);
//设置曝光时间,初始为40000,并关闭自动曝光模式
m_pcMyCamera[i]->setExposureTime(EXPOSURE_TIME);
m_pcMyCamera[i]->SetEnumValue("ExposureAuto",
MV_EXPOSURE_AUTO_MODE_OFF);
}
}
void Widget::on_rdo_continue_mode_clicked()
{
ui->pbn_start_grabbing->setEnabled(true);
m_nTriggerMode = TRIGGER_ON;
}
void Widget::on_rdo_softigger_mode_clicked()
{
// 如果开始选择的连续模式,切换到触发模式之前,需要先停止采集
if (m_bContinueStarted == 1) {
on_pbn_stop_grabbing_clicked(); //先执行停止采集
}
ui->pbn_start_grabbing->setEnabled(false);
ui->pbn_software_once->setEnabled(true);
m_nTriggerMode = TRIGGER_OFF;
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
m_pcMyCamera[i]->setTriggerMode(m_nTriggerMode);
}
}
void Widget::on_pbn_start_grabbing_clicked()
{
// 触发模式标记一下,切换触发模式时先执行停止采集图像函数
m_bContinueStarted = 1;
ui->pbn_start_grabbing->setEnabled(false);
ui->pbn_stop_grabbing->setEnabled(true);
// 保存图像控件
ui->pbn_save_BMP->setEnabled(true);
// 图像采集控件
ui->pbn_save_JPG->setEnabled(true);
int camera_Index = 0;
// 先判断什么模式,再判断是否正在采集
if (m_nTriggerMode == TRIGGER_ON) {
// 开始采集之后才创建workthread线程
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
//开启相机采集
m_pcMyCamera[i]->StartGrabbing();
camera_Index = i;
if (camera_Index == 0) {
myThread_Camera_show->getCameraPtr(
m_pcMyCamera[0]); //线程获取左相机指针
myThread_Camera_show->getImagePtr(
myImage_L); //线程获取图像指针
myThread_Camera_show->getCameraIndex(0); //相机 Index==0
if (!myThread_Camera_show->isRunning()) {
myThread_Camera_show->start();
m_pcMyCamera[0]->softTrigger();
m_pcMyCamera[0]->ReadBuffer(*myImage_L); //读取Mat格式的图像
}
}
}
}
}
void Widget::on_pbn_stop_grabbing_clicked()
{
ui->pbn_start_grabbing->setEnabled(true);
ui->pbn_stop_grabbing->setEnabled(false);
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
//关闭相机
if (myThread_Camera_show->isRunning()) {
m_pcMyCamera[0]->StopGrabbing();
myThread_Camera_show->requestInterruption();
myThread_Camera_show->wait();
}
}
}
void Widget::on_pbn_software_once_clicked()
{
// 保存图像控件
ui->pbn_save_BMP->setEnabled(true);
ui->pbn_save_JPG->setEnabled(true);
if (m_nTriggerMode == TRIGGER_OFF) {
int nRet = MV_OK;
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
//开启相机采集
m_pcMyCamera[i]->StartGrabbing();
if (i == 0) {
nRet = m_pcMyCamera[i]->CommandExecute("TriggerSoftware");
m_pcMyCamera[i]->ReadBuffer(*myImage_L);
display_myImage_L(myImage_L); //左相机图像
display_myImage_Main(myImage_L); //主界面显示
}
}
}
}
//在相机配置界面显示
void Widget::display_myImage_L(const Mat *imagePrt)
{
cv::Mat rgb;
//判断是黑白、彩色图像
QImage QmyImage_L;
if (myImage_L->channels() > 1) {
cv::cvtColor(*imagePrt, rgb, CV_BGR2RGB);
QmyImage_L = QImage((const unsigned char *)(rgb.data), rgb.cols,
rgb.rows, QImage::Format_RGB888);
} else {
cv::cvtColor(*imagePrt, rgb, CV_GRAY2RGB);
QmyImage_L = QImage((const unsigned char *)(rgb.data), rgb.cols,
rgb.rows, QImage::Format_RGB888);
}
QmyImage_L = (QmyImage_L)
.scaled(ui->lbl_camera_L->size(), Qt::IgnoreAspectRatio,
Qt::SmoothTransformation); //饱满填充
ui->lbl_camera_L->setPixmap(QPixmap::fromImage(QmyImage_L));
}
//在主界面显示
void Widget::display_myImage_Main(const Mat *imagePrt)
{
cv::Mat rgb;
cv::cvtColor(*imagePrt, rgb, CV_BGR2RGB);
QImage QmyImage_L;
QmyImage_L = QImage((const unsigned char *)(rgb.data), rgb.cols,
rgb.rows, QImage::Format_RGB888);
QmyImage_L = (QmyImage_L)
.scaled(ui->lbl_camera_L->size(), Qt::IgnoreAspectRatio,
Qt::SmoothTransformation); //饱满填充
//显示图像
this->mainWid=new MainWidget();
//ui->lbl_camera_L->setPixmap(QPixmap::fromImage(QmyImage_L));
mainWid->ui->lbl_res_pic->setPixmap(QPixmap::fromImage(QmyImage_L));
}
void Widget::CloseDevices()
{
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) {
// 关闭线程、相机
if (myThread_Camera_show->isRunning()) {
myThread_Camera_show->requestInterruption();
myThread_Camera_show->wait();
m_pcMyCamera[0]->StopGrabbing();
}
m_pcMyCamera[i]->Close();
}
// 关闭之后再枚举一遍
memset(&m_stDevList, 0,
sizeof(MV_CC_DEVICE_INFO_LIST)); // 初始化设备信息列表
int devices_num = MV_OK;
devices_num =
CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE,
&m_stDevList); // 枚举子网内所有设备,相机设备数量
}
void Widget::on_pbn_close_camera_clicked()
{
ui->pbn_open_camera->setEnabled(true);
ui->pbn_close_camera->setEnabled(false);
// 图像采集控件
ui->rdo_continue_mode->setEnabled(false);
ui->rdo_softigger_mode->setEnabled(false);
ui->pbn_start_grabbing->setEnabled(false);
ui->pbn_stop_grabbing->setEnabled(false);
ui->pbn_software_once->setEnabled(false);
// 参数控件
ui->le_set_exposure->setEnabled(false);
ui->le_set_gain->setEnabled(false);
// 保存图像控件
ui->pbn_save_BMP->setEnabled(false);
ui->pbn_save_JPG->setEnabled(false);
// 关闭设备,销毁线程
CloseDevices();
ui->lbl_camera_messagee->clear();
ui->lbl_camera_L->clear();
ui->lbl_camera_L->setPixmap(QPixmap(":/icon/MVS.png"));
//ui->lbl_camera_R->clear();
}
void Widget::on_pbn_save_BMP_clicked()
{
m_nSaveImageType = MV_Image_Bmp;
SaveImage();
}
void Widget::on_pbn_save_JPG_clicked()
{
m_nSaveImageType = MV_Image_Jpeg;
SaveImage();
}
void Widget::SaveImage()
{
// 获取1张图
MV_FRAME_OUT_INFO_EX stImageInfo = { 0 };
memset(&stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));
unsigned int nDataLen = 0;
int nRet = MV_OK;
//保存图片的路径
QString saveDirPath="/home/joe/program/VersionDetect/test2/image/1.jpg";
for (int i = 0; i < devices_num; i++) {
//保存图像的缓存类指针
const char *imageName_c_str=NULL;
// 仅在第一次保存图像时申请缓存,在CloseDevice时释放
if (NULL == m_pcMyCamera[i]->m_pBufForDriver) {
unsigned int nRecvBufSize = 0;
m_pcMyCamera[i]->GetIntValue("PayloadSize", &nRecvBufSize);
m_pcMyCamera[i]->m_nBufSizeForDriver = nRecvBufSize; // 一帧数据大小
m_pcMyCamera[i]->m_pBufForDriver =
(unsigned char *)malloc(m_pcMyCamera[i]->m_nBufSizeForDriver);
}
nRet = m_pcMyCamera[i]->GetOneFrameTimeout(
m_pcMyCamera[i]->m_pBufForDriver, &nDataLen,
m_pcMyCamera[i]->m_nBufSizeForDriver, &stImageInfo, 1000);
if (MV_OK == nRet) {
// 仅在第一次保存图像时申请缓存,在 CloseDevice 时释放
if (NULL == m_pcMyCamera[i]->m_pBufForSaveImage) {
// BMP图片大小:width * height * 3 + 2048(预留BMP头大小)
m_pcMyCamera[i]->m_nBufSizeForSaveImage =
stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
m_pcMyCamera[i]->m_pBufForSaveImage = (unsigned char *)malloc(
m_pcMyCamera[i]->m_nBufSizeForSaveImage);
}
// 设置对应的相机参数
MV_SAVE_IMAGE_PARAM_EX stParam = { 0 };
stParam.enImageType = m_nSaveImageType; // 需要保存的图像类型
stParam.enPixelType = stImageInfo.enPixelType; // 相机对应的像素格式
stParam.nBufferSize =
m_pcMyCamera[i]->m_nBufSizeForSaveImage; // 存储节点的大小
stParam.nWidth = stImageInfo.nWidth; // 相机对应的宽
stParam.nHeight = stImageInfo.nHeight; // 相机对应的高
stParam.nDataLen = stImageInfo.nFrameLen;
stParam.pData = m_pcMyCamera[i]->m_pBufForDriver;
stParam.pImageBuffer = m_pcMyCamera[i]->m_pBufForSaveImage;
stParam.nJpgQuality = 90; // jpg编码,仅在保存Jpg图像时有效
nRet = m_pcMyCamera[i]->SaveImage(&stParam);
QString image_name;
//图像名称
char chImageName[IMAGE_NAME_LEN] = {0};
if (MV_Image_Bmp == stParam.enImageType) {
if (i == 0) {
snprintf(chImageName, IMAGE_NAME_LEN,
"Image_w%d_h%d_fn%d_L.bmp", stImageInfo.nWidth,
stImageInfo.nHeight, stImageInfo.nFrameNum);
image_name = "Image_w";
image_name.append(QString::number(stImageInfo.nWidth));
image_name.append("_h");
image_name.append(QString::number(stImageInfo.nHeight));
image_name.append("_fn");
image_name.append(QString::number(stImageInfo.nFrameNum));
image_name.append("_L.bmp");
}
if (i == 1) {
snprintf(chImageName, IMAGE_NAME_LEN,
"Image_w%d_h%d_fn%03d_R.bmp", stImageInfo.nWidth,
stImageInfo.nHeight, stImageInfo.nFrameNum);
}
} else if (MV_Image_Jpeg == stParam.enImageType) {
if (i == 0) {
snprintf(chImageName, IMAGE_NAME_LEN,
"Image_w%d_h%d_fn%d_L.jpg", stImageInfo.nWidth,
stImageInfo.nHeight, stImageInfo.nFrameNum);
image_name = "Image_w";
image_name.append(QString::number(stImageInfo.nWidth));
image_name.append("_h");
image_name.append(QString::number(stImageInfo.nHeight));
image_name.append("_fn");
image_name.append(QString::number(stImageInfo.nFrameNum));
image_name.append("_L.jpg");
}
if (i == 1) {
snprintf(chImageName, IMAGE_NAME_LEN,
"Image_w%d_h%d_fn%03d_R.jpg", stImageInfo.nWidth,
stImageInfo.nHeight, stImageInfo.nFrameNum);
}
}
QString imagePath = saveDirPath + image_name;
QByteArray ba = imagePath.toLatin1();
imageName_c_str = ba.data();
FILE *fp = fopen(imageName_c_str, "wb");
fwrite(m_pcMyCamera[i]->m_pBufForSaveImage, 1, stParam.nImageLen,
fp);
fclose(fp);
// ui->lbl_camera_R->setPixmap(QPixmap(image_name));
// ui->lbl_camera_R->setScaledContents(true);
}
}
}
void Widget::on_le_set_exposure_textChanged(const QString &arg1)
{
//设置曝光时间
QString str = ui->le_set_exposure->text(); // 读取
int exposure_Time = str.toInt();
for (int i = 0; i < devices_num; i++) {
m_pcMyCamera[i]->SetEnumValue("ExposureAuto",
MV_EXPOSURE_AUTO_MODE_OFF);
m_pcMyCamera[i]->SetFloatValue("ExposureTime", exposure_Time);
}
}
void Widget::on_le_set_gain_textChanged(const QString &arg1)
{
QString str = ui->le_set_gain->text(); // 读取
float gain = str.toFloat();
for (int i = 0; i < devices_num; i++) {
m_pcMyCamera[i]->SetEnumValue("GainAuto", 0);
m_pcMyCamera[i]->SetFloatValue("Gain", gain);
}
}
void Widget::on_pbn_return_main_clicked()
{
//发送信号实现页面切换
//connect(ui->pbn_return_main,SIGNAL(clicked()),this,SIGNAL(back()));
}
3、界面效果
其中返回主界面的button是在部署深度学习模型中要用的,与相机连接无关 ,整体就是:
枚举相机->打开相机->连续模式->连续采集or软触发一次文章来源:https://www.toymoban.com/news/detail-790406.html
参考博客:海康威视在linux下使用笔记——ros驱动相机_hikrobot工业相机ros驱动-CSDN博客
文章来源地址https://www.toymoban.com/news/detail-790406.html
到了这里,关于Qt+opencv+Linux+海康工业相机连接的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!