#include "Logic_camera_thread.h" //QMap Logic_camera_thread::Map_getImageflag; void Logic_camera_thread::adddataIntegrationThread(Logic_hdataintegration* mythread) { mydataIntegrationThread.enqueue( mythread); ifMissImage_mutex = new QMutex; } Logic_camera_thread::~Logic_camera_thread() { Sleep(100); wait(100); exit(); qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_name:" << m_name << " delete thread success! "; } //设置相机key、取图超时、模块、拍照面描述、触发方式 bool Logic_camera_thread::setModule( QString station_name,MyModule module,QJsonObject obj) { //相机SN或usrID m_name = obj.value("相机key").toString(); m_type = "camera";// camera_obj.value("camera_type").toString(); getImgTimeout = obj.value("取图超时").toString().toInt(); maxCheckTime = obj.value("拍照信号-检查完成的时间").toString().toDouble(); if (m_name.isEmpty() || m_type.isEmpty()) { qCritical() << "[Error] " << " camera_key or camera_type is null"; return false; } QJsonArray SurfaceArray = obj.value("拍照面描述").toArray(); for (int i = 0; i < SurfaceArray.size(); i++) cameraProductSurface.enqueue(SurfaceArray[i].toString()); if (getImgTimeout < 10) getImgTimeout = 1000; //m_name = name; // m_type = type; m_Module = module; m_moduleobj = obj; m_stationName = station_name; // getImgTimeout = ImgTimeout; m_missImgae_add = obj.value("缺图时,补图宽高-张数-图像格式").toString(); if ( m_type == "camera" ) { m_triggermodel = m_moduleobj.value("触发方式").toString(); if ( m_triggermodel.isEmpty() ) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " trigger_mod is null ! "; return false; } } QJsonArray read_sn_format = m_moduleobj.value("获取SN方式列表").toArray(); for (int i = 0; i < read_sn_format.size(); i++) { QJsonObject obj = read_sn_format.at(i).toObject(); QString read_sn_area_index = obj.value("读哪个上料通道的SN").toString(); QString trggier_signals_access = obj.value("触发信号").toString(); //触发信号检查 if (!trggier_signals_access.isEmpty())//&& !read_sn_start_data_queue.isEmpty()) { SN_signalList.append(trggier_signals_access); } } return true; } //设置ifMissImage;Logic_myiothread要进行设置,加锁 void Logic_camera_thread::set_ifMissImage(bool flage) { QMutexLocker locker(ifMissImage_mutex); // 加锁 ifMissImage = flage; } void Logic_camera_thread::set_m_stoprun(bool val) { QMutexLocker locker(ifMissImage_mutex); // 加锁 m_stoprun = val; } clock_t maxTime_start, maxTime_stop; void Logic_camera_thread::run() { while (ifRun) { Sleep(2); if (getImgNums == 0) continue; m_stoprun = false; getImg_faileNums = 0; ifsaveImage = false; set_ifMissImage(false); cu_runNum = 0; int last_addImageNums = addImageNums; maxTime_start = clock(); try { //QString tmpDate = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz"); qCritical() << __FUNCTION__ << " line:" << __LINE__ << "runCameraModule::" << runCameraModuleNums++ << " cameraKey::"<< m_Module.module_key <<" getImgNums::"<< getImgNums; if (m_type == "camera") { for (int i = 0; i < getImgNums; i++) { if (!runCameraModule()) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << "runCameraModule run failed! "; getImg_faileNums++; //return; } maxTime_stop = clock(); if (maxTime_stop - maxTime_start > maxCheckTime) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << "maxTime_stop - maxTime_start > maxCheckTime! " << m_Module.module_key; std::cout << "maxTime_stop - maxTime_start > maxCheckTime! " << m_Module.module_key.toStdString() << std::endl; //break; } } //qCritical() << "camera_name::" << m_name << " addImageNums::" << addImageNums <<" thisNums::"<< addImageNums- last_addImageNums ; //判断有无取图失败情况 if (addImageNums - last_addImageNums < getImgNums) qCritical() << __FUNCTION__ << " line:" << __LINE__ << " err add Img::" << m_Module.module_key << " " << addImageNums - last_addImageNums; for (int i = 0; i < mydataIntegrationThread.size(); i++) { mydataIntegrationThread[i]->wait(); } trigger_signal = ""; getImgNums = 0; std::vector vec_mat; //无数据,拿来充函数的参数 if (send_byte.split('_').size() < 2) //为空分割size为1,不崩溃 { //一个开始拍照对应多个相机的,回复的信号只保留一个,后面的不发了。 if (send_byte != "pass") qDebug() << __FUNCTION__ << " line:" << __LINE__ << "feedback_signal err: " << send_byte; } else { QMutexLocker locker(m_iomutex); if (!finstcp_ptr->writeData(vec_mat, send_byte)) { qCritical() << __FUNCTION__ << "line:" << __LINE__ << " finstcp_ptr reciveData error! "; return; } else { qDebug() << __FUNCTION__ << " line:" << __LINE__ << "feedback_signal: " << send_byte; } } send_byte.clear(); //break; } } catch (QString ev) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << "catch ev:" << ev; return; } } } int Logic_camera_thread::matType(QString qstype) { int baseN = -1; if (qstype.contains("CV_8U")) baseN = 0; else if (qstype.contains("CV_8S")) baseN = 1; else if (qstype.contains("CV_16U")) baseN = 2; else if (qstype.contains("CV_16S")) baseN = 3; else if (qstype.contains("CV_32S")) baseN = 4; else if (qstype.contains("CV_32F")) baseN = 5; else if (qstype.contains("CV_64F")) baseN = 6; else if (qstype.contains("CV_16F")) baseN = 7; int lastN = 0; if (qstype.contains("C1")) lastN = 1; else if (qstype.contains("C2")) lastN = 2; else if (qstype.contains("C3")) lastN = 3; else if (qstype.contains("C4")) lastN = 4; if (baseN == -1 || lastN == 0) qCritical() << __FUNCTION__ << " line:" << __LINE__ << "type err:" << m_missImgae_add; return (lastN - 1) * 8 + baseN; } //缺图补图 void Logic_camera_thread::missImgae_addImage(std::vector& camera_mat) { set_ifMissImage(true); //"100*100*2*CV_8SC1#CV_8SC3", QStringList missList = m_missImgae_add.split("*"); if (missList.size() < 4) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << "data err:" << m_missImgae_add; return; } if(missList[3].split("#").size()< missList[2].toInt()) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << "data3 err:" << m_missImgae_add; return; } for (int i = 0; i < missList[2].toInt(); i++) { cv::Mat tmpType; int type = matType(missList[3].split("#")[i]); if (type < 0) return; tmpType = cv::Mat::zeros(cv::Size(missList[0].toInt(), missList[1].toInt()), type); camera_mat.push_back(tmpType); } } bool Logic_camera_thread::runCameraModule() { clock_t start, stop; start = clock(); // 判断触发模式 if ( m_triggermodel.contains("software") ) { QByteArray task_name; std::vector camera_mat; if ( m_Module.module_ptr->run() ){ if ( !m_Module.module_ptr->readData(camera_mat,task_name) ) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " camera_mat is error! "; missImgae_addImage(camera_mat); } }else{ qCritical() << __FUNCTION__ << " line:"<< __LINE__ << " m_name:" << m_name << " get image is error failed!"; missImgae_addImage(camera_mat); } //stop = clock(); //qDebug() << "m_Module.module_key::" << m_Module.module_key << " runCameraModule get image Time ::" << stop - start; if ( camera_mat.empty() ) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " camera_mat is null! "; missImgae_addImage(camera_mat); } //int de = camera_mat[0].rows * camera_mat[0].cols * camera_mat[0].channels() * camera_mat[0].depth() / 8; //图像检查 //for (int i = 0; i < camera_mat.size(); i++) // if ((camera_mat[i].dataend - camera_mat[i].datastart) < camera_mat[i].rows * camera_mat[i].cols * camera_mat[i].channels()) //尝试能否解决mtx内容异常问题 // { // camera_mat[i] = cv::Mat::zeros(camera_mat[i].rows, camera_mat[i].cols, camera_mat[i].type()); // qCritical() << __FUNCTION__ << " line:" << __LINE__ << " camera_mat[i] data err! zeros"; // } //保存图片到容器,并运行对应的条件判断 saveImage(camera_mat); //最大耗时30-40ms; // 界面传输图片来显示 if (ifshowSoureImg == true) //task_thread_num < 1 没有检测任务时,显示原图 if ((camera_mat.at(0).cols > 0) && (camera_mat.at(0).rows > 0) ) { sendDataCommond(m_type, camera_mat.at(0), ""); } //qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_name: " << m_name << " software get mat is success! camera_mat len:" << camera_mat.size(); camera_mat.clear(); return true; } else if ( m_triggermodel.contains("hardware") ) // 硬触发 hardware_trigger { myTime = 0; while (true) { if (CommunicationProcessLevel == 2) { maxTime_stop = clock(); /*if (maxTime_stop - maxTime_start > maxCheckTime) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << "maxCheckTime! hardware" << m_Module.module_key; std::cout << " maxCheckTime! " << m_Module.module_key.toStdString() << std::endl; return true; }*/ } if (!ifRun || m_stoprun == true) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " !ifRun || m_stoprun == true"<< m_Module.module_key; return true; } //QMutexLocker locker(ifMissImage_mutex); // 加锁 QByteArray task_name; std::vector camera_mat; if (CommunicationProcessLevel == 2 && maxTime_stop - maxTime_start > maxCheckTime) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " m_name:" << m_name << " maxTime_stop - maxTime_start > maxCheckTime,missImgae_addImage!"; missImgae_addImage(camera_mat); } else { if (m_Module.module_ptr->run()) { if (!m_Module.module_ptr->readData(camera_mat, task_name)) { Sleep(10); qApp->processEvents(); maxTime_stop = clock(); if (maxTime_stop - maxTime_start > getImgTimeout) { if (CommunicationProcessLevel == 2) { missImgae_addImage(camera_mat); qCritical() << __FUNCTION__ << " line:" << __LINE__ << " m_name:" << m_name << " get image is getImgTimeout failed!"; } } else continue; } } /*else { if (CommunicationProcessLevel == 2) { qCritical() << __FUNCTION__ << " line:" << __LINE__ << " m_name:" << m_name << " get image is error failed!"; missImgae_addImage(camera_mat); } }*/ } if (camera_mat.empty()) { Sleep(2); continue; } ////图像检查 //for (int i = 0; i < camera_mat.size(); i++) // if ((camera_mat[i].dataend - camera_mat[i].datastart) < camera_mat[i].rows * camera_mat[i].cols * camera_mat[i].channels()) //尝试能否解决mtx内容异常问题;camera_mat[i].depth()不是8的倍数 // { // camera_mat[i] = cv::Mat::zeros(camera_mat[i].rows, camera_mat[i].cols, camera_mat[i].type()); // qCritical() << __FUNCTION__ << " line:" << __LINE__ << " camera_mat[i] data err! zeros"; // } //保存图片到容器,并运行对应的条件判断 saveImage(camera_mat); if (ifshowSoureImg == true) //task_thread_num < 1 没有检测任务时,显示原图 if ((camera_mat.at(0).cols > 0) && (camera_mat.at(0).rows > 0)) { sendDataCommond(m_type, camera_mat.at(0), ""); } //qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_name: " << m_name << " hardware get mat is success! get_mat len:" << camera_mat.size(); camera_mat.clear(); m_stoprun = false; if (CommunicationProcessLevel == 2)//标准通信流程 break;//注意,硬触发有开始信号的,取图完返回; else if(m_Module.moduleName.contains("readImage")) Sleep(1000); else Sleep(2); } } return true; } //保存图片到容器,并运行对应的条件判断 bool Logic_camera_thread::saveImage(std::vector camera_mat) { clock_t start, stop; start = clock(); HCameraData *cameraPtr = station_list.value(m_stationName)->getCameraData(m_name); if ( cameraPtr ) { // 获取当前相机容器的下标 int camera_index = cameraPtr->getCameraIndex();//addImageData函数camera_index加一 // 根据相机下标获取sn码容器中的sn码 QVector vector_sn = getSnData(camera_index); QString channel_index = nullptr; //拍照面描述 QString Surface; if(cameraProductSurface.size()>0) Surface = cameraProductSurface[camera_index% cameraProductSurface.size()]; //camera_index,0,1,2;cameraProductSurface,tp1,tp2;对应,tp1,tp2,tp1; //qDebug() << "m_Module.module_key::" << m_Module.module_key << " saveImage getCameraData Time ::" << stop - start; //添加到容器SnCameraData cameraPtr->addImageData(channel_index,vector_sn,camera_mat,Surface); for (int i = 0; i < mydataIntegrationThread.size(); i++) { mydataIntegrationThread[i]->run();//一个mydataIntegrationThread对应多个相机 } stop = clock(); //if((stop - start)>20) // qDebug() << "m_Module.module_key::" << m_Module.module_key << " saveImage mydataIntegrationThread Time ::" << stop - start; start = clock(); addImageNums++; //std::cout <<"camera_name::" << m_name.toStdString() << " addImageNums::" << addImageNums++ << std::endl; }else{ qCritical() << __FUNCTION__ << " line:" << __LINE__ << " cameraPtr is null saveImage failed!"; return false; } ifsaveImage = true; camera_mat.clear(); return true; } //index为图片序号 QVector Logic_camera_thread::getSnData(int index) { HSnData* m_sndata = nullptr; QString m_sn_key = nullptr; // 获取下标对应的sn key //QString read_sn_num = nullptr; // 读取sn的方式 QString my_read_sn_area_index = nullptr; // 属于哪个区域的sn QString delete_sn = nullptr; // 是否删除sn 931 -3 使用 //m_moduleobj为当前相机的配置文件 QJsonArray read_sn_format = m_moduleobj.value("获取SN方式列表").toArray(); for ( int i = 0; i < read_sn_format.size(); i++ ) { QJsonObject obj = read_sn_format.at(i).toObject(); QString read_sn_area_index = obj.value("读哪个上料通道的SN").toString(); QString trggier_signals_access = obj.value("触发信号").toString(); //触发信号检查 if (!trggier_signals_access.isEmpty())//&& !read_sn_start_data_queue.isEmpty()) { if (trggier_signals_access != SN_signal) { continue; } } QJsonArray sn_data_array = obj.value("SN数据列表").toArray(); for (int vvv = 0; vvv < sn_data_array.size(); vvv++) { QJsonObject sn_obj = sn_data_array.at(vvv).toObject(); QString sn_key = sn_obj.value("哪个SN").toString(); // 下标对应的 sn key QJsonArray sn_vaule_array = sn_obj.value("第几张图").toArray(); for (int ggg = 0; ggg < sn_vaule_array.size(); ggg++) { QString value = sn_vaule_array.at(ggg).toString(); if (!value.isEmpty()) { if (value.toInt() == index) //相机第几张图,对应sn_data的value值, { my_read_sn_area_index = read_sn_area_index; m_sn_key = sn_key; break; } } } } } if (!my_read_sn_area_index.isEmpty()){ m_sndata = station_list.value(m_stationName)->getSnInfoData(my_read_sn_area_index.toInt()); // 获取相应区域SN }else{ m_sndata = station_list.value(m_stationName)->getSnInfoData(0); // 默认只有一个区域 } QVector vector_sn; if ( m_sndata ) { if (!m_sn_key.isEmpty()) { int sn_index = 0; QString snsnsn = m_sn_key.split("sn")[1]; //5-2:sn1,sn2 if (!snsnsn.isEmpty()) { sn_index = m_sn_key.split("sn")[1].toInt(); } QVector mVec_sn = m_sndata->getFirstValue(); if (sn_index - 1 < mVec_sn.size() && sn_index > 0) { vector_sn.push_back(mVec_sn.at(sn_index - 1)); } } } return vector_sn; } void Logic_camera_thread::setMutex(QMutex *mutex) { if (m_mutex == nullptr) m_mutex = new QMutex;// mutex; } bool Logic_camera_thread::sendDataCommond( QString m_type,cv::Mat mat,QByteArray byteArray) { QMutexLocker locker(m_mutex); dataPack m_pack; m_pack.mat = mat; m_pack.byteArray = byteArray; m_pack.retFlag = m_type; m_pack.cameraName = m_name; if (ifshowSoureImg == true) //task_thread_num < 1 没有检测任务时,显示原图 { // 界面显示包 camera_ImageDataPack.enqueue(m_pack); } return true; } void Logic_camera_thread::degressSnIndex() { QMutexLocker locker(m_mutex); if (m_sn_index == 0) return; m_sn_index--; } //获取一个数据包,并删除列表的头一个 dataPack Logic_camera_thread::getdataPack() { QMutexLocker locker(m_mutex); // 加锁 dataPack m_pack = camera_ImageDataPack.dequeue(); return m_pack; } int Logic_camera_thread::dataPack_size() { QMutexLocker locker(m_mutex); // 加锁 return camera_ImageDataPack.size(); }