@ -1346,6 +1346,11 @@ int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg)
pAIDetList . push_back ( AI_Factory - > Defect ) ;
pAIDetList . push_back ( AI_Factory - > Defect ) ;
pAIDetList . push_back ( AI_Factory - > Defect_QueXi ) ;
pAIDetList . push_back ( AI_Factory - > Defect_QueXi ) ;
// 与 pAIDetList 一一对应的模型名称,用于区分残点由哪个模型检出
std : : vector < std : : string > pAIDetNameList ;
pAIDetNameList . push_back ( AI_DET_MODEL_NAME_Defect ) ;
pAIDetNameList . push_back ( AI_DET_MODEL_NAME_QueXi ) ;
std : : string strBaseLog = " AI_Detect " ;
std : : string strBaseLog = " AI_Detect " ;
m_pdetlog - > AddCheckstr ( PrintLevel_0 , DET_LOG_LEVEL_3 , strBaseLog , " AI_Detect Start " ) ;
m_pdetlog - > AddCheckstr ( PrintLevel_0 , DET_LOG_LEVEL_3 , strBaseLog , " AI_Detect Start " ) ;
@ -1396,6 +1401,14 @@ int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg)
ResultImg = cv : : Mat : : zeros ( img . size ( ) , CV_8UC1 ) ;
ResultImg = cv : : Mat : : zeros ( img . size ( ) , CV_8UC1 ) ;
// 每个模型单独保存一份全图 mask, 便于后续追溯残点由哪个模型检出
m_pImageAllResult - > AI_Model_MaskList . clear ( ) ;
std : : vector < cv : : Mat > modelMaskList ( pAIDetList . size ( ) ) ;
for ( size_t m = 0 ; m < pAIDetList . size ( ) ; m + + )
{
modelMaskList [ m ] = cv : : Mat : : zeros ( img . size ( ) , CV_8UC1 ) ;
}
const int totalTasks = SmallRoiList . size ( ) ;
const int totalTasks = SmallRoiList . size ( ) ;
// std::string str_Root = m_strRootPath + pDetConfig->strProductID + "_" + pDetConfig->strchannel + "_";
// std::string str_Root = m_strRootPath + pDetConfig->strProductID + "_" + pDetConfig->strchannel + "_";
@ -1440,6 +1453,28 @@ int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg)
// 多个模型的结果取并集
// 多个模型的结果取并集
cv : : Mat roiMat = ResultImg ( result - > roi ) ;
cv : : Mat roiMat = ResultImg ( result - > roi ) ;
cv : : bitwise_or ( roiMat , outimg , roiMat ) ;
cv : : bitwise_or ( roiMat , outimg , roiMat ) ;
// 当前模型自己的 mask 单独记录一份
if ( m < modelMaskList . size ( ) & & ! modelMaskList [ m ] . empty ( ) )
{
cv : : Mat modelRoiMat = modelMaskList [ m ] ( result - > roi ) ;
cv : : bitwise_or ( modelRoiMat , outimg , modelRoiMat ) ;
}
// AI 检测残点图存图:每个模型的结果都存,并增加一级 模型名称 目录,
// 用以区分该残点是由哪个模型检出的
// 目录结构:/home/aidlux/BOE/ZB_SOCKET/AI_Detect/<模型名称>/<产品ID>/
if ( m_pbaseCheckFunction - > saveImg . bSaveAIDetImg )
{
std : : string strModelName = ( m < pAIDetNameList . size ( ) ) ? pAIDetNameList [ m ] : std : : string ( AI_DET_MODEL_NAME_UnKnown ) ;
std : : string roi_ext = " [ " + std : : to_string ( result - > roi . x ) + " , " + std : : to_string ( result - > roi . y ) + " ] " ;
std : : string strSaveDir = " /home/aidlux/BOE/ZB_SOCKET/AI_Detect/ " + strModelName + " / " + DetImgInfo_shareP - > strImgProductID + " / " ;
CheckUtil : : CreateDir ( strSaveDir ) ;
std : : string strSavePath_in = strSaveDir + m_strCurDetChannel + " _ " + roi_ext + " _in.png " ;
std : : string strSavePath_out = strSaveDir + m_strCurDetChannel + " _ " + roi_ext + " _out.png " ;
cv : : imwrite ( strSavePath_in , result - > input ) ;
cv : : imwrite ( strSavePath_out , outimg ) ;
}
}
}
// 同一 roi 的多个模型结果取并集后存入 AI_Qx_MaskList
// 同一 roi 的多个模型结果取并集后存入 AI_Qx_MaskList
@ -1474,6 +1509,18 @@ int ImgCheckAnalysisy::AI_Detect_Thread(const cv::Mat &img, cv::Mat &ResultImg)
float mean_AI = ( t3 - t2 ) / ( SmallRoiList . size ( ) * pAIDetList . size ( ) ) ;
float mean_AI = ( t3 - t2 ) / ( SmallRoiList . size ( ) * pAIDetList . size ( ) ) ;
m_pdetlog - > AddCheckstr ( PrintLevel_1 , DET_LOG_LEVEL_3 , strBaseLog , " AI Run Time: sum %ld pre %ld Run %ld mean One Small Img %f " , t3 - t1 , t2 - t1 , t3 - t2 , mean_AI ) ;
m_pdetlog - > AddCheckstr ( PrintLevel_1 , DET_LOG_LEVEL_3 , strBaseLog , " AI Run Time: sum %ld pre %ld Run %ld mean One Small Img %f " , t3 - t1 , t2 - t1 , t3 - t2 , mean_AI ) ;
// 保存各模型的 全图 mask, 并输出各模型检出的残点像素数量, 便于追溯
for ( size_t m = 0 ; m < modelMaskList . size ( ) ; m + + )
{
std : : shared_ptr < ImageAllResult : : AI_Model_MaskImg > temModelMask = std : : make_shared < ImageAllResult : : AI_Model_MaskImg > ( ) ;
temModelMask - > strModelName = ( m < pAIDetNameList . size ( ) ) ? pAIDetNameList [ m ] : std : : string ( AI_DET_MODEL_NAME_UnKnown ) ;
temModelMask - > ModelMask = modelMaskList [ m ] ;
m_pImageAllResult - > AI_Model_MaskList . push_back ( temModelMask ) ;
m_pdetlog - > AddCheckstr ( PrintLevel_0 , DET_LOG_LEVEL_3 , strBaseLog , " Det Model: %s mask pixel num %d " ,
temModelMask - > strModelName . c_str ( ) , cv : : countNonZero ( temModelMask - > ModelMask ) ) ;
}
m_pdetlog - > AddCheckstr ( PrintLevel_0 , DET_LOG_LEVEL_3 , strBaseLog , " AI_Detect End " ) ;
m_pdetlog - > AddCheckstr ( PrintLevel_0 , DET_LOG_LEVEL_3 , strBaseLog , " AI_Detect End " ) ;
// 临时存图
// 临时存图
@ -2058,6 +2105,53 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img)
return 0 ;
return 0 ;
}
}
// 获取指定 残点(blob) 是由哪个(哪些)检测模型检出的
// 做法:对各模型自己输出的全图 mask, 在 blob 的 roi 内统计非零像素;
// 非零则说明该模型在该残点区域有检出。多个模型都检出时用 "+" 连接。
std : : string ImgCheckAnalysisy : : GetBlobModelName ( const cv : : Rect & roi )
{
std : : string strModelName = " " ;
if ( ! m_pImageAllResult )
{
return AI_DET_MODEL_NAME_UnKnown ;
}
for ( auto & pModelMask : m_pImageAllResult - > AI_Model_MaskList )
{
if ( ! pModelMask | | pModelMask - > ModelMask . empty ( ) )
{
continue ;
}
cv : : Rect imgRoi = cv : : Rect ( 0 , 0 , pModelMask - > ModelMask . cols , pModelMask - > ModelMask . rows ) ;
cv : : Rect cutRoi = roi & imgRoi ;
if ( cutRoi . width < = 0 | | cutRoi . height < = 0 )
{
continue ;
}
cv : : Mat roiMask = pModelMask - > ModelMask ( cutRoi ) ;
if ( cv : : countNonZero ( roiMask ) > 0 )
{
if ( strModelName . empty ( ) )
{
strModelName = pModelMask - > strModelName ;
}
else
{
strModelName + = AI_DET_MODEL_NAME_JOIN + pModelMask - > strModelName ;
}
}
}
if ( strModelName . empty ( ) )
{
strModelName = AI_DET_MODEL_NAME_UnKnown ;
}
return strModelName ;
}
int ImgCheckAnalysisy : : BLobToDetResult ( )
int ImgCheckAnalysisy : : BLobToDetResult ( )
{
{
long t1 = CheckUtil : : getcurTime ( ) ;
long t1 = CheckUtil : : getcurTime ( ) ;
@ -2078,6 +2172,9 @@ int ImgCheckAnalysisy::BLobToDetResult()
float fsecondArea = JudgArea ;
float fsecondArea = JudgArea ;
std : : string qx_name = CONFIG_QX_NAME_Names [ config_qx_type ] ;
std : : string qx_name = CONFIG_QX_NAME_Names [ config_qx_type ] ;
// 追溯该残点(blob) 是由哪个检测模型检出的
std : : string strModelName = GetBlobModelName ( roi ) ;
if ( true )
if ( true )
{
{
QX_ERROR_INFO_ temerror ;
QX_ERROR_INFO_ temerror ;
@ -2091,6 +2188,7 @@ int ImgCheckAnalysisy::BLobToDetResult()
temerror . fbreadth = blobs . blobTab [ i ] . breadth ;
temerror . fbreadth = blobs . blobTab [ i ] . breadth ;
temerror . nconfig_qx_type = config_qx_type ;
temerror . nconfig_qx_type = config_qx_type ;
temerror . qx_name = qx_name ;
temerror . qx_name = qx_name ;
temerror . strModelName = strModelName ;
temerror . maxValue = blobs . blobTab [ i ] . maxValue ;
temerror . maxValue = blobs . blobTab [ i ] . maxValue ;
temerror . grayDis = blobs . blobTab [ i ] . grayDis ;
temerror . grayDis = blobs . blobTab [ i ] . grayDis ;
temerror . density = blobs . blobTab [ i ] . density ;
temerror . density = blobs . blobTab [ i ] . density ;
@ -2138,6 +2236,11 @@ int ImgCheckAnalysisy::BLobToDetResult()
m_pDetResult - > pQx_ErrorList - > push_back ( temerror ) ;
m_pDetResult - > pQx_ErrorList - > push_back ( temerror ) ;
m_pdetlog - > AddCheckstr ( PrintLevel_1 , DET_LOG_LEVEL_3 , " BLobToDetResult " ,
" blob idx %d Qx Idx %d qx %d %s detModel %s roi[%d %d %d %d] " ,
i , temerror . Idx , config_qx_type , qx_name . c_str ( ) , strModelName . c_str ( ) ,
roi . x , roi . y , roi . width , roi . height ) ;
// printf("- %s idx %d a %f v %d h %f l %f\n", DetImgInfo_shareP->strChannel.c_str(), i, JudgArea, blobs.blobTab[i].maxValue, blobs.blobTab[i].grayDis, flen);
// printf("- %s idx %d a %f v %d h %f l %f\n", DetImgInfo_shareP->strChannel.c_str(), i, JudgArea, blobs.blobTab[i].maxValue, blobs.blobTab[i].grayDis, flen);
}
}
}
}