1.了解海康威视工业相机
本人学习参考的是:boss_dog的博客,里面有详细的分析相机的数据,各种相机的区别,在VS中部署SDK的环境变量以及官方例程.
1.1.下载SDK
海康威视的工业相机二次开发首先是需要在官方下载相机的SDK,下载地址_官方下载地址,根据自身的环境区下载需要的SDK,本人下载的是(机器视觉工业相机客户端MVS V3.3.1(Windows)).
下载后打开下图中的文件,是VS+C++的Demo,本人用到的是第一个demo,打开相机保存图片.

1.2.环境配置
PS:不管运行海康威视的哪个例程,都需要先配置下环境
在VS项目中配置opencv和mvs的动态链接库等(用到Opencv的话)
①在VS中配置Opencv


②在VS中配置MVS


环境配置完成后,将官方的demo导入到VS中基本上就能运行了.
下图就是实现基本功能的代码,在BasicDemoDlg.cpp中就是自己写的代码根据调用官方的SDK来实现基本功能.


2.在QT中实现官方demo中的功能
2.1.首先我们需要在qt中配置好实现功能的环境:
2.1.1 配置好相机SDK的环境,参考博客:大樱桃的博客_大_樱_桃_CSDN博客-Halcon,工业相机,Halcon_C#l联合编程领域博主.
先在QT中创建一个项目,将海康的MVS文件下Development文件里面的Includes以及Libraries文件复制到qt的项目文件下.


复制完成后在QT中右击项目文件,点击添加库,选择外部库,点击下一步,选择库文件,选择平台和静态链接,点下一步就行了.


导入库后生成的代码片段:

生成代码片段后再加入Include,相机的头文件,相机的SDK和环境就配置完成了.
INCLUDEPATH += $$PWD/IncludesDEPENDPATH += $$PWD/Includes
2.1.2 配置opencv的环境变量:在配置opencv的路上我也是经历了很多坎坷,,,查阅无数文档,大部分都是使用MinGV,可以参考博客:拜小白教你Qt5.8.0+OpenCV3.2.0配置教程(详细版)_拜小白的成长之路,告别小白-CSDN博客,但是我是先使用的VS的运行环境,然后QT在VS的运行环境下建立的,可以参考Qt5.9.6+opencv+VS2017的安装及配置_我内疚的博客-CSDN博客。反正这种配置环境的路上就是不断地查找文档,不断地更改。,慢慢摸索,,最终我在qt上配置的opencv的代码是:
INCLUDEPATH += D:\QtDemo\opencv\includeINCLUDEPATH += D:\QtDemo\opencv\include/opencv2CONFIG(debug, debug|release): {LIBS += -LD:\QtDemo\opencv/lib \-lopencv_world440 \-lopencv_world440d} else:CONFIG(release, debug|release): {LIBS += -LD:\QtDemo\opencv/lib \-lopencv_world440 \-lopencv_world440d}
环境配置完成后,接着把相机封装好的函数体:cpp文件和头文件复制到项目文件下:MVCamera.cpp和MVCamera.h

