From 4092ade8476dd34a0141e1b1b35caaf2871cbf4e Mon Sep 17 00:00:00 2001 From: liusiyang Date: Tue, 21 Jul 2026 08:56:50 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E6=A0=87=E7=AD=BE=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E5=88=86=E5=9D=97(v1.3.3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AlgorithmModule/src/ImgCheckAnalysisy.cpp | 181 ++++++++++++++++------ 1 file changed, 134 insertions(+), 47 deletions(-) diff --git a/AlgorithmModule/src/ImgCheckAnalysisy.cpp b/AlgorithmModule/src/ImgCheckAnalysisy.cpp index 23da02a..32b04c8 100644 --- a/AlgorithmModule/src/ImgCheckAnalysisy.cpp +++ b/AlgorithmModule/src/ImgCheckAnalysisy.cpp @@ -170,7 +170,7 @@ int ImgCheckAnalysisy::GetStatus() std::string ImgCheckAnalysisy::GetVersion() { - return std::string("BOE_1.3.2_" + std::string(__DATE__) + "_" + std::string(__TIME__)); + return std::string("BOE_1.3.3_" + std::string(__DATE__) + "_" + std::string(__TIME__)); } std::string ImgCheckAnalysisy::GetErrorInfo() @@ -2193,79 +2193,165 @@ int ImgCheckAnalysisy::AI_Detect_BQ() m_pImageAllResult->bq_DetAIResult = std::make_shared(); std::shared_ptr pDetAIResult = m_pImageAllResult->bq_DetAIResult; - // 使用与主检测相同的AI模型(后续更改为BQ AI模型) + // 使用BQ AI std::shared_ptr 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); + + int AIOutputImg_width = pAI_Model->output_0.width; + int AIOutputImg_height = pAI_Model->output_0.height; + + // 是否需要 resize到输入图大小进行后续处理 + bool bResizeToSrc = false; + if (AIOutputImg_width != AIInputImg_width || AIOutputImg_height != AIInputImg_height) + { + bResizeToSrc = true; + } + + cv::Size src_sz; + src_sz.width = AIInputImg_width; + src_sz.height = AIInputImg_height; // 创建全图大小的AI mask(与主检测detImg同尺寸) cv::Mat AI_detImage = m_pImageAllResult->AI_detImg; pDetAIResult->AI_MaskImg = cv::Mat::zeros(AI_detImage.size(), CV_8UC1); + cv::Mat AIresultMask = pDetAIResult->AI_MaskImg; - // 先提交所有BQ AI推理任务(仿照AI_Detect_QX的提交-收集模式) - int submitted = 0; - int completed = 0; - while (completed < bqNum) + // 为每个BQ区域生成小ROI列表,仿照AI_Detect_QX的裁剪小块方式 + std::vector BQ_SmallRoiList; + for (int i = 0; i < bqNum; i++) { - // 提交任务(限制并发数不超过2,避免占用过多资源) - if (submitted < bqNum && runner->GetProcessingCount() < 2) + cv::Rect bqRoi = m_pImageAllResult->cameraBaseResult->pBQ_Result->pBQ_expandedRoiList.at(i); + cv::Rect validRoi = bqRoi & cv::Rect(0, 0, AI_detImage.cols, AI_detImage.rows); + if (validRoi.width <= 0 || validRoi.height <= 0) continue; + + // 如果BQ区域大于等于模型输入尺寸,切分成小块 + if (validRoi.width >= AIInputImg_width && validRoi.height >= AIInputImg_height) { - cv::Rect bqRoi = m_pImageAllResult->cameraBaseResult->pBQ_Result->pBQ_expandedRoiList.at(submitted); - cv::Rect validRoi = bqRoi & cv::Rect(0, 0, AI_detImage.cols, AI_detImage.rows); - cv::Mat bqCrop; - if (validRoi.width > 0 && validRoi.height > 0) + std::vector smallList; + int re = CheckUtil::cutSmallImg(AI_detImage, smallList, validRoi, AIInputImg_width, AIInputImg_height, 0, 0); + if (re == 0) { - bqCrop = AI_detImage(validRoi).clone(); + for (const auto& roi : smallList) + { + BQ_SmallRoiList.push_back(roi); + } } - if (!bqCrop.empty()) - { - cv::Mat resizedCrop; - cv::resize(bqCrop, resizedCrop, modelInputSize); + } + else + { + // BQ区域小于模型输入尺寸,以BQ区域中心创建模型输入大小的ROI + int cx = validRoi.x + validRoi.width / 2; + int cy = validRoi.y + validRoi.height / 2; + cv::Rect newRoi; + newRoi.x = cx - AIInputImg_width / 2; + newRoi.y = cy - AIInputImg_height / 2; + newRoi.width = AIInputImg_width; + newRoi.height = AIInputImg_height; + // 裁剪到图像边界 + if (newRoi.x < 0) newRoi.x = 0; + if (newRoi.y < 0) newRoi.y = 0; + if (newRoi.x + newRoi.width > AI_detImage.cols) newRoi.x = AI_detImage.cols - newRoi.width; + if (newRoi.y + newRoi.height > AI_detImage.rows) newRoi.y = AI_detImage.rows - newRoi.height; + if (newRoi.x < 0) { newRoi.x = 0; newRoi.width = AI_detImage.cols; } + if (newRoi.y < 0) { newRoi.y = 0; newRoi.height = AI_detImage.rows; } + BQ_SmallRoiList.push_back(newRoi); + } + } + + const int totalTasks = BQ_SmallRoiList.size(); + if (totalTasks <= 0) + { + m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "no valid small roi for BQ"); + return 0; + } + + m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "BQ small roi num = %d", totalTasks); + + // 调试存图:原图 + BQ小ROI框 + if (DetImgInfo_shareP->bDebugsaveImg) + { + cv::Mat debugImg; + if (AI_detImage.channels() == 1) + { + cv::cvtColor(AI_detImage, debugImg, cv::COLOR_GRAY2BGR); + } + else + { + debugImg = AI_detImage.clone(); + } + for (size_t i = 0; i < BQ_SmallRoiList.size(); i++) + { + cv::rectangle(debugImg, BQ_SmallRoiList.at(i), cv::Scalar(0, 0, 255), 2); + } + cv::imwrite(m_strCurDetCamChannel + "_BQ_original_with_rois.png", debugImg); + } + + int submitted = 0; + int completed = 0; + long t2 = CheckUtil::getcurTime(); - std::shared_ptr task = std::make_shared(); - task->id = submitted; - task->roi = cv::Rect(0, 0, validRoi.width, validRoi.height); - task->input = resizedCrop; - task->output = std::make_shared(); - task->engine = pAI_Model; + while (completed < totalTasks) + { + // 提交任务 + if (submitted < totalTasks && runner->GetProcessingCount() < 10) + { + std::shared_ptr task = std::make_shared(); + task->id = submitted; + task->roi = BQ_SmallRoiList.at(submitted); + task->input = AI_detImage(task->roi).clone(); + task->output = std::make_shared(); + task->engine = pAI_Model; - runner->SubmitTask(task); + // 调试存图:保存每个小块 + if (DetImgInfo_shareP->bDebugsaveImg) + { + cv::imwrite(m_strCurDetCamChannel + "_BQ_crop_" + std::to_string(submitted) + ".png", task->input); } + + runner->SubmitTask(task); submitted++; } - // 收集已完成的结果 + // 收集结果 std::shared_ptr result; if (runner->PopResult(result)) { - int idx = result->id; - if (idx >= 0 && idx < bqNum) + cv::Mat &outimg = *(result->output); + if (!outimg.empty()) { - 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); + // 调试存图:保存模型原始输出mask + if (DetImgInfo_shareP->bDebugsaveImg) + { + cv::imwrite(m_strCurDetCamChannel + "_BQ_outmask_" + std::to_string(result->id) + ".png", outimg); + } - if (validRoi.width > 0 && validRoi.height > 0) + cv::Mat AIresult; + if (bResizeToSrc) { - 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)); + cv::resize(outimg, AIresult, src_sz, 0, 0, 0); + } + else + { + AIresult = outimg; + } - // 将BQ的mask结果放到全图mask的对应位置 - resizedMask.copyTo(pDetAIResult->AI_MaskImg(validRoi), resizedMask); + cv::Rect srcsize_roi = result->roi; + AIresult.copyTo(AIresultMask(srcsize_roi), AIresult); - 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); - } + // 调试存图:保存resize后的mask + if (DetImgInfo_shareP->bDebugsaveImg && bResizeToSrc) + { + cv::imwrite(m_strCurDetCamChannel + "_BQ_mask_resized_" + std::to_string(result->id) + ".png", AIresult); } + + m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "BQ[%d] AI done, roi=[%d,%d,%d,%d]", + result->id, srcsize_roi.x, srcsize_roi.y, srcsize_roi.width, srcsize_roi.height); + } + else + { + m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "BQ[%d] AI output empty", result->id); } completed++; } @@ -2276,7 +2362,8 @@ int ImgCheckAnalysisy::AI_Detect_BQ() } long te = CheckUtil::getcurTime(); - m_pdetlog->AddCheckstr(PrintLevel_1, strBaseLog, "============= End, time=%ld ms", te - ts); + float mean_AI = (te - t2) / totalTasks; + m_pdetlog->AddCheckstr(PrintLevel_1, strBaseLog, "============= End; AI Run Time: sum %ld pre %ld Run %ld mean One Small Img %f", te - ts, t2 - ts, te - t2, mean_AI); // 调试存图 if (DetImgInfo_shareP->bDebugsaveImg)