Merge remote-tracking branch 'origin/dev_lsy' into dev_offline

dev_offline
liusiyang 4 weeks ago
commit 0537877995

@ -174,7 +174,8 @@ public:
std::shared_ptr<AIModel_Base> AI_defect_zf; // L127 L255 std::shared_ptr<AIModel_Base> AI_defect_zf; // L127 L255
std::shared_ptr<AIModel_Base> AI_defect_bq; // L127 L255 std::shared_ptr<AIModel_Base> AI_defect_bq;
std::shared_ptr<AIModel_Base> AI_defect_Tag;
std::shared_ptr<AIModel_Base> AI_defect_127Cell; // L127 L255 std::shared_ptr<AIModel_Base> AI_defect_127Cell; // L127 L255

@ -143,7 +143,7 @@ int AIFactory::InitALLAIModle(GPU_Config gupconfig)
boe_config.inputType = AIModel_Base::Input_CHW; boe_config.inputType = AIModel_Base::Input_CHW;
AI_defect_zf->Init(boe_config); AI_defect_zf->Init(boe_config);
} }
// 标签 检测 // 标签 定位
if (!AI_defect_bq) if (!AI_defect_bq)
{ {
AI_defect_bq = AIModel_Base::GetInstance(); AI_defect_bq = AIModel_Base::GetInstance();
@ -154,6 +154,17 @@ int AIFactory::InitALLAIModle(GPU_Config gupconfig)
boe_config.inputType = AIModel_Base::Input_CHW; boe_config.inputType = AIModel_Base::Input_CHW;
AI_defect_bq->Init(boe_config); AI_defect_bq->Init(boe_config);
} }
// 标签 检测
if (!AI_defect_Tag)
{
AI_defect_Tag = AIModel_Base::GetInstance();
AIModel_Base::AIModelRun_Config boe_config;
boe_config.gpuconfig.copy(gupconfig);
boe_config.strPath = "/home/aidlux/BOE/UseModel_FOG/defect_L127.engine";
boe_config.strName = "tag";
boe_config.inputType = AIModel_Base::Input_CHW;
AI_defect_Tag->Init(boe_config);
}
// 字符 127cell // 字符 127cell
if (!AI_defect_127Cell) if (!AI_defect_127Cell)
{ {

@ -175,6 +175,7 @@ public:
std::shared_ptr<Image_AI_Det_Result> qx_DetAIResult; // BLob 检测要用到的一些 参数 。 std::shared_ptr<Image_AI_Det_Result> qx_DetAIResult; // BLob 检测要用到的一些 参数 。
std::shared_ptr<Image_AI_Det_Result> cell127_DetAIResult; // 127 cell 检测要用到的一些 参数 。 std::shared_ptr<Image_AI_Det_Result> cell127_DetAIResult; // 127 cell 检测要用到的一些 参数 。
std::shared_ptr<Image_AI_Det_Result> bq_DetAIResult; // BQ标签检测要用到的一些 参数 。
// 结果图片 // 结果图片
cv::Mat resultImg; cv::Mat resultImg;

@ -345,7 +345,10 @@ struct BQ_Result
{ {
int nresult = 1; int nresult = 1;
bool bShield_BQ = true; // 是否屏蔽标签 bool bShield_BQ = true; // 是否屏蔽标签
std::vector<cv::Rect> pBQ_roiList; // 标签的区域 bool bBQ_AI_Det = false; // 是否启用标签独立AI检测
std::vector<cv::Rect> pBQ_roiList; // 标签的原始区域
std::vector<cv::Rect> pBQ_expandedRoiList; // 标签的扩展后区域用于AI检测
std::vector<cv::Mat> pBQ_cropImages; // 标签扩展区域图像
std::vector<cv::Point> BQ_centerPoint; // 标签的中心点位置 std::vector<cv::Point> BQ_centerPoint; // 标签的中心点位置
}; };
struct CameraBaseResult struct CameraBaseResult

@ -194,6 +194,12 @@ private:
// 获得 127cell blob // 获得 127cell blob
int GetBlob_127cell(); int GetBlob_127cell();
// 获得 BQ标签 blob
int GetBlob_BQ();
// BQ标签 AI 检测
int AI_Detect_BQ();
// 对AI mask图片进行 结果处理 // 对AI mask图片进行 结果处理
int AIMaskDet(); int AIMaskDet();

@ -123,7 +123,7 @@ int AI_Edge_Algin::Detect(const cv::Mat &img, DetConfig *pDetConfig, std::shared
return 7; return 7;
} }
if (max_contour_index >= 0) if (max_contour_index >= 0&& contours.size() > 0)
{ {
result_roi = boundingRect(contours[max_contour_index]); result_roi = boundingRect(contours[max_contour_index]);
} }

@ -697,6 +697,7 @@ int CameraCheckAnalysisy::preDet_BQ(const cv::Mat &L255CutImg, std::shared_ptr<I
long ts = CheckUtil::getcurTime(); long ts = CheckUtil::getcurTime();
m_pCheck_Result->cameraBaseResult->pBQ_Result = std::make_shared<BQ_Result>(); m_pCheck_Result->cameraBaseResult->pBQ_Result = std::make_shared<BQ_Result>();
m_pCheck_Result->cameraBaseResult->pBQ_Result->bShield_BQ = m_AnalysisyConfig.commonCheckConfig.baseConfig.bShield_BQ; m_pCheck_Result->cameraBaseResult->pBQ_Result->bShield_BQ = m_AnalysisyConfig.commonCheckConfig.baseConfig.bShield_BQ;
m_pCheck_Result->cameraBaseResult->pBQ_Result->bBQ_AI_Det = m_pbaseCheckFunction->Det_BQ.bBQ_AI_Det;
cv::Rect Det_CropRoi = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->cutRoi; cv::Rect Det_CropRoi = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->cutRoi;
@ -725,11 +726,25 @@ int CameraCheckAnalysisy::preDet_BQ(const cv::Mat &L255CutImg, std::shared_ptr<I
for (int i = 0; i < m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_roiList.size(); i++) for (int i = 0; i < m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_roiList.size(); i++)
{ {
cv::Rect boundingRect = m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_roiList.at(i); cv::Rect boundingRect = m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_roiList.at(i);
boundingRect.x -= 5; int BQ_expand = m_pbaseCheckFunction->Det_BQ.BQ_expand;
boundingRect.y -= 5; boundingRect.x -= BQ_expand;
boundingRect.width += 10; boundingRect.y -= BQ_expand;
boundingRect.height += 10; boundingRect.width += 2 * BQ_expand;
boundingRect.height += 2 * BQ_expand;
boundingRect = boundingRect & cv::Rect(0, 0, detImg_mask.cols, detImg_mask.rows);
if (boundingRect.width > 0 && boundingRect.height > 0)
{
// 同时屏蔽主AI避免重复检测
detImg_mask(boundingRect).setTo(255); detImg_mask(boundingRect).setTo(255);
// 保存裁剪图像供独立BQ AI检测
if (m_pbaseCheckFunction->Det_BQ.bBQ_AI_Det)
{
m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_expandedRoiList.push_back(boundingRect);
cv::Mat bqCrop = L255CutImg(boundingRect).clone();
m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_cropImages.push_back(bqCrop);
}
}
} }
if (L255->result->in_shareImage->bDebugsaveImg) if (L255->result->in_shareImage->bDebugsaveImg)
{ {

@ -170,7 +170,7 @@ int ImgCheckAnalysisy::GetStatus()
std::string ImgCheckAnalysisy::GetVersion() std::string ImgCheckAnalysisy::GetVersion()
{ {
return std::string("BOE_1.2.7_" + std::string(__DATE__) + "_" + std::string(__TIME__)); return std::string("BOE_1.2.8_" + std::string(__DATE__) + "_" + std::string(__TIME__));
} }
std::string ImgCheckAnalysisy::GetErrorInfo() std::string ImgCheckAnalysisy::GetErrorInfo()
@ -518,6 +518,14 @@ int ImgCheckAnalysisy::CheckRun()
Edge_Det(); Edge_Det();
// BQ标签AI检测
{
long t_BQ_s = CheckUtil::getcurTime();
int recBQ = AI_Detect_BQ();
long t_BQ_e = CheckUtil::getcurTime();
m_pdetlog->AddCheckstr(PrintLevel_0, "4、BQ Detect", "-------------------------BQ AI Detect--------%ld ms-------\n", t_BQ_e - t_BQ_s);
}
m_CheckResult_shareP->resultMaskImg = m_pImageAllResult->qx_DetAIResult->AI_MaskImg; m_CheckResult_shareP->resultMaskImg = m_pImageAllResult->qx_DetAIResult->AI_MaskImg;
// cv::imwrite("dddddddd.png", m_pImageAllResult->qx_DetAIResult->AI_MaskImg); // cv::imwrite("dddddddd.png", m_pImageAllResult->qx_DetAIResult->AI_MaskImg);
@ -1697,6 +1705,8 @@ int ImgCheckAnalysisy::GetALLBlob()
re = GetBlob_QX(); re = GetBlob_QX();
long t4 = CheckUtil::getcurTime(); long t4 = CheckUtil::getcurTime();
re = GetBlob_127cell(); re = GetBlob_127cell();
long t5 = CheckUtil::getcurTime();
re = GetBlob_BQ();
if (blobs.blobCount > 100) if (blobs.blobCount > 100)
{ {
@ -1706,8 +1716,8 @@ int ImgCheckAnalysisy::GetALLBlob()
long te = CheckUtil::getcurTime(); long te = CheckUtil::getcurTime();
m_pdetlog->AddCheckstr(PrintLevel_0, strBaseLog, m_pdetlog->AddCheckstr(PrintLevel_0, strBaseLog,
"---GetALLBlob End ;use time %ld ms yx %ld ms lack %ld ms qx %ld ms 127 %ld ms", "---GetALLBlob End ;use time %ld ms yx %ld ms lack %ld ms qx %ld ms 127 %ld ms bq %ld ms",
te - t1, t2 - t1, t3 - t2, t4 - t3, te - t4); te - t1, t2 - t1, t3 - t2, t4 - t3, t5 - t4, te - t5);
// getchar(); // getchar();
return 0; return 0;
@ -2145,6 +2155,199 @@ int ImgCheckAnalysisy::GetBlob_127cell()
return 0; return 0;
} }
// BQAI检测
int ImgCheckAnalysisy::AI_Detect_BQ()
{
std::string strBaseLog = "AI_Detect_BQ";
// 检查BQ标签AI检测是否启用
if (!m_pImageAllResult->cameraBaseResult->pBQ_Result)
{
return 0;
}
if (!m_pImageAllResult->cameraBaseResult->pBQ_Result->bBQ_AI_Det)
{
return 0;
}
int bqNum = static_cast<int>(m_pImageAllResult->cameraBaseResult->pBQ_Result->pBQ_cropImages.size());
if (bqNum <= 0)
{
return 0;
}
m_pdetlog->AddCheckstr(PrintLevel_1, strBaseLog, "============= Start, BQ num = %d", bqNum);
long ts = CheckUtil::getcurTime();
// 初始化BQ AI检测结果
m_pImageAllResult->bq_DetAIResult = std::make_shared<ImageAllResult::Image_AI_Det_Result>();
std::shared_ptr<ImageAllResult::Image_AI_Det_Result> pDetAIResult = m_pImageAllResult->bq_DetAIResult;
// 使用与主检测相同的AI模型后续更改为BQ AI模型
std::shared_ptr<AIModel_Base> pAI_Model = AI_Factory->AI_defect_Tag;
int AIInputImg_width = pAI_Model->input_0.width;
int AIInputImg_height = pAI_Model->input_0.height;
cv::Size modelInputSize(AIInputImg_width, AIInputImg_height);
// 创建全图大小的AI mask与主检测detImg同尺寸
cv::Mat AI_detImage = m_pImageAllResult->AI_detImg;
pDetAIResult->AI_MaskImg = cv::Mat::zeros(AI_detImage.size(), CV_8UC1);
// 先提交所有BQ AI推理任务仿照AI_Detect_QX的提交-收集模式)
int submitted = 0;
int completed = 0;
while (completed < bqNum)
{
// 提交任务限制并发数不超过2避免占用过多资源
if (submitted < bqNum && runner->GetProcessingCount() < 2)
{
cv::Mat bqCrop = m_pImageAllResult->cameraBaseResult->pBQ_Result->pBQ_cropImages.at(submitted);
if (!bqCrop.empty())
{
cv::Mat resizedCrop;
cv::resize(bqCrop, resizedCrop, modelInputSize);
std::shared_ptr<AIMulThreadRunBase::AITask> task = std::make_shared<AIMulThreadRunBase::AITask>();
task->id = submitted;
task->roi = cv::Rect(0, 0, modelInputSize.width, modelInputSize.height);
task->input = resizedCrop;
task->output = std::make_shared<cv::Mat>();
task->engine = pAI_Model;
runner->SubmitTask(task);
}
submitted++;
}
// 收集已完成的结果
std::shared_ptr<AIMulThreadRunBase::AITask> result;
if (runner->PopResult(result))
{
int idx = result->id;
if (idx >= 0 && idx < bqNum)
{
cv::Rect bqRoi = m_pImageAllResult->cameraBaseResult->pBQ_Result->pBQ_expandedRoiList.at(idx);
cv::Rect validRoi = bqRoi & cv::Rect(0, 0, AI_detImage.cols, AI_detImage.rows);
if (validRoi.width > 0 && validRoi.height > 0)
{
cv::Mat &outMask = *(result->output);
if (!outMask.empty())
{
// 将AI输出mask resize回BQ裁剪图原始尺寸
cv::Mat resizedMask;
cv::resize(outMask, resizedMask, cv::Size(bqRoi.width, bqRoi.height));
// 将BQ的mask结果放到全图mask的对应位置
resizedMask.copyTo(pDetAIResult->AI_MaskImg(validRoi), resizedMask);
m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "BQ[%d] AI done, roi=[%d,%d,%d,%d]",
idx, validRoi.x, validRoi.y, validRoi.width, validRoi.height);
}
else
{
m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "BQ[%d] AI output empty", idx);
}
}
}
completed++;
}
else
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
long te = CheckUtil::getcurTime();
m_pdetlog->AddCheckstr(PrintLevel_1, strBaseLog, "============= End, time=%ld ms", te - ts);
// 调试存图
if (DetImgInfo_shareP->bDebugsaveImg)
{
cv::imwrite(m_strCurDetCamChannel + "_AI_BQ_mask.png", pDetAIResult->AI_MaskImg);
}
return 0;
}
int ImgCheckAnalysisy::GetBlob_BQ()
{
std::string strBaseLog = "GetBlob_BQ";
// 检查BQ标签AI检测是否启用
if (!m_pImageAllResult->cameraBaseResult->pBQ_Result)
{
return 0;
}
if (!m_pImageAllResult->cameraBaseResult->pBQ_Result->bBQ_AI_Det)
{
return 0;
}
if (!m_pImageAllResult->bq_DetAIResult)
{
m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "bq_DetAIResult is null, skip");
return 0;
}
std::shared_ptr<ImageAllResult::Image_AI_Det_Result> pDetAIResult = m_pImageAllResult->bq_DetAIResult;
cv::Mat maskimg = pDetAIResult->AI_MaskImg;
if (maskimg.empty())
{
m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "AI_MaskImg is empty, skip");
return 0;
}
long t1 = CheckUtil::getcurTime();
// 使用与主流程相同的blob提取方式GetBlobs_V3
// BQ检测的mask中缺陷像素值为非零值
ERROR_DOTS_BLOBS blobs_bq;
memset(&blobs_bq, 0x00, sizeof(ERROR_DOTS_BLOBS));
unsigned char *pGrayErrordata = (unsigned char *)maskimg.data;
int width = maskimg.cols;
int height = maskimg.rows;
int minArea = 10; // BQ标签区域最小缺陷面积阈值
// 使用逐像素扫描方式提取blobGetBlobs_V3对mask中的非零值进行blob提取
GetBlobs_V3(&blobs_bq, pGrayErrordata, width, height, minArea);
// 设置BQ blob的默认缺陷类型后续分类会重新确定类型
// 使用非cell类型确保进入AI_Classify_New分类流程
for (int i = 0; i < blobs_bq.blobCount; i++)
{
blobs_bq.blobTab[i].ErrType = CONFIG_QX_NAME_LD; // 以亮点作为初始类型,后续分类修正
}
// 将BQ的blob汇入主blob列表
PushBlob(&blobs, &blobs_bq);
long te = CheckUtil::getcurTime();
m_pdetlog->AddCheckstr(PrintLevel_1, strBaseLog,
"BQ blob num = %d, merged to main blobs (total=%d), time=%ld ms",
blobs_bq.blobCount, blobs.blobCount, te - t1);
// 调试存图
if (DetImgInfo_shareP->bDebugsaveImg && blobs_bq.blobCount > 0)
{
cv::Mat tm;
cv::cvtColor(maskimg, tm, cv::COLOR_GRAY2RGB);
for (int i = 0; i < blobs_bq.blobCount; i++)
{
cv::Rect roi;
roi.x = blobs_bq.blobTab[i].minx;
roi.y = blobs_bq.blobTab[i].miny;
roi.width = blobs_bq.blobTab[i].maxx - blobs_bq.blobTab[i].minx + 1;
roi.height = blobs_bq.blobTab[i].maxy - blobs_bq.blobTab[i].miny + 1;
cv::rectangle(tm, roi, cv::Scalar(0, 0, 255), 2);
}
cv::imwrite(m_strCurDetCamChannel + "_BQ_blob.png", tm);
}
return 0;
}
int ImgCheckAnalysisy::AIMaskDet() int ImgCheckAnalysisy::AIMaskDet()
{ {
m_pdetlog->AddCheckstr(PrintLevel_0, "AIMaskDet", "=======start"); m_pdetlog->AddCheckstr(PrintLevel_0, "AIMaskDet", "=======start");

@ -2261,6 +2261,40 @@ struct Base_Function_AD_Check
} }
}; };
struct Base_Function_Det_BQ
{
int BQ_expand;
bool bBQ_AI_Det; // 是否启用标签独立AI检测汇入主流程分类
Base_Function_Det_BQ()
{
Init();
}
void Init()
{
BQ_expand = 0;
bBQ_AI_Det = false;
}
void copy(Base_Function_Det_BQ tem)
{
this->BQ_expand = tem.BQ_expand;
this->bBQ_AI_Det = tem.bBQ_AI_Det;
}
void print(std::string str)
{
printf("%d BQ_expand %d bBQ_AI_Det %d\n", str.c_str(),
BQ_expand, bBQ_AI_Det);
}
std::string GetInfo(std::string str)
{
char buffer[256];
sprintf(buffer, "%d BQ_expand %d bBQ_AI_Det %d\n", str.c_str(),
BQ_expand, bBQ_AI_Det);
std::string str123 = buffer;
return str123;
}
};
// 基础检测功能 // 基础检测功能
struct BaseCheckFunction struct BaseCheckFunction
{ {
@ -2270,6 +2304,7 @@ struct BaseCheckFunction
Base_Function_BigNG bigNG; Base_Function_BigNG bigNG;
Base_Function_EdgeChannel edgeChannel; Base_Function_EdgeChannel edgeChannel;
Base_Function_AD_Check ad_check; Base_Function_AD_Check ad_check;
Base_Function_Det_BQ Det_BQ;
BaseCheckFunction() BaseCheckFunction()
{ {
Init(); Init();
@ -2282,6 +2317,7 @@ struct BaseCheckFunction
bigNG.Init(); bigNG.Init();
edgeChannel.Init(); edgeChannel.Init();
ad_check.Init(); ad_check.Init();
Det_BQ.Init();
} }
void copy(BaseCheckFunction tem) void copy(BaseCheckFunction tem)
{ {
@ -2291,6 +2327,7 @@ struct BaseCheckFunction
this->bigNG.copy(tem.bigNG); this->bigNG.copy(tem.bigNG);
this->edgeChannel.copy(tem.edgeChannel); this->edgeChannel.copy(tem.edgeChannel);
this->ad_check.copy(tem.ad_check); this->ad_check.copy(tem.ad_check);
this->Det_BQ.copy(tem.Det_BQ);
} }
void print(std::string str) void print(std::string str)
{ {
@ -2301,6 +2338,7 @@ struct BaseCheckFunction
bigNG.print("bigNG"); bigNG.print("bigNG");
edgeChannel.print("edgeChannel"); edgeChannel.print("edgeChannel");
ad_check.print("ad_check"); ad_check.print("ad_check");
Det_BQ.print("Det_BQ");
} }
std::string GetInfo(std::string str) std::string GetInfo(std::string str)
{ {
@ -2311,6 +2349,7 @@ struct BaseCheckFunction
str123 += bigNG.GetInfo("bigNG"); str123 += bigNG.GetInfo("bigNG");
str123 += edgeChannel.GetInfo("edgeChannel"); str123 += edgeChannel.GetInfo("edgeChannel");
str123 += ad_check.GetInfo("ad_check"); str123 += ad_check.GetInfo("ad_check");
str123 += Det_BQ.GetInfo("Det_BQ");
// str123 += "\n"; // str123 += "\n";
return str123; return str123;
} }

@ -1471,6 +1471,21 @@ int BaseFuntonConfigJson::GetFunction(Json::Value value)
_config.ad_check.Init(); _config.ad_check.Init();
} }
} }
// 标签配置参数
if ("Det_BQ" == strCode)
{
auto value_f = value;
// std::cout << value_f << std::endl;
// getchar();
_config.Det_BQ.bBQ_AI_Det = value_f["isOpen"].asBool();
{
if (value_f["form"]["bShield_BQ"]["BQ_expand"])
{
_config.Det_BQ.BQ_expand = value_f["form"]["bShield_BQ"]["BQ_expand"].asInt();
}
}
// _config.edgeDet.print("edgeDet");
// getchar();
}
return 0; return 0;
} }

Loading…
Cancel
Save