继上篇文章: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; } } } else { 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; else 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(); });
运行结果如下: