376 lines
10 KiB
C++
376 lines
10 KiB
C++
#include <iostream>
|
|
#include <qthread.h>
|
|
#include <qqueue.h>
|
|
#include <qmutex.h>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <filesystem>
|
|
#include <opencv.hpp>
|
|
#include <string>
|
|
#include <handleAiModel.h>
|
|
#include <sqliteController/sqlControler.h>
|
|
#include <QtConcurrent/qtconcurrent>
|
|
#include <QMetaType>
|
|
#include <fileManager.h>
|
|
#include <qtcpserver.h>
|
|
#include <qtcpsocket.h>
|
|
class threadConroller;
|
|
class algoThread;
|
|
class subThread;
|
|
class detDataController;
|
|
//class detData;
|
|
struct saveStruct
|
|
{
|
|
std::string filePath;
|
|
std::string fileName;
|
|
cv::Mat file;
|
|
};
|
|
struct MatchResult {
|
|
cv::Rect boundingRect;
|
|
double confidence;
|
|
};
|
|
struct correctionStruct
|
|
{
|
|
std::vector<double> in_X_X0Y;
|
|
std::vector<double> in_Y_X0Y;
|
|
std::vector<double> in_Z_X0Y;
|
|
std::vector<double> in_Z_X0Y_Value;
|
|
std::vector<double> in_X_X0Z;
|
|
std::vector<double> in_Y_X0Z;;
|
|
std::vector<double> in_Z_X0Z;
|
|
std::vector<double> in_Y_X0Z_Value;
|
|
std::vector<double> in_X_Y0Z;
|
|
std::vector<double> in_Y_Y0Z;
|
|
std::vector<double> in_Z_Y0Z;
|
|
std::vector<double> in_X_Y0Z_Value;
|
|
};
|
|
class cameraImages
|
|
{
|
|
public:
|
|
struct imgData
|
|
{
|
|
size_t timCode;
|
|
std::vector<cv::Mat>imgs;
|
|
};
|
|
QList< imgData*> imgList;
|
|
imgData* getData(size_t timeCode)
|
|
{
|
|
for (int i = 0; i < imgList.size(); i++)
|
|
{
|
|
if (imgList[i]->timCode == timeCode)
|
|
{
|
|
imgData* ptr = imgList[i];
|
|
imgList.removeAt(i);
|
|
return ptr;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
imgData* waitForImg(size_t timeCode,int timeOut=10000)
|
|
{
|
|
imgData* ptr=nullptr;
|
|
int cnt = 0;
|
|
while (cnt < timeOut)
|
|
{
|
|
ptr = getData(timeCode);
|
|
if (ptr!=nullptr)
|
|
{
|
|
std::cout <<"cost Time"<< cnt << endl;
|
|
return ptr;
|
|
}
|
|
cnt += 10;
|
|
QThread::msleep(10);
|
|
}
|
|
qDebug() << "timeCode:" << timeCode << "no img,return nullptr";
|
|
return nullptr;
|
|
}
|
|
void insertImg(size_t timeCode, std::vector<cv::Mat>*mats)
|
|
{
|
|
std::vector<cv::Mat>imgs;
|
|
imgs.swap(*mats);
|
|
imgData* _strcut = new imgData({ timeCode, imgs });
|
|
imgList.push_back(_strcut);
|
|
}
|
|
|
|
};
|
|
class detData
|
|
{
|
|
public:
|
|
const unsigned long long timeCode = getTimeCode();//根据时间和随机数生成的值,唯一
|
|
|
|
std::string SNcode;
|
|
|
|
QString cameraKeyName;
|
|
QString algoThreadName;
|
|
std::string cameraNameStr;
|
|
correctionStruct* correctionData=nullptr;
|
|
double camera1Width = 0, camera1Height = 0;
|
|
|
|
int algoThreadIndex = -1;//进入第几个算法线程
|
|
int cameraIndex = -1; //是第几次拍照
|
|
int imgAmountMin = 1;
|
|
|
|
std::array<bool, 20>skip;
|
|
std::vector<std::pair<std::string, double>> sqlVec;
|
|
|
|
std::vector<cv::Mat> imgs;
|
|
std::vector<cv::Mat> resultImgs;
|
|
int oriShowIndex = -1;//原图在第几个框展示
|
|
int resShowIndex = -1;//结果图在第几个框展示
|
|
std::string snErrorsnError = std::string("snErrNoSn");
|
|
detDataController* dController=nullptr;
|
|
static unsigned long long getTimeCode() {
|
|
auto now = std::chrono::high_resolution_clock::now();
|
|
auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
|
|
|
|
std::random_device rd;
|
|
std::mt19937_64 gen(rd());
|
|
std::uniform_int_distribution<unsigned long long> dis(0, std::numeric_limits<unsigned long long>::max());
|
|
unsigned long long randomValue = dis(gen);
|
|
|
|
unsigned long long uniqueNumber = (timestamp << 32) | randomValue;
|
|
return uniqueNumber;
|
|
}
|
|
|
|
void Init(QString IN_cameraKeyName, QString IN_algoThreadName,
|
|
std::string IN_SN, int IN_oriShowIndex)
|
|
{
|
|
|
|
|
|
cameraKeyName = IN_cameraKeyName;
|
|
algoThreadName = IN_algoThreadName;
|
|
oriShowIndex = IN_oriShowIndex;
|
|
SNcode = IN_SN;
|
|
//algoThreadCls::datastruct _struct = bridge.back.json.algoThreads.getData(IN_algoThreadName);
|
|
//algoThreadIndex = _struct.threadIndex;
|
|
//resShowIndex = _struct.showIndex;
|
|
}
|
|
static detData* CreateDetData(QString IN_cameraKeyName, QString IN_algoThreadName,
|
|
std::string IN_SN, int IN_oriShowIndex)
|
|
{
|
|
detData* data = new detData(IN_cameraKeyName, IN_algoThreadName, IN_SN, IN_oriShowIndex);
|
|
return data;
|
|
}
|
|
|
|
detData(QString IN_cameraKeyName, QString IN_algoThreadName,
|
|
std::string IN_SN, int IN_oriShowIndex)
|
|
{
|
|
cameraKeyName = IN_cameraKeyName;
|
|
algoThreadName = IN_algoThreadName;
|
|
oriShowIndex = IN_oriShowIndex;
|
|
SNcode = IN_SN;
|
|
}
|
|
~detData()
|
|
{
|
|
for (auto img : imgs)
|
|
img.release();
|
|
for (auto img : resultImgs)
|
|
img.release();
|
|
//delete cameraImgPtr;
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
imgs.clear();
|
|
//timeCode = -1;
|
|
resShowIndex = -1;
|
|
oriShowIndex = -1;
|
|
algoThreadIndex = -1;
|
|
cameraIndex = -1;
|
|
//snCountIndex = -1;
|
|
std::string SNcode = "";
|
|
}
|
|
bool isEmpty()
|
|
{
|
|
if (imgs.size() == 0)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
};
|
|
class detDataController
|
|
{
|
|
public:
|
|
std::unordered_map<unsigned long long, detData*>map;
|
|
//std::map<unsigned long long, detData*>tstMap;
|
|
QLinkedList< detData> detDatas;
|
|
QMutex dataMutex;
|
|
detData* insertDetData(QString IN_cameraKeyName, QString IN_algoThreadName,
|
|
std::string IN_SN, int IN_oriShowIndex)
|
|
{
|
|
dataMutex.lock();
|
|
detData data(IN_cameraKeyName, IN_algoThreadName, IN_SN, IN_oriShowIndex);
|
|
data.dController = this;
|
|
detDatas.push_back(data);
|
|
map.insert({ data.timeCode,&detDatas.back() });
|
|
dataMutex.unlock();
|
|
detData* dataPtr = getDetData(data.timeCode);
|
|
|
|
if (dataPtr == nullptr)
|
|
qDebug() << "创建新容器失败";
|
|
return dataPtr;
|
|
}
|
|
detData* getDetData(unsigned long long timeCode)
|
|
{
|
|
dataMutex.lock();
|
|
std::unordered_map<unsigned long long, detData*>::iterator
|
|
it = map.find(timeCode);
|
|
if (it != map.end())
|
|
{
|
|
dataMutex.unlock();
|
|
return it->second;
|
|
}
|
|
dataMutex.unlock();
|
|
return nullptr;
|
|
}
|
|
bool deleteDetData(unsigned long long timeCode)
|
|
{
|
|
dataMutex.lock();
|
|
std::unordered_map<unsigned long long, detData*>::iterator it = map.find(timeCode);
|
|
if (it != map.end())
|
|
{
|
|
map.erase(it);
|
|
QLinkedList<detData>::iterator linkedListIt;
|
|
for (linkedListIt = detDatas.begin(); linkedListIt != detDatas.end(); ++linkedListIt)
|
|
{
|
|
if (linkedListIt->timeCode == timeCode)
|
|
{
|
|
detDatas.erase(linkedListIt);
|
|
dataMutex.unlock();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
dataMutex.unlock();
|
|
return false;
|
|
}
|
|
|
|
};
|
|
class sncodeCls
|
|
{
|
|
public:
|
|
struct snPack
|
|
{
|
|
unsigned long long timecode;
|
|
std::string sn;
|
|
int startpos;
|
|
};
|
|
QList<snPack>snWaittingVec;
|
|
QList<snPack>snResList;
|
|
std::string snErrorsnError = "snErrNoSn";
|
|
int tcpStartPos=0;
|
|
bool clearSameSnRequestData();
|
|
void checkSnFromWaittingVec(QByteArray byte);
|
|
std::string readSnFromQByteArray(QByteArray byte, int dmPos,
|
|
bool highLowConversion, bool clearAfterRead, long long timeCode, int Size = -1);
|
|
QString snHex(QString sn);
|
|
std::string getData(unsigned long long timeCode);
|
|
std::string waitForSn(unsigned long long timeCode, int timeOut=1000);
|
|
sncodeCls();
|
|
};
|
|
|
|
/// <summary>
|
|
/// 辅助线程
|
|
/// </summary>
|
|
class imgSaveThread : public QThread
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
bool oriThread = false;
|
|
std::string snErrorsnError2= std::string ("snErrNoSn");
|
|
struct imgSaveStruct{
|
|
std::string cameraKeyName;
|
|
std::string SNcode;
|
|
int showIndex = -1;
|
|
unsigned long long timeCode;
|
|
std::vector<cv::Mat>imgs;
|
|
|
|
};
|
|
QMutex mutex;
|
|
bool m_runFlag = true;
|
|
std::vector<std::pair<std::string, size_t>>snWithHash;
|
|
|
|
sncodeCls* snDatas;
|
|
sqlController* sql;
|
|
std::string fileNameTemp;
|
|
|
|
QMutex oriMutex;
|
|
QQueue<imgSaveStruct>oriQueue;
|
|
QMutex resMutex;
|
|
QQueue<imgSaveStruct>resQueue;
|
|
QString dateTimeNow;
|
|
|
|
void saveOriImg(detData* data)
|
|
{
|
|
imgSaveStruct saveStruct;
|
|
saveStruct.SNcode = data->SNcode;
|
|
//saveStruct.snCountIndex = data->snCountIndex;
|
|
saveStruct.cameraKeyName = data->cameraKeyName.toStdString();
|
|
saveStruct.timeCode = data->timeCode;
|
|
saveStruct.showIndex = data->oriShowIndex;
|
|
for (auto mat : data->imgs)
|
|
saveStruct.imgs.push_back(mat);
|
|
oriMutex.lock();
|
|
oriQueue.push_back(saveStruct);
|
|
oriMutex.unlock();
|
|
this->start();
|
|
}
|
|
void saveResImg(detData* data)
|
|
{
|
|
imgSaveStruct saveStruct;
|
|
saveStruct.SNcode = data->SNcode;
|
|
|
|
//saveStruct.snCountIndex = data->snCountIndex;
|
|
saveStruct.cameraKeyName = data->cameraKeyName.toStdString();
|
|
saveStruct.timeCode = data->timeCode;
|
|
saveStruct.showIndex = data->resShowIndex;
|
|
|
|
for (auto mat : data->resultImgs)
|
|
saveStruct.imgs.push_back(mat);
|
|
|
|
resMutex.lock();
|
|
resQueue.push_back(saveStruct);
|
|
resMutex.unlock();
|
|
this->start();
|
|
}
|
|
|
|
void Init(threadConroller* tC);
|
|
void run();
|
|
private:
|
|
void saveOriginalImg(imgSaveStruct&);
|
|
void saveResultImg(imgSaveStruct&);
|
|
};
|
|
|
|
/// <summary>
|
|
/// 线程池管理
|
|
/// </summary>
|
|
class threadConroller : public QThread
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit threadConroller(QObject* parent = nullptr);
|
|
QMutex queueMutex;
|
|
cameraImages cameraImgs;
|
|
QQueue<detData*> detDataQueue;
|
|
sqlController* sql;
|
|
handleAiModel models;//初始化模型
|
|
autoDelete* autoDeleteThread;
|
|
|
|
QMutex insertQueueMutex;
|
|
QQueue<detData*>insertQueue;
|
|
std::vector<algoThread*>algoThreadList;
|
|
imgSaveThread* oriSaveThread = new imgSaveThread;//原图保存线程
|
|
imgSaveThread* resSaveThread = new imgSaveThread;//结果图保存线程
|
|
void run();
|
|
void addTask(detData*);
|
|
bool getFreeThread();
|
|
bool addTaskFreeThread(detData*);
|
|
sncodeCls snDatas;
|
|
~threadConroller();
|
|
private:
|
|
QList<detData*>imgWaitList;
|
|
};
|
|
|
|
#pragma once
|