配置環(huán)境:
Qt5.12.5
OpenCV3.4.9
??礛VS3.1.0
開(kāi)發(fā)工具:QT Creator-4.11.0
1、開(kāi)發(fā)步驟:
1)創(chuàng)建QT項(xiàng)目,在pro文件中添加相機(jī)的引用文件
1.1)添加??档膸?kù):
將海康SDK庫(kù)MVS\Development\Includes和MVS\Development\Libraries\win64下復(fù)制到自己的工程目錄下
然后把庫(kù)添加到.pro文件中
點(diǎn)擊下一步之后就會(huì)在.pro文件中出現(xiàn)如下代碼
然后在這后面加上以下代碼,添加依賴項(xiàng)
1 INCLUDEPATH += $$PWD/includes/
2 INCLUDEPATH += $$PWD/includes/GenICam/
3
4 DEPENDPATH += $$PWD/includes/
5 DEPENDPATH += $$PWD/includes/GenICam/
1.2)配置OpenCV
跟上面配置HKSDK步驟相同庫(kù)文件目錄為OpenCV的安裝目錄D:/OpenCV/opencv/build/x64/vc14/lib/opencv_world349d.lib
配置完成會(huì)在。pro文件中出現(xiàn)如下代碼
需要在后面添加如下代碼
INCLUDEPATH += D:\OpenCV\opencv\build\include \
D:\OpenCV\opencv\build\include\opencv \
D:\OpenCV\opencv\build\include\opencv2
DEPENDPATH += D:\OpenCV\opencv\build\include \
D:\OpenCV\opencv\build\include\opencv \
D:\OpenCV\opencv\build\include\opencv2
這樣??礢DK和OpenCV庫(kù)就配置完成了,可以在項(xiàng)目引入他們的頭文件了。
2、開(kāi)發(fā)步驟:
新建一個(gè)類(lèi):mycanera.h和mycaner.cpp生成這兩個(gè)文件(ps:建文件時(shí)將camera打錯(cuò)了,^_^)
mycanera.h文件參考一下代碼:
#ifndef MYCANERA_H
#define MYCANERA_H
#include "MvCameraControl.h"
#pragma execution_character_set("utf-8") //設(shè)置當(dāng)前文件為UTF-8編碼
#pragma warning( disable : 4819 ) //解決SDK中包含中文問(wèn)題;忽略C4819錯(cuò)誤
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <string>
#include <QDebug>
using namespace std;
using namespace cv;
class MyCanera
{
public:
MyCanera();
~MyCanera();
//聲明相關(guān)變量及函數(shù)等
//枚舉相機(jī)設(shè)備列表
static int EnumDevices(MV_CC_DEVICE_INFO_LIST* pstDevList);
// ch:連接相機(jī)
int connectCamera(string id);
//設(shè)置相機(jī)觸發(fā)模式
int setTriggerMode(unsigned int TriggerModeNum);
//開(kāi)啟相機(jī)采集
int startCamera();
//發(fā)送軟觸發(fā)
int softTrigger();
//讀取buffer
int ReadBuffer(Mat &image);
//設(shè)置心跳時(shí)間
int setHeartBeatTime(unsigned int time);
//設(shè)置曝光時(shí)間
int setExposureTime(float ExposureTimeNum);
//關(guān)閉相機(jī)
int closeCamera();
private: void* m_hDevHandle; public: unsigned char* m_pBufForSaveImage; // 用于保存圖像的緩存 unsigned int m_nBufSizeForSaveImage; unsigned char* m_pBufForDriver; // 用于從驅(qū)動(dòng)獲取圖像的緩存 unsigned int m_nBufSizeForDriver; MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:設(shè)備信息列表結(jié)構(gòu)體變量,用來(lái)存儲(chǔ)設(shè)備列表 MV_CC_DEVICE_INFO *m_Device = NULL; //設(shè)備對(duì)象 }; #endif // MYCANERA_H
mycanera.cpp文件參考一下代碼:
#include "mycanera.h"
#include <QDebug>
MyCanera::MyCanera()
{
m_hDevHandle = NULL;
}
MyCanera::~MyCanera()
{
if (m_hDevHandle)
{
MV_CC_DestroyHandle(m_hDevHandle);
m_hDevHandle = NULL;
}
}
//查詢?cè)O(shè)備列表
int MyCanera::EnumDevices(MV_CC_DEVICE_INFO_LIST* pstDevList)
{
int temp= MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, pstDevList);
if (MV_OK != temp)
{
return -1;
}
return 0;
}
//連接相機(jī)
//id:自定義相機(jī)名稱
int MyCanera::connectCamera(string id)
{
int temp= EnumDevices(&m_stDevList);
if(temp!=0)
//設(shè)備更新成功接收命令的返回值為0,返回值不為0則為異常
return -1;
if(m_stDevList.nDeviceNum==0)
//未找到任何相機(jī)
return 2;
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++)
{
MV_CC_DEVICE_INFO* pDeviceInfo = m_stDevList.pDeviceInfo[i];
if (NULL == pDeviceInfo)
{
continue;
}
//qDebug() << (char*)pDeviceInfo->SpecialInfo.stGigEInfo.chUserDefinedName;//自定義相機(jī)名稱
//qDebug() << (char*)pDeviceInfo->SpecialInfo.stGigEInfo.chSerialNumber;//相機(jī)序列號(hào)
if(id == (char*)pDeviceInfo->SpecialInfo.stGigEInfo.chUserDefinedName||id == (char*)pDeviceInfo->SpecialInfo.stGigEInfo.chSerialNumber)
{
m_Device= m_stDevList.pDeviceInfo[i];
break;
}else
{
continue;
}
}
if(m_Device==NULL)
{
//未找到指定名稱的相機(jī)
qDebug() << "未找到指定名稱的相機(jī)";
return 3;
}
temp = MV_CC_CreateHandle(&m_hDevHandle, m_Device);//創(chuàng)建句柄
if(temp !=0)
return -1;
temp = MV_CC_OpenDevice(m_hDevHandle);//打開(kāi)設(shè)備
if (temp !=0)
{
MV_CC_DestroyHandle(m_hDevHandle);
m_hDevHandle = NULL;
return -1;
}else
{
setTriggerMode(1);//設(shè)置觸發(fā)模式:1-打開(kāi)觸發(fā)模式 0-關(guān)閉觸發(fā)模式
return 0;
}
if (m_Device->nTLayerType == MV_GIGE_DEVICE)//設(shè)備類(lèi)型為網(wǎng)絡(luò)接口
{
//std::cout<<"Gige Camera"<<std::endl;
}
}
//設(shè)置相機(jī)是否開(kāi)啟觸發(fā)模式
int MyCanera::setTriggerMode(unsigned int TriggerModeNum)
{
int nRet = MV_CC_SetTriggerMode(m_hDevHandle,TriggerModeNum);
if (MV_OK != nRet)
{
return -1;
}
}
//啟動(dòng)相機(jī)采集
int MyCanera::startCamera()
{
int temp=MV_CC_StartGrabbing(m_hDevHandle);
if(temp!=0)
{
qDebug() << "抓圖失敗";
return -1;
}else
{
qDebug() << "抓圖成功";
return 0;
}
}
//發(fā)送軟觸發(fā)
int MyCanera::softTrigger()
{
int enumValue = MV_CC_SetEnumValue(m_hDevHandle,"TriggerSource",MV_TRIGGER_SOURCE_SOFTWARE);
if(enumValue != 0){
qDebug() << "設(shè)置軟觸發(fā)失敗";
return -1;
}else {
qDebug() << "設(shè)置軟觸發(fā)";
}
int comdValue= MV_CC_SetCommandValue(m_hDevHandle, "TriggerSoftware");
if(comdValue!=0)
{
qDebug() << "軟觸發(fā)失敗";
return -1;
}else
{
qDebug() << "軟觸發(fā)一次";
return 0;
}
}
//讀取相機(jī)中的圖像
int MyCanera::ReadBuffer(Mat &image)
{
unsigned int nBufSize = 0;//緩存大小
MVCC_INTVALUE stIntvalue; //獲取一幀數(shù)據(jù)的大小
memset(&stIntvalue, 0, sizeof(MVCC_INTVALUE));
int tempValue = MV_CC_GetIntValue(m_hDevHandle, "PayloadSize", &stIntvalue);
if (tempValue != 0)
{
qDebug() << "GetIntValue失敗";
return -1;
}else{qDebug() << "GetIntValue成功";}
nBufSize = stIntvalue.nCurValue;
m_pBufForDriver = (unsigned char *)malloc(nBufSize);
MV_FRAME_OUT_INFO_EX stImageInfo;
memset(&stImageInfo,0,sizeof(MV_FRAME_OUT_INFO));
qDebug() << MV_CC_StartGrabbing(m_hDevHandle);
int timeout= MV_CC_GetOneFrameTimeout(m_hDevHandle, m_pBufForDriver, nBufSize, &stImageInfo, 1000);
if(timeout!=0)
{
qDebug() << "GetOneFrameTimeout失敗";
return -1;
}
m_nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
m_pBufForSaveImage = (unsigned char*)malloc(m_nBufSizeForSaveImage); //向系統(tǒng)申請(qǐng)M_nBufSizeForSaveImage內(nèi)存空間
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)
{
image=Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC1,m_pBufForDriver);
}
else
{
//轉(zhuǎn)換圖像格式為BGR8
MV_CC_PIXEL_CONVERT_PARAM stConvertParam = {0};
memset(&stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));
stConvertParam.nWidth = stImageInfo.nWidth; //ch:圖像寬 | en:image width
stConvertParam.nHeight = stImageInfo.nHeight; //ch:圖像高 | en:image height
stConvertParam.pSrcData = m_pBufForDriver; //ch:輸入數(shù)據(jù)緩存 | en:input data buffer
stConvertParam.nSrcDataLen = stImageInfo.nFrameLen; //ch:輸入數(shù)據(jù)大小 | en:input data size
stConvertParam.enSrcPixelType = stImageInfo.enPixelType; //ch:輸入像素格式 | en:input pixel format
//stConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed; //ch:輸出像素格式 | en:output pixel format 適用于OPENCV的圖像格式
stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed; //ch:輸出像素格式 | en:output pixel format
stConvertParam.pDstBuffer = m_pBufForSaveImage; //ch:輸出數(shù)據(jù)緩存 | en:output data buffer
stConvertParam.nDstBufferSize = m_nBufSizeForSaveImage; //ch:輸出緩存大小 | en:output buffer size
MV_CC_ConvertPixelType(m_hDevHandle, &stConvertParam);
image=Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC3,m_pBufForSaveImage);
}
return 0;
}
//設(shè)置心跳時(shí)間
int MyCanera::setHeartBeatTime(unsigned int time)
{
//心跳時(shí)間最小為500ms
if(time<500)
time=500;
int temp=MV_CC_SetIntValue(m_hDevHandle, "GevHeartbeatTimeout", time);
if(temp!=0)
{
return -1;
}
else
{
return 0;
}
}
//設(shè)置曝光時(shí)間
int MyCanera::setExposureTime(float ExposureTimeNum)
{
int temp= MV_CC_SetFloatValue(m_hDevHandle, "ExposureTime",ExposureTimeNum );
if(temp!=0)
return -1;
return 0;
}
//關(guān)閉相機(jī)
int MyCanera::closeCamera()
{
int nRet = MV_OK;
if (NULL == m_hDevHandle)
{
qDebug() << "沒(méi)有句柄,不用關(guān)閉";
return -1;
}
MV_CC_CloseDevice(m_hDevHandle);
nRet = MV_CC_DestroyHandle(m_hDevHandle);
m_hDevHandle = NULL;
return nRet;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "mycanera.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
MyCanera *m_pcMycamera;
MV_CC_DEVICE_INFO_LIST m_stDevList;//設(shè)備列表
string cameraName; //相機(jī)名稱
Mat imageMat; //使用OpenCV接受采集圖像
QImage cvMat2QImage(const cv::Mat& mat);
QImage image;
private slots:
void on_pushButton_link_clicked();
void on_pushButton_close_clicked();
void on_pushButton_caiji_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
minwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mycanera.h"
#include <QDebug>
#include <QImage>
#include <QImageReader>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_pcMycamera = new MyCanera;
int neRt = m_pcMycamera->EnumDevices(&m_stDevList);
qDebug() << neRt;
qDebug() << m_stDevList.pDeviceInfo[0]->nTLayerType;
//獲取相機(jī)的IP地址
if(1 == m_stDevList.pDeviceInfo[0]->nTLayerType){
int nIp1,nIp2,nIp3,nIp4;
nIp1 = ((m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24);
nIp2 = ((m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16);
nIp3 = ((m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8);
nIp4 = (m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff);
QString nIp = QString("%1.%2.%3.%4").arg(nIp1).arg(nIp2).arg(nIp3).arg(nIp4);
qDebug() << nIp;
}
}
MainWindow::~MainWindow()
{
delete ui;
}
//連接相機(jī)
void MainWindow::on_pushButton_link_clicked()
{
cameraName = (char *)m_stDevList.pDeviceInfo[0]->SpecialInfo.stGigEInfo.chUserDefinedName;
qDebug() << QString::fromStdString(cameraName);
int linkCamera = m_pcMycamera->connectCamera(cameraName);
qDebug() << linkCamera;
if(linkCamera == 0){
qDebug() << "連接相機(jī)成功";
}else {
qDebug() << "連接相機(jī)失敗";
}
//開(kāi)啟抓圖
int satrtCamera = m_pcMycamera->startCamera();
if(satrtCamera != 0){
qDebug() << "啟動(dòng)相機(jī)采集失敗";
}else {
qDebug() << "正在啟動(dòng)相機(jī)采集信息";
}
}
//關(guān)閉設(shè)備
void MainWindow::on_pushButton_close_clicked()
{
//關(guān)閉設(shè)備,釋放資源
int close = m_pcMycamera->closeCamera();
if(close != 0){
qDebug() << "相機(jī)關(guān)閉失敗";
}
}
//采集單張圖像按鈕
void MainWindow::on_pushButton_caiji_clicked()
{
//設(shè)置相機(jī)軟觸發(fā)
int softTrigger = m_pcMycamera->softTrigger();//發(fā)送軟觸發(fā)
if(softTrigger != 0){
qDebug() << "失敗";
}else {
qDebug() << "成功觸發(fā)一次";
}
//讀取相機(jī)中的圖像
int readInt = m_pcMycamera->ReadBuffer(imageMat);
if(readInt != 0){
qDebug() << "讀取圖像失敗";
}
image = cvMat2QImage(imageMat);
ui->label_image->setPixmap(QPixmap::fromImage(image));
}
//Mat轉(zhuǎn)QImage函數(shù)
QImage MainWindow::cvMat2QImage(const cv::Mat& mat)
{
// 8-bits unsigned, NO. OF CHANNELS = 1
if(mat.type() == CV_8UC1)
{
QImage qimage(mat.cols, mat.rows, QImage::Format_Indexed8);
// Set the color table (used to translate colour indexes to qRgb values)
qimage.setColorCount(256);
for(int i = 0; i < 256; i++)
{
qimage.setColor(i, qRgb(i, i, i));
}
// Copy input Mat
uchar *pSrc = mat.data;
for(int row = 0; row < mat.rows; row ++)
{
uchar *pDest = qimage.scanLine(row);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return qimage;
}
// 8-bits unsigned, NO. OF CHANNELS = 3
else if(mat.type() == CV_8UC3)
{
// Copy input Mat
const uchar *pSrc = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
else if(mat.type() == CV_8UC4)
{
// Copy input Mat
const uchar *pSrc = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
else
{
return QImage();
}
}
運(yùn)行結(jié)果:(ps:停止采集沒(méi)有用)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-716567.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-716567.html
到了這里,關(guān)于Qt+OpenCV調(diào)用??迪鄼C(jī)SDK采集圖像(C++)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!