本文接上次的博客海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一),上个博客中并未用到QT,本文介绍项目内容及源码,供大家参考。

由于我的项目中是用海康相机作为拍照的一个中介,重点是在目标识别方向,请阅读源码时自动忽略。
如果对目标识别感兴趣,可以参考我的YOLO系列
https://blog.csdn.net/qq_45445740/category_9794819.html

目录

  • 1.说明
    • 1.1 环境配置
    • 1.2 背景说明
  • 2.源码
    • MvCamera.h
    • mythread.h
    • PcbDetectv3.h
    • main.cpp
    • PcbDetectv3.cpp
    • MvCamera.cpp
    • mythread.cpp
    • 效果

1.说明

1.1 环境配置

关于我在VS中的软件版本及相关的环境配置,请移步
海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一)(里面有详细的软硬件介绍)

1.2 背景说明

简单介绍下我的项目需求
通过相机对物体拍照,后进行目标识别,并返回识别目标的准确位置。这里相机采用海康威视工业相机,人机交互界面选择QT。
界面功能介绍:搜索当前相机的信号,相机可进行图像的连续采集或触发式采集。

2.源码

MvCamera.h

/************************************************************************/
/* 以C++接口为基础,对常用函数进行二次封装,方便用户使用                */
/************************************************************************/#ifndef _MV_CAMERA_H_
#define _MV_CAMERA_H_#include "MvCameraControl.h"
#include <string.h>#ifndef MV_NULL
#define MV_NULL    0
#endif#include"opencv2/opencv.hpp"
#include"opencv2/imgproc/types_c.h"
using namespace cv;class 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:Free image bufferint FreeImageBuffer(MV_FRAME_OUT* pFrame);// 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: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 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 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);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//_MV_CAMERA_H_
#pragma once

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

PcbDetectv3.h

#pragma once
#include <QtWidgets/QWidget>
#include <QMessageBox>
#include <QCloseEvent>
#include <QSettings>
#include <QDebug>#include<opencv2\opencv.hpp>
#include<opencv2\dnn.hpp>
#include<fstream>
#include<iostream>#include "MvCamera.h"
#include "mythread.h"
#include "ui_PcbDetectv3.h"using namespace std;
using namespace cv;
using namespace cv::dnn;#define MAX_DEVICE_NUM   2class PcbDetectv3 : public QWidget
{Q_OBJECTpublic:PcbDetectv3(QWidget *parent = Q_NULLPTR);//~PcbDetectv3();private:Ui::PcbDetectv3Class ui;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;//设备数量/*ch:按下控件操作 | en:Control operation*/
/* 槽函数声明*/
private slots:void OnBnClickedEnumButton();              // ch:按下查找设备按钮:枚举  void OnBnClickedOpenButton();               // ch:打开设备 | en:Open devicevoid OnBnClickedCloseButton();              // ch:关闭设备 | en:Close Devicesvoid Img_display();                        // ch:Qlable 显示图像void display_myImage_L(const Mat* imagePrt, int cameraIndex);void display_myImage_R(const Mat* imagePrt, int cameraIndex);/*ch:图像采集 | en:Image Acquisition*/void OnBnClickedContinusModeRadio();        // ch:连续模式 | en:Continus Modevoid OnBnClickedTriggerModeRadio();         // ch:触发模式 | en:Trigger Modevoid OnBnClickedStartGrabbingButton();      // ch:开始采集 | en:Start Grabbingvoid OnBnClickedStopGrabbingButton();       // ch:结束采集 | en:Stop Grabbingvoid OnBnClickedSoftwareOnceButton();       // ch:软触发一次 | en:Software Trigger Execute Once/*ch:图像保存 | en:Image Save*/void OnBnClickedSaveBmpButton();            // ch:保存bmp | en:Save bmpvoid OnBnClickedSaveJpgButton();            // ch:保存jpg | en:Save jpg/*使用权重进行读取识别*/void StartRecognize();
private:void OpenDevices();                    // ch:打开设备 | en:Open devicevoid CloseDevices();                   // ch:关闭设备 | en:Close Devicepublic://MyThread* myThread; //线程对象MyThread* myThread_LeftCamera = NULL;  //左相机线程对象MyThread* myThread_RightCamera = NULL; //右相机线程对象//槽函数
private slots:/*ch:设置、获取参数操作 | en:Set and get parameters operation*/void SetTriggerMode(int m_nTriggerMode);                // ch:设置触发模式 | en:Set Trigger Modeint GetTriggerMode();//void SetExposureTime();              // ch:设置曝光时间 | en:Set Exposure Timeint GetExposureTime();//void SetGain();                       // ch:设置增益 | en:Set Gainint GetGain();//void SetFrameRate();                  // ch:设置帧率 | en:Set Frame Rateint GetFrameRate();/*ch:图片保存 | en:Save Image*/void SaveImage();                     // ch:保存图片 | en:Save Image/*ch:自定义变量 | en:User Defined Variable*/public:/*ch:状态 | en:Status*/bool  m_bOpenDevice;                        // ch:是否打开设备 | en:Whether to open devicebool  m_bStartGrabbing;                     // ch:是否开始抓图 | en:Whether to start grabbingint   m_nTriggerMode;                       // ch:触发模式 | en:Trigger Modeint   m_bContinueStarted;                      // 开启过连续采集图像MV_SAVE_IAMGE_TYPE   m_nSaveImageType;      // ch:保存图像格式 | en:Save Image Type
};

main.cpp

#include "PcbDetectv3.h"
#include <QtWidgets/QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);PcbDetectv3 w;w.show();return a.exec();
}

PcbDetectv3.cpp

#include "PcbDetectv3.h"
#include <QWidget>
#include <QValidator>#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          64PcbDetectv3::PcbDetectv3(QWidget *parent): QWidget(parent)
{ui.setupUi(this);  /*按键使能初始化*/// 相机初始化控件ui.bntEnumDevices->setEnabled(true);ui.bntCloseDevices->setEnabled(false);ui.bntOpenDevices->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);// 线程对象实例化myThread_LeftCamera = new MyThread;  //左相机线程对象myThread_RightCamera = new MyThread; //右相机线程对象// 图像指针实例化myImage_L = new cv::Mat();    // 图像指针实例化myImage_R = new cv::Mat();    // 图像指针实例化 // 初始化变量int devices_num = 0;int m_nTriggerMode = TRIGGER_ON;int m_bStartGrabbing = START_GRABBING_ON;int m_bContinueStarted = 0;MV_SAVE_IAMGE_TYPE m_nSaveImageType = MV_Image_Bmp;// 将线程的信号与槽进行绑定connect(myThread_LeftCamera, SIGNAL(Display(const Mat*, int)), this, SLOT(display_myImage_L(const Mat*, int)));connect(myThread_RightCamera, SIGNAL(Display(const Mat*, int)), this, SLOT(display_myImage_R(const Mat*, int)));// 相机初始化connect(ui.bntEnumDevices, SIGNAL(clicked()), this, SLOT(OnBnClickedEnumButton()));connect(ui.bntOpenDevices, SIGNAL(clicked()), this, SLOT(OnBnClickedOpenButton()));connect(ui.bntCloseDevices, SIGNAL(clicked()), this, SLOT(OnBnClickedCloseButton()));// 图像采集connect(ui.rbnt_Continue_Mode, SIGNAL(clicked()), this, SLOT(OnBnClickedContinusModeRadio()));connect(ui.rbnt_SoftTigger_Mode, SIGNAL(clicked()), this, SLOT(OnBnClickedTriggerModeRadio())); connect(ui.bntStartGrabbing, SIGNAL(clicked()), this, SLOT(OnBnClickedStartGrabbingButton()));connect(ui.bntStopGrabbing, SIGNAL(clicked()), this, SLOT(OnBnClickedStopGrabbingButton()));connect(ui.bntSoftwareOnce, SIGNAL(clicked()), this, SLOT(OnBnClickedSoftwareOnceButton()));connect(ui.bntSave_BMP, SIGNAL(clicked()), this, SLOT(OnBnClickedSaveBmpButton())); connect(ui.bntSave_JPG, SIGNAL(clicked()), this, SLOT(OnBnClickedSaveJpgButton()));
}/*************************************************** 定义槽函数 *************************************************** */
// ch:按下查找设备按钮:枚举 | en:Click Find Device button:Enumeration
void PcbDetectv3::OnBnClickedEnumButton()
{memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));    // ch:初始化设备信息列表  int nRet = MV_OK;nRet = CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList);             // ch:枚举子网内所有设备,相机设备数量devices_num = m_stDevList.nDeviceNum;if (devices_num > 0){ui.bntOpenDevices->setEnabled(true);// 设备数大于0,使能打开设备按键}
}// 打开相机,开启相机
void PcbDetectv3::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);
}void PcbDetectv3::OnBnClickedOpenButton()
{// 使能 "开始采集" 按键//ui->bntStartGrabbing->setEnabled(true);ui.bntOpenDevices->setEnabled(false);ui.bntCloseDevices->setEnabled(true);ui.rbnt_Continue_Mode->setEnabled(true);ui.rbnt_SoftTigger_Mode->setEnabled(true);ui.rbnt_Continue_Mode->setCheckable(true);OpenDevices();
}// ch:关闭设备 | en:Close Device
void PcbDetectv3::CloseDevices()
{for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++){// 关闭线程、相机if (myThread_LeftCamera->isRunning()){myThread_LeftCamera->requestInterruption();myThread_LeftCamera->wait();m_pcMyCamera[0]->StopGrabbing();//myThread_LeftCamera->~MyThread();// 销毁线程}if (myThread_RightCamera->isRunning()){myThread_RightCamera->requestInterruption();myThread_RightCamera->wait();m_pcMyCamera[1]->StopGrabbing();}m_pcMyCamera[i]->Close();}// ch:关闭之后再枚举一遍 | en:Enumerate after closememset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));    // ch:初始化设备信息列表  int devices_num = MV_OK;devices_num = CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList);           // ch:枚举子网内所有设备,相机设备数量
}// ch:按下关闭设备按钮:关闭设备 ,包含销毁句柄| en:Click Close button: Close Device
void PcbDetectv3::OnBnClickedCloseButton()
{ui.bntOpenDevices->setEnabled(true);ui.bntCloseDevices->setEnabled(false);// 图像采集控件ui.rbnt_Continue_Mode->setEnabled(false);ui.rbnt_SoftTigger_Mode->setEnabled(false);ui.bntStartGrabbing->setEnabled(false);ui.bntStopGrabbing->setEnabled(false);// 保存图像控件ui.bntSave_BMP->setEnabled(false);ui.bntSave_JPG->setEnabled(false);// 关闭设备,销毁线程CloseDevices();
}// 开始连续采集图像
void PcbDetectv3::OnBnClickedStartGrabbingButton()
{m_bContinueStarted = 1; // 为触发模式标记一下,切换触发模式时先执行停止采集图像函数// 图像采集控件ui.bntStartGrabbing->setEnabled(false);ui.bntStopGrabbing->setEnabled(true);// 保存图像控件ui.bntSave_BMP->setEnabled(true);ui.bntSave_JPG->setEnabled(true);int camera_Index = 0;// 先判断什么模式,再判断是否正在采集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();camera_Index = i;if (camera_Index == 0){myThread_LeftCamera->getCameraPtr(m_pcMyCamera[0]); //线程获取左相机指针myThread_LeftCamera->getImagePtr(myImage_L);  //线程获取左图像指针myThread_LeftCamera->getCameraIndex(0); //左相机 Index==0if (!myThread_LeftCamera->isRunning()){myThread_LeftCamera->start();m_pcMyCamera[0]->softTrigger();m_pcMyCamera[0]->ReadBuffer(*myImage_L);//读取Mat格式的图像}}if (camera_Index == 1){myThread_RightCamera->getCameraPtr(m_pcMyCamera[1]); //线程获取右相机指针myThread_RightCamera->getImagePtr(myImage_R);   //线程获取右图像指针myThread_RightCamera->getCameraIndex(1); //右相机 Index==1if (!myThread_RightCamera->isRunning()){myThread_RightCamera->start();m_pcMyCamera[1]->softTrigger();m_pcMyCamera[1]->ReadBuffer(*myImage_R);//读取Mat格式的图像}}}}
}// ch:按下结束采集按钮 | en:Click Stop button
void PcbDetectv3::OnBnClickedStopGrabbingButton()
{ui.bntStartGrabbing->setEnabled(true);ui.bntStopGrabbing->setEnabled(false);for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++){//关闭相机if (myThread_LeftCamera->isRunning()){m_pcMyCamera[0]->StopGrabbing();myThread_LeftCamera->requestInterruption();myThread_LeftCamera->wait();}if (myThread_RightCamera->isRunning()){m_pcMyCamera[1]->StopGrabbing();myThread_RightCamera->requestInterruption();myThread_RightCamera->wait();}}
}void PcbDetectv3::Img_display()
{}void PcbDetectv3::display_myImage_L(const Mat* imagePrt, int cameraIndex)
{cv::Mat rgb;cv::cvtColor(*imagePrt, rgb, CV_BGR2RGB);判断是黑白、彩色图像QImage QmyImage_L;if (myImage_L->channels() > 1){QmyImage_L = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_RGB888);}else{QmyImage_L = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_Indexed8);}QmyImage_L = (QmyImage_L).scaled(ui.label_camera_display->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//显示图像ui.label_camera_display->setPixmap(QPixmap::fromImage(QmyImage_L));
}void PcbDetectv3::display_myImage_R(const Mat* imagePrt, int cameraIndex)
{cv::Mat rgb;cv::cvtColor(*imagePrt, rgb, CV_BGR2RGB);判断是黑白、彩色图像QImage QmyImage_R;if (myImage_R->channels() > 1){QmyImage_R = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_RGB888);}else{QmyImage_R = QImage((const unsigned char*)(rgb.data), rgb.cols, rgb.rows, QImage::Format_Indexed8);}QmyImage_R = (QmyImage_R).scaled(ui.label_detect_display->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//显示图像ui.label_detect_display->setPixmap(QPixmap::fromImage(QmyImage_R));
}// ch:获取曝光时间 | en:Get Exposure Time
int PcbDetectv3::GetExposureTime(void)
{int i = 0;return i;
}// ch:获取增益 | en:Get Gain
int PcbDetectv3::GetGain(void)
{int i = 0;return i;
}// ch:获取帧率 | en:Get Frame Rate
int PcbDetectv3::GetFrameRate(void)
{int i = 0;return i;
}// ch:获取触发模式 | en:Get Trigger Mode
int PcbDetectv3::GetTriggerMode(void)
{int i = 0;return 0;
}// ch:设置触发模式 | en:Set Trigger Mode
void PcbDetectv3::SetTriggerMode(int m_nTriggerMode)
{}// ch:按下连续模式按钮 | en:Click Continues button
void PcbDetectv3::OnBnClickedContinusModeRadio()
{ui.bntStartGrabbing->setEnabled(true);m_nTriggerMode = TRIGGER_ON;
}// ch:按下触发模式按钮 | en:Click Trigger Mode button
void PcbDetectv3::OnBnClickedTriggerModeRadio()
{if (m_bContinueStarted == 1) // 从连续采集模式已经正在采集的状态切换过来{OnBnClickedStopGrabbingButton();//先执行停止采集}ui.bntStartGrabbing->setEnabled(false);ui.bntSoftwareOnce->setEnabled(true);m_nTriggerMode = TRIGGER_OFF;for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++){m_pcMyCamera[i]->setTriggerMode(m_nTriggerMode);//ui.label_Real_fps->setText("000");}
}// ch:按下软触发一次按钮 | en:Click Execute button
void PcbDetectv3::OnBnClickedSoftwareOnceButton()
{// 保存图像控件ui.bntSave_BMP->setEnabled(true);ui.bntSave_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, i);//左相机图像//m_pcMyCamera[i]->StopGrabbing();}if (i == 1){           //开启相机采集nRet = m_pcMyCamera[i]->CommandExecute("TriggerSoftware");m_pcMyCamera[i]->ReadBuffer(*myImage_R);display_myImage_R(myImage_R, i);//m_pcMyCamera[i]->StopGrabbing();}}}
}// ch:按下保存bmp图片按钮 | en:Click Save BMP button
void PcbDetectv3::OnBnClickedSaveBmpButton()
{m_nSaveImageType = MV_Image_Bmp;SaveImage();}// ch:按下保存jpg图片按钮 | en:Click Save JPG button
void PcbDetectv3::OnBnClickedSaveJpgButton()
{m_nSaveImageType = MV_Image_Jpeg;SaveImage();
}// ch:保存图片 | en:Save Image
void PcbDetectv3::SaveImage()
{// 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;int 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;unsigned int 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){if (i == 0){/*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, "current_image.bmp", stImageInfo.nFrameNum);}if (i == 1){//sprintf_s(chImageName, IMAGE_NAME_LEN, "%03d_R.bmp", stImageInfo.nFrameNum);sprintf_s(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){//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, "current_image.bmp", stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);}if (i == 1){sprintf_s(chImageName, IMAGE_NAME_LEN, "Image_w%d_h%d_fn%03d_R.bmp", stImageInfo.nWidth, stImageInfo.nHeight, stImageInfo.nFrameNum);}}FILE* fp = fopen(chImageName, "wb");fwrite(m_pcMyCamera[i]->m_pBufForSaveImage, 1, stParam.nImageLen, fp);//ui->label_debug->setText("save imgs");fclose(fp);}}
}/*目标识别*/
// 使用权重进行读取识别
void PcbDetectv3::StartRecognize()
{//---------------------------------------加载类别---------------------------------------ifstream classNamesFile("./model/classes.names"); //ifstream默认以输入方式打开文件vector<string> classNamesVec;if (classNamesFile.is_open()){string className = "";while (std::getline(classNamesFile, className))classNamesVec.push_back(className);}//---------------------------------------模型设置---------------------------------------String cfg = "./model/yolo-obj.cfg";String weight = "./model/yolo-obj_4000.weights";//模型读入dnn::Net net = readNetFromDarknet(cfg, weight);//预处理读取的图像,并将图像读入网络Mat frame = imread("./current_image.bmp");//imshow("src", frame);Mat inputBlob = blobFromImage(frame, 1.0 / 255, Size(608, 608), Scalar());net.setInput(inputBlob);//获取未连接输出层std::vector<String> outNames = net.getUnconnectedOutLayersNames();std::vector<Mat> outs;net.forward(outs, outNames);//---------------------------------------目标检测---------------------------------------//需要的变量float* data;Mat scores;vector<Rect> boxes;vector<int> classIds;vector<float> confidences;int centerX, centerY, width, height, left, top;float confidenceThreshold = 0.2; // 置信度设置double confidence;Point classIdPoint;//找出所有的目标及其位置for (size_t i = 0; i < outs.size(); ++i){data = (float*)outs[i].data;for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols){scores = outs[i].row(j).colRange(5, outs[i].cols);minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);//minMaxLoc(src, minVal, maxVal, minLoc, maxLoc, mask)在一个数组中找到全局最小值和全局最大值if (confidence > confidenceThreshold){centerX = (int)(data[0] * frame.cols);centerY = (int)(data[1] * frame.rows);width = (int)(data[2] * frame.cols);height = (int)(data[3] * frame.rows);left = centerX - width / 2;top = centerY - height / 2;classIds.push_back(classIdPoint.x);confidences.push_back((float)confidence);boxes.push_back(Rect(left, top, width, height));}}}vector<int> indices;NMSBoxes(boxes, confidences, 0.3, 0.2, indices);//---------------------------------------效果展示---------------------------------------Scalar rectColor, textColor; //box 和 text 的颜色Rect box, textBox;int idx; //类别索引String className;Size labelSize;QString show_text;show_text = QString::fromLocal8Bit("当前图像的尺寸:"); // QString与string的转化,解决中文乱码问题//show_text = "The pixel size of the current image: ";show_text.append(QString::number(frame.size().width)); //将int转换成QStringshow_text.append(QString::fromLocal8Bit("×"));show_text.append(QString::number(frame.size().height));show_text.append("\n");cout << "当前图像的尺寸:" << frame.size() << endl;for (size_t i = 0; i < indices.size(); ++i){idx = indices[i];className = classNamesVec[classIds[idx]];labelSize = getTextSize(className, FONT_HERSHEY_SIMPLEX, 0.5, 1, 0);box = boxes[idx];textBox = Rect(Point(box.x - 1, box.y),Point(box.x + labelSize.width, box.y - labelSize.height));rectColor = Scalar(idx * 11 % 256, idx * 22 % 256, idx * 33 % 256);textColor = Scalar(255 - idx * 11 % 256, 255 - idx * 22 % 256, 255 - idx * 33 % 256);rectangle(frame, box, rectColor, 20, 8, 0);  // 20表示线宽rectangle(frame, textBox, rectColor, -1, 8, 0);putText(frame, className.c_str(), Point(box.x, box.y - 2), FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, 8);// API参考:https://blog.csdn.net/KYJL888/article/details/82217192cout << className << ":" << "width:" << box.width << ",height:" << box.height << ",center:" << (box.tl() + box.br()) / 2 << endl;show_text.append(QString::fromLocal8Bit(className.c_str())); //string转化成Qstring类型show_text.append(": width:");show_text.append(QString::number(box.width));show_text.append(", height:");show_text.append(QString::number(box.height));show_text.append(", center:");int center_x = (box.tl().x + box.br().x) / 2;show_text.append(QString::number(center_x));show_text.append(",");int center_y = (box.tl().y + box.br().y) / 2;show_text.append(QString::number(center_y));show_text.append("\n");}ui.label_show_results->setText(show_text);//imshow("dst", frame);//imwrite("test.bmp", frame);  // 保存图像Mat show_detect_img;cvtColor(frame, show_detect_img, COLOR_BGR2RGB);         // 图像格式转换QImage disImage = QImage((const unsigned char*)(show_detect_img.data), show_detect_img.cols, show_detect_img.rows, QImage::Format_RGB888);ui.label_detect_display->setPixmap(QPixmap::fromImage(disImage.scaled(ui.label_detect_display->size(), Qt::KeepAspectRatio)));
}

