|
|
/*
|
|
|
* @Author: your name
|
|
|
* @Date: 2022-04-20 15:50:00
|
|
|
* @LastEditTime: 2025-09-22 16:44:43
|
|
|
* @LastEditors: xiewenji 527774126@qq.com
|
|
|
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
|
|
* @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp
|
|
|
*/
|
|
|
#include "ALLImgCheckAnalysisy.hpp"
|
|
|
#include "CheckUtil.hpp"
|
|
|
#include "Define.h"
|
|
|
#include "AI_Factory.h"
|
|
|
#include <fstream>
|
|
|
|
|
|
std::vector<ReadFlawCode> m_FlawCodeList;
|
|
|
|
|
|
std::vector<std::string> QX_Result_Names =
|
|
|
{
|
|
|
"OK",
|
|
|
"aotudian",
|
|
|
"other",
|
|
|
"line",
|
|
|
"zangwu",
|
|
|
"edge",
|
|
|
"ymhs",
|
|
|
"dianzhuang",
|
|
|
"posun",
|
|
|
"xianwei",
|
|
|
"shuizi",
|
|
|
"danban",
|
|
|
"fuchen",
|
|
|
};
|
|
|
std::vector<std::string> QX_Result_Code =
|
|
|
{
|
|
|
"P0000",
|
|
|
"MA507",
|
|
|
"MA508",
|
|
|
"MA506",
|
|
|
"MA504",
|
|
|
"MA503",
|
|
|
"MA502",
|
|
|
"MA505",
|
|
|
"MA501",
|
|
|
"P0001",
|
|
|
"P0002",
|
|
|
"P0003",
|
|
|
"P0004",
|
|
|
};
|
|
|
|
|
|
int ReadFlawCodeConfig(std::string json_path)
|
|
|
{
|
|
|
m_FlawCodeList.erase(m_FlawCodeList.begin(), m_FlawCodeList.end());
|
|
|
std::string strPath = json_path;
|
|
|
printf("ReadFlawCodeConfig path %s\n", strPath.c_str());
|
|
|
Json::CharReaderBuilder builder;
|
|
|
builder["collectComments"] = true;
|
|
|
Json::Value root;
|
|
|
std::string err;
|
|
|
std::ifstream ifs(strPath);
|
|
|
if (!ifs.is_open())
|
|
|
{
|
|
|
printf("error:file is open\n");
|
|
|
return 0;
|
|
|
}
|
|
|
if (!Json::parseFromStream(builder, ifs, &root, &err))
|
|
|
{
|
|
|
printf("error:parseFromStream\n");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < root.size(); i++)
|
|
|
{
|
|
|
// printf("Node idx %d /%d \n", i, root.size());
|
|
|
|
|
|
ReadFlawCode tem;
|
|
|
tem.flaw_name = root[i]["zh_name"].asString();
|
|
|
tem.flaw_code = root[i]["en_name"].asString();
|
|
|
string desc = root[i]["desc"].asString();
|
|
|
{
|
|
|
|
|
|
std::istringstream stream(desc);
|
|
|
std::string token;
|
|
|
|
|
|
// 使用 getline 按照分号分割
|
|
|
while (std::getline(stream, token, ';'))
|
|
|
{
|
|
|
tem.config_flaw_name.push_back(token);
|
|
|
}
|
|
|
}
|
|
|
m_FlawCodeList.push_back(tem);
|
|
|
}
|
|
|
for(int i = 0; i < m_FlawCodeList.size(); i++)
|
|
|
{
|
|
|
if(i >= QX_Result_Names.size()) {
|
|
|
QX_Result_Names.push_back(m_FlawCodeList.at(i).flaw_name);
|
|
|
QX_Result_Code.push_back(m_FlawCodeList.at(i).flaw_code);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
QX_Result_Names.at(i) = m_FlawCodeList.at(i).flaw_name;
|
|
|
QX_Result_Code.at(i) = m_FlawCodeList.at(i).flaw_code;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
double calculateDistanceBetweenRectCenters(const cv::Rect &rect1, const cv::Rect &rect2, float fx, float fy)
|
|
|
{
|
|
|
// 计算矩形1的中心点
|
|
|
cv::Point center1(rect1.x + rect1.width / 2, rect1.y + rect1.height / 2);
|
|
|
|
|
|
// 计算矩形2的中心点
|
|
|
cv::Point center2(rect2.x + rect2.width / 2, rect2.y + rect2.height / 2);
|
|
|
center1.x *= fx;
|
|
|
center1.y *= fy;
|
|
|
|
|
|
center2.x *= fx;
|
|
|
center2.y *= fy;
|
|
|
|
|
|
// 计算中心点之间的欧几里得距离
|
|
|
double distance = cv::norm(center1 - center2);
|
|
|
|
|
|
return distance;
|
|
|
}
|
|
|
|
|
|
ALLImgCheckAnalysisy::ALLImgCheckAnalysisy()
|
|
|
{
|
|
|
|
|
|
m_strTest = "";
|
|
|
m_pdetlog = std::make_shared<DetLog>();
|
|
|
}
|
|
|
|
|
|
ALLImgCheckAnalysisy::~ALLImgCheckAnalysisy()
|
|
|
{
|
|
|
StopThread();
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::split_img(cv::Mat img, std::vector<cv::Mat> &out_img_list)
|
|
|
{
|
|
|
out_img_list.clear();
|
|
|
if (img.empty() || img.rows < 2)
|
|
|
{
|
|
|
return -1;
|
|
|
}
|
|
|
// 上下拆分成两张
|
|
|
int half = img.rows / 2;
|
|
|
out_img_list.push_back(img(cv::Rect(0, 0, img.cols, half)).clone());
|
|
|
out_img_list.push_back(img(cv::Rect(0, half, img.cols, img.rows - half)).clone());
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::RunStart(void *pconfig1)
|
|
|
{
|
|
|
VERSION_INFO *pVersionconfig = (VERSION_INFO *)pconfig1;
|
|
|
if (pVersionconfig == NULL)
|
|
|
{
|
|
|
printf("**************************** \n");
|
|
|
m_nErrorCode = CHECK_ERROR_VERSION; // 参数或接口版本问题
|
|
|
return m_nErrorCode;
|
|
|
}
|
|
|
|
|
|
int v1 = ALL_INTERFACE_VERSION;
|
|
|
int v2 = CONFIGBASE_VERSION;
|
|
|
int v3 = RESULT_VERSION;
|
|
|
printf("**************************** ALL_INTERFACE_VERSION so: %d in:%d CONFIGBASE_VERSION so:%d in:%d RESULT_VERSION so:%d in:%d\n",
|
|
|
v1, pVersionconfig->InterfaceVersion, v2, pVersionconfig->ConfigVersion, v3, pVersionconfig->ResultVersion);
|
|
|
// 版本控制
|
|
|
if (pVersionconfig->InterfaceVersion != ALL_INTERFACE_VERSION ||
|
|
|
pVersionconfig->ConfigVersion != CONFIGBASE_VERSION ||
|
|
|
pVersionconfig->ResultVersion != RESULT_VERSION)
|
|
|
{
|
|
|
m_nErrorCode = CHECK_ERROR_VERSION; // 参数或接口版本问题
|
|
|
return m_nErrorCode;
|
|
|
}
|
|
|
int re = 0;
|
|
|
|
|
|
re = InitCameraCheckAnalysisy();
|
|
|
if (re != 0)
|
|
|
{
|
|
|
printf("*************InitCameraCheckAnalysisy error %d*************** \n", re);
|
|
|
m_nErrorCode = INIT_CameraCheck_Error;
|
|
|
return m_nErrorCode;
|
|
|
}
|
|
|
|
|
|
re = InitRun();
|
|
|
if (CHECK_OK != re)
|
|
|
{
|
|
|
m_nErrorCode = re;
|
|
|
return m_nErrorCode;
|
|
|
}
|
|
|
re = InitAIFactory();
|
|
|
if (CHECK_OK != re)
|
|
|
{
|
|
|
m_nErrorCode = re;
|
|
|
return m_nErrorCode;
|
|
|
}
|
|
|
re = InitTemplateMask();
|
|
|
if (CHECK_OK != re)
|
|
|
{
|
|
|
m_nErrorCode = re;
|
|
|
return m_nErrorCode;
|
|
|
}
|
|
|
// 把模板信息下发到各个相机检测实例
|
|
|
for (auto &item : m_pCameraCheckAnalysisyList)
|
|
|
{
|
|
|
if (item.second)
|
|
|
{
|
|
|
item.second->SetTplInfo(m_tplOuterRect, m_tplPinContours);
|
|
|
}
|
|
|
}
|
|
|
m_nErrorCode = CHECK_OK;
|
|
|
printf(">>>> ALLImgCheckAnalysisy Start Succ \n");
|
|
|
|
|
|
m_nErrorCode = CHECK_OK;
|
|
|
m_bInitSucc = true;
|
|
|
return m_nErrorCode;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::SetDataRun_SharePtr(std::shared_ptr<shareImage> p)
|
|
|
{
|
|
|
|
|
|
int re = PushInImg_New(p);
|
|
|
|
|
|
// printf("SetDataRun_SharePtr======================= re %d \n", re);
|
|
|
|
|
|
return re;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::GetCheckReuslt(std::shared_ptr<CheckResult> &pResult)
|
|
|
{
|
|
|
std::unique_lock<std::mutex> lk(mtx_CheckResult); // 使用 unique_lock
|
|
|
CheckResult_cond.wait(lk, [this]
|
|
|
{ return !m_CheckResultList.empty(); }); // 等待直到数据队列非空
|
|
|
pResult = m_CheckResultList.front(); // 从队列中取出数
|
|
|
m_CheckResultList.pop();
|
|
|
lk.unlock();
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::ReJson(std::shared_ptr<shareImage> p, std::shared_ptr<CheckResult> &pResult)
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::CheckImg(std::shared_ptr<shareImage> p, std::shared_ptr<CheckResult> &pResult)
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::GetStatus()
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::UpdateConfig(void *pconfig, int nConfigType)
|
|
|
{
|
|
|
int re = 0;
|
|
|
RunInfoST *tempconfig;
|
|
|
switch (nConfigType)
|
|
|
{
|
|
|
case CHECK_CONFIG_Run:
|
|
|
tempconfig = (RunInfoST *)pconfig;
|
|
|
m_RunConfig.copy(*tempconfig);
|
|
|
break;
|
|
|
case CHECK_CONFIG_Module:
|
|
|
m_pConfigManager = (ConfigManagerBase *)pconfig;
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
std::string ALLImgCheckAnalysisy::GetVersion()
|
|
|
{
|
|
|
return std::string("BOE_2.0.5");
|
|
|
}
|
|
|
|
|
|
std::string ALLImgCheckAnalysisy::GetErrorInfo()
|
|
|
{
|
|
|
std::string result = "";
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::ErrorReturn(std::shared_ptr<shareImage> p)
|
|
|
{
|
|
|
|
|
|
std::shared_ptr<CheckResult> result = std::make_shared<CheckResult>();
|
|
|
result->in_shareImage = p;
|
|
|
result->checkStatus = 1;
|
|
|
result->nresult = -CHECK_ERROR_PushImg_ID_Error;
|
|
|
result->basicResult.img_id = p->img_id;
|
|
|
result->basicResult.imgtype = p->imgtype;
|
|
|
result->basicResult.imgstr = p->imgstr;
|
|
|
result->basicResult.strChannel = p->strChannel;
|
|
|
// printf("ErrorReturn==== %s %s\n", p->strImgProductID.c_str(), p->strChannel.c_str());
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_CheckResult);
|
|
|
m_CheckResultList.push(result);
|
|
|
}
|
|
|
CheckResult_cond.notify_all();
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
std::shared_ptr<Product> ALLImgCheckAnalysisy::GetProduct(std::string strProduct)
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_ProductList);
|
|
|
for (int i = 0; i < m_ProductList.size(); i++)
|
|
|
{
|
|
|
// printf("ddd %s \n", m_ProductList.at(i)->productBaseResult->strproductName.c_str());
|
|
|
if (m_ProductList.at(i)->productBaseResult->strproductName == strProduct)
|
|
|
{
|
|
|
return m_ProductList.at(i);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return std::shared_ptr<Product>();
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::InitAIFactory()
|
|
|
{
|
|
|
std::shared_ptr<AIFactory> AI_Factory;
|
|
|
AI_Factory = AIFactory::GetInstance();
|
|
|
|
|
|
GPU_Config gpu;
|
|
|
gpu.gpu_0 = true;
|
|
|
gpu.gpu_1 = true;
|
|
|
|
|
|
AI_Factory->InitALLAIModle(gpu);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::InitTemplateMask()
|
|
|
{
|
|
|
std::shared_ptr<AIFactory> AI_Factory = AIFactory::GetInstance();
|
|
|
if (!AI_Factory || !AI_Factory->Align_Outer || !AI_Factory->Pin_Loc)
|
|
|
{
|
|
|
return -1;
|
|
|
}
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "---Init Tpl---" , "start");
|
|
|
|
|
|
// 模板图路径,暂时使用固定路径
|
|
|
string tplImgPath = "/home/aidlux/BOE/ZB_PLATE/Tpl/tpl.bmp"; // 模板图片路径
|
|
|
Mat tplImg = imread(tplImgPath, IMREAD_UNCHANGED);
|
|
|
if (tplImg.empty())
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "", "Failed to load template image!");
|
|
|
return -2;
|
|
|
}
|
|
|
|
|
|
// 模板外接矩形,通过模型Align_Outer得到
|
|
|
RotatedRect tplOuterRect; // 模板外接矩形
|
|
|
std::shared_ptr<AIModel_Base> pBackPlate_Align;
|
|
|
pBackPlate_Align = AI_Factory->Align_Outer;
|
|
|
cv::Size sz;
|
|
|
sz.width = pBackPlate_Align->input_0.width;
|
|
|
sz.height = pBackPlate_Align->input_0.height;
|
|
|
cv::Mat detImg;
|
|
|
cout << "imgSize: " << tplImg.size() << ", " << "detImgSize: " << detImg.size() << ", " << "szSize: " << sz << endl;
|
|
|
|
|
|
cv::resize(tplImg, detImg, sz);
|
|
|
int re = 0;
|
|
|
cv::Mat mask;
|
|
|
if (detImg.channels() != 1)
|
|
|
{
|
|
|
cv::cvtColor(detImg, detImg, cv::COLOR_RGB2GRAY);
|
|
|
}
|
|
|
|
|
|
re = pBackPlate_Align->AIDet(detImg, mask);
|
|
|
if (re != 0)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "Init Tpl", "AICheck_Edge----error %d ", re);
|
|
|
int re123 = 100 + re;
|
|
|
return re123;
|
|
|
}
|
|
|
|
|
|
// 找到最大轮廓
|
|
|
bool found;
|
|
|
std::vector<cv::Point> boundingBox = CheckUtil::getLargestContourROI(mask, found);
|
|
|
if (!found)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "AI_Edge_Algin ", "No contours found!----error ");
|
|
|
return 4;
|
|
|
}
|
|
|
// 边缘轮廓点集还原为原图坐标,并计算得到RotateROI
|
|
|
if (sz.width <= 0 || sz.height <= 0)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "AI_Edge_Algin ", "invalid model input size!----error ");
|
|
|
return 5;
|
|
|
}
|
|
|
// 检测小图 到 原图 的缩放比例
|
|
|
const float scale_x = static_cast<float>(tplImg.cols) / sz.width;
|
|
|
const float scale_y = static_cast<float>(tplImg.rows) / sz.height;
|
|
|
// 轮廓点还原到原图坐标系
|
|
|
std::vector<cv::Point2f> srcContour;
|
|
|
srcContour.reserve(boundingBox.size());
|
|
|
for (const auto &pt : boundingBox)
|
|
|
{
|
|
|
srcContour.emplace_back(pt.x * scale_x, pt.y * scale_y);
|
|
|
}
|
|
|
|
|
|
if (srcContour.size() < 3)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "AI_Edge_Algin ", "contour points too few!----error ");
|
|
|
return 6;
|
|
|
}
|
|
|
tplOuterRect = cv::minAreaRect(srcContour);
|
|
|
|
|
|
// 模板Pinmask,通过模型Pin_Loc得到
|
|
|
Mat tplPinMask; // 模板mask
|
|
|
std::shared_ptr<AIModel_Base> pBackPlate_Pin;
|
|
|
pBackPlate_Pin = AI_Factory->Pin_Loc;
|
|
|
sz.width = pBackPlate_Pin->input_0.width;
|
|
|
sz.height = pBackPlate_Pin->input_0.height;
|
|
|
cv::Mat pinImg = tplImg(tplOuterRect.boundingRect()).clone(); // 裁剪模板图像为外接矩形区域
|
|
|
cout << "imgSize: " << tplImg.size() << ", " << "pinImgSize: " << pinImg.size() << ", " << "szSize: " << sz << endl;
|
|
|
|
|
|
cv::resize(pinImg, detImg, sz);
|
|
|
if (detImg.channels() != 1)
|
|
|
{
|
|
|
cv::cvtColor(detImg, detImg, cv::COLOR_RGB2GRAY);
|
|
|
}
|
|
|
|
|
|
re = pBackPlate_Pin->AIDet(detImg, tplPinMask);
|
|
|
if (re != 0)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "AI_Pin ", "AICheck_Pin----error %d ", re);
|
|
|
int re123 = 100 + re;
|
|
|
return re123;
|
|
|
}
|
|
|
|
|
|
// 统计tplPinMask的blob边缘点,并绘制到tplImg上
|
|
|
vector<vector<Point>> pin_contours;
|
|
|
vector<Vec4i> hierarchy;
|
|
|
cv::findContours(tplPinMask, pin_contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
|
// mask 尺寸 -> 裁剪图(pinImg) 尺寸 的缩放比例
|
|
|
const float pin_scale_x = (tplPinMask.cols > 0) ? static_cast<float>(pinImg.cols) / tplPinMask.cols : 0.0f;
|
|
|
const float pin_scale_y = (tplPinMask.rows > 0) ? static_cast<float>(pinImg.rows) / tplPinMask.rows : 0.0f;
|
|
|
// 将轮廓点从 mask 坐标系 映射回 tplImg 坐标系
|
|
|
m_tplPinContours.clear();
|
|
|
m_tplPinContours.reserve(pin_contours.size());
|
|
|
for (size_t i = 0; i < pin_contours.size(); i++)
|
|
|
{
|
|
|
std::vector<cv::Point> mapped;
|
|
|
mapped.reserve(pin_contours[i].size());
|
|
|
for (const auto &pt : pin_contours[i])
|
|
|
{
|
|
|
mapped.emplace_back(cvRound(pt.x * pin_scale_x),
|
|
|
cvRound(pt.y * pin_scale_y));
|
|
|
}
|
|
|
m_tplPinContours.push_back(mapped);
|
|
|
}
|
|
|
// 保存模板外接矩形
|
|
|
m_tplOuterRect = tplOuterRect;
|
|
|
|
|
|
// 绘制到 tplImg 上
|
|
|
{
|
|
|
Mat showImg = pinImg.clone();
|
|
|
cv::drawContours(pinImg, m_tplPinContours, -1, Scalar(0, 255, 0), 2);
|
|
|
cv::imwrite("/home/aidlux/BOE/ZB_PLATE/Tpl/tpl_pin_contours.png", pinImg);
|
|
|
}
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_1, "---Init Tpl---" , "end");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::LoadRunConfig(void *p)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::LoadCheckConfig(void *p)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::InitRun()
|
|
|
{
|
|
|
int re;
|
|
|
re = StartThread();
|
|
|
if (CHECK_OK != re)
|
|
|
{
|
|
|
return re;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::StartCheck()
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::SetIDLE()
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::StartThread()
|
|
|
{
|
|
|
m_bExit = false;
|
|
|
|
|
|
{ // 开启检测线程
|
|
|
ptr_thread_Run = std::make_shared<std::thread>(std::bind(&ALLImgCheckAnalysisy::Run, this));
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::StopThread()
|
|
|
{
|
|
|
m_bExit = true;
|
|
|
if (ptr_thread_Run != nullptr)
|
|
|
{
|
|
|
if (ptr_thread_Run->joinable())
|
|
|
{
|
|
|
ptr_thread_Run->join();
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::ExitSystem()
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::InitCameraCheckAnalysisy()
|
|
|
{
|
|
|
string defect_list_file = m_pConfigManager->GetJsonPath();
|
|
|
if (defect_list_file == "") {
|
|
|
defect_list_file = "/var/aidlux/efs/model/defect_list.json";
|
|
|
}
|
|
|
else{
|
|
|
defect_list_file += "/defect_list.json";
|
|
|
}
|
|
|
ReadFlawCodeConfig(defect_list_file);
|
|
|
m_pCameraCheckAnalysisyList.clear();
|
|
|
for (const auto &config : m_pConfigManager->Config_instances_)
|
|
|
{
|
|
|
|
|
|
std::cout << "key: " << config.first << std::endl;
|
|
|
std::shared_ptr<CameraCheckAnalysisy> p = std::make_shared<CameraCheckAnalysisy>();
|
|
|
|
|
|
p->m_RunConfig.copy(m_RunConfig);
|
|
|
p->m_pConfig = config.second;
|
|
|
int re = p->Init(config.first);
|
|
|
if (re != 0)
|
|
|
{
|
|
|
std::cout << "Init CameraCheckAnalysisy " << config.first << " Failed" << std::endl;
|
|
|
return -1;
|
|
|
}
|
|
|
m_pCameraCheckAnalysisyList[config.first] = p;
|
|
|
}
|
|
|
if (m_pCameraCheckAnalysisyList.size() <= 0)
|
|
|
{
|
|
|
printf("ALLImgCheckAnalysisy::InitCameraCheckAnalysisy error camera config is null \n");
|
|
|
return 1;
|
|
|
/* code */
|
|
|
}
|
|
|
|
|
|
// for (const auto &pCameraCheckAnalysisy : m_pCameraCheckAnalysisyList)
|
|
|
// {
|
|
|
// std::cout << "key: " << pCameraCheckAnalysisy.first << std::endl;
|
|
|
// }
|
|
|
printf("ALLImgCheckAnalysisy::InitCameraCheckAnalysisy end \n");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::InitData()
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::Det_Product(std::shared_ptr<Product> &product)
|
|
|
{
|
|
|
|
|
|
// 处理每个相机
|
|
|
while (true)
|
|
|
{
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(product->mtx_CameraResultList); //
|
|
|
for (auto &ptr : product->m_pCameraResultList)
|
|
|
{
|
|
|
if (ptr->GetCheckStep() == Check_Step_NODet)
|
|
|
{
|
|
|
m_pCameraCheckAnalysisyList[ptr->cameraBaseResult->strCameraName]->StartCheck(ptr);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 判断每个相机是否都处理完了。
|
|
|
bool bdetComplete = product->bCheckCamplate();
|
|
|
// 处理完成,退出循环
|
|
|
if (bdetComplete)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 联合分析
|
|
|
// AnalysiyAll(0);
|
|
|
SetProductResult(product);
|
|
|
product->SetCheckEnd();
|
|
|
string cur_time = CheckUtil::getCurTimeHMS();
|
|
|
printf("[%s]>>>>>>>>>>>>>>>Det_Product****************det End************\n", cur_time.c_str());
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
std::shared_ptr<Product> ALLImgCheckAnalysisy::GetProduct()
|
|
|
{
|
|
|
|
|
|
std::unique_lock<std::mutex> lk(mtx_ProductList); // 使用 unique_lock
|
|
|
ProductList_cond.wait(lk, [this]
|
|
|
{ return !m_ProductList.empty(); }); // 等待直到数据队列非空
|
|
|
std::shared_ptr<Product> tem = m_ProductList.at(0);
|
|
|
lk.unlock();
|
|
|
return tem;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::AnalysiyAll(int productIdx)
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::SetProductResult(std::shared_ptr<Product> product)
|
|
|
{
|
|
|
|
|
|
int nDetCamNum = product->m_pCameraResultList.size();
|
|
|
// 相机2的起始位置
|
|
|
bool bNG = false;
|
|
|
for (int icam = 0; icam < nDetCamNum; icam++)
|
|
|
{
|
|
|
|
|
|
std::shared_ptr<CameraResult> pcam = product->m_pCameraResultList.at(icam);
|
|
|
for (int i = 0; i < pcam->ImageALLDetResultList.size(); i++)
|
|
|
{
|
|
|
|
|
|
std::shared_ptr<CheckResult> pCheckResult = pcam->ImageALLDetResultList.at(i)->result;
|
|
|
|
|
|
if (pCheckResult->qxImageResult.size() > 0)
|
|
|
{
|
|
|
bNG = true;
|
|
|
}
|
|
|
if (bNG)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (bNG)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (bNG)
|
|
|
{
|
|
|
for (int icam = 0; icam < nDetCamNum; icam++)
|
|
|
{
|
|
|
|
|
|
std::shared_ptr<CameraResult> pcam = product->m_pCameraResultList.at(icam);
|
|
|
for (int i = 0; i < pcam->ImageALLDetResultList.size(); i++)
|
|
|
{
|
|
|
|
|
|
std::shared_ptr<CheckResult> pCheckResult = pcam->ImageALLDetResultList.at(i)->result;
|
|
|
pCheckResult->nProductResult = 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::SetSetComplet_New(std::shared_ptr<Product> product, int nerror)
|
|
|
{
|
|
|
if (product)
|
|
|
{
|
|
|
|
|
|
int nDetCamNum = product->m_pCameraResultList.size();
|
|
|
for (int icam = 0; icam < nDetCamNum; icam++)
|
|
|
{
|
|
|
std::shared_ptr<CameraResult> pcam = product->m_pCameraResultList.at(icam);
|
|
|
for (int i = 0; i < pcam->ImageALLDetResultList.size(); i++)
|
|
|
{
|
|
|
std::shared_ptr<CheckResult> pCheckResult = pcam->ImageALLDetResultList.at(i)->result;
|
|
|
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock123(mtx_CheckResult);
|
|
|
m_CheckResultList.push(pCheckResult);
|
|
|
}
|
|
|
CheckResult_cond.notify_all();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::PushInImg_New(std::shared_ptr<shareImage> p)
|
|
|
{
|
|
|
|
|
|
if (!m_bInitSucc)
|
|
|
{
|
|
|
printf("Init fail exit \n");
|
|
|
return CHECK_ERROR_Config_Null;
|
|
|
}
|
|
|
|
|
|
std::string strlog = "";
|
|
|
m_strTest += " PushInImg->SN:";
|
|
|
m_strTest += p->strImgProductID;
|
|
|
m_strTest += " Channel:";
|
|
|
m_strTest += p->strChannel;
|
|
|
m_strTest += " CameraID:";
|
|
|
m_strTest += p->strCameraName;
|
|
|
std::string strBase = "";
|
|
|
strBase += " PushInImg->SN:";
|
|
|
strBase += p->strImgProductID;
|
|
|
strBase += " Channel:";
|
|
|
strBase += p->strChannel;
|
|
|
printf("strBase %s p->Status %d\n", strBase.c_str(), p->Status);
|
|
|
std::shared_ptr<Product> product;
|
|
|
{
|
|
|
std::string strcameraName = p->strCameraName;
|
|
|
cout << "strcameraName: " << strcameraName << endl;
|
|
|
if(m_pCameraCheckAnalysisyList.size() <= 0){
|
|
|
cout << "m_pCameraCheckAnalysisyList.size(): " << m_pCameraCheckAnalysisyList.size() << endl;
|
|
|
}
|
|
|
for (auto it = m_pCameraCheckAnalysisyList.begin(); it != m_pCameraCheckAnalysisyList.end(); ++it) {
|
|
|
std::cout << "m_pCameraCheckAnalysisyList_Key: " << it->first << std::endl;
|
|
|
}
|
|
|
// 判断 相机名称是否存在
|
|
|
|
|
|
if (!m_pCameraCheckAnalysisyList.count(strcameraName) && -1 != p->Status)
|
|
|
{
|
|
|
return CHECK_ERROR_Camear_ID_Error;
|
|
|
}
|
|
|
|
|
|
product = GetProduct(p->strImgProductID);
|
|
|
bool ProductID_Exist = false; // 是否存在当前产品ID
|
|
|
if (product)
|
|
|
{
|
|
|
ProductID_Exist = true;
|
|
|
}
|
|
|
|
|
|
// 产品存在 并且 模式 是第一张图, 则,返回异常。
|
|
|
if (IN_IMG_Status_Start == p->Status && ProductID_Exist)
|
|
|
{
|
|
|
return CHECK_ERROR_PRODUCT_ID_EXIST;
|
|
|
}
|
|
|
// 产品存在,但是 图片都已经完了的状态
|
|
|
if (ProductID_Exist && product->bIsImgComplete)
|
|
|
{
|
|
|
ErrorReturn(p);
|
|
|
return CHECK_ERROR_PRODUCT_ID_EXIST;
|
|
|
}
|
|
|
// 产品不存在 新建一个
|
|
|
if (!product)
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_ProductList);
|
|
|
{
|
|
|
if (m_ProductList.size() > 5)
|
|
|
{
|
|
|
|
|
|
return CHECK_ERROR_PushImg_ListSize;
|
|
|
}
|
|
|
}
|
|
|
product = std::make_shared<Product>();
|
|
|
product->productBaseResult->strproductName = p->strImgProductID;
|
|
|
m_ProductList.push_back(product);
|
|
|
std::string strTimg = CheckUtil::getCurTimeHMS();
|
|
|
product->productBaseResult->detlog->AddCheckstr(PrintLevel_0, "PushInImg", "add new product %s %s ", p->strImgProductID.c_str(), strTimg.c_str());
|
|
|
}
|
|
|
// 送入图的状态 不是结束
|
|
|
if (-1 != p->Status)
|
|
|
{
|
|
|
// 对应相机的 检测结果
|
|
|
std::shared_ptr<CameraResult> pCamera = product->GetCameraResult(strcameraName);
|
|
|
|
|
|
if (pCamera.get() == nullptr)
|
|
|
{
|
|
|
ErrorReturn(p);
|
|
|
return CHECK_ERROR_Camear_ID_Error;
|
|
|
}
|
|
|
// 添加产品信息
|
|
|
pCamera->AddDetImage(p);
|
|
|
}
|
|
|
product->UpdatePushStatus(p->Status);
|
|
|
if (-1 == p->Status || IN_IMG_Status_End == p->Status)
|
|
|
{
|
|
|
m_strTest += "\n";
|
|
|
product->AddLog(m_strTest);
|
|
|
m_strTest = "";
|
|
|
}
|
|
|
|
|
|
ProductList_cond.notify_all();
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int ALLImgCheckAnalysisy::Run()
|
|
|
{
|
|
|
|
|
|
while (!m_bExit)
|
|
|
{
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
|
|
|
|
|
std::shared_ptr<Product> product = GetProduct();
|
|
|
|
|
|
int re = Det_Product(product);
|
|
|
// // 检测失败
|
|
|
// if (re != 0)
|
|
|
// {
|
|
|
// continue;
|
|
|
// }
|
|
|
SetSetComplet_New(product, re);
|
|
|
|
|
|
// 更新 产品队列
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(mtx_ProductList); //
|
|
|
if (!m_ProductList.empty())
|
|
|
{
|
|
|
m_ProductList.erase(m_ProductList.begin());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
int ALLImgCheckAnalysisy::set_cpu_id(const std::vector<int> &cpu_set_vec)
|
|
|
{
|
|
|
// for cpu affinity
|
|
|
int nRet = 0;
|
|
|
#ifdef __linux
|
|
|
cpu_set_t _cur_cpu_set;
|
|
|
CPU_ZERO(&_cur_cpu_set);
|
|
|
for (auto _id : cpu_set_vec)
|
|
|
{
|
|
|
CPU_SET(_id, &_cur_cpu_set);
|
|
|
}
|
|
|
if (0 > pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &_cur_cpu_set))
|
|
|
{
|
|
|
perror("set cpu affinity failed: ");
|
|
|
printf("Warning: set cpu affinity failed ... ...\n");
|
|
|
nRet = -1;
|
|
|
}
|
|
|
#endif //__linux
|
|
|
return nRet;
|
|
|
}
|