feat 初步添加BQ模型检测

dev_heyuan
liusiyang 1 month ago
parent eb2cf825ce
commit 768a227910

@ -173,6 +173,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();

@ -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;
@ -718,7 +719,7 @@ int CameraCheckAnalysisy::preDet_BQ(const cv::Mat &L255CutImg, std::shared_ptr<I
} }
// 如果要屏蔽标签 // 如果要屏蔽标签
if (m_pCheck_Result->cameraBaseResult->pBQ_Result->bShield_BQ && m_pbaseCheckFunction->Det_BQ.bOpen) if (m_pCheck_Result->cameraBaseResult->pBQ_Result->bShield_BQ)
{ {
m_pdetlog->AddCheckstr(PrintLevel_2, "preDet_BQ", "shieldBQ is Open"); m_pdetlog->AddCheckstr(PrintLevel_2, "preDet_BQ", "shieldBQ is Open");
cv::Mat detImg_mask = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask; cv::Mat detImg_mask = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask;
@ -733,7 +734,16 @@ int CameraCheckAnalysisy::preDet_BQ(const cv::Mat &L255CutImg, std::shared_ptr<I
boundingRect = boundingRect & cv::Rect(0, 0, detImg_mask.cols, detImg_mask.rows); boundingRect = boundingRect & cv::Rect(0, 0, detImg_mask.cols, detImg_mask.rows);
if (boundingRect.width > 0 && boundingRect.height > 0) 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)

@ -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);
@ -1695,6 +1703,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)
{ {
@ -1704,8 +1714,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;
@ -2143,6 +2153,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_NF;
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");

@ -2263,8 +2263,8 @@ struct Base_Function_AD_Check
struct Base_Function_Det_BQ struct Base_Function_Det_BQ
{ {
bool bOpen;
int BQ_expand; int BQ_expand;
bool bBQ_AI_Det; // 是否启用标签独立AI检测汇入主流程分类
Base_Function_Det_BQ() Base_Function_Det_BQ()
{ {
@ -2272,24 +2272,24 @@ struct Base_Function_Det_BQ
} }
void Init() void Init()
{ {
bOpen = false;
BQ_expand = 0; BQ_expand = 0;
bBQ_AI_Det = false;
} }
void copy(Base_Function_Det_BQ tem) void copy(Base_Function_Det_BQ tem)
{ {
this->bOpen = tem.bOpen;
this->BQ_expand = tem.BQ_expand; this->BQ_expand = tem.BQ_expand;
this->bBQ_AI_Det = tem.bBQ_AI_Det;
} }
void print(std::string str) void print(std::string str)
{ {
printf("%s>>bOpen %d BQ_expand %d\n", str.c_str(), printf("%d BQ_expand %d bBQ_AI_Det %d\n", str.c_str(),
bOpen, BQ_expand); BQ_expand, bBQ_AI_Det);
} }
std::string GetInfo(std::string str) std::string GetInfo(std::string str)
{ {
char buffer[256]; char buffer[256];
sprintf(buffer, "%s>>bOpen %d BQ_expand %d\n", str.c_str(), sprintf(buffer, "%d BQ_expand %d bBQ_AI_Det %d\n", str.c_str(),
bOpen, BQ_expand); BQ_expand, bBQ_AI_Det);
std::string str123 = buffer; std::string str123 = buffer;
return str123; return str123;
} }

@ -1477,18 +1477,13 @@ int BaseFuntonConfigJson::GetFunction(Json::Value value)
auto value_f = value; auto value_f = value;
// std::cout << value_f << std::endl; // std::cout << value_f << std::endl;
// getchar(); // getchar();
_config.Det_BQ.bOpen = value_f["isOpen"].asBool(); _config.Det_BQ.bBQ_AI_Det = value_f["isOpen"].asBool();
if (_config.Det_BQ.bOpen)
{ {
if (value_f["form"]["bShield_BQ"]["BQ_expand"]) if (value_f["form"]["bShield_BQ"]["BQ_expand"])
{ {
_config.Det_BQ.BQ_expand = value_f["form"]["bShield_BQ"]["BQ_expand"].asInt(); _config.Det_BQ.BQ_expand = value_f["form"]["bShield_BQ"]["BQ_expand"].asInt();
} }
} }
else
{
_config.Det_BQ.Init();
}
// _config.edgeDet.print("edgeDet"); // _config.edgeDet.print("edgeDet");
// getchar(); // getchar();
} }

Loading…
Cancel
Save