# S3315算法功能说明 S3315项目为某高性能微波防空设备,跟踪算法基于12-12版基线代码开发 相较基线功能,存在如下改动: ## Arith_SysStruct.h 1.默认帧频 50Hz,记忆帧数150帧(3s),最大目标检测个数 50(小) + 10(面) 新增标记 ``` bEnForceGuidel; // 半自动截获强制提取目标3s BBOOL bTracking; // 管道被跟踪标记,用于标记辅跟踪目标 SINT32 nShowPipeID; //送显批号 ``` ## Arith_EOController.cpp 2.g_TrackCurrentID = 2; //辅跟踪目标默认从2开始,仅控制显示输出 ``` //点选取消辅跟踪目标 void Arith_EOController::GLB_Cancle_Point(SINT32 nPipeNum,POINT32S ptCanclePos) { SINT32 nSelecID = -1; SINT32 nNearstDis = 999999; // 便历距离最近的跟踪器 for (int i = 0; i < nPipeNum; i++) { PIPE* pPipe = &g_GLB_PipeProc->getPipeArray()[i]; if (!pPipe->bTracking || pPipe->bTrackingPipe) //1号目标或非辅跟踪目标跳过 { continue; } SINT32 disX = ABS(pPipe->ptCurrentPnt.x - ptCanclePos.x); SINT32 disY = ABS(pPipe->ptCurrentPnt.y - ptCanclePos.y); SINT32 nDis2 = disX * disX + disY * disY; if (nDis2 < nNearstDis) { nNearstDis = nDis2; nSelecID = i; } } if (-1 != nSelecID) { PIPE* pPipe = &g_GLB_PipeProc->getPipeArray()[nSelecID]; pPipe->bTracking = FALSE; pPipe->nDelCntThres = GLB_PIPE_DEL_MIN_STARE; } } ``` ## Arith_Status_SEARCH.cpp ``` //强制提取 SINT32 Arith_EOController::Proc_ForceLock(GD_VIDEO_FRAME_S img, GLB_INPUT& g_Input, GLB_PARAMETERS& g_para) { SINT32 nTrackPipeID = -1; SINT32 nWidth = img.u32Width; SINT32 nHeight = img.u32Height; //3s强制提取由外部控制 // 对空模式可以转压点强制提取 if (GLB_SCEN_SKY == g_GLB_stPara.nWorkScene) { TARGET_OBJECT tTargetRe = { 0 }; SPEED32F sfAglSpeed = { 0 }; TARGET_OBJECT* Temp_Target_Array = g_GLB_Detectors->GetTargetArray(); SINT32 Temp_nTargetNum = 0; g_GLB_stPara.snLockBoxSize.w = 40; g_GLB_stPara.snLockBoxSize.h = 40; MINMAXRECT mmCenterRect = { g_GLB_stPara.ptLockPos.x - g_GLB_stPara.snLockBoxSize.w / 2, g_GLB_stPara.ptLockPos.y - g_GLB_stPara.snLockBoxSize.h / 2 , g_GLB_stPara.ptLockPos.x + g_GLB_stPara.snLockBoxSize.w / 2 ,g_GLB_stPara.ptLockPos.y + g_GLB_stPara.snLockBoxSize.h / 2 }; BBOOL bPipeReObjFound = g_GLB_Detectors->pDST_Module->DST_PipeTargetReDetect(img, nWidth, nHeight, g_GLB_stPara.ptLockPos, sfAglSpeed, mmCenterRect, &tTargetRe, &nTrackPipeID,Temp_Target_Array, &Temp_nTargetNum); // 还没有检出,执行第三次超级弱小目标检测 if (!bPipeReObjFound) { BBOOL bPipeSeObjFound = g_GLB_Detectors->pDST_Module->DST_PipeTargetRReDetect(img, nWidth, nHeight, g_GLB_stPara.ptLockPos, sfAglSpeed, mmCenterRect, &tTargetRe, &nTrackPipeID,Temp_Target_Array, &Temp_nTargetNum); } nTrackPipeID = g_GLB_PipeProc->SO_ForceLock(img, g_GLB_stPara.ptLockPos, g_GLB_stPara.snLockBoxSize, Temp_Target_Array, Temp_nTargetNum, g_Input); } // 对地模式转固定波门框选 if (GLB_SCEN_GROUND == g_GLB_stPara.nWorkScene) { nTrackPipeID = g_GLB_PipeProc->SO_RectLock(img, g_GLB_stPara.ptLockPos, g_GLB_stPara.snLockBoxSize, g_Input); } return nTrackPipeID; } ``` ## NeoArithStandardDll.cpp ``` //取消跟踪接口 STD_TRACKER_API void ARIDLL_unLockCommand(ArithHandle hArithSrc) // 当前帧平台姿态----姿态值与方位俯仰重复 Input->afPlatformRPY = { 0 }; // 输出管道稳定目标 void ARIDLL_OutputPipeTarget(Arith_EOController* pArith, ARIDLL_OUTPUT* pstOutput) { ······· //显式输出算法状态 //对输出目标进行排序,防止ARM转发取差量时跳动 for (int i = 0; i < pstOutput->nTrackObjCnts; i++) { ARIDLL_OBJINFO trackObj_temp_i = pstOutput->stTrackers[i]; for (int j = i+1; j < pstOutput->nTrackObjCnts; j++) { //ARIDLL_OBJINFO trackObj_temp_j = pstOutput->stTrackers[j]; if (pstOutput->stTrackers[j].nOutputID < trackObj_temp_i.nOutputID) { pstOutput->stTrackers[i] = pstOutput->stTrackers[j]; pstOutput->stTrackers[j] = trackObj_temp_i; } } } if(2 == pstOutput->nStatus)//搜索状态 { if (pstOutput->nAlarmObjCnts > 0) { pstOutput->nStatus = 11; //自动截获状态 } if (pArith->g_GLB_stPara.bEnForceGuide) { pstOutput->nStatus = 12; //半自动截获状态 } } //if (3 == pstOutput->nStatus || 5 == pstOutput->nStatus || 9 == pstOutput->nStatus)//跟踪状态 //{ if (pstOutput->nTrackObjCnts > 0) { pstOutput->nStatus = 3; //单目标跟踪 } if (pstOutput->nTrackObjCnts > 1) { pstOutput->nStatus = 9; //多目标跟踪 } //} int Index = ARIDLL_Sort_PipeByDistance(pArith, pstOutput); if (0 < Index) { ARIDLL_OBJINFO TempObj = pstOutput->stAlarmObjs[0]; pstOutput->stAlarmObjs[0] = pstOutput->stAlarmObjs[Index]; pstOutput->stAlarmObjs[Index] = TempObj; } LOG_DEBUG_OUTPUT("stAlarmObjs[0]:nX:{},nY:{}; stTrackers[0]:nX:{},nY:{}", pstOutput->stAlarmObjs[0].nX, pstOutput->stAlarmObjs[0].nY, pstOutput->stTrackers[0].nX, pstOutput->stTrackers[0].nY); } ``` ``` //点选锁定及取消辅跟踪目标接口 STD_TRACKER_API ARIDLL_OBJINFO ARIDLL_LockOrUnLock(ArithHandle hArithSrc, GD_VIDEO_FRAME_S img, int nX, int nY, int Radius) { Arith_EOController* pArith = (Arith_EOController*)hArithSrc; PIPE* pPipeArray = pArith->g_GLB_PipeProc->getPipeArray(); int MaxPipeNum = pArith->g_GLB_PipeProc->PIPE_GetMaxPipeNum(); // 返回目标 ARIDLL_OBJINFO obj = { 0 }; int UnLockIndex = -1; LOG_DEBUG("LOCK_X:{},LOCK_Y:{}", nX, nY); if (0 != nX && 0 != nY) { for (int i = 0; i < MaxPipeNum; ++i) { PIPE* pPipeTemp = &pPipeArray[i]; if (!pPipeTemp->bTracking) { continue; } if (pPipeTemp->ptCurrentPnt.x > nX + Radius || pPipeTemp->ptCurrentPnt.x < nX - Radius || pPipeTemp->ptCurrentPnt.y > nY + Radius || pPipeTemp->ptCurrentPnt.y < nY - Radius) { continue; } UnLockIndex = i; } } if (-1 != UnLockIndex) { PIPE* pPipe = &pPipeArray[UnLockIndex]; obj.unTrackingStatus = TrackingStatus::NOT_TRACKING; pPipe->bTracking = FALSE; pPipe->nDelCntThres = GLB_PIPE_DEL_MIN_STARE; if (pPipe != NULL) { // 管道中最新目标 TARGET_OBJECT* pTarget = &pPipe->objHistoryList[pPipe->ubEnd]; //obj.nInPipesID = pATarget->nInPipesID_1 - 1; obj.bInCurrFov = pPipe->bInsideFOV; obj.nPipeLostCnt = pPipe->unLostCnt; obj.nTotalCnt = pPipe->unTotalCnt; obj.fAz = pPipe->afStopAgl.fAz; obj.fPt = pPipe->afStopAgl.fPt; obj.fProb = pPipe->fConfidence; obj.nFrameId = pPipe->nLostFrmID; obj.nX = pPipe->ptCurrentPnt.x; obj.nY = pPipe->ptCurrentPnt.y; obj.nObjW = pTarget->snSize.w; obj.nObjH = pTarget->snSize.h; obj.nOutputID = pPipe->nAlarmBatchID_1; // 若有外部引导批号,则上报该批号 if (pPipe->nGuideBatchID > 0) { obj.nOutputID = pPipe->nGuideBatchID; } } } else { //obj = ARIDLL_LockTarget(pArith, img, nX, nY, 0, 0); ARIDLL_LockCommand(pArith, nX, nY, 0, 0); } return obj; } ``` ``` //排序输出距离中心最近目标索引 STD_TRACKER_API int ARIDLL_Sort_PipeByDistance(ArithHandle hArithSrc, ARIDLL_OUTPUT* pstOutput) { Arith_EOController* pArith = (Arith_EOController*)hArithSrc; float centre_x = pArith->g_GLB_stInput.nImageWidth / 2.f; float centre_y = pArith->g_GLB_stInput.nImageHeight / 2.f; float min_distance = 99999999; int Index = -1; for (int i = 0; i < pstOutput->nAlarmObjCnts; ++i) { float distance = (pstOutput->stAlarmObjs[i].nX - centre_x) * (pstOutput->stAlarmObjs[i].nX - centre_x) + (pstOutput->stAlarmObjs[i].nY - centre_y) * (pstOutput->stAlarmObjs[i].nY - centre_y); if (distance < min_distance) { Index = i; min_distance = distance; } } return Index; } ```