
vs2019+QT调用SDK连接海康相机显示图片
连接,采图,获取与设置参数,曝光,增益,帧率
新建项目-文件结构:


debug x64
调用类:
TTcamera.cpp
1#include "TTcamera.h" 2#include <QDebug> 3TTcamera::TTcamera() 4{ 5 m_hDevHandle = NULL; 6 m_pBufForSaveImage = nullptr; 7 m_nBufSizeForSaveImage = 0; 8 m_pBufForDriver = nullptr; 9 m_nBufSizeForDriver = 0; 10 memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); 11 m_Device = NULL; 12 13} 14 15TTcamera::~TTcamera() 16{ 17 if (m_pBufForDriver != nullptr) { 18 free(m_pBufForDriver); 19 m_pBufForDriver = nullptr; 20 } 21 if (m_pBufForSaveImage != nullptr) { 22 free(m_pBufForSaveImage); 23 m_pBufForSaveImage = nullptr; 24 } 25 26 if (m_hDevHandle) { 27 MV_CC_DestroyHandle(m_hDevHandle); 28 m_hDevHandle = NULL; 29 } 30} 31 32int TTcamera::InitSDK() 33{ 34 return MV_CC_Initialize(); 35} 36// ch:反初始化SDK | en:Finalize SDK 37int TTcamera::FinalizeSDK() 38{ 39 return MV_CC_Finalize(); 40} 41 42//查询设备列表 43int TTcamera::EnumDevices(MV_CC_DEVICE_INFO_LIST* pstDevList) 44{ 45 int temp = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, pstDevList); 46 if (MV_OK != temp) 47 { 48 return -1; 49 } 50 return 0; 51} 52 53//连接相机 54//id:自定义相机名称 55int TTcamera::connectCamera(string id) 56{ 57 int temp = EnumDevices(&m_stDevList); 58 if (temp != 0) { 59 qDebug() << "枚举设备失败,错误码:" << temp; 60 return -1; 61 } 62 63 if (m_stDevList.nDeviceNum == 0) { 64 qDebug() << "未找到任何相机"; 65 return 2; 66 } 67 68 m_Device = NULL; 69 for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++) 70 { 71 MV_CC_DEVICE_INFO* pDeviceInfo = m_stDevList.pDeviceInfo[i]; 72 if (NULL == pDeviceInfo) 73 { 74 continue; 75 } 76 77 if (id == (char*)pDeviceInfo->SpecialInfo.stGigEInfo.chUserDefinedName || 78 id == (char*)pDeviceInfo->SpecialInfo.stGigEInfo.chSerialNumber) 79 { 80 m_Device = m_stDevList.pDeviceInfo[i]; 81 break; 82 } 83 } 84 85 if (m_Device == NULL) { 86 qDebug() << "未找到指定名称的相机"; 87 return 3; 88 } 89 90 temp = MV_CC_CreateHandle(&m_hDevHandle, m_Device); 91 if (temp != MV_OK) { 92 qDebug() << "创建句柄失败,错误码:" << temp; 93 return -1; 94 } 95 96 temp = MV_CC_OpenDevice(m_hDevHandle); 97 if (temp != MV_OK) { 98 qDebug() << "打开设备失败,错误码:" << temp; 99 MV_CC_DestroyHandle(m_hDevHandle); 100 m_hDevHandle = NULL; 101 return -1; 102 } 103 104 // 设置触发模式为关闭(连续采集模式) 105 int triggerResult = setTriggerMode(0); 106 if (triggerResult != 0) { 107 qDebug() << "设置触发模式失败"; 108 MV_CC_CloseDevice(m_hDevHandle); 109 MV_CC_DestroyHandle(m_hDevHandle); 110 m_hDevHandle = NULL; 111 return -1; 112 } 113 114 return 0; 115} 116//设置相机是否开启触发模式 117int TTcamera::setTriggerMode(unsigned int TriggerModeNum) 118{ 119 int nRet = MV_CC_SetTriggerMode(m_hDevHandle, TriggerModeNum); 120 if (MV_OK != nRet) 121 { 122 return -1; 123 } 124 125} 126//启动相机采集 127int TTcamera::startCamera() 128{ 129 if (m_hDevHandle == NULL) { 130 qDebug() << "相机句柄为空,无法启动采集"; 131 return -1; 132 } 133 134 int temp = MV_CC_StartGrabbing(m_hDevHandle); 135 if (temp != 0) 136 { 137 qDebug() << "抓图失败,错误码:" << temp; 138 return -1; 139 } 140 else 141 { 142 qDebug() << "抓图成功"; 143 return 0; 144 } 145} 146//发送软触发 147int TTcamera::softTrigger() 148{ 149 int enumValue = MV_CC_SetEnumValue(m_hDevHandle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE); 150 if (enumValue != 0) { 151 qDebug() << "设置软触发失败"; 152 return -1; 153 } 154 else { 155 qDebug() << "设置软触发"; 156 } 157 int comdValue = MV_CC_SetCommandValue(m_hDevHandle, "TriggerSoftware"); 158 if (comdValue != 0) 159 { 160 qDebug() << "软触发失败"; 161 return -1; 162 } 163 else 164 { 165 qDebug() << "软触发一次"; 166 return 0; 167 } 168} 169//读取相机中的图像 170int TTcamera::ReadBuffer(Mat& image) 171{ 172 if (m_hDevHandle == NULL) { 173 qDebug() << "相机句柄为空,无法读取图像"; 174 return -1; 175 } 176 177 // 释放之前分配的内存 178 if (m_pBufForDriver != nullptr) { 179 free(m_pBufForDriver); 180 m_pBufForDriver = nullptr; 181 } 182 if (m_pBufForSaveImage != nullptr) { 183 free(m_pBufForSaveImage); 184 m_pBufForSaveImage = nullptr; 185 } 186 187 unsigned int nBufSize = 0; 188 MVCC_INTVALUE stIntvalue; 189 memset(&stIntvalue, 0, sizeof(MVCC_INTVALUE)); 190 191 int tempValue = MV_CC_GetIntValue(m_hDevHandle, "PayloadSize", &stIntvalue); 192 if (tempValue != 0) 193 { 194 qDebug() << "GetIntValue失败,错误码:" << tempValue; 195 return -1; 196 } 197 198 nBufSize = stIntvalue.nCurValue; 199 m_pBufForDriver = (unsigned char*)malloc(nBufSize); 200 if (m_pBufForDriver == nullptr) { 201 qDebug() << "内存分配失败"; 202 return -1; 203 } 204 205 MV_FRAME_OUT_INFO_EX stImageInfo; 206 memset(&stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX)); 207 208 int timeout = MV_CC_GetOneFrameTimeout(m_hDevHandle, m_pBufForDriver, nBufSize, &stImageInfo, 1000); 209 if (timeout != 0) 210 { 211 qDebug() << "GetOneFrameTimeout失败,错误码:" << timeout; 212 free(m_pBufForDriver); 213 m_pBufForDriver = nullptr; 214 return -1; 215 } 216 217 m_nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048; 218 m_pBufForSaveImage = (unsigned char*)malloc(m_nBufSizeForSaveImage); 219 if (m_pBufForSaveImage == nullptr) { 220 qDebug() << "内存分配失败"; 221 free(m_pBufForDriver); 222 m_pBufForDriver = nullptr; 223 return -1; 224 } 225 226 bool isMono; 227 switch (stImageInfo.enPixelType) 228 { 229 case PixelType_Gvsp_Mono8: 230 case PixelType_Gvsp_Mono10: 231 case PixelType_Gvsp_Mono10_Packed: 232 case PixelType_Gvsp_Mono12: 233 case PixelType_Gvsp_Mono12_Packed: 234 isMono = true; 235 break; 236 default: 237 isMono = false; 238 break; 239 } 240 241 if (isMono) 242 { 243 image = Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC1, m_pBufForDriver); 244 } 245 else 246 { 247 MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; 248 stConvertParam.nWidth = stImageInfo.nWidth; 249 stConvertParam.nHeight = stImageInfo.nHeight; 250 stConvertParam.pSrcData = m_pBufForDriver; 251 stConvertParam.nSrcDataLen = stImageInfo.nFrameLen; 252 stConvertParam.enSrcPixelType = stImageInfo.enPixelType; 253 stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed; 254 stConvertParam.pDstBuffer = m_pBufForSaveImage; 255 stConvertParam.nDstBufferSize = m_nBufSizeForSaveImage; 256 257 int convertResult = MV_CC_ConvertPixelType(m_hDevHandle, &stConvertParam); 258 if (convertResult != MV_OK) { 259 qDebug() << "像素格式转换失败,错误码:" << convertResult; 260 free(m_pBufForDriver); 261 free(m_pBufForSaveImage); 262 m_pBufForDriver = nullptr; 263 m_pBufForSaveImage = nullptr; 264 return -1; 265 } 266 267 image = Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC3, m_pBufForSaveImage); 268 } 269 270 return 0; 271} 272//设置心跳时间 273int TTcamera::setHeartBeatTime(unsigned int time) 274{ 275 //心跳时间最小为500ms 276 if (time < 500) 277 time = 500; 278 int temp = MV_CC_SetIntValue(m_hDevHandle, "GevHeartbeatTimeout", time); 279 if (temp != 0) 280 { 281 return -1; 282 } 283 else 284 { 285 return 0; 286 } 287} 288//设置曝光时间 289int TTcamera::setExposureTime(float ExposureTimeNum) 290{ 291 int temp = MV_CC_SetFloatValue(m_hDevHandle, "ExposureTime", ExposureTimeNum); 292 if (temp != 0) 293 return -1; 294 return 0; 295} 296// ch:获取和设置Enum型参数,如 PixelFormat 297// en:Get Enum type parameters, such as PixelFormat 298int TTcamera::GetEnumValue( char* strKey, MVCC_ENUMVALUE* pEnumValue) 299{ 300 return MV_CC_GetEnumValue(m_hDevHandle, strKey, pEnumValue); 301} 302int TTcamera::GetSDKVersion() 303{ 304 return MV_CC_GetSDKVersion(); 305} 306// ch:获取和设置Float型参数,如 ExposureTime和Gain 307// en:Get Float type parameters, such as ExposureTime and Gain 308int TTcamera::GetFloatValue(char* strKey, MVCC_FLOATVALUE* pFloatValue) 309{ 310 return MV_CC_GetFloatValue(m_hDevHandle, strKey, pFloatValue); 311} 312int TTcamera::SetEnumValue( char* strKey, unsigned int nValue) 313{ 314 return MV_CC_SetEnumValue(m_hDevHandle, strKey, nValue); 315} 316int TTcamera::SetFloatValue( char* strKey, float fValue) 317{ 318 return MV_CC_SetFloatValue(m_hDevHandle, strKey, fValue); 319} 320int TTcamera::SetBoolValue( char* strKey, bool bValue) 321{ 322 return MV_CC_SetBoolValue(m_hDevHandle, strKey, bValue); 323} 324//关闭相机 325int TTcamera::closeCamera() 326{ 327 int nRet = MV_OK; 328 if (NULL == m_hDevHandle) 329 { 330 qDebug() << "没有句柄,不用关闭"; 331 return -1; 332 } 333 MV_CC_CloseDevice(m_hDevHandle); 334 nRet = MV_CC_DestroyHandle(m_hDevHandle); 335 m_hDevHandle = NULL; 336 return nRet; 337}
TTcamera.h
1 2#ifndef TTcamera_H 3#define TTcamera_H 4#include "MvCameraControl.h" 5#pragma execution_character_set("utf-8") //设置当前文件为UTF-8编码 6#pragma warning( disable : 4819 ) //解决SDK中包含中文问题;忽略C4819错误 7#include <stdio.h> 8#include <iostream> 9#include "opencv2/core/core.hpp" 10#include "opencv2/opencv.hpp" 11#include "opencv2/highgui/highgui.hpp" 12#include <string> 13#include <QDebug> 14#include <QDateTime> // 用于生成时间戳文件名 15 16using namespace std; 17using namespace cv; 18class TTcamera 19{ 20public: 21 TTcamera(); 22 ~TTcamera(); 23 static int InitSDK(); 24 static int FinalizeSDK(); 25 //声明相关变量及函数等 26 //枚举相机设备列表 27 static int EnumDevices(MV_CC_DEVICE_INFO_LIST* pstDevList); 28 static int GetSDKVersion(); 29 30 // ch:连接相机 31 int connectCamera(string id); 32 33 //设置相机触发模式 34 int setTriggerMode(unsigned int TriggerModeNum); 35 36 //开启相机采集 37 int startCamera(); 38 39 //发送软触发 40 int softTrigger(); 41 42 //读取buffer 43 int ReadBuffer(Mat& image); 44 45 //设置心跳时间 46 int setHeartBeatTime(unsigned int time); 47 48 //设置曝光时间 49 int setExposureTime(float ExposureTimeNum); 50 //关闭相机 51 int closeCamera(); 52 int TTcamera::GetFloatValue(char* strKey, MVCC_FLOATVALUE* pFloatValue); 53 int TTcamera::GetEnumValue(char* strKey, MVCC_ENUMVALUE* pEnumValue); 54 int TTcamera::SetEnumValue(char* strKey, unsigned int nValue); 55 int TTcamera::SetFloatValue( char* strKey, float fValue); 56 int TTcamera::SetBoolValue(char* strKey, bool bValue); 57private: 58 void* m_hDevHandle; 59public: 60 unsigned char* m_pBufForSaveImage; // 用于保存图像的缓存 61 unsigned int m_nBufSizeForSaveImage; 62 unsigned char* m_pBufForDriver; // 用于从驱动获取图像的缓存 63 unsigned int m_nBufSizeForDriver; 64 MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表 65 MV_CC_DEVICE_INFO* m_Device = NULL; //设备对象 66}; 67#endif // TTcamera_H
QtWidgetsApplication1.h
1#pragma once 2 3#include <QtWidgets/QMainWindow> 4#include "ui_QtWidgetsApplication1.h" 5#include "TTcamera.h" 6#include <QCloseEvent> 7#include <Qtimer> 8 9class QtWidgetsApplication1 : public QMainWindow 10{ 11 Q_OBJECT 12 13public: 14 QtWidgetsApplication1(QWidget *parent = nullptr); 15 ~QtWidgetsApplication1(); 16 17 18 TTcamera* m_pcMycamera; 19 MV_CC_DEVICE_INFO_LIST m_stDevList;//设备列表 20 string cameraName; //相机名称 21 Mat imageMat; //使用OpenCV接受采集图像 22 QImage cvMat2QImage(const cv::Mat& mat); 23 QImage image; 24 25 26private: 27 Ui::QtWidgetsApplication1Class ui; 28 QTimer* m_timer; // 用于定时获取图像 29 bool m_bIsGrabbing; // 标记是否正在连续采集 30 void closeEvent(QCloseEvent* e); 31 int GetExposureTime(); 32 // 定时器超时槽函数 33 int GetTriggerMode(); 34 int GetGain(); 35 int m_nTriggerMode; // ch:触发模式 | en:Trigger Mode 36 bool m_bSoftWareTriggerCheck; 37private slots: 38 void on_pushButton_link_clicked(); 39 40 void on_pushButton_close_clicked(); 41 42 void on_pushButton_caiji_clicked(); 43 void on_pushButton_realtime_clicked(); // 实时显示按钮 44 int GetFrameRate(); 45 void updateFrame(); 46 47 48 void GetPara(); 49 int GetTriggerSource(); 50 int SetExposureTime(); 51 int SetGain(); 52 53 int SetFrameRate(); 54 void SetPara(); 55 void ShowMsg(QString msg); 56 void CloseWindow(); 57 58private: 59 // Ui::MainWindow* ui; 60 61 62}; 63
QtWidgetsApplication1.cpp
1#include "QtWidgetsApplication1.h" 2#include "qmessagebox.h" 3 4 5QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) 6 : QMainWindow(parent) 7{ 8 ui.setupUi(this); 9 TTcamera::InitSDK(); 10 int i_version = TTcamera::GetSDKVersion(); 11 connect(ui.pushButton_start, &QPushButton::clicked, this, [=] { 12 QMessageBox::information(this,"title","btn test"); 13 14 }); 15 connect(ui.pushButton_realtime, &QPushButton::clicked, this, [=] { 16 // on_pushButton_realtime_clicked(); 17 18 }); 19 connect(ui.on_pushButton_caiji, &QPushButton::clicked, this, [=] { 20 21 on_pushButton_caiji_clicked(); 22 }); 23 connect(ui.on_pushButton_close, &QPushButton::clicked, this, [=] { 24 on_pushButton_close_clicked(); 25 26 }); 27 connect(ui.on_pushButton_link, &QPushButton::clicked, this, [=] { 28 on_pushButton_link_clicked(); 29 30 }); 31 connect(ui.pushButton_exit, &QPushButton::clicked, this, &QtWidgetsApplication1::CloseWindow); 32 33 connect(ui.pushButton_get_para, &QPushButton::clicked, this, &QtWidgetsApplication1::GetPara); 34 connect(ui.pushButton_set_para, &QPushButton::clicked, this, &QtWidgetsApplication1::SetPara); 35 36 // ui->setupUi(this); 37 // 初始化定时器和状态变量 38 m_timer = new QTimer(this); 39 m_bIsGrabbing = false; 40 connect(m_timer, SIGNAL(timeout()), this, SLOT(updateFrame())); 41 42 m_pcMycamera = new TTcamera; 43 int neRt = m_pcMycamera->EnumDevices(&m_stDevList); 44 qDebug() << neRt; 45 qDebug() << m_stDevList.pDeviceInfo[0]->nTLayerType; 46 //获取相机的IP地址 47 if (1 == m_stDevList.pDeviceInfo[0]->nTLayerType) { 48 int nIp1, nIp2, nIp3, nIp4; 49 nIp1 = ((m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24); 50 nIp2 = ((m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16); 51 nIp3 = ((m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8); 52 nIp4 = (m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff); 53 QString nIp = QString("%1.%2.%3.%4").arg(nIp1).arg(nIp2).arg(nIp3).arg(nIp4); 54 qDebug() << nIp; 55 } 56 57 58} 59 60QtWidgetsApplication1::~QtWidgetsApplication1() 61{} 62 63//连接相机 64void QtWidgetsApplication1::on_pushButton_link_clicked() 65{ 66 cameraName = (char*)m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.chUserDefinedName; 67 //cameraName = (char*)m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.chSerialNumber; 68 qDebug() << "尝试连接相机:" << QString::fromStdString(cameraName); 69 70 int linkCamera = m_pcMycamera->connectCamera(cameraName); 71 qDebug() << "连接结果:" << linkCamera; 72 73 if (linkCamera == 0) { 74 qDebug() << "连接相机成功"; 75 76 // 开启抓图 77 int satrtCamera = m_pcMycamera->startCamera(); 78 if (satrtCamera != 0) { 79 qDebug() << "启动相机采集失败"; 80 81 } 82 else { 83 qDebug() << "正在启动相机采集信息"; 84 QMessageBox::information(this, "title", "已连接相机"); 85 } 86 } 87 else { 88 qDebug() << "连接相机失败,错误码:" << linkCamera; 89 90 // 尝试使用序列号连接 91 QString serialNumber = QString::fromLocal8Bit((char*)m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.chSerialNumber); 92 qDebug() << "尝试使用序列号连接:" << serialNumber; 93 94 int linkBySerial = m_pcMycamera->connectCamera(serialNumber.toStdString()); 95 qDebug() << "使用序列号连接结果:" << linkBySerial; 96 } 97} 98//添加实时显示按钮的槽函数 99void QtWidgetsApplication1::on_pushButton_realtime_clicked() 100{ 101 if (!m_bIsGrabbing) { 102 // 开始实时显示 103 if (m_pcMycamera->setTriggerMode(0) == 0) { // 设置为连续采集模式 104 m_timer->start(33); // 约30帧/秒 105 m_bIsGrabbing = true; 106 ui.pushButton_realtime->setText("停止实时显示"); 107 } 108 } 109 else { 110 // 停止实时显示 111 m_timer->stop(); 112 m_bIsGrabbing = false; 113 ui.pushButton_realtime->setText("开始实时显示"); 114 } 115} 116// ch:获取帧率 | en:Get Frame Rate 117int QtWidgetsApplication1::GetFrameRate() 118{ 119 MVCC_FLOATVALUE stFloatValue = { 0 }; 120 char temp_info[] = "ResultingFrameRate"; 121 int nRet = m_pcMycamera->GetFloatValue(temp_info, &stFloatValue); 122 if (MV_OK != nRet) 123 { 124 return nRet; 125 } 126 // m_dFrameRateEdit = stFloatValue.fCurValue; 127 ui.lineEdit_frame_rate->setText(QString::number(stFloatValue.fCurValue)); 128 129 return MV_OK; 130} 131 132// 定时器超时槽函数,用于更新画面 133void QtWidgetsApplication1::updateFrame() 134{ 135 // 读取相机中的图像 136 int readInt = m_pcMycamera->ReadBuffer(imageMat); 137 if (readInt != 0) { 138 qDebug() << "读取图像失败"; 139 return; 140 } 141 142 // 转换并显示图像 143 image = cvMat2QImage(imageMat); 144 ui.label_image->setPixmap(QPixmap::fromImage(image).scaled( 145 ui.label_image->width(), 146 ui.label_image->height(), 147 Qt::KeepAspectRatio)); 148} 149// ch:获取曝光时间 | en:Get Exposure Time 150int QtWidgetsApplication1::GetExposureTime() 151{ 152 MVCC_FLOATVALUE stFloatValue = { 0 }; 153 char temp_info[] = "ExposureTime"; 154 int nRet = m_pcMycamera->GetFloatValue(temp_info, &stFloatValue); 155 if (MV_OK != nRet) 156 { 157 return nRet; 158 } 159 160 ui.lineEdit_expose->setText(QString::number(stFloatValue.fCurValue)); 161 162 return MV_OK; 163} 164int QtWidgetsApplication1::GetTriggerMode() 165{ 166 MVCC_ENUMVALUE stEnumValue = { 0 }; 167 char temp_info[] = "TriggerMode"; 168 int nRet = m_pcMycamera->GetEnumValue(temp_info, &stEnumValue); 169 if (MV_OK != nRet) 170 { 171 return nRet; 172 } 173 174 m_nTriggerMode = stEnumValue.nCurValue; 175 if (MV_TRIGGER_MODE_ON == m_nTriggerMode) 176 { 177 //OnBnClickedTriggerModeRadio(); 178 } 179 else 180 { 181 m_nTriggerMode = MV_TRIGGER_MODE_OFF; 182 //OnBnClickedContinusModeRadio(); 183 } 184 185 return MV_OK; 186} 187// ch:获取增益 | en:Get Gain 188int QtWidgetsApplication1::GetGain() 189{ 190 MVCC_FLOATVALUE stFloatValue = { 0 }; 191 char temp_info[] = "Gain"; 192 int nRet = m_pcMycamera->GetFloatValue(temp_info, &stFloatValue); 193 if (MV_OK != nRet) 194 { 195 return nRet; 196 } 197 ui.lineEdit_gain->setText(QString::number(stFloatValue.fCurValue)); 198 199 return MV_OK; 200} 201void QtWidgetsApplication1::GetPara() 202{ 203 int nRet = GetTriggerMode(); 204 if (nRet != MV_OK) 205 { 206 // ShowErrorMsg(TEXT("Get Trigger Mode Fail"), nRet); 207 ShowMsg("Get Trigger Mode Fail"); 208 } 209 210 nRet = GetExposureTime(); 211 if (nRet != MV_OK) 212 { 213 // ShowErrorMsg(TEXT("Get Exposure Time Fail"), nRet); 214 ShowMsg("Get Exposure Time Fail"); 215 } 216 217 nRet = GetGain(); 218 if (nRet != MV_OK) 219 { 220 // ShowErrorMsg(TEXT("Get Gain Fail"), nRet); 221 ShowMsg("Get Gain Fail"); 222 } 223 224 nRet = GetFrameRate(); 225 if (nRet != MV_OK) 226 { 227 // ShowErrorMsg(TEXT("Get Frame Rate Fail"), nRet); 228 ShowMsg("Get Frame Rate Fail"); 229 } 230 231 nRet = GetTriggerSource(); 232 if (nRet != MV_OK) 233 { 234 // ShowErrorMsg(TEXT("Get Trigger Source Fail"), nRet); 235 ShowMsg("Get Trigger Source Fail"); 236 } 237 238 239} 240// ch:获取触发源 | en:Get Trigger Source 241int QtWidgetsApplication1::GetTriggerSource() 242{ 243 MVCC_ENUMVALUE stEnumValue = { 0 }; 244 char temp_info[] = "TriggerSource"; 245 int nRet = m_pcMycamera->GetEnumValue(temp_info, &stEnumValue); 246 if (MV_OK != nRet) 247 { 248 return nRet; 249 } 250 251 if ((unsigned int)MV_TRIGGER_SOURCE_SOFTWARE == stEnumValue.nCurValue) 252 { 253 m_bSoftWareTriggerCheck = true; 254 } 255 else 256 { 257 m_bSoftWareTriggerCheck = false; 258 } 259 260 return MV_OK; 261} 262// ch:设置曝光时间 | en:Set Exposure Time 263int QtWidgetsApplication1::SetExposureTime() 264{ 265 char temp_info[] = "ExposureAuto"; 266 m_pcMycamera->SetEnumValue(temp_info, MV_EXPOSURE_AUTO_MODE_OFF); 267 268 char temp_info2[] = "ExposureTime"; 269 return m_pcMycamera->SetFloatValue(temp_info2, ui.lineEdit_expose->text().toFloat()); 270} 271// ch:设置增益 | en:Set Gain 272int QtWidgetsApplication1::SetGain() 273{ 274 // ch:设置增益前先把自动增益关闭,失败无需返回 275 //en:Set Gain after Auto Gain is turned off, this failure does not need to return 276 char temp_info[] = "GainAuto"; 277 m_pcMycamera->SetEnumValue(temp_info, 0); 278 char temp_info2[] = "Gain"; 279 return m_pcMycamera->SetFloatValue(temp_info2, ui.lineEdit_gain->text().toFloat()); 280} 281 282 283// ch:设置帧率 | en:Set Frame Rate 284int QtWidgetsApplication1::SetFrameRate() 285{ 286 char temp_info[] = "AcquisitionFrameRateEnable"; 287 int nRet = m_pcMycamera->SetBoolValue(temp_info, true); 288 if (MV_OK != nRet) 289 { 290 return nRet; 291 } 292 char temp_info2[] = "AcquisitionFrameRate"; 293 return m_pcMycamera->SetFloatValue(temp_info2, ui.lineEdit_frame_rate->text().toFloat()); 294} 295void QtWidgetsApplication1::SetPara() 296{ 297 bool bIsSetSucceed = true; 298 int nRet = SetExposureTime(); 299 if (nRet != MV_OK) 300 { 301 bIsSetSucceed = false; 302 // ShowErrorMsg(TEXT("Set Exposure Time Fail"), nRet); 303 ShowMsg("Set Exposure Time Fail"); 304 } 305 nRet = SetGain(); 306 if (nRet != MV_OK) 307 { 308 bIsSetSucceed = false; 309 //ShowErrorMsg(TEXT("Set Gain Fail"), nRet); 310 311 ShowMsg("Set Gain Fail"); 312 } 313 nRet = SetFrameRate(); 314 if (nRet != MV_OK) 315 { 316 bIsSetSucceed = false; 317 //ShowErrorMsg(TEXT("Set Frame Rate Fail"), nRet); 318 ShowMsg("Set Frame Rate Fail"); 319 } 320 321 if (true == bIsSetSucceed) 322 { 323 324 // ShowErrorMsg(TEXT("Set Parameter Succeed"), nRet); 325 ShowMsg("Set Parameter Succeed"); 326 327 } 328} 329void QtWidgetsApplication1::ShowMsg(QString msg) 330{ 331 QMessageBox::information(this,"title",msg); 332} 333void QtWidgetsApplication1::CloseWindow() 334{ 335 if (QMessageBox::question(this, tr("Tips"), tr("退出程序吗?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) 336 { 337 on_pushButton_close_clicked(); 338 QApplication::exit(); 339 } 340 341} 342 343// 修改单张采集函数,确保在单张采集时使用触发模式 344void QtWidgetsApplication1::on_pushButton_caiji_clicked() 345{ 346 // 如果正在实时显示,先停止 347 if (m_bIsGrabbing) { 348 m_timer->stop(); 349 m_bIsGrabbing = false; 350 ui.pushButton_realtime->setText("开始实时显示"); 351 } 352 353 // 设置为触发模式 354 m_pcMycamera->setTriggerMode(1); 355 356 // 发送软触发 357 int softTrigger = m_pcMycamera->softTrigger(); 358 if (softTrigger != 0) { 359 qDebug() << "软触发失败"; 360 } 361 else { 362 qDebug() << "成功触发一次"; 363 } 364 365 // 读取相机中的图像 366 int readInt = m_pcMycamera->ReadBuffer(imageMat); 367 if (readInt != 0) { 368 qDebug() << "读取图像失败"; 369 } 370 image = cvMat2QImage(imageMat); 371 ui.label_image->setPixmap(QPixmap::fromImage(image).scaled( 372 ui.label_image->width(), 373 ui.label_image->height(), 374 Qt::KeepAspectRatio)); 375} 376void QtWidgetsApplication1::closeEvent(QCloseEvent* ee) 377{ 378 if (QMessageBox::question(this, tr("Tips"), tr("关闭程序吗?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) 379 { 380 // setWindowState(Qt::WindowMinimized); 381 // emit SigToMainLog("已执行最小化"); 382 on_pushButton_close_clicked(); 383 384 ee->accept(); 385 386 } 387 else 388 { 389 ee->ignore(); 390 // return; 391 // 392 } 393} 394//关闭设备 395void QtWidgetsApplication1::on_pushButton_close_clicked() 396{ 397 //关闭设备,释放资源 398 int close = m_pcMycamera->closeCamera(); 399 if (close != 0) { 400 qDebug() << "相机关闭失败"; 401 QMessageBox::information(this,"title","相机关闭失败"); 402 } 403 else 404 { 405 QMessageBox::information(this, "title", "相机已经关闭"); 406 } 407 TTcamera::FinalizeSDK(); 408 409} 410 411//Mat转QImage函数 412QImage QtWidgetsApplication1::cvMat2QImage(const cv::Mat& mat) 413{ 414 // 8-bits unsigned, NO. OF CHANNELS = 1 415 if (mat.type() == CV_8UC1) 416 { 417 QImage qimage(mat.cols, mat.rows, QImage::Format_Indexed8); 418 // Set the color table (used to translate colour indexes to qRgb values) 419 qimage.setColorCount(256); 420 for (int i = 0; i < 256; i++) 421 { 422 qimage.setColor(i, qRgb(i, i, i)); 423 } 424 // Copy input Mat 425 uchar* pSrc = mat.data; 426 for (int row = 0; row < mat.rows; row++) 427 { 428 uchar* pDest = qimage.scanLine(row); 429 memcpy(pDest, pSrc, mat.cols); 430 pSrc += mat.step; 431 } 432 return qimage; 433 } 434 // 8-bits unsigned, NO. OF CHANNELS = 3 435 else if (mat.type() == CV_8UC3) 436 { 437 // Copy input Mat 438 const uchar* pSrc = (const uchar*)mat.data; 439 // Create QImage with same dimensions as input Mat 440 QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888); 441 return image.rgbSwapped(); 442 } 443 else if (mat.type() == CV_8UC4) 444 { 445 // Copy input Mat 446 const uchar* pSrc = (const uchar*)mat.data; 447 // Create QImage with same dimensions as input Mat 448 QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32); 449 return image.copy(); 450 } 451 else 452 { 453 return QImage(); 454 } 455} 456 457
QtWidgetsApplication1.ui
1<?xml version="1.0" encoding="UTF-8"?> 2<ui version="4.0"> 3 <class>QtWidgetsApplication1Class</class> 4 <widget class="QMainWindow" name="QtWidgetsApplication1Class"> 5 <property name="geometry"> 6 <rect> 7 <x>0</x> 8 <y>0</y> 9 <width>837</width> 10 <height>644</height> 11 </rect> 12 </property> 13 <property name="windowTitle"> 14 <string>QtWidgetsApplication1</string> 15 </property> 16 <widget class="QWidget" name="centralWidget"> 17 <layout class="QVBoxLayout" name="verticalLayout"> 18 <item> 19 <layout class="QHBoxLayout" name="horizontalLayout"> 20 <item> 21 <widget class="QGroupBox" name="groupBox"> 22 <property name="minimumSize"> 23 <size> 24 <width>500</width> 25 <height>500</height> 26 </size> 27 </property> 28 <property name="maximumSize"> 29 <size> 30 <width>16777215</width> 31 <height>500</height> 32 </size> 33 </property> 34 <property name="title"> 35 <string>显示画面</string> 36 </property> 37 <layout class="QGridLayout" name="gridLayout"> 38 <item row="0" column="0"> 39 <widget class="QLabel" name="label_image"> 40 <property name="styleSheet"> 41 <string notr="true">background-color: rgb(0, 0, 0);</string> 42 </property> 43 <property name="frameShadow"> 44 <enum>QFrame::Sunken</enum> 45 </property> 46 <property name="text"> 47 <string/> 48 </property> 49 </widget> 50 </item> 51 </layout> 52 </widget> 53 </item> 54 <item> 55 <widget class="QGroupBox" name="groupBox_2"> 56 <property name="minimumSize"> 57 <size> 58 <width>0</width> 59 <height>500</height> 60 </size> 61 </property> 62 <property name="maximumSize"> 63 <size> 64 <width>16777215</width> 65 <height>500</height> 66 </size> 67 </property> 68 <property name="title"> 69 <string>参数</string> 70 </property> 71 <widget class="QLabel" name="label"> 72 <property name="geometry"> 73 <rect> 74 <x>20</x> 75 <y>60</y> 76 <width>54</width> 77 <height>12</height> 78 </rect> 79 </property> 80 <property name="text"> 81 <string>曝光</string> 82 </property> 83 </widget> 84 <widget class="QLabel" name="label_2"> 85 <property name="geometry"> 86 <rect> 87 <x>20</x> 88 <y>100</y> 89 <width>54</width> 90 <height>12</height> 91 </rect> 92 </property> 93 <property name="text"> 94 <string>增益</string> 95 </property> 96 </widget> 97 <widget class="QLabel" name="label_3"> 98 <property name="geometry"> 99 <rect> 100 <x>20</x> 101 <y>140</y> 102 <width>54</width> 103 <height>12</height> 104 </rect> 105 </property> 106 <property name="text"> 107 <string>帧率</string> 108 </property> 109 </widget> 110 <widget class="QPushButton" name="pushButton_get_para"> 111 <property name="geometry"> 112 <rect> 113 <x>20</x> 114 <y>180</y> 115 <width>75</width> 116 <height>23</height> 117 </rect> 118 </property> 119 <property name="text"> 120 <string>获取</string> 121 </property> 122 </widget> 123 <widget class="QPushButton" name="pushButton_set_para"> 124 <property name="geometry"> 125 <rect> 126 <x>110</x> 127 <y>180</y> 128 <width>75</width> 129 <height>23</height> 130 </rect> 131 </property> 132 <property name="text"> 133 <string>设置</string> 134 </property> 135 </widget> 136 <widget class="QLineEdit" name="lineEdit_expose"> 137 <property name="geometry"> 138 <rect> 139 <x>80</x> 140 <y>50</y> 141 <width>113</width> 142 <height>20</height> 143 </rect> 144 </property> 145 </widget> 146 <widget class="QLineEdit" name="lineEdit_gain"> 147 <property name="geometry"> 148 <rect> 149 <x>80</x> 150 <y>90</y> 151 <width>113</width> 152 <height>20</height> 153 </rect> 154 </property> 155 </widget> 156 <widget class="QLineEdit" name="lineEdit_frame_rate"> 157 <property name="geometry"> 158 <rect> 159 <x>80</x> 160 <y>130</y> 161 <width>113</width> 162 <height>20</height> 163 </rect> 164 </property> 165 </widget> 166 </widget> 167 </item> 168 </layout> 169 </item> 170 <item> 171 <layout class="QGridLayout" name="gridLayout_2"> 172 <item row="0" column="0"> 173 <widget class="QPushButton" name="on_pushButton_link"> 174 <property name="styleSheet"> 175 <string notr="true">background:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, 176stop:0 rgba(204, 250, 227, 255), /*第1个颜色值*/ 177stop:0.25 rgba(126, 242, 185, 255), /*第2个颜色值*/ 178stop:0.5 rgba(76, 237, 157, 255), /*第3个颜色值*/ 179stop:0.65 rgba(91, 239, 166, 255), /*第4个颜色值*/ 180stop:1 rgba(184, 248, 217, 255));/*第5个颜色值*/ 181border: 2px solid rgb(78,238,158);/*边框颜色值*/ 182 border-radius: 10px; 183font: 16pt "Arial"; 184 </string> 185 </property> 186 <property name="text"> 187 <string>开始连接</string> 188 </property> 189 </widget> 190 </item> 191 <item row="0" column="1"> 192 <widget class="QPushButton" name="pushButton_realtime"> 193 <property name="styleSheet"> 194 <string notr="true">background:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, 195stop:0 rgba(199, 238, 249, 255), 196stop:0.25 rgba(132, 217, 243, 255), 197stop:0.5 rgba(80, 200, 238, 255), 198stop:0.65 rgba(87, 203, 239, 255), 199stop:1 rgba(186, 233, 249, 255)); 200 border: 2px solid rgb(106,208,240); 201 border-radius: 10px; 202font: 16pt "Arial"; 203 </string> 204 </property> 205 <property name="text"> 206 <string>实时显示</string> 207 </property> 208 </widget> 209 </item> 210 <item row="0" column="2"> 211 <widget class="QPushButton" name="on_pushButton_caiji"> 212 <property name="styleSheet"> 213 <string notr="true">background:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, 214stop:0 rgba(250, 204, 246, 255), /*第1个颜色值*/ 215stop:0.25 rgba(243, 144, 236, 255), /*第2个颜色值*/ 216stop:0.5 rgba(238, 81, 223, 255), /*第3个颜色值*/ 217stop:0.65 rgba(239, 92, 225, 255), /*第4个颜色值*/ 218stop:1 rgba(249, 186, 243, 255));/*第5个颜色值*/ 219border: 2px solid rgb(240,102,255);/*边框颜色值*/ 220 border-radius: 10px; 221font: 16pt "Arial"; 222</string> 223 </property> 224 <property name="text"> 225 <string>图像采集</string> 226 </property> 227 </widget> 228 </item> 229 <item row="0" column="3"> 230 <widget class="QPushButton" name="on_pushButton_close"> 231 <property name="styleSheet"> 232 <string notr="true">background:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, 233stop:0 rgba(249, 202, 201, 255), /*第1个颜色值*/ 234stop:0.25 rgba(242, 126, 126, 255), /*第2个颜色值*/ 235stop:0.5 rgba(237, 78, 78, 255), /*第3个颜色值*/ 236stop:0.65 rgba(238, 89, 89, 255), /*第4个颜色值*/ 237stop:1 rgba(247, 175, 175, 255));/*第5个颜色值*/ 238border: 2px solid rgb(237,80,78);/*边框颜色值*/ 239 border-radius: 10px; 240 font: 16pt "Arial";</string> 241 </property> 242 <property name="text"> 243 <string>关闭连接</string> 244 </property> 245 </widget> 246 </item> 247 <item row="0" column="4"> 248 <widget class="QPushButton" name="pushButton_exit"> 249 <property name="styleSheet"> 250 <string notr="true">background:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, 251stop:0 rgba(247, 250, 204, 255), 252stop:0.25 rgba(236, 243, 133, 255), 253stop:0.5 rgba(226, 237, 76, 255), 254stop:0.65 rgba(229, 239, 91, 255), 255stop:1 rgba(229, 233, 160, 255)); 256 border: 2px solid rgb(225,238,78); 257 border-radius: 10px; 258font: 16pt "Arial"; 259</string> 260 </property> 261 <property name="text"> 262 <string>退出</string> 263 </property> 264 </widget> 265 </item> 266 <item row="1" column="0"> 267 <widget class="QPushButton" name="pushButton_start"> 268 <property name="styleSheet"> 269 <string notr="true">.QPushButton { 270 background:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, 271stop:0 rgba(233, 233, 233, 255), 272stop:0.35 rgba(220, 220, 220, 255), 273stop:0.5 rgba(213, 213, 213, 255), 274stop:0.65 rgba(230, 230, 230, 255), 275stop:1 rgba(242, 242, 242, 255)); 276 border: 1px solid rgb(128,126,126); 277 border-radius: 5px; 278font: 16pt "Arial"; 279} 280.QPushButton:hover{ 281 background:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, 282stop:0 rgba(250, 250, 250, 255), 283stop:0.5 rgba(255, 255, 255, 255), 284stop:1 rgba(250, 250, 250, 255)); 285 border: 1px solid rgb(63,140,161); 286 border-radius: 5px; 287} 288 289.QPushButton:pressed{ 290 background:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, 291stop:0 rgba(255, 255, 255, 255), 292stop:0.5 rgba(235, 247, 253, 255), 293stop:1 rgba(213, 237, 250, 255)); 294 border: 1px solid rgb(3,110,183); 295 border-radius: 5px; 296 297} 298 299 </string> 300 </property> 301 <property name="text"> 302 <string>显示消息</string> 303 </property> 304 </widget> 305 </item> 306 </layout> 307 </item> 308 </layout> 309 </widget> 310 <widget class="QMenuBar" name="menuBar"> 311 <property name="geometry"> 312 <rect> 313 <x>0</x> 314 <y>0</y> 315 <width>837</width> 316 <height>23</height> 317 </rect> 318 </property> 319 </widget> 320 <widget class="QToolBar" name="mainToolBar"> 321 <attribute name="toolBarArea"> 322 <enum>TopToolBarArea</enum> 323 </attribute> 324 <attribute name="toolBarBreak"> 325 <bool>false</bool> 326 </attribute> 327 </widget> 328 <widget class="QStatusBar" name="statusBar"/> 329 </widget> 330 <layoutdefault spacing="6" margin="11"/> 331 <resources> 332 <include location="QtWidgetsApplication1.qrc"/> 333 </resources> 334 <connections/> 335</ui> 336
海康官网下载最新SDK,如:MVS_STD_4.3.2_240529.zip
安装后:项目属性,包含目录:
C:\Program Files (x86)\MVS\Development\Includes

库目录添加:

链接器-》输入:

《第4篇 vs2019+QT调用SDK连接海康相机显示图片》 是转载文章,点击查看原文。
