You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

433 lines
12 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "Arith_Tracker.h"
#include "PIPE/API_MOT_PipeProc.h"
#include "Arith_Common.hpp"
#include <string>
// 模拟多态,有限类别手动指派,考虑到使用继承的效率和兼容性问题。
// Tracker::Tracker(SINT32 nWidth, SINT32 nHeight, GLB_SCEN_MODE type)
// {
// pGroundTracker = NULL;
// pSkyTracker = NULL;
// pAitTracker = NULL;
// pCustomTracker = NULL;
// if (type == GLB_SCEN_MODE::GLB_SCEN_SKY)
// {
// pSkyTracker = new SkyTracker(nWidth,nHeight);
// }
// else if(type == GLB_SCEN_MODE::GLB_SCEN_GROUND)
// {
// pGroundTracker = new GroundTracker(nWidth, nHeight);
// }
// else if (type == GLB_SCEN_MODE::GLB_SCEN_AIT)
// {
// std::string JsPath = std::string(SOURCE_PATH) + "/AITracker/x86_onnx/gd_ai_nanotrack_v3_241009.json";
// pAitTracker = new AIT_Interface(JsPath.c_str());
// //pAitTracker = new AIT_Interface();
// }
// else if(type == GLB_SCEN_MODE::GLB_SCEN_CUSTOM)
// {
// pCustomTracker = new CustomTracker(nWidth,nHeight);
// }
// m_LockingPipe = NULL;
// // 跟踪器输出
// ObjStatus = { 0 };
// m_type = type;
// emTUFlag = LockStateUnknown; // 目标锁定解锁标记
// }
Tracker::Tracker(SINT32 nWidth, SINT32 nHeight, GLB_SCEN_MODE type, ARIDLL_PARMA* pstArithPara)
{
pGroundTracker = NULL;
pSkyTracker = NULL;
pAitTracker = NULL;
pCustomTracker = NULL;
if (type == GLB_SCEN_MODE::GLB_SCEN_SKY)
{
pSkyTracker = new SkyTracker(nWidth, nHeight, pstArithPara->stSkyParam);
}
else if(type == GLB_SCEN_MODE::GLB_SCEN_GROUND)
{
pGroundTracker = new GroundTracker(nWidth, nHeight, pstArithPara->stGrdParam);
}
// else if (type == GLB_SCEN_MODE::GLB_SCEN_AIT)
// {
////pAitTracker = new AIT_Interface();
////std::string JsPath = std::string(SOURCE_PATH) + "/AITracker/x86_onnx/gd_ai_nanotrack_v3_241009.json";
////pAitTracker = new AIT_Interface(JsPath.c_str());
//pAitTracker = new AIT_Interface(pstArithPara->stAITParam);
////pAitTracker->nTracker = AIT_GetHandle();
////printf ("AIT_Interface:[%s]\n",JsPath);
////pAitTracker = new AIT_Interface();
// }
else if(type == GLB_SCEN_MODE::GLB_SCEN_CUSTOM)
{
pCustomTracker = new CustomTracker(nWidth,nHeight);
}
m_LockingPipe = NULL;
// 跟踪器输出
ObjStatus = { 0 };
m_type = type;
emTUFlag = LockStateUnknown; // 目标锁定解锁标记
}
Tracker::~Tracker()
{
if (pSkyTracker)
{
delete pSkyTracker;
pSkyTracker = nullptr;
}
if (pGroundTracker)
{
delete pGroundTracker;
pGroundTracker = nullptr;
}
if (pAitTracker)
{
delete pAitTracker;
pAitTracker = nullptr;
}
if(pCustomTracker)
{
delete pCustomTracker;
pCustomTracker = NULL;
}
}
bool Tracker::Init(GD_VIDEO_FRAME_S img, PIPE* pLockPipe, GLB_INPUT* p_GLB_Input)
{
m_LockingPipe = pLockPipe;
memset(&ObjStatus,0,sizeof(OBJECTSTATUS));
BBOOL bInitSucFlag = false;
if (m_type == GLB_SCEN_MODE::GLB_SCEN_SKY)
{
bInitSucFlag = pSkyTracker->Init(img, pLockPipe, p_GLB_Input);
}
else if (m_type == GLB_SCEN_MODE::GLB_SCEN_GROUND)
{
bInitSucFlag = pGroundTracker->Init(img, pLockPipe, p_GLB_Input);
}
// else if (m_type == GLB_SCEN_MODE::GLB_SCEN_AIT)
// {
//bInitSucFlag = pAitTracker->AIT_Init(img, pLockPipe, p_GLB_Input);
// }
else if(m_type == GLB_SCEN_MODE::GLB_SCEN_CUSTOM)
{
bInitSucFlag = pCustomTracker->Init(img, pLockPipe, p_GLB_Input);
}
return bInitSucFlag;
}
bool Tracker::Track(GD_VIDEO_FRAME_S img, GLB_INPUT* p_GLB_Input, API_MOT_PIPE* g_GLB_PipeProc, ARIDLL_PARMA* g_stArithPara)
{
bool bTrackStatus = false;
// 异常保护
if (m_LockingPipe == NULL || !m_LockingPipe->bTrackingPipe)
{
return false;
}
// 基于窗口平均计算管道长短时预测点
Predict_ObjAglTrackPredict(&m_LockingPipe->stMotionMod_mean, img.u32Width, img.u32Height, p_GLB_Input);
if (m_LockingPipe->stMotionMod_mean.bTrackStable)
{
m_LockingPipe->afCurrentAgl = m_LockingPipe->stMotionMod_mean.ObjAglListsLong.arfFilter.afAngle;
m_LockingPipe->ptCurrentPnt.x = m_LockingPipe->stMotionMod_mean.crnObjPrediRtLong.cx;
m_LockingPipe->ptCurrentPnt.y = m_LockingPipe->stMotionMod_mean.crnObjPrediRtLong.cy;
}
else
{
m_LockingPipe->afCurrentAgl = m_LockingPipe->stMotionMod_mean.ObjAglListsNear.arfFilter.afAngle;
m_LockingPipe->ptCurrentPnt.x = m_LockingPipe->stMotionMod_mean.crnObjPrediRtNear.cx;
m_LockingPipe->ptCurrentPnt.y = m_LockingPipe->stMotionMod_mean.crnObjPrediRtNear.cy;
}
// 跟踪找到目标
if (m_type == GLB_SCEN_MODE::GLB_SCEN_SKY)
{
emTUFlag = pSkyTracker->Track(img, p_GLB_Input, g_GLB_PipeProc, g_stArithPara, m_type);
ObjStatus = pSkyTracker->ObjStatus;
}
else if (m_type == GLB_SCEN_MODE::GLB_SCEN_GROUND)
{
bTrackStatus = pGroundTracker->Track(img, p_GLB_Input, g_GLB_PipeProc, m_type);
ObjStatus = pGroundTracker->ObjStatus;
}
//else if (m_type == GLB_SCEN_MODE::GLB_SCEN_AIT)
//{
// bTrackStatus = pAitTracker->AIT_Run(img, p_GLB_Input, m_LockingPipe);
// ObjStatus = pAitTracker->m_ObjStatus;
//}
else if (m_type == GLB_SCEN_MODE::GLB_SCEN_CUSTOM)
{
bTrackStatus = pCustomTracker->Track(img, p_GLB_Input, g_GLB_PipeProc);
ObjStatus = pCustomTracker->ObjStatus;
}
// 将跟踪结果输出到管道
UpdateTracker2Pipe(p_GLB_Input, m_type, m_LockingPipe, g_GLB_PipeProc);
// 返回跟踪状态
return bTrackStatus;
}
SINT32 Tracker::MemTrack(GD_VIDEO_FRAME_S img, GLB_INPUT* p_GLB_Input, API_MOT_PIPE* g_GLB_PipeProc, ARIDLL_PARMA* g_stArithPara)
{
bool bTrackStatus = false;
// 基于窗口平均计算管道长短时预测点
Predict_ObjAglTrackPredict(&m_LockingPipe->stMotionMod_mean, img.u32Width, img.u32Height, p_GLB_Input);
m_LockingPipe->afCurrentAgl = m_LockingPipe->stMotionMod_mean.ObjAglListsNear.arfFilter.afAngle;
m_LockingPipe->ptCurrentPnt.x = m_LockingPipe->stMotionMod_mean.crnObjPrediRtNear.cx;
m_LockingPipe->ptCurrentPnt.y = m_LockingPipe->stMotionMod_mean.crnObjPrediRtNear.cy;
// 跟踪找到目标
if (m_type == GLB_SCEN_MODE::GLB_SCEN_SKY)
{
emTUFlag = pSkyTracker->MemTrack(img, p_GLB_Input, g_GLB_PipeProc, g_stArithPara, m_type);
ObjStatus = pSkyTracker->ObjStatus;
}
else if (m_type == GLB_SCEN_MODE::GLB_SCEN_GROUND)
{
bTrackStatus = pGroundTracker->MemTrack(img, p_GLB_Input, g_GLB_PipeProc, m_type);
ObjStatus = pGroundTracker->ObjStatus;
}
//else if (m_type == GLB_SCEN_MODE::GLB_SCEN_AIT)
//{
// //bTrackStatus = pAitTracker->AIT_Run(img, p_GLB_Input, m_LockingPipe);
// //ObjStatus = pAitTracker->m_ObjStatus;
//}
else if (m_type == GLB_SCEN_MODE::GLB_SCEN_CUSTOM)
{
//bTrackStatus = pCustomTracker->Track(img, p_GLB_Input, g_GLB_PipeProc);
//ObjStatus = pCustomTracker->ObjStatus;
}
// 将跟踪结果输出到管道
UpdateTracker2Pipe(p_GLB_Input, m_type, m_LockingPipe, g_GLB_PipeProc);
// 返回跟踪状态
return bTrackStatus;
}
// 解锁:清除管道锁定标记
void Tracker::Cancle()
{
if (m_type == GLB_SCEN_MODE::GLB_SCEN_SKY)
{
pSkyTracker->Cancle();
}
else if(m_type == GLB_SCEN_MODE::GLB_SCEN_GROUND)
{
pGroundTracker->Cancle();
}
// else if (m_type == GLB_SCEN_MODE::GLB_SCEN_AIT)
// {
//pAitTracker->AIT_Cancle();
// }
else if(m_type == GLB_SCEN_MODE::GLB_SCEN_CUSTOM)
{
pCustomTracker->Cancle();
}
}
// 使用新管道初始化跟踪器,且不改变原跟踪批号、管道号以及跟踪器编号。
bool Tracker::ResetByBackPipe(PIPE* pNewPipe, GD_VIDEO_FRAME_S img, GLB_INPUT* p_GLB_Input,BBOOL bReInit)
{
BBOOL bInitSucc = TRUE;
// 异常保护
if (m_LockingPipe == NULL || !m_LockingPipe->bTrackingPipe)
{
return false;
}
// 正在跟踪的管道
PIPE * pPipeOld = m_LockingPipe;
// 遗传告警信息
SINT32 nInAlarmArrayIndex_1 = pPipeOld->nInAlarmArrayIndex_1;//管道位于告警队列位置从1开始
SINT32 nAlarmBatchID_1 = pPipeOld->nAlarmBatchID_1;//管道告警批号从1开始
SINT32 nGuideBatchID= pPipeOld->nGuideBatchID;//外部批号,如果存在外部批号,则使用外部批号送显,内部批号不变,灵活度高
// 将新管道信息完全拷贝到跟踪管道
memcpy(pPipeOld,pNewPipe,sizeof(PIPE));
// 恢复原管道告警关联信息
pPipeOld->nInAlarmArrayIndex_1 = nInAlarmArrayIndex_1;
pPipeOld->nAlarmBatchID_1 = nAlarmBatchID_1;
pPipeOld->nGuideBatchID = nGuideBatchID;
// 恢复跟踪标记
pPipeOld->bTrackingPipe = true;
// 新管道被eat,需完全删除交外部执行tracker没这个权限。
// 跟踪器初始化
bInitSucc = Init(img,m_LockingPipe,p_GLB_Input);
return bInitSucc;
}
//Tracker_Param Tracker::GetParam()
//{
// return Tracker_Param();
//}
RECT32S Tracker::getTrackerBox()
{
RECT32S rc = { 0 };
rc.x = SINT32(ObjStatus.ptPos.x - ObjStatus.sfSize.w / 2);
rc.y = SINT32(ObjStatus.ptPos.y - ObjStatus.sfSize.h / 2);
rc.w = SINT32(ObjStatus.sfSize.w);
rc.h = SINT32(ObjStatus.sfSize.h);
return rc;
}
/*
* 将跟踪器结果输出为管道目标信息不要丢特征否则可能导致SA跟踪器特征突变一直无法跟踪
*/
bool Tracker::UpdateTracker2Pipe(GLB_INPUT* p_GLB_Input,GLB_SCEN_MODE type, PIPE* pPipeOut, API_MOT_PIPE* g_GLB_PipeProc)
{
PIPE* pPipe = pPipeOut;
if (!pPipe->bTrackingPipe)
{
g_GLB_PipeProc->DelPipe(pPipe);
return false;
}
// 总帧数+1
pPipe->unTotalCnt++;
// 目标丢失
if (ObjStatus.unContiLostCnt > 0)
{
//标记管道丢失
pPipe->bLost = true;
pPipe->unLostCnt++;
pPipe->unContinueExistCnt = 0;
// 用跟踪器预测位置,更新管道预测点
pPipe->ptCurrentPnt.x = ObjStatus.ptPos.x;
pPipe->ptCurrentPnt.y = ObjStatus.ptPos.y;
pPipe->afCurrentAgl.fAz = ObjStatus.afAngle.fAz;
pPipe->afCurrentAgl.fPt = ObjStatus.afAngle.fPt;
// ab滤波器预测
Filter_Predict(&pPipe->stMotionMod, p_GLB_Input->unFrmId);
// 3d滤波器预测
PodXYZFilter_Predict(&pPipe->stXYZMotionMod, p_GLB_Input->unFrmId);
}
// 目标更新
else
{
//获取在当前帧中查找到的最相似目标
//KCF获得的目标只有位置和尺度信息
TARGET_OBJECT Target = { 0 };
Target.unFrmID = p_GLB_Input->unFrmId;
Target.bObject = true;
Target.pfCenPos = ObjStatus.ptPos;
//ptTarget.pnMaxPos = ptTarget.pfCenPos;
Target.afAngle = ObjStatus.afAngle;
Target.unClsType = ObjStatus.unClsType;
// 3D坐标计算
Pole targetPole = {0};
targetPole.alpha = ObjStatus.afAngle.fPt;
targetPole.beta = ObjStatus.afAngle.fAz;
Target.pos3d = getXYZFromPole_withHeight(targetPole,p_GLB_Input->nElevationDiff);
Target.fMatchConf = ObjStatus.fConfidence;
// 尺度重要KCF和SA之间除位置外唯一的切换特征
Target.snSize.w = (SINT16)ObjStatus.sfSize.w;
Target.snSize.h = (SINT16)ObjStatus.sfSize.h;
Target.snSize.s = (SINT32)ObjStatus.sfSize.s;
Target.snAIDetSize.w = (SINT16)ObjStatus.snAIDetSize.w;
Target.snAIDetSize.h = (SINT16)ObjStatus.snAIDetSize.h;
Target.snAIDetSize.s = (SINT32)ObjStatus.snAIDetSize.s;
Target.nObjTypeSrc = ObjStatus.nObjTypeSrc;
Target.unObjPxlsCnt = (UINT32)ObjStatus.fObjPxlsCnt;
Target.pxObjGray = ObjStatus.pxObjGray;
Target.fSNR = ObjStatus.fSNR;
Target.emClsSrc = ObjStatus.emClsSrc;
Target.fBGMean = ObjStatus.fBGMean;
Target.fBGStd = ObjStatus.fBGStd;
//// 如果对空小面目标跟踪器已经检出目标,且是融合决策目标,直接加入管道
//if (type == GLB_SCEN_MODE::GLB_SCEN_SKY && pSkyTracker->mTargetFusion.bObject)
//{
// Target = pSkyTracker->mTargetFusion;
//}
UINT16 fGrayFilter; // 灰度滤波值
POINT32F ptCentroid; // 质心定位置
// 将跟踪决策目标加入管道
g_GLB_PipeProc->PIPE_AddObjToOccupiedPipe(pPipe, pPipe->nPipeID, &Target, 0, p_GLB_Input);
// LOG_INFO("FrmId:{0},Cx:{1},Cy:{2},fAz:{3},fPt:{4},AlgSpeedX:{5},AlgSpeedY:{6},pixSpeedX:{7},pixSpeedY:{8},fObjStd:{9},fBGStd:{10},fSNR:{11},fObjPxlsCnt:{12},fGrayFilter:{13},ptCentroidX:{14},ptCentroidX:{15}",
// p_GLB_Input->unFrmId, ObjStatus.ptPos.x, ObjStatus.ptPos.y,
// ObjStatus.afAngle.fAz, ObjStatus.afAngle.fPt, ObjStatus.sfAglSpeed.vx, ObjStatus.sfAglSpeed.vy,
// ObjStatus.sfSpeed.vx, ObjStatus.sfSpeed.vy, ObjStatus.fObjStd, ObjStatus.fBGStd, ObjStatus.fSNR, ObjStatus.fObjPxlsCnt,
// pPipe->ObjectFilter.fGray, ObjStatus.ptCentroid.x, ObjStatus.ptCentroid.y
// );
}
return true;
}
// 返回对地跟踪器的TLD模块
API_TLD * Tracker::GetpTLDTracker()
{
if (pGroundTracker)
{
return pGroundTracker->m_pTLDTracker;
}
else
{
return NULL;
}
}