504 lines
13 KiB
C++
504 lines
13 KiB
C++
#include <threadPoolController.h>
|
|
#include <ReadBarcode.h>
|
|
#include "camera_thread.h"
|
|
#include "myiothread.h"
|
|
#include <FrontendBackendBridge.h>
|
|
|
|
/// <summary>
|
|
/// 检查目标文件夹是否存在,不存在则创建
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
void createDirectoryIfNotExists_2(const std::string& path) {
|
|
// 检查路径是否存在
|
|
if (!std::filesystem::exists(path)) {
|
|
// 创建路径
|
|
|
|
std::filesystem::create_directories(path);
|
|
//std::cout << "已创建文件夹: " << path << std::endl;
|
|
}
|
|
else {/*
|
|
std::cout << "文件夹已存在: " << path << std::endl;*/
|
|
}
|
|
}
|
|
std::string getCurrentDateTime_2() {
|
|
// 获取当前时间点
|
|
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
|
|
|
// 转换为字符串
|
|
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
|
|
std::tm* localTime = std::localtime(¤tTime);
|
|
std::stringstream ss;
|
|
ss << std::put_time(localTime, "%H-%M-%S");
|
|
|
|
return ss.str();
|
|
}
|
|
int threadAmount = 0;
|
|
int maxThread = 16;
|
|
/// <summary>
|
|
/// 获取当前时间点,以"小时-分钟-秒"返回
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
std::string getCurrentDateTime() {
|
|
// 获取当前时间点
|
|
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
|
|
|
// 转换为字符串
|
|
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
|
|
std::tm* localTime = std::localtime(¤tTime);
|
|
std::stringstream ss;
|
|
ss << std::put_time(localTime, "%H-%M-%S");
|
|
|
|
return ss.str();
|
|
}
|
|
/// <summary>
|
|
/// 检查目标文件夹是否存在,不存在则创建
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
void createDirectoryIfNotExists(const std::string& path) {
|
|
// 检查路径是否存在
|
|
if (!std::filesystem::exists(path)) {
|
|
// 创建路径
|
|
std::filesystem::create_directories(path);
|
|
//std::cout << "已创建文件夹: " << path << std::endl;
|
|
}
|
|
else {/*
|
|
std::cout << "文件夹已存在: " << path << std::endl;*/
|
|
}
|
|
}
|
|
|
|
////////////THREAD//CONTROLLER////////////////////////
|
|
threadConroller::threadConroller(QObject* parent) : QThread(parent)
|
|
{
|
|
//sql初始化
|
|
sql = new sqlController;
|
|
sql->initPara();
|
|
//辅助线程初始化
|
|
oriSaveThread->oriThread = true;
|
|
oriSaveThread->Init(this);
|
|
|
|
resSaveThread->Init(this);
|
|
threadAmount = bridge.back.json.algoThreads.algoDataMap.size();
|
|
for (int i = 0; i < threadAmount; i++)
|
|
{
|
|
algoThread* aT = new algoThread();
|
|
aT->Init(this);
|
|
//QObject::connect(aT, &algoThread::subThreadStart, [&]() {
|
|
// supportThread->start();
|
|
// });
|
|
algoThreadList.push_back(aT);
|
|
}
|
|
}
|
|
|
|
void threadConroller::run()
|
|
{
|
|
return;
|
|
while (1)
|
|
{
|
|
while (insertQueue.size() > 0)
|
|
{
|
|
insertQueueMutex.lock();
|
|
while (insertQueue.size() > 0)
|
|
{
|
|
imgWaitList.push_back(insertQueue.dequeue());
|
|
}
|
|
insertQueueMutex.unlock();
|
|
}
|
|
if (imgWaitList.size() > 0)
|
|
{
|
|
for (int i = 0; i < imgWaitList.size(); i++)
|
|
{
|
|
int imgSize = imgWaitList[i]->imgs.size();
|
|
int imgAmountMin = imgWaitList[i]->imgAmountMin;
|
|
if (imgSize >= imgAmountMin)
|
|
{
|
|
int threadId = imgWaitList[i]->algoThreadIndex;
|
|
if (threadId == -1)
|
|
{
|
|
cout << "threadId return -1 ,algoName " << imgWaitList[i]->algoThreadName.toStdString() << endl;
|
|
imgWaitList.removeAt(i);
|
|
return;
|
|
}
|
|
algoThreadList[threadId]->addDetTask(imgWaitList[i]);
|
|
cout << "Size " << imgWaitList.size() << " delete " << i << endl;
|
|
imgWaitList.erase(imgWaitList.begin() + i);
|
|
for (auto& data : imgWaitList)
|
|
{
|
|
cout << "remain " << data->cameraKeyName.toStdString() << " " << data->algoThreadName.toStdString() << " " << data->cameraNameStr << endl;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
QThread::msleep(10);
|
|
}
|
|
}
|
|
void threadConroller::addTask(detData* data)
|
|
{
|
|
cout << __LINE__ << "insert Data " << data ->timeCode<< endl;
|
|
{
|
|
algoThreadCls::datastruct _struct = bridge.back.json.algoThreads.getData(data->algoThreadName);
|
|
data->algoThreadIndex = _struct.threadIndex;
|
|
data->resShowIndex = _struct.showIndex;
|
|
data->imgAmountMin = _struct.imgAmountMin;
|
|
}
|
|
{
|
|
CameraListCls::datastruct _struct = bridge.back.json.camera.getData(data->cameraKeyName);
|
|
data->oriShowIndex = _struct.showIndex;
|
|
}
|
|
insertQueueMutex.lock();
|
|
//insertQueue.push_back(data);
|
|
int threadId = data->algoThreadIndex;
|
|
if (threadId == -1)
|
|
{
|
|
cout << "threadId return -1 ,algoName " << data->algoThreadName.toStdString() << endl;
|
|
return;
|
|
}
|
|
algoThreadList[threadId]->addDetTask(data);
|
|
insertQueueMutex.unlock();
|
|
//this->start();
|
|
}
|
|
bool threadConroller::getFreeThread()
|
|
{
|
|
#if 0
|
|
int index = 0;
|
|
for (index = 0; index < threadPoolList.size(); index++)
|
|
{
|
|
if (threadPoolList[index]->isRunning() == false)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
for (index = 0; index < threadPoolList.size(); index++)
|
|
{
|
|
if (threadPoolList[index]->nextObj.isEmpty() == true)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
#endif
|
|
return false;
|
|
|
|
}
|
|
bool threadConroller::addTaskFreeThread(detData* data)
|
|
{
|
|
#if 0
|
|
int index = 0;
|
|
for (index = 0; index < threadPoolList.size(); index++)
|
|
{
|
|
if (threadPoolList[index]->isRunning() == false)
|
|
{
|
|
threadPoolList[index]->addDetTask(data);
|
|
threadPoolList[index]->start();
|
|
return true;
|
|
}
|
|
}
|
|
for (index = 0; index < threadPoolList.size(); index++)
|
|
{
|
|
if (threadPoolList[index]->nextObj.isEmpty() == true)
|
|
{
|
|
threadPoolList[index]->addDetTask(data);
|
|
return true;
|
|
}
|
|
}
|
|
#endif
|
|
return false;
|
|
|
|
}
|
|
threadConroller::~threadConroller()
|
|
{
|
|
for (auto thread : algoThreadList)
|
|
{
|
|
thread->m_runFlag = false;
|
|
while (thread->isRunning() == false);
|
|
}
|
|
for (auto thread : algoThreadList)
|
|
{
|
|
delete thread;
|
|
}
|
|
}
|
|
////////////////SUBTHREAD////////////////////////
|
|
bool folderExists(const std::string& folderPath) {
|
|
return std::filesystem::is_directory(folderPath);
|
|
}
|
|
void subThread::Init(threadConroller* tC)
|
|
{
|
|
sql = tC->sql;
|
|
snDatas = &tC->snDatas;
|
|
}
|
|
void subThread::saveOriginalImg(imgSaveStruct& data)
|
|
{
|
|
QDateTime currentDateTime = QDateTime::currentDateTime();
|
|
std::string ymd = currentDateTime.toString("yyyy-MM-dd").toStdString();
|
|
int h = currentDateTime.time().hour();
|
|
if (!data.SNcode.compare(snDatas->snErrorsnError))
|
|
data.SNcode = snDatas->waitForSn(data.timeCode);
|
|
|
|
std::string fileSavePath = bridge.back.json.imgSavePath.toStdString()
|
|
+ "//yuantu//" + ymd + "//" + to_string(h) + "H//";
|
|
std::string fileName;
|
|
std::string resPath;
|
|
//if (data.cameraKeyName != "camera1" &&
|
|
// data.SNcode != snDatas->snErrorsnError)//非相机1,因为相机1时还没创建文件夹
|
|
//{
|
|
// sqlDataStruct sqlData = sql->selectData(data.SNcode, 1);//请求数据库
|
|
// for (auto name : sqlData.dataVec)//查询图片文件夹
|
|
// {
|
|
// if (!name.dataName.compare("updateTime") && name.valueText.compare("NULL"))
|
|
// h = std::stoi(name.valueText);
|
|
// }
|
|
//}
|
|
if (!resPath.compare("NULL") || resPath.length() == 0)
|
|
{
|
|
if ((data.SNcode).length() != 0)
|
|
resPath = fileSavePath + data.SNcode + "//";
|
|
else
|
|
resPath = fileSavePath + data.cameraKeyName + "//";
|
|
}
|
|
createDirectoryIfNotExists_2(resPath);
|
|
//while (folderExists(resPath) != true);
|
|
////////////////
|
|
if (data.cameraKeyName.find_first_of("25D")!=-1)
|
|
{
|
|
sqlDataStruct sqlDataStruct;
|
|
sqlDataStruct.SN = data.SNcode;
|
|
{
|
|
sqlDatas sqlData;
|
|
sqlData.dataName = "updateTime";
|
|
sqlData.valueText = (to_string(h));
|
|
sqlDataStruct.dataVec.push_back(sqlData);
|
|
}
|
|
sql->addData(sqlDataStruct);
|
|
|
|
std::string type, fileName;
|
|
for (int i = 0; i < data.imgs.size(); i++)
|
|
{
|
|
switch (i)
|
|
{
|
|
case 0:type = "SprfSpecularReflectionImage"; break;
|
|
case 1:type = "SprfDiffuseReflectionImage"; break;
|
|
case 2:type = "SprfShapeImage1"; break;
|
|
case 3:type = "SprfShapeImage2"; break;
|
|
case 4:type = "SprfGlossRatioImage"; break;
|
|
case 5:type = "SprfNormalImage"; break;
|
|
default:type = "unknow"; break;
|
|
}
|
|
|
|
fileName = data.cameraKeyName + "-" + type + "-" + getCurrentDateTime_2() + ".bmp";
|
|
cv::imwrite(resPath + fileName, data.imgs[i]);
|
|
qDebug() << "[Debug]"<<QString::fromStdString(data.cameraKeyName)<<" ori:" << QString::fromStdString(resPath + fileName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::string fileName;
|
|
for (int i = 0; i < data.imgs.size(); i++)
|
|
{
|
|
fileName = data.cameraKeyName + "-" + to_string(i) + "-" + getCurrentDateTime_2() + ".bmp";
|
|
cv::imwrite(resPath + fileName, data.imgs[i]);
|
|
qDebug() << "[Debug]typeUnknow ori:" << QString::fromStdString(resPath + fileName);
|
|
//cout << resPath << fileName << endl;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
void subThread::saveResultImg(imgSaveStruct& data)
|
|
{
|
|
try
|
|
{
|
|
QDateTime currentDateTime = QDateTime::currentDateTime();
|
|
std::string ymd = currentDateTime.toString("yyyy-MM-dd").toStdString();
|
|
int h = currentDateTime.time().hour();
|
|
//
|
|
if (data.cameraKeyName != "camera1" &&
|
|
data.SNcode != snDatas->snErrorsnError)
|
|
{
|
|
sqlDataStruct sqlData = sql->selectData(data.SNcode, 1);//请求数据库
|
|
for (auto name : sqlData.dataVec)//查询
|
|
{
|
|
if (!name.dataName.compare("updateTime") && name.valueText.compare("NULL"))
|
|
h = std::stoi(name.valueText);
|
|
}
|
|
}
|
|
//
|
|
std::string fileSavePath = bridge.back.json.imgSavePath.toStdString()
|
|
+ "//result//" + ymd + "//" + to_string(h) + "H//";
|
|
std::string fileName;
|
|
std::string resPath;
|
|
|
|
//
|
|
//sql
|
|
//if (data.cameraKeyName != "camera1")//非相机1,因为相机1时还没创建文件夹
|
|
|
|
//if (data.SNcode.compare("snErrNoSn"))
|
|
//{
|
|
// if (data.cameraKeyName=="camera1")
|
|
// {
|
|
// dateTimeNow = QDateTime::currentDateTime().toString("yyyy_MM_dd--hh-mm-ss.zzz");
|
|
// }
|
|
// resPath = fileSavePath + data.SNcode + "//" + dateTimeNow.toStdString() + "//";
|
|
//}
|
|
if (!resPath.compare("NULL") || resPath.length() == 0)
|
|
{
|
|
if ((data.SNcode).length() != 0)
|
|
resPath = fileSavePath + data.SNcode + "//";
|
|
else
|
|
resPath = fileSavePath + "camera" + data.cameraKeyName + "//";
|
|
}
|
|
createDirectoryIfNotExists_2(resPath);//文件夹处理
|
|
////////
|
|
//while (folderExists(resPath) != true);
|
|
{
|
|
for (int i = 0; i < data.imgs.size(); i++)
|
|
{
|
|
fileName = data.cameraKeyName+"-" + getCurrentDateTime_2() + "_" + to_string(i) + ".jpg";
|
|
cv::imwrite(resPath + fileName, data.imgs[i]);
|
|
qDebug() << "[Debug]typeUnknow ori:" << QString::fromStdString(resPath + fileName);
|
|
}
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
void subThread::run()
|
|
{
|
|
if (oriThread == false)
|
|
while (m_runFlag == true)
|
|
{
|
|
while (resQueue.size() > 0)
|
|
{
|
|
resMutex.lock();
|
|
imgSaveStruct data = resQueue.dequeue();
|
|
resMutex.unlock();
|
|
saveResultImg(data);
|
|
}
|
|
QThread::msleep(10);
|
|
}
|
|
else
|
|
while (m_runFlag == true)
|
|
{
|
|
while (oriQueue.size() > 0)
|
|
{
|
|
oriMutex.lock();
|
|
imgSaveStruct data = oriQueue.dequeue();
|
|
oriMutex.unlock();
|
|
saveOriginalImg(data);
|
|
}
|
|
QThread::msleep(10);
|
|
}
|
|
|
|
}
|
|
////////////////DET//DATA//////////////////
|
|
sncodeCls::sncodeCls()
|
|
{
|
|
tcpStartPos = bridge.back.json.tcp.startPos;
|
|
}
|
|
bool sncodeCls::clearSameSnRequestData()
|
|
{
|
|
std::unordered_map< size_t, size_t >tempMap;
|
|
for (int i = snWaittingVec.size() - 1; i >= 0; i--)
|
|
{
|
|
auto it = tempMap.find(snWaittingVec[i].startpos);
|
|
if (it == tempMap.end()) {
|
|
tempMap.insert({ snWaittingVec[i].startpos,i });
|
|
}
|
|
else
|
|
{
|
|
snWaittingVec.removeAt(i);
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
void sncodeCls::checkSnFromWaittingVec(QByteArray byte)
|
|
{
|
|
while (clearSameSnRequestData() == false);
|
|
for (int i = 0; i < snWaittingVec.size(); i++)
|
|
{//第一位是hash,第二位是index
|
|
string SN = readSnFromQByteArray(byte, snWaittingVec[i].startpos, false, true, 0);
|
|
if (SN.compare(snErrorsnError))//不为空
|
|
{
|
|
snResList.push_back({ snWaittingVec[i].timecode,SN,snWaittingVec[i].startpos });
|
|
while (snResList.size() > 100)
|
|
snResList.pop_front();
|
|
snWaittingVec.removeAt(i);
|
|
}
|
|
}
|
|
}
|
|
string sncodeCls::readSnFromQByteArray(QByteArray byte, int dmPos,
|
|
bool highLowConversion, bool clearAfterRead, long long timeCode, int Size)
|
|
{
|
|
int triggerPos = (dmPos - tcpStartPos) * 2;
|
|
if (triggerPos < 0)
|
|
{
|
|
cout << "Read SN error,trigger is DM:" << dmPos << ",but read start at DM:" << tcpStartPos << endl;
|
|
return snErrorsnError;
|
|
}
|
|
QString str;
|
|
if (byte.at(triggerPos + 1) == 0 && byte.at(triggerPos) == 0)
|
|
return snErrorsnError;
|
|
int snCount = 0;
|
|
while (byte.at(snCount + triggerPos) != 0 || byte.at(snCount + triggerPos + 1) != 0)
|
|
{
|
|
|
|
if (byte.at(snCount + triggerPos) == 0)
|
|
{
|
|
snCount++;
|
|
continue;
|
|
}
|
|
str += QChar(byte.at(snCount + triggerPos));
|
|
snCount++;
|
|
}
|
|
if (highLowConversion == true)
|
|
{
|
|
snHex(str);
|
|
}
|
|
if (str.size() < Size && Size != -1)
|
|
return snErrorsnError;
|
|
if (clearAfterRead == true)
|
|
//for(int i=0;i< snCount;i++)
|
|
bridge.back.sendFinsMsg(
|
|
QString::fromStdString("writeALL_DM" + to_string(dmPos) + "_" + to_string(snCount) + "_0"));
|
|
return str.toStdString();
|
|
}
|
|
QString sncodeCls::snHex(QString sn)
|
|
{
|
|
QString resultStr = "";
|
|
for (int i = 0; i < sn.size() - 1; i = i + 2)
|
|
{
|
|
resultStr = resultStr + sn.at(i + 1) + sn.at(i);
|
|
}
|
|
return resultStr;
|
|
}
|
|
string sncodeCls::getData(unsigned long long timeCode)
|
|
{
|
|
for (int i = snResList.size() - 1; i >= 0; i--)
|
|
{
|
|
if (snResList[i].timecode == timeCode)
|
|
return snResList[i].sn;
|
|
}
|
|
return snErrorsnError;
|
|
}
|
|
string sncodeCls::waitForSn(unsigned long long timeCode, int timeOut)
|
|
{
|
|
int cnt = 0;
|
|
string sn = getData(timeCode);
|
|
if (!sn.compare(snErrorsnError))
|
|
{
|
|
|
|
while (cnt < timeOut)
|
|
{
|
|
sn = getData(timeCode);
|
|
if (sn.compare(snErrorsnError))
|
|
{
|
|
return sn;
|
|
}
|
|
cnt += 10;
|
|
QThread::msleep(10);
|
|
}
|
|
}
|
|
else
|
|
return sn;
|
|
return snErrorsnError;
|
|
} |