接着又是参考:海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(二)_boss-dog的博客-CSDN博客其中的源代码,结合上官方自带的SDK,就完成了一些基本的显示相机采集的画面,保存图片,获取相机IP,软触发等功能。
3.我的源代码是:
MVCamera.h
/************************************************************************//* 以C++接口为基础,对常用函数进行二次封装,方便用户使用 *//************************************************************************/#ifndef _MV_CAMERA_H_#define _MV_CAMERA_H_#include "Includes/MvCameraControl.h"#include <string.h>#include"opencv2/opencv.hpp"#include"opencv2/imgproc/types_c.h"#ifndef MV_NULL#define MV_NULL 0#endifclass CMvCamera{public:CMvCamera();~CMvCamera();// ch:获取SDK版本号 | en:Get SDK Versionstatic int GetSDKVersion();// ch:枚举设备 | en:Enumerate Devicestatic int EnumDevices(unsigned int nTLayerType, MV_CC_DEVICE_INFO_LIST* pstDevList);// ch:判断设备是否可达 | en:Is the device accessiblestatic bool IsDeviceAccessible(MV_CC_DEVICE_INFO* pstDevInfo, unsigned int nAccessMode);// ch:打开设备 | en:Open Deviceint Open(MV_CC_DEVICE_INFO* pstDeviceInfo);// ch:关闭设备 | en:Close Deviceint Close();// ch:判断相机是否处于连接状态 | en:Is The Device Connectedbool IsDeviceConnected();// ch:注册图像数据回调 | en:Register Image Data CallBackint RegisterImageCallBack(void(__stdcall* cbOutput)(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), void* pUser);// ch:开启抓图 | en:Start Grabbingint StartGrabbing();// ch:停止抓图 | en:Stop Grabbingint StopGrabbing();// ch:主动获取一帧图像数据 | en:Get one frame initiativelyint GetImageBuffer(MV_FRAME_OUT* pFrame, int nMsec);// ch:主动获取一帧图像数据 | en:Get one frame initiativelyint GetOneFrameTimeout(unsigned char* pData, unsigned int* pnDataLen, unsigned int nDataSize, MV_FRAME_OUT_INFO_EX* pFrameInfo, int nMsec);// ch:释放图像缓存 | en:Free image bufferint FreeImageBuffer(MV_FRAME_OUT* pFrame);// ch:显示一帧图像 | en:Display one frame imageint DisplayOneFrame(MV_DISPLAY_FRAME_INFO* pDisplayInfo);// ch:设置SDK内部图像缓存节点个数 | en:Set the number of the internal image cache nodes in SDKint SetImageNodeNum(unsigned int nNum);// ch:获取设备信息 | en:Get device informationint GetDeviceInfo(MV_CC_DEVICE_INFO* pstDevInfo);// ch:获取GEV相机的统计信息 | en:Get detect info of GEV cameraint GetGevAllMatchInfo(MV_MATCH_INFO_NET_DETECT* pMatchInfoNetDetect);// ch:获取U3V相机的统计信息 | en:Get detect info of U3V cameraint 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 directoryint GetIntValue(IN const char* strKey, OUT unsigned int* pIntValue);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 directoryint 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 directoryint 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 directoryint 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 directoryint 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 directoryint 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 CallBackint RegisterExceptionCallBack(void(__stdcall* cbException)(unsigned int nMsgType, void* pUser), void* pUser);// ch:注册单个事件回调 | en:Register Event CallBackint RegisterEventCallBack(const char* pEventName, void(__stdcall* cbEvent)(MV_EVENT_OUT_INFO * pEventInfo, void* pUser), void* pUser);// ch:强制IP | en:Force IPint ForceIp(unsigned int nIP, unsigned int nSubNetMask, unsigned int nDefaultGateWay);// ch:配置IP方式 | en:IP configuration methodint SetIpConfig(unsigned int nType);// ch:设置网络传输模式 | en:Set Net Transfer Modeint SetNetTransMode(unsigned int nType);// ch:像素格式转换 | en:Pixel format conversionint ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM* pstCvtParam);// ch:保存图片 | en:save imageint SaveImage(MV_SAVE_IMAGE_PARAM_EX* pstParam);// ch:保存图片为文件 | en:Save the image as a fileint SaveImageToFile(MV_SAVE_IMG_TO_FILE_PARAM* pstParam);//设置是否为触发模式int setTriggerMode(unsigned int TriggerModeNum);//设置触发源int setTriggerSource(unsigned int TriggerSourceNum);//软触发int softTrigger();//读取bufferint ReadBuffer(cv::Mat& image);private:void* m_hDevHandle;public:unsigned int m_nTLayerType;unsigned char* m_pBufForSaveImage; // 用于保存图像的缓存unsigned int m_nBufSizeForSaveImage;unsigned char* m_pBufForDriver; // 用于从驱动获取图像的缓存unsigned int m_nBufSizeForDriver;};#endif//_MV_CAMERA_H_
mythread.h
#ifndef MYTHREAD_H#define MYTHREAD_H#include "QThread"#include "MvCamera.h"#include "opencv2/opencv.hpp"#include "opencv2/core/core.hpp"#include "opencv2/calib3d/calib3d.hpp"#include "opencv2/highgui/highgui.hpp"#include <vector>#include <string>#include <algorithm>#include <iostream>#include <iterator>#include <stdio.h>#include <stdlib.h>#include <ctype.h>using namespace std;using namespace cv;class MyThread :public QThread{Q_OBJECTpublic:MyThread();~MyThread();void run();void getCameraPtr(CMvCamera* camera);void getImagePtr(Mat* image);void getCameraIndex(int index);signals:void mess();void Display(const Mat* image, int index);private:CMvCamera* cameraPtr = NULL;cv::Mat* imagePtr = NULL;int cameraIndex = NULL;int TriggerMode;};#endif // MYTHREAD_H#pragma once
widget.h
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>#include <Windows.h>#include "MvCamera.h"#include "Includes/CameraParams.h"#include "minwindef.h"#include "stringapiset.h"#include "tchar.h"#include "mythread.h"#include "QString"#include "QMessageBox"#include <windows.h>#include "WinUser.h"//声明相机最大数量#define MAX_DEVICE_NUM 2QT_BEGIN_NAMESPACEnamespace Ui { class Widget; }QT_END_NAMESPACEclass Widget : public QWidget{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();//按钮函数private slots:void display_myImage(const Mat* imagePrt, int cameraIndex);void on_checkedbtn_clicked();void on_openbtn_clicked();void on_closebtn_clicked();void on_rbnt_Continue_Mode_clicked();void on_bntStartGrabbing_clicked();void on_rbnt_SoftTigger_Mode_clicked();void on_bntStopGrabbing_clicked();void on_bntSoftwareOnce_clicked();//自定义对象void on_bntSave_BMP_clicked();void on_bntSave_JPG_clicked();public:CMvCamera* m_pcMyCamera[MAX_DEVICE_NUM]; // 相机指针对象MV_CC_DEVICE_INFO_LIST m_stDevList; // 设备信息列表结构体变量,用来存储设备列表_MV_CC_DEVICE_INFO_ m_SpecialInfo; //设备信息int devices_num;//设备数量int nRet;MyThread* myThread_Camera;//相机线程void* m_hGrabThread; // ch:取流线程句柄 | en:Grab thread handleBOOL m_bThreadState;BOOL m_bOpenDevice; // ch:是否打开设备 | en:Whether to open deviceBOOL m_bStartGrabbing; // ch:是否开始抓图 | en:Whether to start grabbingint m_nTriggerMode; //触发模式int m_bContinueStarted; // 开启过连续采集图像cv::Mat* myImage = new cv::Mat(); //用于保存相机图像的图像指针对象MV_SAVE_IAMGE_TYPE m_nSaveImageType; // ch:保存图像格式 | en:Save Image Type//自定义方法private:void OpenDevices(); // ch:打开设备 | en:Open devicevoid CloseDevices(); // ch:关闭设备 | en:Close Device//错误信息void ShowErrorMsg(QString qMessage, int nErrorNum);//保存图片int SaveImage(MV_SAVE_IAMGE_TYPE m_nSaveImageType);private:Ui::Widget *ui;};#endif // WIDGET_H
MVCamera.cpp
#include "MvCamera.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 Versionint CMvCamera::GetSDKVersion(){return MV_CC_GetSDKVersion();}// ch:枚举设备 | en:Enumerate Deviceint CMvCamera::EnumDevices(unsigned int nTLayerType, MV_CC_DEVICE_INFO_LIST* pstDevList){return MV_CC_EnumDevices(nTLayerType, pstDevList);}// ch:判断设备是否可达 | en:Is the device accessiblebool CMvCamera::IsDeviceAccessible(MV_CC_DEVICE_INFO* pstDevInfo, unsigned int nAccessMode){return MV_CC_IsDeviceAccessible(pstDevInfo, nAccessMode);}// ch:打开设备 | en:Open Deviceint 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 Deviceint 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 Connectedbool CMvCamera::IsDeviceConnected(){return MV_CC_IsDeviceConnected(m_hDevHandle);}// ch:注册图像数据回调 | en:Register Image Data CallBackint 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 Grabbingint CMvCamera::StartGrabbing(){return MV_CC_StartGrabbing(m_hDevHandle);}// ch:停止抓图 | en:Stop Grabbingint 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: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:Free image bufferint CMvCamera::FreeImageBuffer(MV_FRAME_OUT* pFrame){return MV_CC_FreeImageBuffer(m_hDevHandle, pFrame);}// ch:设置显示窗口句柄 | en:Set Display Window Handleint 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 SDKint CMvCamera::SetImageNodeNum(unsigned int nNum){return MV_CC_SetImageNodeNum(m_hDevHandle, nNum);}// ch:获取设备信息 | en:Get device informationint CMvCamera::GetDeviceInfo(MV_CC_DEVICE_INFO* pstDevInfo){return MV_CC_GetDeviceInfo(m_hDevHandle, pstDevInfo);}// ch:获取GEV相机的统计信息 | en:Get detect info of GEV cameraint 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 cameraint 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 MVCC_INTVALUE_EX *pIntValue)//{// return MV_CC_GetIntValueEx(m_hDevHandle, strKey, pIntValue);//}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 directoryint 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 directoryint 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 directoryint 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 directoryint 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 directoryint 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 CallBackint CMvCamera::RegisterExceptionCallBack(void(__stdcall* cbException)(unsigned int nMsgType, void* pUser),void* pUser){return MV_CC_RegisterExceptionCallBack(m_hDevHandle, cbException, pUser);}// ch:注册单个事件回调 | en:Register Event CallBackint 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 IPint 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 methodint CMvCamera::SetIpConfig(unsigned int nType){return MV_GIGE_SetIpConfig(m_hDevHandle, nType);}// ch:设置网络传输模式 | en:Set Net Transfer Modeint CMvCamera::SetNetTransMode(unsigned int nType){return MV_GIGE_SetNetTransMode(m_hDevHandle, nType);}// ch:像素格式转换 | en:Pixel format conversionint CMvCamera::ConvertPixelType(MV_CC_PIXEL_CONVERT_PARAM* pstCvtParam){return MV_CC_ConvertPixelType(m_hDevHandle, pstCvtParam);}// ch:保存图片 | en:save imageint CMvCamera::SaveImage(MV_SAVE_IMAGE_PARAM_EX* pstParam){return MV_CC_SaveImageEx2(m_hDevHandle, pstParam);}// ch:保存图片为文件 | en:Save the image as a fileint 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:Onint 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:Softwareint 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 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{//转换图像格式为BGR8MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 };memset(&stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));stConvertParam.nWidth = stImageInfo.nWidth; //ch:图像宽 | en:image widthstConvertParam.nHeight = stImageInfo.nHeight; //ch:图像高 | en:image height//stConvertParam.pSrcData = m_pBufForDriver; //ch:输入数据缓存 | en:input data bufferstConvertParam.pSrcData = pDate; //ch:输入数据缓存 | en:input data bufferstConvertParam.nSrcDataLen = stImageInfo.nFrameLen; //ch:输入数据大小 | en:input data sizestConvertParam.enSrcPixelType = stImageInfo.enPixelType; //ch:输入像素格式 | en:input pixel formatstConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed; //ch:输出像素格式 | en:output pixel format 适用于OPENCV的图像格式//stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed; //ch:输出像素格式 | en:output pixel formatstConvertParam.pDstBuffer = m_pBufForSaveImage; //ch:输出数据缓存 | en:output data bufferstConvertParam.nDstBufferSize = m_nBufSizeForSaveImage; //ch:输出缓存大小 | en:output buffer sizeMV_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;}
mytheard.cpp
#include "mythread.h"MyThread::MyThread(){}MyThread::~MyThread(){terminate();if (cameraPtr != NULL){delete cameraPtr;}if (imagePtr != NULL){delete imagePtr;}}void MyThread::getCameraPtr(CMvCamera* camera){cameraPtr = camera;}void MyThread::getImagePtr(Mat* image){imagePtr = image;}void MyThread::getCameraIndex(int index){cameraIndex = index;}//void MyThread::get_TriggerMode(int m_nTriggerMode)//{// TriggerMode = m_nTriggerMode;//}void MyThread::run(){if (cameraPtr == NULL){return;}if (imagePtr == NULL){return;}while (!isInterruptionRequested()){std::cout << "Thread_Trigger:" << cameraPtr->softTrigger() << std::endl;std::cout << "Thread_Readbuffer:" << cameraPtr->ReadBuffer(*imagePtr) << std::endl;/*emit mess();*/emit Display(imagePtr, cameraIndex);//发送信号 img_display_label接收并显示msleep(30);}}
widget.cpp
#include <QWidget>#include "widget.h"#include "ui_widget.h"#include <QDebug>#include "MvCamera.h"#include "QFileDialog"#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 64Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ui->setupUi(this);//初始化ui->checkedbtn->setEnabled(true);ui->openbtn->setEnabled(false);ui->closebtn->setEnabled(false);ui->rbnt_Continue_Mode->setEnabled(false);ui->rbnt_SoftTigger_Mode->setEnabled(false);ui->bntStartGrabbing->setEnabled(false);ui->bntStopGrabbing->setEnabled(false);ui->bntSoftwareOnce->setEnabled(false);ui->bntSave_BMP->setEnabled(false);ui->bntSave_JPG->setEnabled(false);m_bThreadState =false;m_bStartGrabbing = FALSE;m_bOpenDevice = FALSE;devices_num = 0;nRet = MV_OK;m_hGrabThread = NULL;m_bContinueStarted = 0;m_nSaveImageType = MV_Image_Bmp;//实例化myThread_Camera = new MyThread();connect(myThread_Camera,SIGNAL(Display(const Mat*,int)),this,SLOT(display_myImage(const Mat*,int)));connect(myThread_Camera,SIGNAL(mess()),this,SLOT(display_myImage(const Mat*,int)));}Widget::~Widget(){delete ui;}//错误信息// ch:显示错误信息 | en:Show error messagevoid Widget::ShowErrorMsg(QString qMessage, int nErrorNum){QString errorMsg;if (nErrorNum == 0){errorMsg= qMessage;}else{errorMsg=QString("%1: Error = %2: ").arg(qMessage).arg(nErrorNum);}switch(nErrorNum){case 1: errorMsg += "Error or invalid handle "; break;case 2: errorMsg += "Not supported function "; break;case 3: errorMsg += "Cache is full "; break;case 4: errorMsg += "Function calling order error "; break;case 5: errorMsg += "Incorrect parameter "; break;case 6: errorMsg += "Applying resource failed "; break;case 7: errorMsg += "No data "; break;case 8: errorMsg += "Precondition error, or running environment changed "; break;case 9: errorMsg += "Version mismatches "; break;case 10: errorMsg += "Insufficient memory "; break;case 11: errorMsg += "Abnormal image, maybe incomplete image because of lost packet "; break;case 12: errorMsg += "Unknown error "; break;case 13: errorMsg += "General error "; break;case 14: errorMsg += "Node accessing condition error "; break;case 15: errorMsg += "No permission "; break;case 16: errorMsg += "Device is busy, or network disconnected "; break;case 17: errorMsg += "Network error "; break;}QMessageBox::information(NULL, "PROMPT", errorMsg , QMessageBox::Yes || QMessageBox::No , QMessageBox::Yes);}//查找设备void Widget::on_checkedbtn_clicked(){QString str;memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); // ch:初始化设备信息列表nRet = CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList);// ch:枚举子网内所有设备,相机设备数量devices_num = m_stDevList.nDeviceNum;if (devices_num > 0){ui->openbtn->setEnabled(true);// 设备数大于0,打印第一台设备信息// qDebug() << m_stDevList.pDeviceInfo[0];// qDebug() << m_stDevList.nDeviceNum;// qDebug() << m_SpecialInfo.SpecialInfo.stGigEInfo.chModelName;// qDebug() <<m_SpecialInfo.SpecialInfo.stGigEInfo.chManufacturerName;wchar_t* pUserName = NULL;int nIp1 = ((m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24);//将相机的ip地址转成十进制int nIp2 = ((m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16);int nIp3 = ((m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8);int nIp4 = (m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff);if (strcmp("", (LPCSTR)(m_SpecialInfo.SpecialInfo.stGigEInfo.chUserDefinedName)) != 0)//空字符串与用户自定义名称比较,如果用户有自定义名字那么就用用户自定义名字,如果没有就用厂商名称{DWORD dwLenUserName = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)(m_SpecialInfo.SpecialInfo.stGigEInfo.chUserDefinedName), -1, NULL, 0);pUserName = new wchar_t[dwLenUserName];MultiByteToWideChar(CP_ACP, 0, (LPCSTR)(m_SpecialInfo.SpecialInfo.stGigEInfo.chUserDefinedName), -1, pUserName, dwLenUserName);}else{char strUserName[256] = {0};sprintf_s(strUserName, 256, "%s %s (%s)", m_SpecialInfo.SpecialInfo.stGigEInfo.chManufacturerName,m_SpecialInfo.SpecialInfo.stGigEInfo.chModelName,m_SpecialInfo.SpecialInfo.stGigEInfo.chSerialNumber);DWORD dwLenUserName = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)(strUserName), -1, NULL, 0);pUserName = new wchar_t[dwLenUserName];MultiByteToWideChar(CP_ACP, 0, (LPCSTR)(strUserName), -1, pUserName, dwLenUserName);}str = QString("相机个数:[%1],相机IP:(%3.%4.%5.%6 )").arg(m_stDevList.nDeviceNum).arg(nIp1).arg(nIp2).arg(nIp3).arg(nIp4);ui->textEdit->setText(str);qDebug() << str;qDebug() << m_pcMyCamera;}else{ShowErrorMsg(("NO DEVICE !!!"), 0);}}void Widget::OpenDevices(){m_bThreadState = true;m_bOpenDevice = true;// 创建相机指针对象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]); //打开相机// if(nRet != MV_OK){// ShowErrorMsg(("Open Fill"),1);// }//设置触发模式m_pcMyCamera[i]->setTriggerMode(TRIGGER_ON);//设置触发源为软触发m_pcMyCamera[i]->setTriggerSource(TRIGGER_SOURCE);qDebug() << m_pcMyCamera[i];}}//打开设备void Widget::on_openbtn_clicked(){OpenDevices();if(nRet !=MV_OK){ShowErrorMsg(("Open Fill"),1);}else{ui->openbtn->setEnabled(false);ui->closebtn->setEnabled(true);ui->rbnt_Continue_Mode->setEnabled(true);ui->rbnt_SoftTigger_Mode->setEnabled(true);ui->bntStartGrabbing->setEnabled(true);}}//关闭设备void Widget::CloseDevices(){for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++){m_bThreadState = FALSE;myThread_Camera->requestInterruption();myThread_Camera->wait();m_pcMyCamera[i]->StopGrabbing();m_pcMyCamera[i]->Close();m_bStartGrabbing = FALSE;m_bOpenDevice = FALSE;}}// ch:按下关闭设备按钮:关闭设备 ,包含销毁句柄void Widget::on_closebtn_clicked(){ui->openbtn->setEnabled(true);ui->closebtn->setEnabled(false);ui->bntSoftwareOnce->setEnabled(false);ui->bntStartGrabbing->setEnabled(false);ui->bntStopGrabbing->setEnabled(false);ui->rbnt_Continue_Mode->setEnabled(false);ui->rbnt_SoftTigger_Mode->setEnabled(false);//销毁句柄CloseDevices();qDebug() << m_pcMyCamera;}//按下连续采集按钮void Widget::on_rbnt_Continue_Mode_clicked(){ui->bntStartGrabbing->setEnabled(true);m_nTriggerMode = TRIGGER_ON;}// ch:按下触发模式按钮 | en:Click Trigger Mode buttonvoid Widget::on_rbnt_SoftTigger_Mode_clicked(){if (m_bContinueStarted == 1) // 从连续采集模式已经正在采集的状态切换过来{on_bntStopGrabbing_clicked();//先执行停止采集}m_bContinueStarted = 0;m_nTriggerMode = TRIGGER_OFF;for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++){m_pcMyCamera[i]->setTriggerMode(m_nTriggerMode);}ui->bntStartGrabbing->setEnabled(false);ui->bntStopGrabbing->setEnabled(true);ui->bntSoftwareOnce->setEnabled(true);}//软触发一次void Widget::on_bntSoftwareOnce_clicked(){ui->bntSave_BMP->setEnabled(true);ui->bntSave_JPG->setEnabled(true);if (m_nTriggerMode == TRIGGER_OFF){nRet = MV_OK;for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++){//开启相机采集m_pcMyCamera[i]->StartGrabbing();nRet = m_pcMyCamera[i]->CommandExecute("TriggerSoftware");m_pcMyCamera[i]->ReadBuffer(*myImage);display_myImage(myImage, i);//相机图像}}}// 开始采集图像void Widget::on_bntStartGrabbing_clicked(){if(m_bContinueStarted == 0){on_bntStopGrabbing_clicked();}m_bContinueStarted = 1; // 为触发模式标记一下,切换触发模式时先执行停止采集图像函数// 图像采集控件ui->bntStartGrabbing->setEnabled(false);ui->bntStopGrabbing->setEnabled(true);ui->bntSoftwareOnce->setEnabled(false);// 保存图像控件ui->bntSave_BMP->setEnabled(true);ui->bntSave_JPG->setEnabled(true);// 先判断什么模式,再判断是否正在采集if (m_nTriggerMode == TRIGGER_ON){// ch:开始采集之后才创建workthread线程 | en:Create workthread after start grabbingfor (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++){//开启相机采集m_pcMyCamera[i]->StartGrabbing();myThread_Camera->getCameraPtr(m_pcMyCamera[i]);//线程获取相机指针myThread_Camera->getImagePtr(myImage);//线程获取图像指针myThread_Camera->getCameraIndex(i); //相机数if(!myThread_Camera->isRunning()){myThread_Camera->start();m_pcMyCamera[i]->softTrigger();m_pcMyCamera[i]->ReadBuffer(*myImage);//ui->Display_Camera_Image->setPixmap(m_pcMyCamera[i]->ReadBuffer(*myImage));}}}}//停止采集void Widget::on_bntStopGrabbing_clicked(){ui->bntStartGrabbing->setEnabled(true);ui->bntStopGrabbing->setEnabled(false);ui->bntSave_BMP->setEnabled(false);ui->bntSave_JPG->setEnabled(false);ui->bntSoftwareOnce->setEnabled(false);for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++){//停止线程,相机停止采集if (myThread_Camera->isRunning()){m_pcMyCamera[i]->StopGrabbing();myThread_Camera->requestInterruption();myThread_Camera->wait();}}}//显示图像void Widget::display_myImage(const Mat* imagePrt, int cameraIndex){cv::Mat rgb;cv::cvtColor(*imagePrt, rgb, CV_BGR2RGB);//判断是黑白、彩色图像QImage QmyImage;if (rgb.channels() > 1){// QmyImage = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_RGB888);QmyImage =QImage((const unsigned char*)(rgb.data),rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);// cv::namedWindow("test",cv::WINDOW_FREERATIO);// cv::imshow("test",rgb);// cv::waitKey(0);}else{QmyImage = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_Indexed8);}QmyImage = (QmyImage).scaled(ui->Display_Camera_Image->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//显示图像ui->Display_Camera_Image->setPixmap(QPixmap::fromImage(QmyImage));ui->Display_Camera_Image->show();// Sleep(1);}//保存图片int Widget::SaveImage(MV_SAVE_IAMGE_TYPE m_nSaveImageType){// ch:获取1张图 | en:Get one frameMV_FRAME_OUT_INFO_EX stImageInfo = { 0 };memset(&stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));unsigned int nDataLen = 0;nRet = MV_OK;for (int i = 0; i < devices_num; i++){// ch:仅在第一次保存图像时申请缓存,在 CloseDevice 时释放// en:Request buffer first time save image, release after CloseDeviceif (NULL == m_pcMyCamera[i]->m_pBufForDriver){unsigned int nRecvBufSize = 0;nRet = 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){// ch:仅在第一次保存图像时申请缓存,在 CloseDevice 时释放// en:Request buffer first time save image, release after CloseDeviceif (NULL == m_pcMyCamera[i]->m_pBufForSaveImage){// ch:BMP图片大小:width * height * 3 + 2048(预留BMP头大小)// en:BMP image size: width * height * 3 + 2048 (Reserved BMP header size)m_pcMyCamera[i]->m_nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;m_pcMyCamera[i]->m_pBufForSaveImage = (unsigned char*)malloc(m_pcMyCamera[i]->m_nBufSizeForSaveImage);}// ch:设置对应的相机参数 | en:Set camera parameterMV_SAVE_IMAGE_PARAM_EX stParam = { 0 };stParam.enImageType = m_nSaveImageType; // ch:需要保存的图像类型 | en:Image format to save;stParam.enPixelType = stImageInfo.enPixelType; // 相机对应的像素格式 | en:Pixel formatstParam.nBufferSize = m_pcMyCamera[i]->m_nBufSizeForSaveImage; // 存储节点的大小 | en:Buffer node sizestParam.nWidth = stImageInfo.nWidth; // 相机对应的宽 | en:WidthstParam.nHeight = stImageInfo.nHeight; // 相机对应的高 | en:HeightstParam.nDataLen = stImageInfo.nFrameLen;stParam.pData = m_pcMyCamera[i]->m_pBufForDriver;stParam.pImageBuffer = m_pcMyCamera[i]->m_pBufForSaveImage;stParam.nJpgQuality = 90; // ch:jpg编码,仅在保存Jpg图像时有效。保存BMP时SDK内忽略该参数nRet = m_pcMyCamera[i]->SaveImage(&stParam);char chImageName[IMAGE_NAME_LEN] = { 0 };if (MV_Image_Bmp == stParam.enImageType){//图片输出格式为BMP/*sprintf_s(chImageName, IMAGE_NAME_LEN, "Image_w%d_h%d_fn%03d_L.bmp", stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);*///sprintf_s(chImageName, IMAGE_NAME_LEN, "%03d_L.bmp", stImageInfo.nFrameNum);sprintf_s(chImageName, IMAGE_NAME_LEN, "%d-current_image.bmp", stImageInfo.nFrameNum);}else if (MV_Image_Jpeg == stParam.enImageType){//sprintf_s(chImageName, IMAGE_NAME_LEN, "Image_w%d_h%d_fn%03d_L.bmp", stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);sprintf_s(chImageName, IMAGE_NAME_LEN, "%d-current_image.jpg", stImageInfo.nFrameNum);}//qDebug() << chImageName;//将图片保存到指定路径QString filename=QFileDialog::getSaveFileName(this,tr("save Image"),chImageName);QByteArray ba = filename.toLatin1();char* Filename = ba.data(); //将QString装换为char*FILE* fp = fopen(Filename, "wb");//只写打开或新建一个二进制文件;只允许写数据fwrite(m_pcMyCamera[i]->m_pBufForSaveImage, 1, stParam.nImageLen, fp);//ui->label_debug->setText("save imgs");fclose(fp);}}return MV_OK;}//图片保存为BMPvoid Widget::on_bntSave_BMP_clicked(){nRet = SaveImage(MV_Image_Bmp);if(nRet != MV_OK){ShowErrorMsg("NO IMAGE",11);}else{QMessageBox::information(NULL,"SAVE BMP","Save Image Successed",QMessageBox::Yes);}}//图片保存为JPGvoid Widget::on_bntSave_JPG_clicked(){nRet = SaveImage(MV_Image_Jpeg);if(nRet != MV_OK){ShowErrorMsg("NO IMAGE",11);}else{QMessageBox::information(NULL,"SAVE JPEG","Save Image Successed",QMessageBox::Yes);}}
4.下面是实现的效果图:
