海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(二)
生活随笔
收集整理的這篇文章主要介紹了
海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(二)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文接上次的博客海康威視工業相機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 oncemythread.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 oncePcbDetectv3.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++)(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 运筹学—线性规划单纯形表
- 下一篇: s3c2440移植MQTT