MvCamera.cpp

#include "MvCamera.h"
#include <opencv.hpp>
#include"opencv2/opencv.hpp"
#include"opencv2/imgproc/types_c.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: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 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{//转换图像格式为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;
}

mythread.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);}
}

效果

(因为放假回家相机没带回来,这里只看下界面效果)

海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(二)相关推荐

  1. 海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一)

    最近在做一个项目,涉及到工业相机,需要对其进行二次开发.相机方面选择了海康威视,网上关于海康威视工业相机SDK的开发资料很少,官方文档里面虽然写的是支持C++开发的,但其实是C.自己也摸索了一段时间, ...

  2. 基于Qt+海康sdk+MySql的远程录像下载程序

    一.前言 距离上次完成的Linux下QT实时音频采集传输项目已经有一个月的时间.之后又在Linux上完成了许多大大小小的项目,多是与UI有关. 这次给实现的是Windows下的QT+Mysql+海康s ...

  3. Linux环境中对海康威视工业相机SDK进行二次开发(QT+CMake+Opencv+海康SDK)

    关于在Windows环境中对海康威视工业相机SDK进行二次开发的话,可以参考这两篇博客. 海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一) 海康威视工业相机SDK二 ...

  4. (一)Qt+OpenCV调用海康工业相机SDK示例开发

    系列文章目录 提示:这里是该系列文章的所有文章的目录 第一章: (一)Qt+OpenCV调用海康工业相机SDK示例开发 第二章: (二)Qt多线程实现海康工业相机图像实时采集 文章目录 系列文章目录 ...

  5. 海康SDK开发实时读取摄像头图像

    1.概述 最近项目需要实时读取网络摄像头,并对图像做处理,参考网络资料和海康SDK开发文档,文档中给了两种方式(1)SDK直接解码显示(2)实时流数据回调,用户自行处理码流数据(开发文档上以软解显示为 ...

  6. 海康威视摄像机的实时读取篇二(海康SDK开发环境配置)

    利用海康SDK+OpenCV,实现海康摄像机图像实时读取.篇二介绍海康SDK开发环境配置及相关注意事项. 海康SDK开发环境配置 海康SDK开发环境配置具体步骤类似篇一(http://blog.csd ...

  7. 海康工业相机SDK+OpenCV实例(1):海康SDK和OPENCV的安装与编译

    海康工业相机SDK+OpenCV实例(1) 海康SDK和OPENCV的安装与编译 文章目录 海康工业相机SDK+OpenCV实例(1) 海康SDK和OPENCV的安装与编译 前言 一.海康SDK安装 ...

  8. 海康摄像头二次开发python_python实现海康sdk二次开发,移动侦测事件(一)

    1.概述 最近一段时间要从海康摄像头读取数据,作为程序的输入源,c++版本有海康有自己的demo,较为简单,很容易就实现了,但是为我们其他的程序都是基于python的,因此,需要使用Python调用海 ...

  9. 海康摄像机-新手二次开发

    一直对海康摄像机的二次开发感兴趣,之前用Delphi做了些DEMO,能预览和抓图,但太过久远了,海康的SDK与Delphi的开发接口都已经升级了,所以这一回再用Delphi做个通用的Unit.希望对有 ...

  10. 海康摄像头的二次开发(java)

    海康摄像头的二次开发(java) 我第一次接触海康摄像头的二次开发的项目,一开始的时候摸不清套路,走了不少弯路,现在准备把我的一些经验留下来,让大家参考一下. 1.首先到海康的官网下载设备网络SDK: ...

最新文章

  1. 前后端分离的思考与实践(三)
  2. 《数据科学:R语言实现》——2.7 爬取网络数据
  3. java 近似值 循环次数,java题求解
  4. PHP Mysql类【转】
  5. git push时出现错误refusing to update checked out branch: refs/heads/master
  6. 选择HLS或WebRTC需要考虑的五个因素
  7. linux文件系统的设计,基于Linux的文件系统设计.doc
  8. 让Netty“榨干”你的CPU
  9. 简单算术表达式求值(信息学奥赛一本通-T1397)
  10. MySQL表自动增长列插入数据
  11. 服务器运维硬件,服务器硬件运维巡检报告模板
  12. solr5.2.1安装
  13. 12. 表数据入口(Table Data Gateway)
  14. STM32-关于Proteus 仿真无法运行STM32CubeMX自动生成的代码
  15. 2020年30种最佳的免费网页爬虫软件
  16. 如何打出日语中的叠字符号「々」
  17. 用PS绘出真实火焰效果
  18. linux黑屏无法唤醒,解决笔记本CentOS7合盖后黑屏无法唤醒
  19. 张飞硬件课程第六部:开关电源(上)
  20. 洛谷4995 跳跳!

热门文章

  1. chrome浏览器设置思源黑体
  2. MyBatis下载和环境搭建
  3. 《量子保密通信技术白皮书》
  4. java调用sqluldr_java 使用 oracle sqluldr2 快速导出数据文件
  5. 微信小程序模板订阅消息推送
  6. 微信小程序如何使用阿里矢量库
  7. PaddleNLP--UIE(二)--小样本快速提升性能(含doccona标注)
  8. Python爬虫实现英汉互译
  9. 各省份的车牌简称 备案地区的简称
  10. eclipse字体大小调整