@ -170,7 +170,7 @@ int ImgCheckAnalysisy::GetStatus()
std : : string ImgCheckAnalysisy : : GetVersion ( )
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 ( )
std : : string ImgCheckAnalysisy : : GetErrorInfo ( )
@ -2193,79 +2193,165 @@ int ImgCheckAnalysisy::AI_Detect_BQ()
m_pImageAllResult - > bq_DetAIResult = std : : make_shared < ImageAllResult : : Image_AI_Det_Result > ( ) ;
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 ;
std : : shared_ptr < ImageAllResult : : Image_AI_Det_Result > pDetAIResult = m_pImageAllResult - > bq_DetAIResult ;
// 使用 与主检测相同的AI模型( 后续更改为 BQ AI模型)
// 使用 BQ AI
std : : shared_ptr < AIModel_Base > pAI_Model = AI_Factory - > AI_defect_Tag ;
std : : shared_ptr < AIModel_Base > pAI_Model = AI_Factory - > AI_defect_Tag ;
int AIInputImg_width = pAI_Model - > input_0 . width ;
int AIInputImg_width = pAI_Model - > input_0 . width ;
int AIInputImg_height = pAI_Model - > input_0 . height ;
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同尺寸)
// 创建全图大小的AI mask( 与主检测detImg同尺寸)
cv : : Mat AI_detImage = m_pImageAllResult - > AI_detImg ;
cv : : Mat AI_detImage = m_pImageAllResult - > AI_detImg ;
pDetAIResult - > AI_MaskImg = cv : : Mat : : zeros ( AI_detImage . size ( ) , CV_8UC1 ) ;
pDetAIResult - > AI_MaskImg = cv : : Mat : : zeros ( AI_detImage . size ( ) , CV_8UC1 ) ;
cv : : Mat AIresultMask = pDetAIResult - > AI_MaskImg ;
// 先提交所有BQ AI推理任务( 仿照AI_Detect_QX的提交-收集模式)
// 为每个BQ区域生成小ROI列表, 仿照AI_Detect_QX的裁剪小块方式
int submitted = 0 ;
std : : vector < cv : : Rect > BQ_SmallRoiList ;
int completed = 0 ;
for ( int i = 0 ; i < bqNum ; i + + )
while ( completed < bqNum )
{
{
// 提交任务( 限制并发数不超过2, 避免占用过多资源)
cv : : Rect bqRoi = m_pImageAllResult - > cameraBaseResult - > pBQ_Result - > pBQ_expandedRoiList . at ( i ) ;
if ( submitted < bqNum & & runner - > GetProcessingCount ( ) < 2 )
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 ) ;
std : : vector < cv : : Rect > smallList ;
cv : : Rect validRoi = bqRoi & cv : : Rect ( 0 , 0 , AI_detImage . cols , AI_detImage . rows ) ;
int re = CheckUtil : : cutSmallImg ( AI_detImage , smallList , validRoi , AIInputImg_width , AIInputImg_height , 0 , 0 ) ;
cv : : Mat bqCrop ;
if ( re = = 0 )
if ( validRoi . width > 0 & & validRoi . height > 0 )
{
{
bqCrop = AI_detImage ( validRoi ) . clone ( ) ;
for ( const auto & roi : smallList )
{
BQ_SmallRoiList . push_back ( roi ) ;
}
}
}
if ( ! bqCrop . empty ( ) )
}
{
else
cv : : Mat resizedCrop ;
{
cv : : resize ( bqCrop , resizedCrop , modelInputSize ) ;
// 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 < AIMulThreadRunBase : : AITask > task = std : : make_shared < AIMulThreadRunBase : : AITask > ( ) ;
while ( completed < totalTasks )
task - > id = submitted ;
{
task - > roi = cv : : Rect ( 0 , 0 , validRoi . width , validRoi . height ) ;
// 提交任务
task - > input = resizedCrop ;
if ( submitted < totalTasks & & runner - > GetProcessingCount ( ) < 10 )
task - > output = std : : make_shared < cv : : Mat > ( ) ;
{
task - > engine = pAI_Model ;
std : : shared_ptr < AIMulThreadRunBase : : AITask > task = std : : make_shared < AIMulThreadRunBase : : AITask > ( ) ;
task - > id = submitted ;
task - > roi = BQ_SmallRoiList . at ( submitted ) ;
task - > input = AI_detImage ( task - > roi ) . clone ( ) ;
task - > output = std : : make_shared < cv : : Mat > ( ) ;
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 + + ;
submitted + + ;
}
}
// 收集已完成的结果
// 收集 结果
std : : shared_ptr < AIMulThreadRunBase : : AITask > result ;
std : : shared_ptr < AIMulThreadRunBase : : AITask > result ;
if ( runner - > PopResult ( result ) )
if ( runner - > PopResult ( result ) )
{
{
int idx = result - > id ;
cv : : Mat & outimg = * ( result - > output ) ;
if ( idx > = 0 & & idx < bqNum )
if ( ! outimg . empty ( ) )
{
{
cv : : Rect bqRoi = m_pImageAllResult - > cameraBaseResult - > pBQ_Result - > pBQ_expandedRoiList . at ( idx ) ;
// 调试存图: 保存模型原始输出mask
cv : : Rect validRoi = bqRoi & cv : : Rect ( 0 , 0 , AI_detImage . cols , AI_detImage . rows ) ;
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 ) ;
cv : : resize( outimg , AIresult , src_sz , 0 , 0 , 0 ) ;
if ( ! outMask . empty ( ) )
}
{
else
// 将AI输出mask resize回BQ裁剪图原始尺寸
{
cv : : Mat resizedMask ;
AIresult = outimg ;
cv : : resize ( outMask , resizedMask , cv : : Size ( bqRoi . width , bqRoi . height ) ) ;
}
// 将BQ的mask结果放到全图mask的对应位置
cv : : Rect srcsize_roi = result - > roi ;
resizedMask . copyTo ( pDetAIResult - > AI_MaskImg ( validRoi ) , resizedMask ) ;
AIresult . copyTo ( AIresultMask ( srcsize_roi ) , AIresult ) ;
m_pdetlog - > AddCheckstr ( PrintLevel_2 , strBaseLog , " BQ[%d] AI done, roi=[%d,%d,%d,%d] " ,
// 调试存图: 保存resize后的mask
idx , validRoi . x , validRoi . y , validRoi . width , validRoi . height ) ;
if ( DetImgInfo_shareP - > bDebugsaveImg & & bResizeToSrc )
}
{
else
cv : : imwrite ( m_strCurDetCamChannel + " _BQ_mask_resized_ " + std : : to_string ( result - > id ) + " .png " , AIresult ) ;
{
m_pdetlog - > AddCheckstr ( PrintLevel_2 , strBaseLog , " BQ[%d] AI output empty " , idx ) ;
}
}
}
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 + + ;
completed + + ;
}
}
@ -2276,7 +2362,8 @@ int ImgCheckAnalysisy::AI_Detect_BQ()
}
}
long te = CheckUtil : : getcurTime ( ) ;
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 )
if ( DetImgInfo_shareP - > bDebugsaveImg )