上篇是代码之前的工作,这一篇讲解代码。
首先来看操作相机的整个接口流程:
接下来详细分析:
1.枚举设备:
注:将MV_GIGE_DEVICE和MV_USB_DEVICE设备信息保存到m_stDevList结构体中,以便后续使用。
2.创建句柄
也就是将设备信息与变量进行绑定,以后只要拿到这个句柄,就可以进行相关设备的操作:
3.打开设备:
4.开启一个线程,用于图像数据的取流操作:
4-1.新建一个线程类,其中含有对于widget的引用,便于线程窗口zhong句柄信息:
打开设备之后就开启线程:
在线程函数中,完成图像帧数据的读取操作:
void WorkThread::run()
{
MV_FRAME_OUT stImageInfo = {0};
int nRet = MV_OK;
bool f=isRun();
while(f)
{
nRet=m_widget.m_pcMyCamera->GetImageBuffer(&stImageInfo, 1000);
if (nRet == MV_OK)
{
m_widget.m_mutex.lock();
if(NULL == m_widget.m_pSaveImageBuf || stImageInfo.stFrameInfo.nFrameLen > m_widget.m_nSaveImageBufSize)
{
if(m_widget.m_pSaveImageBuf)
{
free(m_widget.m_pSaveImageBuf);
m_widget.m_pSaveImageBuf=NULL;
}
m_widget.m_pSaveImageBuf = (unsigned char *)malloc(sizeof(unsigned char) * stImageInfo.stFrameInfo.nFrameLen);
if (m_widget.m_pSaveImageBuf == NULL)
{
m_widget.m_mutex.unlock();
return;
}
m_widget.m_nSaveImageBufSize = stImageInfo.stFrameInfo.nFrameLen;
}
memcpy(m_widget.m_pSaveImageBuf, stImageInfo.pBufAddr, stImageInfo.stFrameInfo.nFrameLen);
memcpy(&m_widget.m_stImageInfo, &(stImageInfo.stFrameInfo), sizeof(MV_FRAME_OUT_INFO_EX));
m_widget.m_mutex.unlock();
auto pixmap = QPixmap::fromImage(QImage(stImageInfo.pBufAddr,stImageInfo.stFrameInfo.nWidth,stImageInfo.stFrameInfo.nHeight,QImage::Format_Indexed8));
m_widget.ui->label->setPixmap(pixmap);
m_widget.m_pcMyCamera->FreeImageBuffer(&stImageInfo);
}
else
{
if (MV_TRIGGER_MODE_ON == m_widget.m_nTriggerMode)
{
qDebug()<<__FUNCTION__;
// Sleep(5);
}
}
}
}
之后在主线程中进行取流操作:
void Widget::slot_grabbingBtn()
{
if (false == m_bOpenDevice || true == m_bStartGrabbing || NULL == m_pcMyCamera)
{
return;
}
memset(&m_stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));
m_WorkThread->SetRun(true);
m_WorkThread->start();
int nRet = m_pcMyCamera->StartGrabbing();
if (MV_OK != nRet)
{
m_WorkThread->SetRun(false);
QMessageBox::information(this,"Device","Start grabbing fail");
return;
}
m_bStartGrabbing = true;
EnableControls();
}
完成了取流操作,其他是一些基本的操作函数,先代码奉上:
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QMutex>
#include "MvCameraControl.h"
#include "MvCamera.h"
#include "workthread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
friend class WorkThread;
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void slot_searchDevice(); //查询设备
void slot_openDevice(); //打开设备
void slot_closeDevice(); //关闭设备
void slot_continusModeBtn(); //连续模式
void slot_triggerModeBtn(); //触发模式
void slot_grabbingBtn(); //开始采集
void slot_stopGrbbingBtn(); //停止采集
void slot_softwareTriggerBtn(); //软触发
void slot_softwareoOnceBtn(); //软触发一次
void slot_saveBmpBtn(); //保存Bmp图片
void slot_saveJpgBtn(); //保存Jpg图片
void slot_saveTiffBtn(); //保存Tiff图片
void slot_savePngBtn(); //保存Png图片
void slot_getParameterBtn(); //获取参数
void slot_setParameterBtn(); //设置参数
public:
int GrabThreadProcess(); //线程取流函数,用于图像显示的取流操作
int SaveImage(MV_SAVE_IAMGE_TYPE enSaveImageType); //由于图片类型不同,但是他们大部分的实现代码相同,于是定义一个公共的函数,便于操作。
int GetTriggerMode(); //获取触发模式
int SetTriggerMode(); //设置触发模式
int GetExposureTime(); //获取曝光时间
int SetExposureTime(); //设置曝光时间
int GetGain(); //获取增益
int SetGain(); //设置增益
int GetFrameRate(); //获取帧率
int SetFrameRate(); //设置帧率
int GetTriggerSource(); //获取触发源
int SetTriggerSource(); //设置触发源
//按钮使能,比如在没有打开设备之前,后续的比如采集图片之类按钮将变灰不能按下,只有满足一定条件才可以进行操作,每次在按下一个按钮的最后都将调用该函数做一个判断。
void EnableControls();
void InitUi(); //初始化界面
// ch:去除自定义的像素格式
bool RemoveCustomPixelFormats(enum MvGvspPixelType enPixelFormat);
private:
MV_CC_DEVICE_INFO_LIST m_stDevList; //保存设备信息的链表
CMvCamera* m_pcMyCamera; //用于操作相机的指针
bool m_isDeviceReady; //是否查询到设备
bool m_bOpenDevice; //是否打开设备
bool m_bSoftWareTriggerCheck; //软触发按钮是否被按下
bool m_bStartGrabbing; //是否开始抓图
int m_nDeviceCombo;
int m_nTriggerMode; //触发模式
MV_FRAME_OUT_INFO_EX m_stImageInfo; //保存一帧图像信息
unsigned char* m_pSaveImageBuf; //保存一帧图像的指针
unsigned int m_nSaveImageBufSize; //保存一帧图像的大小
int m_nTriggerSource; //触发源
WorkThread* m_WorkThread; //线程句柄,用于开启线程取流图像用
QMutex m_mutex;
double m_dExposureEdit;
double m_dGainEdit;
double m_dFrameRateEdit;
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp:
#include "widget.h"
#include "ui_widget.h"
#include<QMessageBox>
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
,m_bOpenDevice(false)
,m_nDeviceCombo(0)
,m_nTriggerMode(MV_TRIGGER_MODE_OFF)
,m_bStartGrabbing(false)
,m_pcMyCamera(NULL)
,m_pSaveImageBuf(NULL)
,m_nSaveImageBufSize(0)
,m_bSoftWareTriggerCheck(false)
, m_nTriggerSource(MV_TRIGGER_SOURCE_SOFTWARE)
,m_dExposureEdit(0)
,m_dGainEdit(0)
,m_dFrameRateEdit(0)
,m_isDeviceReady(false)
{
m_WorkThread=new WorkThread(*this);
ui->setupUi(this);
InitUi();
connect(ui->searchDeviceBtn ,SIGNAL(clicked()),this,SLOT(slot_searchDevice()));
connect(ui->openDeviceBtn ,SIGNAL(clicked()),this,SLOT(slot_openDevice()));
connect(ui->closeDeviceBtn ,SIGNAL(clicked()),this,SLOT(slot_closeDevice()));
connect(ui->continusModeBtn ,SIGNAL(clicked()),this,SLOT(slot_continusModeBtn()));
connect(ui->triggerModeBtn ,SIGNAL(clicked()),this,SLOT(slot_triggerModeBtn()));
connect(ui->startGrabBtn ,SIGNAL(clicked()),this,SLOT(slot_grabbingBtn()));
connect(ui->softwareTriggerBtn,SIGNAL(stateChanged(int)),this,SLOT(slot_softwareTriggerBtn()));
connect(ui->softwareOnceBtn ,SIGNAL(clicked()),this,SLOT(slot_softwareoOnceBtn()));
connect(ui->saveBmpBtn ,SIGNAL(clicked()),this,SLOT(slot_saveBmpBtn()));
connect(ui->saveJpgBtn ,SIGNAL(clicked()),this,SLOT(slot_saveJpgBtn()));
connect(ui->saveTiffBtn ,SIGNAL(clicked()),this,SLOT(slot_saveTiffBtn()));
connect(ui->savePngBtn ,SIGNAL(clicked()),this,SLOT(slot_savePngBtn()));
connect(ui->GetParamterBtn ,SIGNAL(clicked()),this,SLOT(slot_getParameterBtn()));
connect(ui->SetParameterBtn ,SIGNAL(clicked()),this,SLOT(slot_setParameterBtn()));
connect(ui->stopGrabBtn ,SIGNAL(clicked()),this,SLOT(slot_stopGrbbingBtn()));
}
void Widget::slot_setParameterBtn()
{
bool bIsSetSucceed = true;
int nRet = SetExposureTime();
if (nRet != MV_OK)
{
bIsSetSucceed = false;
QMessageBox::critical(this,"Exposure","Set Exposure Time Fail");
}
nRet = SetGain();
if (nRet != MV_OK)
{
bIsSetSucceed = false;
QMessageBox::critical(this,"Gain","Set Gain Fail");
}
nRet = SetFrameRate();
if (nRet != MV_OK)
{
bIsSetSucceed = false;
QMessageBox::critical(this,"Frame","Set Frame Rate Fail");
}
if (true == bIsSetSucceed)
{
QMessageBox::critical(this,"Parameter","Set Parameter Succeed");
}
}
void Widget::slot_stopGrbbingBtn()
{
if (false == m_bOpenDevice || false == m_bStartGrabbing || NULL == m_pcMyCamera)
{
return;
}
m_WorkThread->SetRun(false);
bool f=m_WorkThread->isRun();
if(f)
{
m_WorkThread->quit();
m_WorkThread->wait();
m_WorkThread=NULL;
}
int nRet = m_pcMyCamera->StopGrabbing();
if(MV_OK != nRet)
{
QMessageBox::critical(this,"grabbing","Stop grabbing fail");
return;
}
m_bStartGrabbing = false;
}
int Widget::SetTriggerSource()
{
int nRet = MV_OK;
m_bSoftWareTriggerCheck=ui->softwareTriggerBtn->isChecked();
if (m_bSoftWareTriggerCheck)
{
m_nTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
nRet = m_pcMyCamera->SetEnumValue("TriggerSource", m_nTriggerSource);
if (MV_OK != nRet)
{
QMessageBox::critical(this,"Trigger","Set Software Trigger Fail");
return nRet;
}
// GetDlgItem(IDC_SOFTWARE_ONCE_BUTTON )->EnableWindow(TRUE);
}
else
{
m_nTriggerSource = MV_TRIGGER_SOURCE_LINE0;
nRet = m_pcMyCamera->SetEnumValue("TriggerSource", m_nTriggerSource);
if (MV_OK != nRet)
{
QMessageBox::critical(this,"Hardware","Set Hardware Trigger Fail");
return nRet;
}
//GetDlgItem(IDC_SOFTWARE_ONCE_BUTTON )->EnableWindow(FALSE);
}
return nRet;
}
int Widget::SetFrameRate()
{
int nRet = m_pcMyCamera->SetBoolValue("AcquisitionFrameRateEnable", true);
if (MV_OK != nRet)
{
return nRet;
}
return m_pcMyCamera->SetFloatValue("AcquisitionFrameRate", (float)m_dFrameRateEdit);
}
int Widget::SetGain()
{
// ch:设置增益前先把自动增益关闭,失败无需返回
//en:Set Gain after Auto Gain is turned off, this failure does not need to return
m_pcMyCamera->SetEnumValue("GainAuto", 0);
return m_pcMyCamera->SetFloatValue("Gain", (float)m_dGainEdit);
}
int Widget::SetExposureTime()
{
// ch:调节这两个曝光模式,才能让曝光时间生效
// en:Adjust these two exposure mode to allow exposure time effective
int nRet = m_pcMyCamera->SetEnumValue("ExposureMode", MV_EXPOSURE_MODE_TIMED);
if (MV_OK != nRet)
{
return nRet;
}
m_pcMyCamera->SetEnumValue("ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF);
return m_pcMyCamera->SetFloatValue("ExposureTime", (float)m_dExposureEdit);
}
int Widget::SetTriggerMode()
{
return m_pcMyCamera->SetEnumValue("TriggerMode", m_nTriggerMode);
}
void Widget::slot_getParameterBtn()
{
int nRet = GetTriggerMode();
if (nRet != MV_OK)
{
QMessageBox::critical(this,"Mode","Get Trigger Mode Fail");
}
nRet = GetExposureTime();
if (nRet != MV_OK)
{
QMessageBox::critical(this,"Mode","Get Exposure Time Fail");
}
ui->ExposureLineEdit->setText(QString("%1").arg(m_dExposureEdit));
nRet = GetGain();
if (nRet != MV_OK)
{
QMessageBox::critical(this,"Gain","Get Gain Fail");
}
ui->GainLineEdit->setText(QString("%1").arg(m_dGainEdit));
nRet = GetFrameRate();
if (nRet != MV_OK)
{
QMessageBox::critical(this,"Frame","Get Frame Rate Fail");
}
ui->FrameRateLineEdit->setText(QString("%1").arg(m_dFrameRateEdit));
nRet = GetTriggerSource();
if (nRet != MV_OK)
{
QMessageBox::critical(this,"Trigger","Get Trigger Source Fail");
}
}
int Widget::GetTriggerSource()
{
MVCC_ENUMVALUE stEnumValue = {0};
int nRet = m_pcMyCamera->GetEnumValue("TriggerSource", &stEnumValue);
if (MV_OK != nRet)
{
return nRet;
}
if ((unsigned int)MV_TRIGGER_SOURCE_SOFTWARE == stEnumValue.nCurValue)
{
m_bSoftWareTriggerCheck = true;
}
else
{
m_bSoftWareTriggerCheck = false;
}
return MV_OK;
}
int Widget::GetGain()
{
MVCC_FLOATVALUE stFloatValue = {0};
int nRet = m_pcMyCamera->GetFloatValue("Gain", &stFloatValue);
if (MV_OK != nRet)
{
return nRet;
}
m_dGainEdit = stFloatValue.fCurValue;
return MV_OK;
}
int Widget::GetFrameRate()
{
MVCC_FLOATVALUE stFloatValue = {0};
int nRet = m_pcMyCamera->GetFloatValue("ResultingFrameRate", &stFloatValue);
if (MV_OK != nRet)
{
return nRet;
}
m_dFrameRateEdit = stFloatValue.fCurValue;
return MV_OK;
}
int Widget::GetTriggerMode()
{
MVCC_ENUMVALUE stEnumValue = {0};
int nRet = m_pcMyCamera->GetEnumValue("TriggerMode", &stEnumValue);
if(MV_OK != nRet)
{
return nRet;
}
m_nTriggerMode = stEnumValue.nCurValue;
EnableControls();
return MV_OK;
}
int Widget::GetExposureTime()
{
MVCC_FLOATVALUE stFloatValue = {0};
int nRet = m_pcMyCamera->GetFloatValue("ExposureTime", &stFloatValue);
if(MV_OK != nRet)
{
return nRet;
}
m_dExposureEdit = stFloatValue.fCurValue;
return MV_OK;
}
void Widget::slot_savePngBtn()
{
int nRet = SaveImage(MV_Image_Png);
if (MV_OK != nRet)
{
QMessageBox::critical(this,"picture","Save Png fail");
return;
}
QMessageBox::critical(this,"picture","Save Png succeed!");
}
void Widget::slot_saveTiffBtn()
{
int nRet = SaveImage(MV_Image_Tif);
if (MV_OK != nRet)
{
QMessageBox::critical(this,"picture","Save jpg fail");
return;
}
QMessageBox::critical(this,"picture","Save jpg succeed!");
}
void Widget::slot_saveJpgBtn()
{
int nRet = SaveImage(MV_Image_Jpeg);
if (MV_OK != nRet)
{
QMessageBox::critical(this,"picture","Save jpg fail");
return;
}
QMessageBox::critical(this,"picture","Save jpg succeed!");
}
int Widget::SaveImage(MV_SAVE_IAMGE_TYPE enSaveImageType)
{
MV_SAVE_IMG_TO_FILE_PARAM stSaveFileParam;
memset(&stSaveFileParam, 0, sizeof(MV_SAVE_IMG_TO_FILE_PARAM));
m_mutex.lock();
if (m_pSaveImageBuf == NULL || m_stImageInfo.enPixelType == 0)
{
m_mutex.unlock();
return MV_E_NODATA;
}
if(RemoveCustomPixelFormats(m_stImageInfo.enPixelType))
{
m_mutex.unlock();
return MV_E_SUPPORT;
}
stSaveFileParam.enImageType = enSaveImageType; // ch:需要保存的图像类型 | en:Image format to save
stSaveFileParam.enPixelType = m_stImageInfo.enPixelType; // ch:相机对应的像素格式 | en:Camera pixel type
stSaveFileParam.nWidth = m_stImageInfo.nWidth; // ch:相机对应的宽 | en:Width
stSaveFileParam.nHeight = m_stImageInfo.nHeight; // ch:相机对应的高 | en:Height
stSaveFileParam.nDataLen = m_stImageInfo.nFrameLen;
stSaveFileParam.pData = m_pSaveImageBuf;
stSaveFileParam.iMethodValue = 0;
// ch:jpg图像质量范围为(50-99], png图像质量范围为[0-9] | en:jpg image nQuality range is (50-99], png image nQuality range is [0-9]
if (MV_Image_Bmp == stSaveFileParam.enImageType)
{
sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.bmp", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_stImageInfo.nFrameNum);
}
else if (MV_Image_Jpeg == stSaveFileParam.enImageType)
{
stSaveFileParam.nQuality = 80;
sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.jpg", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_stImageInfo.nFrameNum);
}
else if (MV_Image_Tif == stSaveFileParam.enImageType)
{
sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.tif", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_stImageInfo.nFrameNum);
}
else if (MV_Image_Png == stSaveFileParam.enImageType)
{
stSaveFileParam.nQuality = 8;
sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.png", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_stImageInfo.nFrameNum);
}
int nRet = m_pcMyCamera->SaveImageToFile(&stSaveFileParam);
m_mutex.unlock();
return nRet;
}
void Widget::slot_saveBmpBtn()
{
int nRet = SaveImage(MV_Image_Bmp);
if (MV_OK != nRet)
{
QMessageBox::critical(this,"picture","Save bmp fail");
return;
}
QMessageBox::critical(this,"picture","Save bmp succeed!");
}
void Widget::slot_closeDevice()
{
bool f=m_WorkThread->isRun();
if (f)
{
m_WorkThread->quit();
m_WorkThread->wait();
m_WorkThread->SetRun(false);
}
if(m_pcMyCamera)
{
m_pcMyCamera->Close();
delete m_pcMyCamera;
m_pcMyCamera = NULL;
}
m_bStartGrabbing=false;
m_bOpenDevice = false;
if(m_pSaveImageBuf)
{
free(m_pSaveImageBuf);
m_pSaveImageBuf=NULL;
}
m_nSaveImageBufSize=0;
EnableControls();
}
void Widget::slot_continusModeBtn()
{
m_nTriggerMode = MV_TRIGGER_MODE_OFF;
m_pcMyCamera->SetEnumValue("TriggerMode", m_nTriggerMode);
EnableControls();
}
void Widget::slot_triggerModeBtn()
{
m_nTriggerMode = MV_TRIGGER_MODE_ON;
m_pcMyCamera->SetEnumValue("TriggerMode", m_nTriggerMode);
EnableControls();
}
void Widget::slot_grabbingBtn()
{
if (false == m_bOpenDevice || true == m_bStartGrabbing || NULL == m_pcMyCamera)
{
return;
}
memset(&m_stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));
m_WorkThread->SetRun(true);
m_WorkThread->start();
int nRet = m_pcMyCamera->StartGrabbing();
if (MV_OK != nRet)
{
m_WorkThread->SetRun(false);
QMessageBox::information(this,"Device","Start grabbing fail");
return;
}
m_bStartGrabbing = true;
EnableControls();
}
void Widget::slot_softwareTriggerBtn()
{
int nRet = MV_OK;
m_bSoftWareTriggerCheck=ui->softwareTriggerBtn->isChecked();
if (m_bSoftWareTriggerCheck)
{
m_nTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
nRet = m_pcMyCamera->SetEnumValue("TriggerSource", m_nTriggerSource);
if (MV_OK != nRet)
{
QMessageBox::information(this,"Device","Set Software Trigger Fail");
return;
}
}
else
{
m_nTriggerSource = MV_TRIGGER_SOURCE_LINE0;
nRet = m_pcMyCamera->SetEnumValue("TriggerSource", m_nTriggerSource);
if (MV_OK != nRet)
{
QMessageBox::information(this,"Device","Set Hardware Trigger Fail");
return;
}
}
EnableControls();
return;
}
void Widget::slot_softwareoOnceBtn()
{
if(true != m_bStartGrabbing)
{
return;
}
m_pcMyCamera->CommandExecute("TriggerSoftware");
}
void Widget::InitUi()
{
memset(&m_stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));
m_WorkThread->SetRun(false);
EnableControls();
}
void Widget::EnableControls()
{
//如果查询到设备,开启打开设备按钮
ui->openDeviceBtn->setEnabled(m_isDeviceReady?true:false);
ui->closeDeviceBtn->setEnabled(m_bOpenDevice?true:false);
ui->continusModeBtn->setEnabled(m_bOpenDevice?true:false);
ui->triggerModeBtn->setEnabled(m_bOpenDevice?true:false);
ui->startGrabBtn->setEnabled(m_bOpenDevice?true:false);
ui->stopGrabBtn->setEnabled(m_bOpenDevice?true:false);
//首先是否是在采集图像中,在采集图像的过程中,判断是否为触发模式,只有在触发模式下,才能开启软触发按钮。
ui->softwareTriggerBtn->setEnabled(m_bStartGrabbing?((MV_TRIGGER_MODE_ON == m_nTriggerMode)?true:false):false);
ui->softwareOnceBtn->setEnabled(
(MV_TRIGGER_MODE_OFF == m_nTriggerMode) ? false:
(m_bSoftWareTriggerCheck?true:false) );
ui->saveBmpBtn->setEnabled(m_bStartGrabbing?true:false);
ui->saveJpgBtn->setEnabled(m_bStartGrabbing?true:false);
ui->saveTiffBtn->setEnabled(m_bStartGrabbing?true:false);
ui->savePngBtn->setEnabled(m_bStartGrabbing?true:false);
ui->GetParamterBtn->setEnabled(m_bOpenDevice?true:false);
ui->SetParameterBtn ->setEnabled(m_bOpenDevice?true:false);
ui->ExposureLineEdit->setEnabled(m_bOpenDevice?true:false);
ui->GainLineEdit->setEnabled(m_bOpenDevice?true:false);
ui->FrameRateLineEdit->setEnabled(m_bOpenDevice?true:false);
}
bool Widget::RemoveCustomPixelFormats(MvGvspPixelType enPixelFormat)
{
int nResult = enPixelFormat & MV_GVSP_PIX_CUSTOM;
if(MV_GVSP_PIX_CUSTOM == nResult)
{
return true;
}
else
{
return false;
}
}
void Widget::slot_openDevice()
{
if (true == m_bOpenDevice || NULL != m_pcMyCamera)
{
return;
}
int nIndex = m_nDeviceCombo;
if ((nIndex < 0) | (nIndex >= MV_MAX_DEVICE_NUM))
{
QMessageBox::critical(this,"Device","Device index is error!");
return;
}
// ch:由设备信息创建设备实例 | en:Device instance created by device information
if (NULL == m_stDevList.pDeviceInfo[nIndex])
{
QMessageBox::critical(this,"Device","Device does not exist!");
return;
}
m_pcMyCamera = new CMvCamera;
if (NULL == m_pcMyCamera)
{
return;
}
int nRet = m_pcMyCamera->Open(m_stDevList.pDeviceInfo[nIndex]);
if (MV_OK != nRet)
{
delete m_pcMyCamera;
m_pcMyCamera = NULL;
QMessageBox::critical(this,"Device","Device Open error!");
return;
}
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
if (m_stDevList.pDeviceInfo[nIndex]->nTLayerType == MV_GIGE_DEVICE)
{
unsigned int nPacketSize = 0;
nRet = m_pcMyCamera->GetOptimalPacketSize(&nPacketSize);
if (nRet == MV_OK)
{
nRet = m_pcMyCamera->SetIntValue("GevSCPSPacketSize",nPacketSize);
if(nRet != MV_OK)
{
QMessageBox::critical(this,"Device","Warning: Set Packet Size fail!");
}
}
else
{
QMessageBox::critical(this,"Device","Warning: Get Packet Size fail!");
}
}
m_bOpenDevice = true;
EnableControls();
slot_getParameterBtn();
}
void Widget::slot_searchDevice()
{
QString strMsg;
ui->comboBox->clear();
memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
//ch:枚举子网内所有设备,将查询到的设备信息保存到m_stDevList列表中。
int nRet = CMvCamera::EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &m_stDevList);
if (MV_OK != nRet)
{
QMessageBox::critical(this,"device","No device!");
return;
}
// ch:将值加入到信息列表框中并显示出来 | en:Add value to the information list box and display
for (unsigned int i = 0; i < m_stDevList.nDeviceNum; i++)
{
MV_CC_DEVICE_INFO* pDeviceInfo = m_stDevList.pDeviceInfo[i];
if (NULL == pDeviceInfo)
{
continue;
}
if (pDeviceInfo->nTLayerType == MV_GIGE_DEVICE)
{
int nIp1 = ((m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24);
int nIp2 = ((m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16);
int nIp3 = ((m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8);
int nIp4 = (m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff);
char strUserName[256] = {0};
sprintf_s(strUserName, 256, "%s %s (%s)", pDeviceInfo->SpecialInfo.stGigEInfo.chManufacturerName,
pDeviceInfo->SpecialInfo.stGigEInfo.chModelName,
pDeviceInfo->SpecialInfo.stGigEInfo.chSerialNumber);
QString UserName(strUserName);
strMsg= QString("[%1]GigE: %2 %3.%4.%5.%6")
.arg( QString::number(i)).
arg(strUserName).
arg(QString::number(nIp1)).
arg(QString::number(nIp2)).
arg(QString::number(nIp3)).
arg( QString::number(nIp4));
ui->comboBox->addItem(strMsg);
}
}
if (0 == m_stDevList.nDeviceNum)
{
QMessageBox::critical(this,"device","No device!");
return;
}
ui->comboBox->setCurrentIndex(0);
m_isDeviceReady=true; //设备已经打开
EnableControls();
}
Widget::~Widget()
{
delete ui;
slot_closeDevice();
}
workthread.h:
#ifndef WORKTHREAD_H
#define WORKTHREAD_H
#include <QThread>
class Widget;
class WorkThread : public QThread
{
public:
explicit WorkThread(Widget&m_widget_,QObject *parent = nullptr);
void run();
bool isRun();
void SetRun(bool f);
private:
Widget& m_widget;
bool runflag_;
};
#endif // WORKTHREAD_H
workthread.cpp:
#include "workthread.h"
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
WorkThread::WorkThread(Widget&m_widget_,QObject *parent)
: QThread{parent}
,m_widget(m_widget_)
,runflag_(false)
{
}
bool WorkThread::isRun()
{
return runflag_;
}
void WorkThread::SetRun(bool f)
{
runflag_=f;
}
void WorkThread::run()
{
MV_FRAME_OUT stImageInfo = {0};
int nRet = MV_OK;
bool f=isRun();
while(f)
{
nRet=m_widget.m_pcMyCamera->GetImageBuffer(&stImageInfo, 1000);
if (nRet == MV_OK)
{
m_widget.m_mutex.lock();
if(NULL == m_widget.m_pSaveImageBuf || stImageInfo.stFrameInfo.nFrameLen > m_widget.m_nSaveImageBufSize)
{
if(m_widget.m_pSaveImageBuf)
{
free(m_widget.m_pSaveImageBuf);
m_widget.m_pSaveImageBuf=NULL;
}
m_widget.m_pSaveImageBuf = (unsigned char *)malloc(sizeof(unsigned char) * stImageInfo.stFrameInfo.nFrameLen);
if (m_widget.m_pSaveImageBuf == NULL)
{
m_widget.m_mutex.unlock();
return;
}
m_widget.m_nSaveImageBufSize = stImageInfo.stFrameInfo.nFrameLen;
}
memcpy(m_widget.m_pSaveImageBuf, stImageInfo.pBufAddr, stImageInfo.stFrameInfo.nFrameLen);
memcpy(&m_widget.m_stImageInfo, &(stImageInfo.stFrameInfo), sizeof(MV_FRAME_OUT_INFO_EX));
m_widget.m_mutex.unlock();
auto pixmap = QPixmap::fromImage(QImage(stImageInfo.pBufAddr,stImageInfo.stFrameInfo.nWidth,stImageInfo.stFrameInfo.nHeight,QImage::Format_Indexed8));
m_widget.ui->label->setPixmap(pixmap);
m_widget.m_pcMyCamera->FreeImageBuffer(&stImageInfo);
}
else
{
if (MV_TRIGGER_MODE_ON == m_widget.m_nTriggerMode)
{
qDebug()<<__FUNCTION__;
// Sleep(5);
}
}
}
}
ui_widget.h:
/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 5.15.1
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_WIDGET_H
#define UI_WIDGET_H
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QRadioButton>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_Widget
{
public:
QPushButton *searchDeviceBtn;
QPushButton *openDeviceBtn;
QPushButton *closeDeviceBtn;
QGroupBox *init_groupbox;
QGroupBox *savepicture_groupbox;
QPushButton *saveBmpBtn;
QPushButton *saveJpgBtn;
QPushButton *saveTiffBtn;
QPushButton *savePngBtn;
QPushButton *startGrabBtn;
QRadioButton *continusModeBtn;
QRadioButton *triggerModeBtn;
QPushButton *stopGrabBtn;
QCheckBox *softwareTriggerBtn;
QPushButton *softwareOnceBtn;
QGroupBox *grabpicture_groupbox;
QLabel *Exposure;
QLabel *Gain;
QLabel *GrabRate;
QLineEdit *ExposureLineEdit;
QLineEdit *GainLineEdit;
QLineEdit *FrameRateLineEdit;
QPushButton *GetParamterBtn;
QPushButton *SetParameterBtn;
QGroupBox *parameter_groupbox;
QWidget *layoutWidget;
QVBoxLayout *verticalLayout;
QComboBox *comboBox;
QLabel *label;
void setupUi(QWidget *Widget)
{
if (Widget->objectName().isEmpty())
Widget->setObjectName(QString::fromUtf8("Widget"));
Widget->resize(1028, 679);
searchDeviceBtn = new QPushButton(Widget);
searchDeviceBtn->setObjectName(QString::fromUtf8("searchDeviceBtn"));
searchDeviceBtn->setGeometry(QRect(760, 30, 191, 29));
openDeviceBtn = new QPushButton(Widget);
openDeviceBtn->setObjectName(QString::fromUtf8("openDeviceBtn"));
openDeviceBtn->setGeometry(QRect(760, 70, 93, 29));
closeDeviceBtn = new QPushButton(Widget);
closeDeviceBtn->setObjectName(QString::fromUtf8("closeDeviceBtn"));
closeDeviceBtn->setGeometry(QRect(860, 70, 93, 29));
init_groupbox = new QGroupBox(Widget);
init_groupbox->setObjectName(QString::fromUtf8("init_groupbox"));
init_groupbox->setGeometry(QRect(710, 10, 281, 101));
savepicture_groupbox = new QGroupBox(Widget);
savepicture_groupbox->setObjectName(QString::fromUtf8("savepicture_groupbox"));
savepicture_groupbox->setGeometry(QRect(710, 300, 281, 141));
saveBmpBtn = new QPushButton(savepicture_groupbox);
saveBmpBtn->setObjectName(QString::fromUtf8("saveBmpBtn"));
saveBmpBtn->setGeometry(QRect(10, 30, 93, 29));
saveJpgBtn = new QPushButton(savepicture_groupbox);
saveJpgBtn->setObjectName(QString::fromUtf8("saveJpgBtn"));
saveJpgBtn->setGeometry(QRect(140, 30, 93, 29));
saveTiffBtn = new QPushButton(savepicture_groupbox);
saveTiffBtn->setObjectName(QString::fromUtf8("saveTiffBtn"));
saveTiffBtn->setGeometry(QRect(10, 80, 93, 29));
savePngBtn = new QPushButton(savepicture_groupbox);
savePngBtn->setObjectName(QString::fromUtf8("savePngBtn"));
savePngBtn->setGeometry(QRect(140, 80, 93, 29));
startGrabBtn = new QPushButton(Widget);
startGrabBtn->setObjectName(QString::fromUtf8("startGrabBtn"));
startGrabBtn->setGeometry(QRect(730, 180, 111, 25));
startGrabBtn->setCheckable(false);
continusModeBtn = new QRadioButton(Widget);
continusModeBtn->setObjectName(QString::fromUtf8("continusModeBtn"));
continusModeBtn->setGeometry(QRect(740, 130, 118, 24));
triggerModeBtn = new QRadioButton(Widget);
triggerModeBtn->setObjectName(QString::fromUtf8("triggerModeBtn"));
triggerModeBtn->setGeometry(QRect(850, 130, 118, 24));
stopGrabBtn = new QPushButton(Widget);
stopGrabBtn->setObjectName(QString::fromUtf8("stopGrabBtn"));
stopGrabBtn->setGeometry(QRect(850, 180, 111, 25));
softwareTriggerBtn = new QCheckBox(Widget);
softwareTriggerBtn->setObjectName(QString::fromUtf8("softwareTriggerBtn"));
softwareTriggerBtn->setGeometry(QRect(750, 230, 71, 24));
softwareOnceBtn = new QPushButton(Widget);
softwareOnceBtn->setObjectName(QString::fromUtf8("softwareOnceBtn"));
softwareOnceBtn->setGeometry(QRect(860, 230, 93, 29));
grabpicture_groupbox = new QGroupBox(Widget);
grabpicture_groupbox->setObjectName(QString::fromUtf8("grabpicture_groupbox"));
grabpicture_groupbox->setGeometry(QRect(710, 110, 281, 181));
Exposure = new QLabel(Widget);
Exposure->setObjectName(QString::fromUtf8("Exposure"));
Exposure->setGeometry(QRect(750, 470, 69, 20));
Gain = new QLabel(Widget);
Gain->setObjectName(QString::fromUtf8("Gain"));
Gain->setGeometry(QRect(750, 510, 69, 20));
GrabRate = new QLabel(Widget);
GrabRate->setObjectName(QString::fromUtf8("GrabRate"));
GrabRate->setGeometry(QRect(750, 550, 69, 20));
ExposureLineEdit = new QLineEdit(Widget);
ExposureLineEdit->setObjectName(QString::fromUtf8("ExposureLineEdit"));
ExposureLineEdit->setGeometry(QRect(830, 470, 113, 25));
GainLineEdit = new QLineEdit(Widget);
GainLineEdit->setObjectName(QString::fromUtf8("GainLineEdit"));
GainLineEdit->setGeometry(QRect(830, 510, 113, 25));
FrameRateLineEdit = new QLineEdit(Widget);
FrameRateLineEdit->setObjectName(QString::fromUtf8("FrameRateLineEdit"));
FrameRateLineEdit->setGeometry(QRect(830, 550, 113, 25));
GetParamterBtn = new QPushButton(Widget);
GetParamterBtn->setObjectName(QString::fromUtf8("GetParamterBtn"));
GetParamterBtn->setGeometry(QRect(750, 600, 93, 29));
SetParameterBtn = new QPushButton(Widget);
SetParameterBtn->setObjectName(QString::fromUtf8("SetParameterBtn"));
SetParameterBtn->setGeometry(QRect(850, 600, 93, 29));
parameter_groupbox = new QGroupBox(Widget);
parameter_groupbox->setObjectName(QString::fromUtf8("parameter_groupbox"));
parameter_groupbox->setGeometry(QRect(710, 450, 281, 201));
layoutWidget = new QWidget(Widget);
layoutWidget->setObjectName(QString::fromUtf8("layoutWidget"));
layoutWidget->setGeometry(QRect(10, 10, 661, 651));
verticalLayout = new QVBoxLayout(layoutWidget);
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
verticalLayout->setContentsMargins(0, 0, 0, 0);
comboBox = new QComboBox(layoutWidget);
comboBox->setObjectName(QString::fromUtf8("comboBox"));
verticalLayout->addWidget(comboBox);
label = new QLabel(layoutWidget);
label->setObjectName(QString::fromUtf8("label"));
verticalLayout->addWidget(label);
parameter_groupbox->raise();
init_groupbox->raise();
grabpicture_groupbox->raise();
searchDeviceBtn->raise();
openDeviceBtn->raise();
closeDeviceBtn->raise();
savepicture_groupbox->raise();
startGrabBtn->raise();
continusModeBtn->raise();
triggerModeBtn->raise();
stopGrabBtn->raise();
softwareTriggerBtn->raise();
softwareOnceBtn->raise();
Exposure->raise();
Gain->raise();
GrabRate->raise();
ExposureLineEdit->raise();
GainLineEdit->raise();
FrameRateLineEdit->raise();
GetParamterBtn->raise();
SetParameterBtn->raise();
layoutWidget->raise();
retranslateUi(Widget);
QMetaObject::connectSlotsByName(Widget);
} // setupUi
void retranslateUi(QWidget *Widget)
{
Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
searchDeviceBtn->setText(QCoreApplication::translate("Widget", "\346\237\245\350\257\242\350\256\276\345\244\207", nullptr));
openDeviceBtn->setText(QCoreApplication::translate("Widget", "\346\211\223\345\274\200\350\256\276\345\244\207", nullptr));
closeDeviceBtn->setText(QCoreApplication::translate("Widget", "\345\205\263\351\227\255\350\256\276\345\244\207", nullptr));
init_groupbox->setTitle(QCoreApplication::translate("Widget", "\345\210\235\345\247\213\345\214\226", nullptr));
savepicture_groupbox->setTitle(QCoreApplication::translate("Widget", "\345\233\276\347\211\207\344\277\235\345\255\230", nullptr));
saveBmpBtn->setText(QCoreApplication::translate("Widget", "\344\277\235\345\255\230BMP", nullptr));
saveJpgBtn->setText(QCoreApplication::translate("Widget", "\344\277\235\345\255\230JPG", nullptr));
saveTiffBtn->setText(QCoreApplication::translate("Widget", "\344\277\235\345\255\230tiff", nullptr));
savePngBtn->setText(QCoreApplication::translate("Widget", "\344\277\235\345\255\230PNG", nullptr));
startGrabBtn->setText(QCoreApplication::translate("Widget", "\345\274\200\345\247\213\351\207\207\351\233\206", nullptr));
continusModeBtn->setText(QCoreApplication::translate("Widget", "\350\277\236\347\273\255\346\250\241\345\274\217", nullptr));
triggerModeBtn->setText(QCoreApplication::translate("Widget", "\350\247\246\345\217\221\346\250\241\345\274\217", nullptr));
stopGrabBtn->setText(QCoreApplication::translate("Widget", "\345\201\234\346\255\242\351\207\207\351\233\206", nullptr));
softwareTriggerBtn->setText(QCoreApplication::translate("Widget", "\350\275\257\350\247\246\345\217\221", nullptr));
softwareOnceBtn->setText(QCoreApplication::translate("Widget", "\350\275\257\350\247\246\345\217\221\344\270\200\346\254\241", nullptr));
grabpicture_groupbox->setTitle(QCoreApplication::translate("Widget", "\345\233\276\345\203\217\351\207\207\351\233\206", nullptr));
Exposure->setText(QCoreApplication::translate("Widget", "\346\233\235\345\205\211", nullptr));
Gain->setText(QCoreApplication::translate("Widget", "\345\242\236\347\233\212", nullptr));
GrabRate->setText(QCoreApplication::translate("Widget", "\345\270\247\347\216\207", nullptr));
ExposureLineEdit->setText(QCoreApplication::translate("Widget", "0", nullptr));
GainLineEdit->setText(QCoreApplication::translate("Widget", "0", nullptr));
FrameRateLineEdit->setText(QCoreApplication::translate("Widget", "0", nullptr));
GetParamterBtn->setText(QCoreApplication::translate("Widget", "\345\217\202\346\225\260\350\216\267\345\217\226", nullptr));
SetParameterBtn->setText(QCoreApplication::translate("Widget", "\345\217\202\346\225\260\350\256\276\347\275\256", nullptr));
parameter_groupbox->setTitle(QCoreApplication::translate("Widget", "\345\217\202\346\225\260", nullptr));
label->setText(QString());
} // retranslateUi
};
namespace Ui {
class Widget: public Ui_Widget {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_WIDGET_H
ui设计器中的效果如下: