/*********版权所有(C)2024,武汉高德红外股份有限公司*************** * 文件名称: Arith_ObjArrest.cpp * 文件标识: 跟踪目标重捕时机的返回 * 内容摘要: * 其它说明: "Arith_ObjArrest.cpp"的函数、全局变量、宏定义,统一前缀为简写"ObjArrest_" * 当前版本: 固化V2.0 * 创建作者: lk * 创建日期: 2024.01.23 *************************************************************************/ #include "Arith_OccludeJudge.h" #include "Arith_ImgOperate.h" #include "Arith_ObjArrest.h" #include "Arith_CoordModule.h" #include "TLD/API_TLD.h" TargetArrest::TargetArrest(OccJudge* pOccFea, API_KCF_Tracker* pKCFTracker, API_TLD* pTLDTracker) { // 遮挡判断模块 m_pOccFea = pOccFea; // 跟踪器模块 m_pKCFTracker = pKCFTracker; m_pTLDTracker = pTLDTracker; m_ArrestCntKCF = 0; // TLD_KCF重捕调用次数计数 m_ArrestCntAI = 0; //TLD_DaSiamRPN重捕调用次数计数 m_bRecaptureKCF = 0; //TLD_KCF重捕成功标志位 m_bRecaptureAI = 0; //TLD_DaSiamRPN重捕成功标志位 0-未重捕1-强重捕标志2-弱重捕标志 //brCurrentBoxTLDPre = { 0 }; //记录上一帧TLD检测位置 //brCurrentBoxNNPre = { 0 }; //brCurrentBoxNNPreAI = { 0 }; m_nContiFrameCnt = 0; //DaSiamRPN重捕连续帧计数 m_nNNContiFrameCnt = 0; //第二条成功重捕连续帧计数 m_nDelayArrestCnt = 0; //延时重捕帧计数 g_GLB_nConfShortConfirmContinueFrame = 0; // 相关性确认的连续帧数,避免出现错误重捕 g_GLB_nConfLongConfirmContinueFrame = 0; // 相关性确认的连续帧数,避免出现错误重捕 g_GLB_nMaxConfContinueFrame = 0; //最大NN置信度处,相关性确认的连续帧数,避免出现错误重捕 m_nArrestKCFStatus = 0; m_nArrestAIStatus = 0; m_bEnableArrestCorr = false; m_bEnableArrestAngle = false; m_bEnableAreestEsay = true; m_nArrestEsayCnt = 30; } TargetArrest::~TargetArrest() { } //计算两向量夹角 float AngleBetweenVectors(POINT32F v1, POINT32F v2) { FLOAT32 cosTheta = 0.f; FLOAT32 dotProduct = v1.x * v2.x + v1.y * v2.y; FLOAT32 mag1 = (FLOAT32)sqrt(v1.x * v1.x + v1.y * v1.y); FLOAT32 mag2 = (FLOAT32)sqrt(v2.x * v2.x + v2.y * v2.y); if (mag1 * mag2 < 0.001f) { cosTheta = 0; } else { cosTheta = dotProduct / (mag1 * mag2); } return FLOAT32(acos(cosTheta) * (180.0f / PI)); } //求两个矩形交并比 float DecideOverlap(CENTERRECT32F r1, CENTERRECT32F r2) { float x1 = r1.cx; float y1 = r1.cy; float width1 = r1.w; float height1 = r1.h; float x2 = r2.cx; float y2 = r2.cy; float width2 = r2.w; float height2 = r2.h; int endx = int(MAX(x1 + width1, x2 + width2)); int startx = int(MIN(x1, x2)); int width = int(width1 + width2 - (endx - startx)); int endy = int(MAX(y1 + height1, y2 + height2)); int starty = int(MIN(y1, y2)); int height = int(height1 + height2 - (endy - starty)); float ratio = 0.0f; float Area, Area1, Area2; if (width <= 0 || height <= 0) return 0.0f; else { Area = float(width * height); Area1 = float(width1 * height1); Area2 = float(width2 * height2); ratio = Area / (Area1 + Area2 - Area); } return ratio; } void TargetArrest::AID_RecaptureKCF_Run(GD_VIDEO_FRAME_S img, PIPE* pLockingPipe, GLB_INPUT* p_GLB_Input) { if (NULL == pLockingPipe) { return; } // 重捕区域 OBJECTSTATUS* pObjStatusKCF = m_pKCFTracker->GetTrackeStatus(); // 位置宽高改变 pObjStatusKCF->ptPos.x = pLockingPipe->ptCurrentPnt.x; pObjStatusKCF->ptPos.y = pLockingPipe->ptCurrentPnt.y; pObjStatusKCF->sfSize.w = pLockingPipe->ObjectFilter.sfSize.w; pObjStatusKCF->sfSize.h = pLockingPipe->ObjectFilter.sfSize.h; //重置KCF遮挡状态 pObjStatusKCF->nOcclude_flag = 0; // 初始化目标响应及相似度信息 m_pOccFea->Occ_CleanUpObjOccInfo(); // 清空重捕需要的缓存信息 ObjArrest_CleanUpObjArrestInfo(); // 更新当前目标信息//存在于清空重捕信息之后处理 //m_pKCFTracker->KCF_UpdateTracker(img.u32Width, img.u32Height, pObjStatusKCF, g_GLB_Input); //重捕成功直接重置风险:挂前景干扰物 m_pKCFTracker->KCF_Reset(pObjStatusKCF, FALSE, img, p_GLB_Input); } /**************************************************** * 函数名称:Recapture_Run * 功能描述:Recapture_重捕决策模块 * 输入参数:RECT32F rfBox ----当前帧KCF更新跟踪后的结果 UINT32 nConTrackedCnts ----目标连续跟踪帧数 FLOAT32 fConfidence ----KCF跟踪置信度 * 输出参数: * 返 回 值: * 调用关系: * 其它说明: *****************************************************/ void TargetArrest::TLD_RecaptureKCF_Run(GD_VIDEO_FRAME_S img, PIPE* pLockingPipe, GLB_INPUT* p_GLB_Input) { m_bRecaptureKCF = FALSE; FLOAT32 res = 0.f; //TLD输出候选框与模板相关性数值 POINT32F pt = { 0 }; // TLD计算完相关之后的偏移量 FLOAT32 cx = 0.f; FLOAT32 cy = 0.f; RECT32S pKCFCandidateRect = { 0 }; // 基于TLD重捕中心点送给KCF相关确认的区域 MINMAXRECT brCurrentBoxTLD = { 0 }; //TLD当前检测位置 MINMAXRECT brCurrentBoxNN = { 0 }; //TLD当前最大响应检测位置 MINMAXRECT brPredictBox = { 0 }; //TLD当前重捕范围 MINMAXRECT mmRectKCF = { 0 }; DOUBLE64 fIOU = 0.f; FLOAT32 fArrest_thresh = 0.f; //重捕阈值 FLOAT32 fArrest_threshLong = 0.f; FLOAT32 fArrestCorr = 0.f; //重捕范围设置系数 UINT16 nArrest_frmS = 1; // 强重捕确认帧数 UINT16 nArrest_frmL = 2; // 弱重捕确认帧数 BBOOL bIouConfirm = FALSE; //重捕范围条件确认 BBOOL bIouConfirm2 = FALSE; BBOOL bAngleConfirm = FALSE; //重捕范围条件确认 BBOOL bAngleConfirm2 = FALSE; BBOOL bSameObj = FALSE; BBOOL bSameObj2 = FALSE; FLOAT32 fArrestLength = 0.f; //重捕范围 FLOAT32 fArrestAngle = 0.f; //重捕角度 FLOAT32 fArrestAngTH = 0.f; //角度阈值 KcfPara* pKcfpara = m_pKCFTracker->GetKcfPara(); OBJECTSTATUS* pObjStatusKCF = m_pKCFTracker->GetTrackeStatus(); // 重捕区域 CENTERRECT32F crfCandiRect = { 0 }; //上位机参数控制 if (!m_bEnableArrestCorr) { bIouConfirm = TRUE; bIouConfirm2 = TRUE; } if (!m_bEnableArrestAngle) { bAngleConfirm = TRUE; bAngleConfirm2 = TRUE; } // 遮挡判断后持续重捕帧 m_ArrestCntKCF++; //阈值计算 fArrest_thresh = m_pOccFea->m_Occ_Para.fFullOccThre; fArrest_threshLong = fArrest_thresh * 0.95f; //根据长时轨迹的速度计算重捕范围 FLOAT32 v1 = pObjStatusKCF->sfAglSpeed.vx / p_GLB_Input->stCamera.fAglReso; FLOAT32 v2 = pObjStatusKCF->sfAglSpeed.vy / p_GLB_Input->stCamera.fAglReso; FLOAT32 v3 = (pObjStatusKCF->sfSize.w + pObjStatusKCF->sfSize.h) / (2 * p_GLB_Input->unFreq); fArrestLength = 0.5f * FLOAT32(sqrt(v1 * v1 + v2 * v2)) + 0.5f * v3; fArrestLength = m_ArrestCntKCF * fArrestLength; if (m_ArrestCntKCF < p_GLB_Input->unFreq) // 1s内(1x1) { fArrestAngTH = 120.0f; } else if (m_ArrestCntKCF < p_GLB_Input->unFreq * 2)//2s内(2x2) { fArrestAngTH = 20.0f; } else if (m_ArrestCntKCF < p_GLB_Input->unFreq * 4)//3s内(3x3) { fArrestAngTH = 40.0f; } else if (m_ArrestCntKCF < p_GLB_Input->unFreq * 6) { fArrestAngTH = 60.0f; } else { fArrestAngTH = 120.0f; } /* 根据遮挡时长,设置重捕参数,时间越短,重捕条件越严格 */ //if (g_ArrestCntKCF < g_GLB_stInput.stParaLn.unFreq * 2) // 1s内(1x1) //{ // fArrestCorr = (FLOAT32)2 / 2; //} //else if (g_ArrestCntKCF < g_GLB_stInput.stParaLn.unFreq * 4)//2s内(2x2) //{ // fArrestCorr = (FLOAT32)3 / 2; //} //else if (g_ArrestCntKCF < g_GLB_stInput.stParaLn.unFreq * 6)//3s内(3x3) //{ // fArrestCorr = (FLOAT32)5 / 2; //} //else //{ // fArrestCorr = -1; //} //关闭检测范围控制 //fArrestCorr = -1; //+++++++++++++++++++++++++++++++++++++++++++++++++ TLD_Para* pTLD_Para = m_pTLDTracker->TLD_GetPara(); // 仅开TLD重捕 //if (TRUE == g_GLB_stOutput.bEnableTLD) { //打印重捕调试信息 if (pTLD_Para->nClusterNum <= 0) { m_nArrestKCFStatus = 1; } // 获取TLD第一个聚类框 RECT32S tld_ClusterRect0 = m_pTLDTracker->TLD_GetClusterRect()[0]; // 获取TLD 的NN最相似框 RECT32S tld_BestNNRect = pTLD_Para->rsBestNNRect; // 重捕特征1:TLD有稳定的检测结果(NNconf>0.65)------------------------1st if (pTLD_Para->nClusterNum > 0 && m_ArrestCntKCF > 10) { //TLD当前帧检测位置 brCurrentBoxTLD.minX = tld_ClusterRect0.x; brCurrentBoxTLD.maxX = tld_ClusterRect0.x + tld_ClusterRect0.w; brCurrentBoxTLD.minY = tld_ClusterRect0.y; brCurrentBoxTLD.maxY = tld_ClusterRect0.y + tld_ClusterRect0.h; //////////////////////////////////////////////////////////////////////////////////////////////////////////// //重捕特征2:目标KCF响应值----------------------------------------------------2st // TLD送过来的候选区域与目标框计算相关性做确认 cx = (FLOAT32)tld_ClusterRect0.x + tld_ClusterRect0.w / 2.0f; //TLD重捕x中心点 cy = (FLOAT32)tld_ClusterRect0.y + tld_ClusterRect0.h / 2.0f; //TLD重捕y中心点 /*> 送KCF确认的框位置赋值 */ pKCFCandidateRect.w = SINT32(1.0 * pKcfpara->scale * pKcfpara->tempsize.w); pKCFCandidateRect.h = SINT32(1.0 * pKcfpara->scale * pKcfpara->tempsize.h); pKCFCandidateRect.x = SINT32(cx - pKCFCandidateRect.w / 2.0f); pKCFCandidateRect.y = SINT32(cy - pKCFCandidateRect.h / 2.0f); res = m_pKCFTracker->KCF_Detect(img, &pt, pKCFCandidateRect); pt.x -= pKcfpara->featureSizeX / 2.0f; pt.y -= pKcfpara->featureSizeY / 2.0f; crfCandiRect.cx = pKcfpara->scale * pKcfpara->cell_size * pt.x + tld_ClusterRect0.x + tld_ClusterRect0.w / 2.0f; crfCandiRect.cy = pKcfpara->scale * pKcfpara->cell_size * pt.y + tld_ClusterRect0.y + tld_ClusterRect0.h / 2.0f; m_fArrestKcfRes = res; //g_GLB_stOutput.fArrKCFRes = res; //dsp调试参数 //连续帧管道确认稳定捕获 // KCF响应短时重捕帧数累计 if (res > fArrest_thresh) { //计算当前帧TLD框与上一帧TLD框是否存在交并 fIOU = IMGO_CalcObjIou(brCurrentBoxTLD, brCurrentBoxTLDPre); if (fIOU > 0.35f) { g_GLB_nConfShortConfirmContinueFrame++; } else { g_GLB_nConfShortConfirmContinueFrame = 0; } } // KCF响应長时重捕帧数累计 //保存上一帧TLD检测框 brCurrentBoxTLDPre = brCurrentBoxTLD; //打印重捕调试信息 if (g_GLB_nConfShortConfirmContinueFrame < nArrest_frmS) { m_nArrestKCFStatus = 2; } //重捕条件3:TLD检测位置与KCF重捕位置存在交集---------------------------------3st mmRectKCF.minX = SINT16(crfCandiRect.cx - pKcfpara->rfBox.w / 2.0f); mmRectKCF.maxX = SINT16(crfCandiRect.cx + pKcfpara->rfBox.w / 2.0f); mmRectKCF.minY = SINT16(crfCandiRect.cy - pKcfpara->rfBox.h / 2.0f); mmRectKCF.maxY = SINT16(crfCandiRect.cy + pKcfpara->rfBox.h / 2.0f); //计算交并比 fIOU = IMGO_CalcObjIou(brCurrentBoxTLD, mmRectKCF); if (fIOU > 0.35f) { bSameObj = TRUE; } //打印重捕调试信息 if (bSameObj == FALSE) { m_nArrestKCFStatus = 3; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //重捕特征3:短时遮挡目标与预测位置距离信息-------------------------------3st //计算搜索范围 brPredictBox.minX = SINT16(MAX(pObjStatusKCF->ptPos.x - (fArrestLength + tld_ClusterRect0.w) / 2.0f, 0)); brPredictBox.maxX = SINT16(MIN(pObjStatusKCF->ptPos.x + (fArrestLength + tld_ClusterRect0.w) / 2.0f, img.u32Width)); brPredictBox.minY = SINT16(MAX(pObjStatusKCF->ptPos.y - (fArrestLength + tld_ClusterRect0.h) / 2.0f, 0.0)); brPredictBox.maxY = SINT16(MIN(pObjStatusKCF->ptPos.y + (fArrestLength + tld_ClusterRect0.h) / 2.0f, img.u32Height)); //计算交并比 fIOU = IMGO_CalcObjIou(brPredictBox, brCurrentBoxTLD); if (fIOU > 0.001) { bIouConfirm = TRUE; } //打印重捕调试信息 if (bIouConfirm == FALSE) { m_nArrestKCFStatus = 4; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //重捕特征4:目标重捕角度范围限制-------------------------------4st Pole pPreAgl = { 0}; //pPreAgl.beta = pObjDirectList[pObjDirectInfo->nStart].fAz; //pPreAgl.alpha = pObjDirectList[pObjDirectInfo->nStart].fPt; // 取出跟踪管道的短时轨迹 OBJ_ANGLE_R* pTrackAglListNear = &pLockingPipe->stMotionMod_mean.ObjAglListsNear; // 获取前10帧的位置 SINT32 index = -1; // 若未填满队列 if (pTrackAglListNear->nCnt < pTrackAglListNear->nListSize) { index = 0; } else { index = (pTrackAglListNear->nEnd + GLB_OBJTRACK_LEN - 10) % GLB_OBJTRACK_LEN; } pPreAgl.beta = pTrackAglListNear->parHistoryList[index].afAngle.fAz; pPreAgl.alpha = pTrackAglListNear->parHistoryList[index].afAngle.fPt; POINT32F pCurrent = { cx,cy }; Pole pCurrentAgl = getStablePoleFromImagePos(pCurrent, p_GLB_Input->stCamera, p_GLB_Input->servoInfo, p_GLB_Input->afPlatformRPY, p_GLB_Input->setupErr); POINT32F pMag1 = { pObjStatusKCF->sfAglSpeed.vx * 1000, pObjStatusKCF->sfAglSpeed.vy * 1000 }; POINT32F pMag2 = { FLOAT32(pCurrentAgl.beta - pPreAgl.beta) * 1000, FLOAT32(pCurrentAgl.alpha - pPreAgl.alpha) * 1000 }; fArrestAngle = AngleBetweenVectors(pMag1, pMag2); if (fArrestAngle < fArrestAngTH) { bAngleConfirm = TRUE; } ////打印重捕调试信息 if (bAngleConfirm == FALSE) { m_nArrestKCFStatus = 5; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //重捕触发条件:+++++++++++++++++++++++++++++++++++++++++++++ if (g_GLB_nConfShortConfirmContinueFrame >= nArrest_frmS && bIouConfirm && bAngleConfirm && bSameObj) { // 获取TLD预测位置,初始化目标跟踪器 //pt.x -= g_kcfpara.featureSizeX / 2; //pt.y -= g_kcfpara.featureSizeY / 2; //g_GLB_stPara.crfCandiRect.cx = g_kcfpara.scale * g_kcfpara.cell_size * pt.x + g_TLD_ClusterRect[0].x + g_TLD_ClusterRect[0].w / 2; //g_GLB_stPara.crfCandiRect.cy = g_kcfpara.scale * g_kcfpara.cell_size * pt.y + g_TLD_ClusterRect[0].y + g_TLD_ClusterRect[0].h / 2; m_bRecaptureKCF = 1; m_nArrestKCFStatus = 6; } } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //NN最大响应重捕++++++++++++++++++++++++++++++++++++++++++++++++++ //重捕特征1:TLD有稳定的最大响应检测结果(NNconf>0.4)------------------------1st else if (pTLD_Para->fNNConfMax > 0.5 && pTLD_Para->fNNPosConfMax > 0.8 && m_ArrestCntKCF > m_nArrestEsayCnt && m_bEnableAreestEsay) { //NN最大响应当前帧位置 brCurrentBoxNN.minX = tld_BestNNRect.x; brCurrentBoxNN.maxX = tld_BestNNRect.x + tld_BestNNRect.w; brCurrentBoxNN.minY = tld_BestNNRect.y; brCurrentBoxNN.maxY = tld_BestNNRect.y + tld_BestNNRect.h; //重捕特征2:目标KCF响应值----------------------------------------------------2st // TLD低响应送过来的候选区域与目标框计算相关性做确认 cx = tld_BestNNRect.x + tld_BestNNRect.w / 2.0f; //中心点x坐标 cy = tld_BestNNRect.y + tld_BestNNRect.h / 2.0f; //中心点y坐标 /*> 送KCF确认的框位置赋值 */ /*> 送KCF确认的框位置赋值 */ pKCFCandidateRect.w = SINT32(1.0 * pKcfpara->scale * pKcfpara->tempsize.w); pKCFCandidateRect.h = SINT32(1.0 * pKcfpara->scale * pKcfpara->tempsize.h); pKCFCandidateRect.x = SINT32(cx - pKCFCandidateRect.w / 2); pKCFCandidateRect.y = SINT32(cy - pKCFCandidateRect.h / 2); res = m_pKCFTracker->KCF_Detect(img, &pt, pKCFCandidateRect); pt.x -= pKcfpara->featureSizeX / 2.0f; pt.y -= pKcfpara->featureSizeY / 2.0f; crfCandiRect.cx = pKcfpara->scale * pKcfpara->cell_size * pt.x + tld_BestNNRect.x + tld_BestNNRect.w / 2; crfCandiRect.cy = pKcfpara->scale * pKcfpara->cell_size * pt.y + tld_BestNNRect.y + tld_BestNNRect.h / 2; m_fArrestKcfRes = res; //连续帧管道确认稳定捕获 //计算当前帧NN框与上一帧NN框是否存在交并 //kcf高响应计数,提升响应 if (res > fArrest_threshLong) { fIOU = IMGO_CalcObjIou(brCurrentBoxNN, brCurrentBoxNNPre); if (fIOU > 0.35) { g_GLB_nMaxConfContinueFrame++; } else { g_GLB_nMaxConfContinueFrame = 0; } } //保留上一帧NN brCurrentBoxNNPre = brCurrentBoxNN; ////打印重捕调试信息 if (g_GLB_nMaxConfContinueFrame < nArrest_frmL) { m_nArrestKCFStatus = 7; } //重捕条件3:TLD检测位置与KCF重捕位置存在交集---------------------------------3st mmRectKCF.minX = SINT16(crfCandiRect.cx - pKcfpara->rfBox.w / 2); mmRectKCF.maxX = SINT16(crfCandiRect.cx + pKcfpara->rfBox.w / 2); mmRectKCF.minY = SINT16(crfCandiRect.cy - pKcfpara->rfBox.h / 2); mmRectKCF.maxY = SINT16(crfCandiRect.cy + pKcfpara->rfBox.h / 2); //计算交并比 fIOU = IMGO_CalcObjIou(brCurrentBoxNN, mmRectKCF); if (fIOU > 0.35) { bSameObj2 = TRUE; } //打印重捕调试信息 if (bSameObj2 == FALSE) { m_nArrestKCFStatus = 8; } //////////////////////////////////////////////////////////////////////////////////////////////////////////// //重捕特征2:目标与预测位置交并比信息-------------------------------3st //计算搜索范围 brPredictBox.minX = SINT16(MAX(pObjStatusKCF->ptPos.x - (fArrestLength + tld_BestNNRect.w) / 2, 0)); brPredictBox.maxX = SINT16(MIN(pObjStatusKCF->ptPos.x + (fArrestLength + tld_BestNNRect.w) / 2, img.u32Width)); brPredictBox.minY = SINT16(MAX(pObjStatusKCF->ptPos.y - (fArrestLength + tld_BestNNRect.h) / 2, 0)); brPredictBox.maxY = SINT16(MIN(pObjStatusKCF->ptPos.y + (fArrestLength + tld_BestNNRect.h) / 2, img.u32Height)); //计算交并比 fIOU = IMGO_CalcObjIou(brPredictBox, brCurrentBoxNN); if (fIOU > 0.001) { bIouConfirm2 = TRUE; } //打印重捕调试信息 if (bIouConfirm2 == FALSE) { m_nArrestKCFStatus = 9; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //重捕特征4:目标重捕角度范围限制-------------------------------4st //POINT32F pCurrent; //POINT32F pCurrentPre; //pCurrent.x = SERVO_CalcObjAzimuth(cx, g_GLB_stInput.snImgSize.w, g_SERVO_stInput.fAzimuth, g_SERVO_stInput.fResolAz); //pCurrent.y = SERVO_CalcObjPitching(cy, g_GLB_stInput.snImgSize.h, g_SERVO_stInput.fPitching, g_SERVO_stInput.fResolPt); //pCurrentPre.x = pObjDirectList[pObjDirectInfo->nStart].fAz; //pCurrentPre.y = pObjDirectList[pObjDirectInfo->nStart].fPt; ////pCurrent.x = SERVO_CalcObjCoordinateX_1(fAz, nWidth, g_SERVO_stInput.fAzimuth, g_SERVO_stInput.fResolAz, g_SERVO_stInput.fPitching); ////pCurrent.y = SERVO_CalcObjCoordinateY(fPt, nHeight, g_SERVO_stInput.fPitching, g_SERVO_stInput.fResolPt); //POINT32F pMag1 = { pObjStatusKCF->sfAglSpeed.vx * 1000, pObjStatusKCF->sfAglSpeed.vy * 1000 }; //POINT32F pMag2 = { (pCurrent.x - pCurrentPre.x) * 1000, (pCurrent.y - pCurrentPre.y) * 1000 }; //fArrestAngle = AngleBetweenVectors(pMag1, pMag2); Pole pPreAgl = { 0 }; // 取出跟踪管道的短时轨迹 OBJ_ANGLE_R* pTrackAglListNear = &pLockingPipe->stMotionMod_mean.ObjAglListsNear; // 获取前10帧的位置 SINT32 index = -1; // 若未填满队列 if (pTrackAglListNear->nCnt < pTrackAglListNear->nListSize) { index = 0; } else { index = (pTrackAglListNear->nEnd + GLB_OBJTRACK_LEN - 10) % GLB_OBJTRACK_LEN; } pPreAgl.beta = pTrackAglListNear->parHistoryList[index].afAngle.fAz; pPreAgl.alpha = pTrackAglListNear->parHistoryList[index].afAngle.fPt; POINT32F pCurrent = { cx,cy }; Pole pCurrentAgl = getStablePoleFromImagePos(pCurrent, p_GLB_Input->stCamera, p_GLB_Input->servoInfo, p_GLB_Input->afPlatformRPY, p_GLB_Input->setupErr); POINT32F pMag1 = { pObjStatusKCF->sfAglSpeed.vx * 1000, pObjStatusKCF->sfAglSpeed.vy * 1000 }; POINT32F pMag2 = { FLOAT32(pCurrentAgl.beta - pPreAgl.beta) * 1000, FLOAT32(pCurrentAgl.alpha - pPreAgl.alpha) * 1000 }; fArrestAngle = AngleBetweenVectors(pMag1, pMag2); if (fArrestAngle < fArrestAngTH) { bAngleConfirm2 = TRUE; } //打印重捕调试信息 if (bAngleConfirm2 == FALSE) { m_nArrestKCFStatus = 10; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// //重捕触发条件++++++++++++++++++++++++++++++++++++++++++ if (g_GLB_nMaxConfContinueFrame >= nArrest_frmL && bIouConfirm2 && bAngleConfirm2 && bSameObj2) { // 获取TLD预测位置,初始化目标跟踪器 //pt.x -= g_kcfpara.featureSizeX / 2; //pt.y -= g_kcfpara.featureSizeY / 2; //g_GLB_stPara.crfCandiRect.cx = g_kcfpara.scale * g_kcfpara.cell_size * pt.x + g_TLD_rsBestNNRect.x + g_TLD_rsBestNNRect.w/2; // g_GLB_stPara.crfCandiRect.cy = g_kcfpara.scale * g_kcfpara.cell_size * pt.y + g_TLD_rsBestNNRect.y + g_TLD_rsBestNNRect.h/2; m_bRecaptureKCF = 2; m_nArrestKCFStatus = 11; } } } // 如果重捕成功,调用初始化 if (m_bRecaptureKCF > 0) { // 位置改变,宽高不变 pObjStatusKCF->ptPos.x = crfCandiRect.cx; pObjStatusKCF->ptPos.y = crfCandiRect.cy; //重置KCF遮挡状态 pObjStatusKCF->nOcclude_flag = 0; // 初始化目标响应及相似度信息 m_pOccFea->Occ_CleanUpObjOccInfo(); // 清空重捕需要的缓存信息 ObjArrest_CleanUpObjArrestInfo(); // 更新当前目标信息//存在于清空重捕信息之后处理 //m_pKCFTracker->KCF_UpdateTracker(img.u32Width, img.u32Height, pObjStatusKCF, g_GLB_Input); //重捕成功直接重置风险:挂前景干扰物 m_pKCFTracker->KCF_Reset(pObjStatusKCF, FALSE, img, p_GLB_Input); //清除TLD学习连续帧计数 pTLD_Para->nLearnedNum = 0; } return; } /********************************************************** * 函数名称:ObjArrest_CleanUpObjArrestInfo() * 功能描述:初始化重捕信息 * 输入参数:无 * 输出参数:无 * 返 回 值:无 * 调用关系:无 * 其它说明:无 **********************************************************/ void TargetArrest::ObjArrest_CleanUpObjArrestInfo(void) { m_ArrestCntKCF = 0; g_GLB_nConfShortConfirmContinueFrame = 0; g_GLB_nConfLongConfirmContinueFrame = 0; } //初始化解锁清理 void TargetArrest::ObjArrest_CleanUpAllKCFArrestInfo(void) { ObjArrest_CleanUpObjArrestInfo(); m_bRecaptureKCF = 0; } void TargetArrest::ObjArrest_setArrestCorrPara(BBOOL bEnableArrestCorr) { m_bEnableArrestCorr = bEnableArrestCorr; } void TargetArrest::ObjArrest_setArrestAnglePara(BBOOL bEnableArrestAngle) { m_bEnableArrestAngle = bEnableArrestAngle; } void TargetArrest::ObjArrest_setArrestEsayPara(BBOOL bEnableArrestEsay) { m_bEnableAreestEsay = bEnableArrestEsay; } void TargetArrest::ObjArrest_setArrestEsayCntPara(SINT32 nArrestEsayCnt) { m_nArrestEsayCnt = nArrestEsayCnt; }