|
|
|
|
@ -6,9 +6,11 @@
|
|
|
|
|
#include "MemMonitor.h"
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include "CheckUtil.hpp"
|
|
|
|
|
#include "LoadImage.hpp" // #include "LoadImage.h"
|
|
|
|
|
#include "JsonConfig.h"
|
|
|
|
|
#include "AI_Factory.h"
|
|
|
|
|
|
|
|
|
|
bool check_strChannel(string strChannel){
|
|
|
|
|
if(strChannel == "XD" || strChannel == "XON") return false;
|
|
|
|
|
@ -1298,6 +1300,15 @@ int deal::DetImg()
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AI 检测独立测试:读取 in 图 -> 模型推理 -> 保存 out 图(不做其他流程)
|
|
|
|
|
if (runConfig.det_Type == RUNTYPE_RUN_File_AI_DetTest)
|
|
|
|
|
{
|
|
|
|
|
m_nReadThread_type = READ_THREAD_TYPE_READIMG;
|
|
|
|
|
m_nSystemCheckType = CHECK_TYPE_OFFLING;
|
|
|
|
|
TestAIDet();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_nReadThread_type = READ_THREAD_TYPE_READIMG;
|
|
|
|
|
m_nSystemCheckType = CHECK_TYPE_OFFLING;
|
|
|
|
|
|
|
|
|
|
@ -1315,6 +1326,147 @@ int deal::DetImg()
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief AI 检测独立测试:遍历 /home/aidlux/BOE/FOG/AI_Detect/ 下所有 *_in.png,
|
|
|
|
|
/// 送入 AI_defect_NF 模型推理,将输出 *_out.png 保存到 /home/aidlux/BOE/FOG/AI_Detect_TEST/
|
|
|
|
|
/// @return 0 表示成功
|
|
|
|
|
int deal::TestAIDet()
|
|
|
|
|
{
|
|
|
|
|
std::string strSrcRoot = "/home/aidlux/BOE/FOG/AI_Detect/";
|
|
|
|
|
std::string strDstRoot = "/home/aidlux/BOE/FOG/AI_Detect_TEST/";
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<AIFactory> pAIFactory = AIFactory::GetInstance();
|
|
|
|
|
std::shared_ptr<AIModel_Base> pAI_Model = pAIFactory->AI_defect_NF;
|
|
|
|
|
if (!pAI_Model || !pAI_Model->m_bInitSuccess)
|
|
|
|
|
{
|
|
|
|
|
printf("TestAIDet: AI model (AI_defect_NF) not ready!\n");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("TestAIDet: model input [c=%d w=%d h=%d] output [c=%d w=%d h=%d]\n",
|
|
|
|
|
pAI_Model->input_0.channel, pAI_Model->input_0.width, pAI_Model->input_0.height,
|
|
|
|
|
pAI_Model->output_0.channel, pAI_Model->output_0.width, pAI_Model->output_0.height);
|
|
|
|
|
|
|
|
|
|
// 收集所有 *_in.png 文件
|
|
|
|
|
std::vector<std::string> inList;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (!fs::exists(strSrcRoot))
|
|
|
|
|
{
|
|
|
|
|
printf("TestAIDet: src dir not exist: %s\n", strSrcRoot.c_str());
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
for (const auto &entry : fs::recursive_directory_iterator(strSrcRoot))
|
|
|
|
|
{
|
|
|
|
|
if (!entry.is_regular_file())
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
std::string path = entry.path().string();
|
|
|
|
|
std::string name = entry.path().filename().string();
|
|
|
|
|
const std::string suffix = "_in.png";
|
|
|
|
|
if (name.size() >= suffix.size() &&
|
|
|
|
|
name.compare(name.size() - suffix.size(), suffix.size(), suffix) == 0)
|
|
|
|
|
{
|
|
|
|
|
inList.push_back(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (const std::exception &e)
|
|
|
|
|
{
|
|
|
|
|
printf("TestAIDet: traverse error %s\n", e.what());
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::sort(inList.begin(), inList.end());
|
|
|
|
|
printf("TestAIDet: total %zu in images\n", inList.size());
|
|
|
|
|
|
|
|
|
|
const int nModelInCh = pAI_Model->input_0.channel;
|
|
|
|
|
const int nModelInW = pAI_Model->input_0.width;
|
|
|
|
|
const int nModelInH = pAI_Model->input_0.height;
|
|
|
|
|
|
|
|
|
|
int nOK = 0;
|
|
|
|
|
for (size_t i = 0; i < inList.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
const std::string &inPath = inList[i];
|
|
|
|
|
cv::Mat inImg = cv::imread(inPath, cv::IMREAD_UNCHANGED);
|
|
|
|
|
if (inImg.empty())
|
|
|
|
|
{
|
|
|
|
|
printf("[%zu/%zu] read fail: %s\n", i + 1, inList.size(), inPath.c_str());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 统一成模型要求的输入:单通道 8U、模型输入尺寸
|
|
|
|
|
if (inImg.channels() != nModelInCh)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat tmp;
|
|
|
|
|
if (inImg.channels() >= 3)
|
|
|
|
|
{
|
|
|
|
|
cv::cvtColor(inImg, tmp, cv::COLOR_BGR2GRAY);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tmp = inImg.clone();
|
|
|
|
|
}
|
|
|
|
|
inImg = tmp;
|
|
|
|
|
}
|
|
|
|
|
if (inImg.type() != CV_8U)
|
|
|
|
|
{
|
|
|
|
|
inImg.convertTo(inImg, CV_8U);
|
|
|
|
|
}
|
|
|
|
|
if (inImg.cols != nModelInW || inImg.rows != nModelInH)
|
|
|
|
|
{
|
|
|
|
|
cv::resize(inImg, inImg, cv::Size(nModelInW, nModelInH));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Mat outImg;
|
|
|
|
|
int re = pAI_Model->AIDet(inImg, outImg);
|
|
|
|
|
if (re != 0 || outImg.empty())
|
|
|
|
|
{
|
|
|
|
|
printf("[%zu/%zu] infer fail(%d): %s\n", i + 1, inList.size(), re, inPath.c_str());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 输出 resize 回模型输入尺寸(与 AI_Detect_QX 保存的 out 图尺寸保持一致)
|
|
|
|
|
if (outImg.cols != nModelInW || outImg.rows != nModelInH)
|
|
|
|
|
{
|
|
|
|
|
cv::resize(outImg, outImg, cv::Size(nModelInW, nModelInH), 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 相对路径,并保持子目录结构
|
|
|
|
|
std::string rel = inPath.substr(strSrcRoot.size());
|
|
|
|
|
std::string outRel = rel;
|
|
|
|
|
const std::string inSuffix = "_in.png";
|
|
|
|
|
const std::string outSuffix = "_out.png";
|
|
|
|
|
size_t pos = outRel.rfind(inSuffix);
|
|
|
|
|
if (pos != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
outRel.replace(pos, inSuffix.size(), outSuffix);
|
|
|
|
|
}
|
|
|
|
|
std::string outPath = strDstRoot + outRel;
|
|
|
|
|
|
|
|
|
|
// 创建输出父目录
|
|
|
|
|
fs::path outParent = fs::path(outPath).parent_path();
|
|
|
|
|
if (!outParent.empty())
|
|
|
|
|
{
|
|
|
|
|
std::error_code ec;
|
|
|
|
|
fs::create_directories(outParent, ec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cv::imwrite(outPath, outImg))
|
|
|
|
|
{
|
|
|
|
|
nOK++;
|
|
|
|
|
printf("[%zu/%zu] ok: %s -> %s\n", i + 1, inList.size(), rel.c_str(), outRel.c_str());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("[%zu/%zu] save fail: %s\n", i + 1, inList.size(), outPath.c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("TestAIDet: complete, success %d / %zu\n", nOK, inList.size());
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 检查文件图片
|
|
|
|
|
/// @detail 后续实现具体功能
|
|
|
|
|
/// @return 0 表示成功
|
|
|
|
|
|