Files
ds-628/BaseModules/Hd_LogicDll_module/Logic_camera_thread.cpp
T
2025-07-26 01:02:33 +08:00

524 lines
20 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Logic_camera_thread.h"
//QMap<QString, bool> 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)
{
QThread::msleep(1);
//qApp->processEvents();
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");
qDebug() << __FUNCTION__ << " line:" << __LINE__ << "runCameraModule::" << runCameraModuleNums++ << " cameraKey::"<< m_Module.module_key <<" getImgNums::"<< getImgNums;
if (m_type == "camera")
{
#if YH_LOGIC_SWITCH > 0
//602 读2个触发信号并传入相机
QByteArray camera_trigger_signal("cameraTriggerSignal");
for (int i = 1; i < cameraKeyS_runNumS.size(); i++)
{
camera_trigger_signal.append("_");
camera_trigger_signal.append(cameraKeyS_runNumS[i].toLocal8Bit());
}
#endif
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<cv::Mat> 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<cv::Mat>& 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();
// 判断触发模式
auto detDataPtr = dManager->createDetData();
if ( m_triggermodel.contains("software") )
{
QByteArray task_name;
if ( m_Module.module_ptr->run() ){
if ( !m_Module.module_ptr->readData(detDataPtr->imageVec,task_name) )
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " camera_mat is error! ";
missImgae_addImage(detDataPtr->imageVec);
}
}else{
qCritical() << __FUNCTION__ << " line:"<< __LINE__ << " m_name:" << m_name << " get image is error failed!";
missImgae_addImage(detDataPtr->imageVec);
}
//stop = clock();
//qDebug() << "m_Module.module_key::" << m_Module.module_key << " runCameraModule get image Time ::" << stop - start;
if (detDataPtr->imageVec.empty() )
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " camera_mat is null! ";
missImgae_addImage(detDataPtr->imageVec);
}
//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(detDataPtr->uuid); //最大耗时30-40ms;
// 界面传输图片来显示
if (ifshowSoureImg == true) //task_thread_num < 1 没有检测任务时,显示原图
if ((detDataPtr->imageVec.at(0).cols > 0) && (detDataPtr->imageVec.at(0).rows > 0) )
{
sendDataCommond(m_type, detDataPtr->uuid, "");
}
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_name: " << m_name << " software get mat is success! camera_mat len:" << camera_mat.size();
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;
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(detDataPtr->imageVec);
}
else
{
if (m_Module.module_ptr->run())
{
if (!m_Module.module_ptr->readData(detDataPtr->imageVec, task_name))
{
Sleep(10);
qApp->processEvents();
maxTime_stop = clock();
if (maxTime_stop - maxTime_start > getImgTimeout)
{
if (CommunicationProcessLevel == 2)
{
missImgae_addImage(detDataPtr->imageVec);
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 (detDataPtr->imageVec.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(detDataPtr->uuid);
if (ifshowSoureImg == true) //task_thread_num < 1 没有检测任务时,显示原图
if ((detDataPtr->imageVec.at(0).cols > 0) && (detDataPtr->imageVec.at(0).rows > 0))
{
sendDataCommond(m_type, detDataPtr->uuid, "");
}
//qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_name: " << m_name << " hardware get mat is success! get_mat len:" << camera_mat.size();
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(const QString& uuid)
{
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<QString> vector_sn = getSnData(camera_index);
QString channel_index = nullptr;
//拍照面描述
QString Surface;
if (cameraProductSurface.size() > 0)
Surface = SN_signal;
//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,uuid,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;
return true;
}
//index为图片序号
QVector<QString> 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<QString> 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<QString> 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, const QString& uuid,QByteArray byteArray)
{
QMutexLocker locker(m_mutex);
dataPack m_pack;
m_pack.uuid = uuid;
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();
}