继上篇文章:https://www.cnblogs.com/ivint/p/14200731.html (稍作改动。。。)
1、在子线程中实现先由硬件触发再转换成软件触发3次
子线程代码:
//回调函数
void GrabImgThread::getCameraImageCallback(unsigned char *pData, MV_FRAME_OUT_INFO_EX *stImageInfo, void *arg)
(void)(stImageInfo);
GrabImgThread *tmp = (GrabImgThread *)arg;
memcpy(tmp->mpData,pData,tmp->nDataSize);
qDebug() << "getCameraImageCallback回调函数执行了";
tmp->displayCameraImage(); //刷新图像
if(tmp->i ==4){ tmp->i = 0;} //将i清零
//初始化相机
int GrabImgThread::initCamera()
int nRet = -1;
MV_CC_DEVICE_INFO_LIST stDeviceList;
memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
// 枚举相机设备
nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);
if (MV_OK != nRet)
qDebug()<<"MV_CC_EnumDevices fail!";
return -1;
unsigned int nIndex = 0;
MV_CC_DEVICE_INFO* pDeviceInfo;
if (stDeviceList.nDeviceNum > 0)
for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++)
qDebug() <<QString("[device %1]").arg(i);
pDeviceInfo = stDeviceList.pDeviceInfo[i];
if (NULL == pDeviceInfo)
break;
qDebug()<<"Find No Devices!";
return -1;
pDeviceInfo = stDeviceList.pDeviceInfo[0];
//打印相机型号及序列号
qDebug() << QString::fromLocal8Bit(reinterpret_cast<char*>(pDeviceInfo->SpecialInfo.stGigEInfo.chModelName));
qDebug() << QString::fromLocal8Bit(reinterpret_cast<char*>(pDeviceInfo->SpecialInfo.stGigEInfo.chSerialNumber));
//彩色相机判别
if('C' == pDeviceInfo->SpecialInfo.stGigEInfo.chModelName[12])
m_isColor = true;
qDebug() << "==============color=================";
// 选择当前设备创建句柄
nRet = MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[nIndex]);
if (MV_OK != nRet)
qDebug()<<"MV_CC_CreateHandle fail!";
return -1;
// 打开设备
nRet = MV_CC_OpenDevice(handle);
if (MV_OK != nRet)
qDebug()<<"MV_CC_OpenDevice fail!";
return -1;
//获取图像的宽度和高度
MVCC_INTVALUE ptValue;
// int w,h;
MV_CC_GetWidth(handle, &ptValue);
m_imageWidth = ptValue.nCurValue;
MV_CC_GetHeight(handle, &ptValue);
m_imageHeight = ptValue.nCurValue;
if(m_isColor)
nDataSize = m_imageWidth * m_imageHeight * 3;
nDataSize = m_imageWidth * m_imageHeight;
//设置硬触发模式
nRet = MV_CC_SetEnumValue(handle, "TriggerMode", 1);
nRet = MV_CC_SetEnumValue(handle, "TriggerSource", 0);
mpData = (unsigned char *)malloc(nDataSize); //获取一帧图像的内存大小
return 1;
//显示图像函数
int GrabImgThread::displayCameraImage()
image = QImage((uchar*)mpData,m_imageWidth,m_imageHeight,QImage::Format_RGB888);
// ui->lb_image->setPixmap(QPixmap::fromImage(image).scaled(560,420));
qDebug() << "发送图像:" << i << image;
emit doneFinsh(image);
//qDebug() << "displayCameraImage发送完信号执行了";
//获取Enum型参数:获取触发模式
MVCC_ENUMVALUE struEnumValue = {0};
int nRet = MV_CC_GetEnumValue(handle, "TriggerSource", &struEnumValue);
qDebug() << "134行:" << struEnumValue.nCurValue;
//判断是否为硬触发
if(0 == struEnumValue.nCurValue){
QThread::msleep(5);
// nRet = MV_CC_StopGrabbing(handle);//关闭采集
// if(nRet != 0){qDebug() << "StopGrabbing 失败";}
//设置为软触发
int nRet = MV_CC_SetEnumValue(handle, "TriggerMode", 1);
nRet = MV_CC_SetEnumValue(handle, "TriggerSource", 7);
if(nRet != 0){qDebug() << "设置软触发-- 失败";}
qDebug() << "设置软触发成功";
nRet = MV_CC_GetEnumValue(handle, "TriggerSource", &struEnumValue);
qDebug() << "146行-----:" << struEnumValue.nCurValue;
//注册软触发回调函数
// int ret = MV_CC_RegisterImageCallBackForRGB(handle, GrabImgThread::softImageCallback,this);
// if(MV_OK != ret)
// qDebug() << "=======faild =========" ;
//qDebug() << nRet;
// nRet = MV_CC_StartGrabbing(handle);//开启采集
// if(nRet != 0){qDebug() << "StartGrabbing 失败";}
//qDebug() << comdValue; //0
//softBuffImg();
//延迟并发送软触发信号
i++;
if(i<4){
QThread::sleep(1);
int comdValue= MV_CC_SetCommandValue(handle, "TriggerSoftware");
if(comdValue != 0){qDebug() << "发送一次软触发命令-- 失败";}
qDebug() << "发送一次软触发命令";
//i = 0;
//qDebug() << image;
//emit doneFinsh(image);
nRet = MV_CC_GetEnumValue(handle, "TriggerSource", &struEnumValue);
if(nRet != 0){qDebug() << "获取TriggerSource 失败";}
qDebug() << "173行+++++++" << struEnumValue.nCurValue; //打印当前触发源
if(7 == struEnumValue.nCurValue){
QThread::msleep(5);
// nRet = MV_CC_StopGrabbing(handle);//关闭采集
// if(nRet != 0){qDebug() << "StopGrabbing 失败";}
//设置硬触发模式
nRet = MV_CC_SetEnumValue(handle, "TriggerMode", 1);
nRet = MV_CC_SetEnumValue(handle, "TriggerSource", 0);
if(nRet != 0){qDebug() << "软触发改为硬触发-- 失败";}
qDebug() << "软触发改为硬触发";
nRet = MV_CC_GetEnumValue(handle, "TriggerSource", &struEnumValue);
qDebug() << "184==========行:" << struEnumValue.nCurValue;
// //step2: 注册取图回调函数
// int ret = MV_CC_RegisterImageCallBackForRGB(handle, GrabImgThread::getCameraImageCallback,this);
// if(MV_OK != ret)
// qDebug() << "=======faild =======" ;
// //step 3: 开始取图
// nRet = MV_CC_StartGrabbing(handle);
// if(nRet != 0){qDebug() << "MV_CC_StartGrabbing-- 失败";}
return 1;
//线程启动函数
void GrabImgThread::run()
//step 1: 初始化相机
initCamera();
//获取Enum型参数:获取触发模式
MVCC_ENUMVALUE struEnumValue = {0};
int nRet = MV_CC_GetEnumValue(handle, "TriggerSource", &struEnumValue);
//判断是否为硬触发
if(0 == struEnumValue.nCurValue){
//step2: 注册取图回调函数
int ret = MV_CC_RegisterImageCallBackForRGB(handle, GrabImgThread::getCameraImageCallback,this);
if(MV_OK != ret)
qDebug() << "=======faild =======" ;
//step 3: 开始取图
MV_CC_StartGrabbing(handle);
qDebug() << "子线程id:" << QThread::currentThread();
2、在主线程中创建子线程实现获取抓取的图像
主线程代码:
qDebug() << "主线程id:" << QThread::currentThread();
this->setWindowTitle("OCR");
//启动子线程获取图像
grabThread = new GrabImgThread;
grabThread->start();
connect(grabThread, &GrabImgThread::doneFinsh, this,
[=](QImage image){
if(intImage == 0){
ui->label_img->setPixmap(QPixmap::fromImage(image).scaled(560,420));
if(intImage == 1){
ui->label_img2->setPixmap(QPixmap::fromImage(image).scaled(560,420));
if(intImage == 2){
ui->label_img3->setPixmap(QPixmap::fromImage(image).scaled(560,420));
if(intImage == 3){
ui->label_img4->setPixmap(QPixmap::fromImage(image).scaled(560,420));
intImage++;
if(intImage == 4){ intImage = 0;}
//emit softTrigger();
运行结果如下: