Files
ds-628/BaseModules/Hd_LogicDll_module/Logic_camera_thread.cpp
T

528 lines
20 KiB
C++
Raw Normal View History

2024-09-27 15:54:45 +08:00
#include "Logic_camera_thread.h"
2024-09-27 14:31:22 +08:00
//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();
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;
}
void Logic_camera_thread::run()
{
while (ifRun)
{
Sleep(2);
if (getImgNums == 0)
continue;
m_stoprun = false;
getImg_faileNums = 0;
ifsaveImage = false;
2024-09-27 15:54:45 +08:00
//set_ifMissImage(false);
2024-09-27 14:31:22 +08:00
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;
2024-09-27 15:54:45 +08:00
//break;
2024-09-27 14:31:22 +08:00
}
}
//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();
// 判断触发模式
if ( m_triggermodel.contains("software") )
{
QByteArray task_name;
std::vector<cv::Mat> 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;
//图像检查
2024-09-27 15:54:45 +08:00
//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";
// }
2024-09-27 14:31:22 +08:00
//保存图片到容器,并运行对应的条件判断
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();
2024-09-27 15:54:45 +08:00
/*if (maxTime_stop - maxTime_start > maxCheckTime)
2024-09-27 14:31:22 +08:00
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << "maxCheckTime! hardware" << m_Module.module_key;
std::cout << " maxCheckTime! " << m_Module.module_key.toStdString() << std::endl;
return true;
2024-09-27 15:54:45 +08:00
}*/
2024-09-27 14:31:22 +08:00
}
if (!ifRun || m_stoprun == true)
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " !ifRun || m_stoprun == true"<< m_Module.module_key;
return true;
}
2024-09-27 15:54:45 +08:00
//QMutexLocker locker(ifMissImage_mutex); // 加锁
2024-09-27 14:31:22 +08:00
QByteArray task_name;
std::vector<cv::Mat> camera_mat;
2024-09-27 15:54:45 +08:00
if (CommunicationProcessLevel == 2 && waitenum++%100==0)
2024-09-27 14:31:22 +08:00
{
2024-09-27 15:54:45 +08:00
//missImgae_addImage(camera_mat);
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " m_name:" << m_name << " waite trigger!"<< waitenum;
}
if (CommunicationProcessLevel == 2 && maxTime_stop - maxTime_start > maxCheckTime)
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << "maxCheckTime! add img, hardware" << m_Module.module_key;
missImgae_addImage(camera_mat);
2024-09-27 14:31:22 +08:00
}
else
{
2024-09-27 15:54:45 +08:00
if (m_Module.module_ptr->run())
2024-09-27 14:31:22 +08:00
{
2024-09-27 15:54:45 +08:00
if (!m_Module.module_ptr->readData(camera_mat, task_name))
{
Sleep(10);
qApp->processEvents();
myTime += 10;
if (myTime % 1000 == 0)
{
if (CommunicationProcessLevel == 2)
{
//missImgae_addImage(camera_mat);
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " m_name:" << m_name << " waite trigger!";
}
}
if (myTime > maxCheckTime)
{
if (CommunicationProcessLevel == 2)
{
missImgae_addImage(camera_mat);
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " m_name:" << m_name << " get image is getImgTimeout failed!";
}
}
else continue;
}
2024-09-27 14:31:22 +08:00
}
2024-09-27 15:54:45 +08:00
/*else
{
if (CommunicationProcessLevel == 2)
{
qCritical() << __FUNCTION__ << " line:" << __LINE__ << " m_name:" << m_name << " get image is error failed!";
missImgae_addImage(camera_mat);
}
}*/
2024-09-27 14:31:22 +08:00
}
2024-09-27 15:54:45 +08:00
2024-09-27 14:31:22 +08:00
if (camera_mat.empty())
{
Sleep(2);
continue;
}
2024-09-27 15:54:45 +08:00
////图像检查
//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";
// }
2024-09-27 14:31:22 +08:00
//保存图片到容器,并运行对应的条件判断
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<cv::Mat> 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<QString> 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<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,cv::Mat mat,QByteArray byte )
{
QMutexLocker locker(m_mutex);
dataPack m_pack;
m_pack.mat = mat;
m_pack.byte = byte;
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();
}