#include #include #include #include #include #include #include #include enum imgSaveThreadType { oriImg, resImg, segImg, clsImg, additionalSaveNgImg }; class imgSaveThread : public QThread { public: QMutex mutex; QQueue>imgQueue; void run() { while (imgQueue.size() > 0) { mutex.lock(); std::pair data = imgQueue.dequeue(); mutex.unlock(); cv::imwrite(data.first, data.second); data.second.release(); } } void addData(std::string str, cv::Mat& mat) { try { if (mat.data == nullptr || &mat == nullptr) { qDebug() << "在存图线程中发现无效图像"; return; } } catch(...) { qDebug() << "在存图线程中发现无效图像"; return; } mutex.lock(); cv::Mat img; mat.copyTo(img); imgQueue.append(std::make_pair(str, img)); mutex.unlock(); this->start(); } }; class imgSaveThreadManager { public: imgSaveThreadManager(); ~imgSaveThreadManager(); imgSaveThread saveThread; std::string genDirName(std::shared_ptr data, imgSaveThreadType type) { //sqlTableDatas sqlRes = sql->selectSingleData("saveHour", data->SNcode);//查找之前的数据 //获取关键数据 std::string imgSaveDirStr = path;//所有图片的路径 sample "D://CCD" std::string imgTypeDirStr;//二级目录,图片类型决定 sample "Result" std::string dateDirStr;//三级目录,日期决定 sample"2024-6-8" std::string hourDirStr;//四级目录,小时段决定 sample "14H" std::string detailNameStr;//五级目录 主要是SN,如没有sn则可能是相机名称 #pragma region 赋值 //imgTypeDirStr switch (type) { case oriImg: imgTypeDirStr = "Yuantu"; break; case resImg: imgTypeDirStr = "Result"; break; case additionalSaveNgImg: imgTypeDirStr = "NGIMG"; break; default: imgTypeDirStr = "error"; } //dateDirStr hourDirStr //if (sqlRes.rowDatas.size() > 0 && sqlRes.rowDatas[0][0].value != "")//数据存在 //{ // dateDirStr = sqlRes.tableName; // hourDirStr = sqlRes.rowDatas[0][0].value + "H"; //} //else//数据不存在 新建数据 { QDateTime currentDateTime = QDateTime::currentDateTime(); dateDirStr = currentDateTime.toString("yyyy-MM-dd").toStdString(); hourDirStr = std::to_string(currentDateTime.time().hour()) + "H//"; } //detailNameStr if ((data->SNcode).length() != 0) detailNameStr = data->SNcode; else detailNameStr = data->cameraKeyName; #pragma endregion return std::string(imgSaveDirStr + "/" + imgTypeDirStr + "/" + dateDirStr + "/" + hourDirStr + "/" + detailNameStr + "/"); } std::vector genFileNmaes(std::shared_ptr data, imgSaveThreadType type) { std::vector resultFileNames; std::string fileName; for (auto str : data->imgSaveFileParameter) fileName += str + "_"; switch (type) { case oriImg: for (int i = 0; i < data->oriImgs.size(); i++) resultFileNames.push_back(fileName + getCurrentDateTime() + "_Count" + std::to_string(i) + ".bmp"); break; case resImg: for (int i = 0; i < data->resultImgs.size(); i++) resultFileNames.push_back(fileName + getCurrentDateTime() + "_Count" + std::to_string(i) + ".jpg"); break; case segImg: for (int i = 0; i < data->segOriginImgs.size(); i++) resultFileNames.push_back(fileName + "SEG_" + getCurrentDateTime() + "_" + std::to_string(i) + ".bmp"); break; case clsImg: for (int i = 0; i < data->clsOriginImgs.size(); i++) resultFileNames.push_back(fileName + "CLS_RES" + getCurrentDateTime() + "_" + data->clsOriginImgs[i].first + "_Count" + std::to_string(i) + ".bmp"); break; case additionalSaveNgImg: if (data->aiDetOK == false || data->halconOK == false) { for (int i = 0; i < data->segOriginImgs.size(); i++) resultFileNames.push_back(fileName + "NGIMG_" + getCurrentDateTime() + "_" + std::to_string(i) + ".bmp"); } break; } return resultFileNames; } void saveOri(std::shared_ptr data) { std::string fileSavePath = genDirName(data, oriImg);//获取文件夹名 createDirectoryIfNotExists(fileSavePath);//不存在此文件夹则创建 std::vectorfileNames = genFileNmaes(data, oriImg); for (int index = 0; index < fileNames.size(); index++) saveThread.addData(fileSavePath+fileNames[index], data->oriImgs[index]); } void saveRes(std::shared_ptr data) { std::string fileSavePath = genDirName(data, resImg);//获取文件夹名 createDirectoryIfNotExists(fileSavePath);//不存在此文件夹则创建 //结果图保存 std::vectorresFileNames = genFileNmaes(data, resImg); for (int index = 0; index < resFileNames.size(); index++) { saveThread.addData(fileSavePath + resFileNames[index], data->resultImgs[index]); if (data->resImgSavePath.size() > index) *data->resImgSavePath[index] = fileSavePath + resFileNames[index]; } //seg std::string segAndClsPath = fileSavePath + "detImgs//" + getCurrentDateTime() + "//"; std::vectorsegFileNames = genFileNmaes(data, segImg); if (segFileNames.size() > 0) createDirectoryIfNotExists(segAndClsPath);//不存在此文件夹则创建 for (int index = 0; index < segFileNames.size(); index++) saveThread.addData(segAndClsPath + segFileNames[index], data->segOriginImgs[index]); //cls std::vectorclsFileNames = genFileNmaes(data, clsImg); for (int index = 0; index < clsFileNames.size(); index++) saveThread.addData(segAndClsPath + clsFileNames[index], data->clsOriginImgs[index].second); //额外储存NG文件夹 //std::string additionalSaveNgImgPath = genDirName(data, additionalSaveNgImg); //std::vectoradditionalSaveNgImgNames = genFileNmaes(data, additionalSaveNgImg); //if (additionalSaveNgImgNames.size() > 0) // createDirectoryIfNotExists(additionalSaveNgImgPath);//不存在此文件夹则创建 //for (int index = 0; index < additionalSaveNgImgNames.size(); index++) // saveThread.addData(additionalSaveNgImgPath + additionalSaveNgImgNames[index], data->resultImgs[index]); } private: std::string path = ""; }; #pragma once