|
|
|
|
|
#include "Arith_SkyTracker.h"
|
|
|
|
|
|
#include "PIPE/Arith_PIPE_utils.h"
|
|
|
|
|
|
#include "Arith_CoordModule.h"
|
|
|
|
|
|
#include "Arith_Bbox.h"
|
|
|
|
|
|
#include "Arith_timer.h"
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
|
|
SkyTracker::SkyTracker(SINT32 nWidth, SINT32 nHeight)
|
|
|
|
|
|
{
|
|
|
|
|
|
pSATracker = new SA_Tracker(nWidth, nHeight);
|
|
|
|
|
|
pKCFTracker = API_KCF_Tracker::Create(96, 128); // 参数控制模板输入大小 (56, 64) (96, 128) (120, 128)
|
|
|
|
|
|
pBkgMonitor = new BkgMonitor(); // 跟踪目标背景监控
|
|
|
|
|
|
pRadarInfo = new RadarInfo(); // 雷达信息监控
|
|
|
|
|
|
Ai_DMonitor = new AID_Monitor(); // AI Detect 管道监控模块,用于筛选AI检测的重捕候选
|
|
|
|
|
|
|
|
|
|
|
|
mTargetFusion = { 0 };
|
|
|
|
|
|
ObjStatus = { 0 };
|
|
|
|
|
|
m_LockingPipe = nullptr;
|
|
|
|
|
|
g_GLB_nTrackDecisionCnt = 0;
|
|
|
|
|
|
m_bSetMemoryTrack = false;
|
|
|
|
|
|
skyControlInfo.m_bMemoryTrackOcc = false;
|
|
|
|
|
|
skyControlInfo.nTrackMemFrmNum = GLB_MEMORY_FRM_NUM;
|
|
|
|
|
|
|
|
|
|
|
|
mTrakingPara.Sky_bEnableKCF = false;
|
|
|
|
|
|
mTrakingPara.Sky_bEnableFullImgDet = false;
|
|
|
|
|
|
mTrakingPara.Sky_bEnableTrackSA = false;
|
|
|
|
|
|
mTrakingPara.nSmallObjSizeMax = 32;
|
|
|
|
|
|
|
|
|
|
|
|
SkyTrkStatusInfo = { 0 };
|
|
|
|
|
|
|
|
|
|
|
|
bsvmInitDone = FALSE;
|
|
|
|
|
|
pipeClassifyInfo = new PipeMainClassifyInfo;
|
|
|
|
|
|
memset(pipeClassifyInfo, 0, sizeof(PipeMainClassifyInfo));
|
|
|
|
|
|
|
|
|
|
|
|
// svm 模型加载
|
|
|
|
|
|
char svmModelName[256];
|
|
|
|
|
|
std::string basePath = GetDynamicLibraryPath();
|
|
|
|
|
|
snprintf(svmModelName, 256, "%s/%s", basePath.c_str(), "scaled_fly_bird_train.model");
|
|
|
|
|
|
//std::string model_name = std::string(SOURCE_PATH) + "/NeoTracker/src/SVM/models/scaled_fly_bird_train.model";
|
|
|
|
|
|
if ((SVM_model = svm_load_model(svmModelName)) == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
bsvmInitDone = FALSE;
|
|
|
|
|
|
svm_nodeX = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
svm_nodeX = (struct svm_node*)malloc((MAIN_ALARM_DEPTH_MAX + 1) * sizeof(struct svm_node));
|
|
|
|
|
|
bsvmInitDone = TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_TSky_Output.m_nTargetNum = 0;
|
|
|
|
|
|
m_TSky_Output.mTarget_Array = new TARGET_OBJECT[DT_TARGET_MAX_NUM];
|
|
|
|
|
|
|
|
|
|
|
|
// 模板匹配初始化
|
|
|
|
|
|
m_TSky_Output.m_nMatcherNum = 0;
|
|
|
|
|
|
m_TSky_Output.mMatcher_Array = new MATCHER_TARGET[DT_MATCHER_MAX_NUM];
|
|
|
|
|
|
Matcher_Create(&matcher);
|
|
|
|
|
|
|
|
|
|
|
|
SkyTrkState = LockStateUnknown;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SkyTracker::SkyTracker(SINT32 nWidth, SINT32 nHeight, Param_SkyTracker para)
|
|
|
|
|
|
{
|
|
|
|
|
|
pSATracker = new SA_Tracker(nWidth, nHeight);
|
|
|
|
|
|
pKCFTracker = API_KCF_Tracker::Create(96, 128); // 参数控制模板输入大小(56,64) (96,128) (120, 128)
|
|
|
|
|
|
pBkgMonitor = new BkgMonitor(); // 跟踪目标背景监控
|
|
|
|
|
|
pRadarInfo = new RadarInfo(); // 雷达信息监控
|
|
|
|
|
|
Ai_DMonitor = new AID_Monitor(); // AI Detect 管道监控模块,用于筛选AI检测的重捕候选
|
|
|
|
|
|
|
|
|
|
|
|
mTargetFusion = { 0 };
|
|
|
|
|
|
ObjStatus = { 0 };
|
|
|
|
|
|
m_LockingPipe = nullptr;
|
|
|
|
|
|
g_GLB_nTrackDecisionCnt = 0;
|
|
|
|
|
|
m_bSetMemoryTrack = false;
|
|
|
|
|
|
skyControlInfo.m_bMemoryTrackOcc = false;
|
|
|
|
|
|
skyControlInfo.nTrackMemFrmNum = GLB_MEMORY_FRM_NUM;
|
|
|
|
|
|
|
|
|
|
|
|
// 读取跟踪参数配置
|
|
|
|
|
|
mTrakingPara = para;
|
|
|
|
|
|
|
|
|
|
|
|
// 从检测器同步参数到跟踪器
|
|
|
|
|
|
pSATracker->pDST_Module->setDstParm(¶.prmTSkyDet);
|
|
|
|
|
|
//pSATracker->pDAT_Module->setDatParm(¶.prmTSkyDet);
|
|
|
|
|
|
|
|
|
|
|
|
bsvmInitDone = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
SkyTrkStatusInfo = { 0 };
|
|
|
|
|
|
|
|
|
|
|
|
pipeClassifyInfo = new PipeMainClassifyInfo;
|
|
|
|
|
|
memset(pipeClassifyInfo, 0, sizeof(PipeMainClassifyInfo));
|
|
|
|
|
|
|
|
|
|
|
|
// svm 模型加载
|
|
|
|
|
|
char svmModelName[256];
|
|
|
|
|
|
std::string basePath = GetDynamicLibraryPath();
|
|
|
|
|
|
snprintf(svmModelName, 256, "%s/%s", basePath.c_str(), "scaled_fly_bird_train.model");
|
|
|
|
|
|
//std::string model_name = PATH + "/NeoTracker/src/SVM/models/scaled_fly_bird_train.model";;
|
|
|
|
|
|
if ((SVM_model = svm_load_model(svmModelName)) == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_WARN("svm_load_model Failed");
|
|
|
|
|
|
svm_nodeX = NULL;
|
|
|
|
|
|
bsvmInitDone = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
svm_nodeX = (struct svm_node*)malloc((MAIN_ALARM_DEPTH_MAX + 1) * sizeof(struct svm_node));
|
|
|
|
|
|
bsvmInitDone = TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
m_TSky_Output.m_nTargetNum = 0;
|
|
|
|
|
|
m_TSky_Output.mTarget_Array = new TARGET_OBJECT[DT_TARGET_MAX_NUM];
|
|
|
|
|
|
|
|
|
|
|
|
// 模板匹配初始化
|
|
|
|
|
|
m_TSky_Output.m_nMatcherNum = 0;
|
|
|
|
|
|
m_TSky_Output.mMatcher_Array = new MATCHER_TARGET[DT_MATCHER_MAX_NUM];
|
|
|
|
|
|
Matcher_Create(&matcher);
|
|
|
|
|
|
|
|
|
|
|
|
SkyTrkState = LockStateUnknown;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SkyTracker::~SkyTracker()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pSATracker)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete pSATracker;
|
|
|
|
|
|
pSATracker = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (pKCFTracker)
|
|
|
|
|
|
{
|
|
|
|
|
|
API_KCF_Tracker::Destroy(pKCFTracker);
|
|
|
|
|
|
pKCFTracker = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pBkgMonitor)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete pBkgMonitor;
|
|
|
|
|
|
pBkgMonitor = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pRadarInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete pRadarInfo;
|
|
|
|
|
|
pRadarInfo = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_TSky_Output.mTarget_Array)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[]m_TSky_Output.mTarget_Array;
|
|
|
|
|
|
m_TSky_Output.mTarget_Array = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_TSky_Output.mMatcher_Array)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[]m_TSky_Output.mMatcher_Array;
|
|
|
|
|
|
m_TSky_Output.mMatcher_Array = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (matcher)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (matcher->g_Matcher_Image)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[]matcher->g_Matcher_Image;
|
|
|
|
|
|
matcher->g_Matcher_Image = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
delete matcher;
|
|
|
|
|
|
matcher = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (NULL != pipeClassifyInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete pipeClassifyInfo;
|
|
|
|
|
|
pipeClassifyInfo = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Ai_DMonitor)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete Ai_DMonitor;
|
|
|
|
|
|
Ai_DMonitor = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (NULL != svm_nodeX)
|
|
|
|
|
|
{
|
|
|
|
|
|
free(svm_nodeX);
|
|
|
|
|
|
svm_nodeX = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (SVM_model)
|
|
|
|
|
|
{
|
|
|
|
|
|
svm_free_and_destroy_model(&SVM_model);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SkyTracker::Init(GD_VIDEO_FRAME_S img, PIPE* pLockPipe, GLB_INPUT* p_GLB_Input)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_LockingPipe = pLockPipe;
|
|
|
|
|
|
|
|
|
|
|
|
// 锁定管道传指针
|
|
|
|
|
|
if (pSATracker)
|
|
|
|
|
|
{
|
|
|
|
|
|
mTrakingPara.Sky_bEnableTrackSA = true;
|
|
|
|
|
|
pSATracker->Init((UINT16*)img.u64VirAddr[0], img.u32Width, img.u32Height, pLockPipe, p_GLB_Input);
|
|
|
|
|
|
}
|
|
|
|
|
|
pKCFTracker->KCF_InitObjectParameters(img, pLockPipe, p_GLB_Input);//无条件初始化KCF参数,防止后续出现除0
|
|
|
|
|
|
|
|
|
|
|
|
TARGET_OBJECT* pTrackingTarget = &pLockPipe->objHistoryList[pLockPipe->ubEnd];
|
|
|
|
|
|
// 面目标初始化KCF
|
|
|
|
|
|
if (pSATracker && pSATracker->m_SizeMode == SizeType::AreaTarget)
|
|
|
|
|
|
{
|
|
|
|
|
|
mTrakingPara.Sky_bEnableKCF = true;
|
|
|
|
|
|
// 从管道拷贝尺寸信息到面目标匹配输出,用于控制跟踪锁定后的分割降采样倍率
|
|
|
|
|
|
OBJECTSTATUS* m_DatTrkTarget = pSATracker->pDAT_Module->GetTargetMatched();
|
|
|
|
|
|
memset(m_DatTrkTarget, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
m_DatTrkTarget->sfSize.w = (FLOAT32)pTrackingTarget->snSize.w;
|
|
|
|
|
|
m_DatTrkTarget->sfSize.h = (FLOAT32)pTrackingTarget->snSize.h;
|
|
|
|
|
|
m_DatTrkTarget->sfSize.s = (FLOAT32)pTrackingTarget->unObjPxlsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
mTrakingPara.Sky_bEnableKCF = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化Matcher模板匹配信息
|
|
|
|
|
|
RECT32S stTargetRect = { 0 };
|
|
|
|
|
|
stTargetRect.w = pTrackingTarget->snSize.w;
|
|
|
|
|
|
stTargetRect.h = pTrackingTarget->snSize.h;
|
|
|
|
|
|
stTargetRect.x = SINT32(pTrackingTarget->pfCenPos.x - stTargetRect.w / 2);
|
|
|
|
|
|
stTargetRect.y = SINT32(pTrackingTarget->pfCenPos.y - stTargetRect.h / 2);
|
|
|
|
|
|
//templateMatching::Matcher_SetTemplate(matcher, img, stTargetRect); // 设置模板 --3315会崩溃,先注释
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_TSky_Output.m_SizeMode = SizeType::unKnown; // 输出目标尺寸类型为未知
|
|
|
|
|
|
m_TSky_Output.m_nTargetNum = 0; // 局部目标检测结果重置为0
|
|
|
|
|
|
m_TSky_Output.m_nMatcherNum = 0; // 模板匹配结果重置为0
|
|
|
|
|
|
m_TSky_Output.findState = Finded_FAILED; // 小面匹配状态
|
|
|
|
|
|
m_TSky_Output.m_bComplexEnv = FALSE; // 复杂背景标记
|
|
|
|
|
|
m_TSky_Output.m_bInterferenceMem = FALSE; // 过竿遮挡标记
|
|
|
|
|
|
m_TSky_Output.unSimTargetNum = 0; // 相似目标个数
|
|
|
|
|
|
m_TSky_Output.m_bSimInflunce = FALSE; // 相似干扰标记
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 跟踪阶段局部区域单帧目标检测结果
|
|
|
|
|
|
memset(&m_TSky_Output.mTrakingPara_Output, 0, sizeof(Param_SkyTracker));
|
|
|
|
|
|
memset(&m_TSky_Output.ObjectStatusTST, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
memset(&m_TSky_Output.ObjectStatusCEND, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
memset(&m_TSky_Output.ObjectStatusKCF, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
memset(&m_TSky_Output.ObjectStatusDesc, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tracker_JammPipe(PIPE* pLockingPipe, PIPE* pPipeArray, SINT32 nMaxPipeNum)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < nMaxPipeNum; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 管道
|
|
|
|
|
|
PIPE* pPipe = &pPipeArray[i];
|
|
|
|
|
|
if (!pPipe->bOccupy)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
//跟踪器丢失时或干扰状态不判断
|
|
|
|
|
|
if (pLockingPipe->bLost || pLockingPipe->unSimTargetNum > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
FLOAT32 Dis = ABS(pPipe->ptCurrentPnt.x - pLockingPipe->ptCurrentPnt.x) + ABS(pPipe->ptCurrentPnt.y - pLockingPipe->ptCurrentPnt.y);
|
|
|
|
|
|
if (pLockingPipe->nPipeID == pPipe->nPipeID || Dis < MAX(pLockingPipe->ObjectFilter.sfSize.w, pLockingPipe->ObjectFilter.sfSize.h) * 1.5)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
pPipe->bJammPipe = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TrackUnlockState SkyTracker::Track(GD_VIDEO_FRAME_S img, GLB_INPUT* p_GLB_Input, API_MOT_PIPE* g_GLB_PipeProc, ARIDLL_PARMA* g_stArithPara, GLB_SCEN_MODE m_type)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 跟踪成功状态
|
|
|
|
|
|
bool bTrackStatus = false;
|
|
|
|
|
|
|
|
|
|
|
|
SkyTrkState = Locked_Tracking; // 对空(决策)跟踪器的跟踪状态
|
|
|
|
|
|
m_TSky_Output.m_nTargetNum = 0; // 局部目标检测结果重置为0
|
|
|
|
|
|
m_TSky_Output.m_nMatcherNum = 0; // 模板匹配结果重置为0
|
|
|
|
|
|
|
|
|
|
|
|
// 管道队列
|
|
|
|
|
|
PIPE* pPipeArray = g_GLB_PipeProc->getPipeArray();
|
|
|
|
|
|
SINT32 nPipeArrayLen = g_GLB_PipeProc->PIPE_GetMaxPipeNum();
|
|
|
|
|
|
|
|
|
|
|
|
Tracker_JammPipe(m_LockingPipe, pPipeArray, nPipeArrayLen);
|
|
|
|
|
|
|
|
|
|
|
|
// 将当前帧找到目标置为空
|
|
|
|
|
|
//memset(&mTargetFusion, 0, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
// 获取外部传入参数
|
|
|
|
|
|
SetSkyParam(&g_stArithPara->stSkyParam);
|
|
|
|
|
|
|
|
|
|
|
|
//判断当前跟踪目标相对于天地线的位置,决定是否对跟踪阶段的 小、面目标检测进行抑制
|
|
|
|
|
|
skyControlInfo.bTrackLowSkyline = FALSE; //FALSE, TRUE;
|
|
|
|
|
|
|
|
|
|
|
|
//执行小面目标跟踪器
|
|
|
|
|
|
if (pSATracker && mTrakingPara.Sky_bEnableTrackSA)
|
|
|
|
|
|
{
|
|
|
|
|
|
memcpy(&m_TSky_Output.mTrakingPara_Output, &mTrakingPara, sizeof(Param_SkyTracker));
|
|
|
|
|
|
// 执行对空跟踪
|
|
|
|
|
|
pSATracker->Track(img, p_GLB_Input, g_GLB_PipeProc, &skyControlInfo, &m_TSky_Output);
|
|
|
|
|
|
|
|
|
|
|
|
if (SizeType::SmallTarget == pSATracker->m_SizeMode || SizeType::DimTarget == pSATracker->m_SizeMode)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_TSky_Output.m_SizeMode = SizeType::SmallTarget;
|
|
|
|
|
|
memcpy(&m_TSky_Output.ObjectStatusTST, &pSATracker->m_ObjStatus, sizeof(OBJECTSTATUS)); // 导出小目标跟踪结果
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (SizeType::AreaTarget == pSATracker->m_SizeMode)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_TSky_Output.m_SizeMode = SizeType::AreaTarget;
|
|
|
|
|
|
memcpy(&m_TSky_Output.ObjectStatusCEND, &pSATracker->m_ObjStatus, sizeof(OBJECTSTATUS)); // 导出质心跟踪结果
|
|
|
|
|
|
|
|
|
|
|
|
DAT_PARAMETERS* pDAT_stPara = pSATracker->pDAT_Module->GetDatParm();
|
|
|
|
|
|
// 参数对外输出(仅作为输出)
|
|
|
|
|
|
m_TSky_Output.mTrakingPara_Output.prmTSkyDet.nDSmpScale = pDAT_stPara->nDSmpScale;
|
|
|
|
|
|
m_TSky_Output.mTrakingPara_Output.prmTSkyDet.fAreaDetectGradDiffThre = pDAT_stPara->nGradThresMin;
|
|
|
|
|
|
m_TSky_Output.mTrakingPara_Output.prmTSkyDet.nGrayThresMinBright = pDAT_stPara->nGrayThresMinBright;
|
|
|
|
|
|
m_TSky_Output.mTrakingPara_Output.prmTSkyDet.nGrayThresMinDark = pDAT_stPara->nGrayThresMinDark;
|
|
|
|
|
|
}
|
|
|
|
|
|
m_TSky_Output.m_nTargetNum = pSATracker->m_TSA_output.m_nTargetNum;
|
|
|
|
|
|
memcpy(m_TSky_Output.mTarget_Array, pSATracker->m_TSA_output.mTarget_Array, sizeof(TARGET_OBJECT) * m_TSky_Output.m_nTargetNum);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 执行KCF跟踪器
|
|
|
|
|
|
if (pKCFTracker && mTrakingPara.Sky_bEnableKCF)
|
|
|
|
|
|
{
|
|
|
|
|
|
pKCFTracker->KCF_Run(img, p_GLB_Input, &skyControlInfo);
|
|
|
|
|
|
memcpy(&m_TSky_Output.ObjectStatusKCF, pKCFTracker->GetTrackeStatus(), sizeof(OBJECTSTATUS));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 执行快速模板匹配
|
|
|
|
|
|
if (matcher && mTrakingPara.Sky_bEnableMatcher)
|
|
|
|
|
|
{
|
|
|
|
|
|
//time_checker time1;
|
|
|
|
|
|
//time1.TimeStart();
|
|
|
|
|
|
|
|
|
|
|
|
templateMatching::Matcher_Process(matcher, img, &pSATracker->m_ObjStatus, &m_TSky_Output);
|
|
|
|
|
|
|
|
|
|
|
|
//time1.TimeStop();
|
|
|
|
|
|
|
|
|
|
|
|
//int a = time1.timeDistance(); // x86debug 3~5ms
|
|
|
|
|
|
//LOG_INFO("Matcher_Process:", time1.timeDistance());
|
|
|
|
|
|
|
|
|
|
|
|
//m_TSky_Output.ObjectStatusMatcher.
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//AI识别监控
|
|
|
|
|
|
if (mTrakingPara.Sky_bUseAIDet)
|
|
|
|
|
|
{
|
|
|
|
|
|
Ai_DMonitor->Process(img, p_GLB_Input, &ObjStatus, m_LockingPipe, g_GLB_PipeProc);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 跟踪决策及模型更新
|
|
|
|
|
|
bTrackStatus = TrackDecision(img, p_GLB_Input);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 跟踪成功
|
|
|
|
|
|
if (bTrackStatus)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 自动切换跟踪器
|
|
|
|
|
|
SetTrackModeAuto(img, p_GLB_Input);
|
|
|
|
|
|
|
|
|
|
|
|
// 小面跟踪目标及背景监控
|
|
|
|
|
|
if (pSATracker && mTrakingPara.Sky_bEnableTrackSA)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 面目标的情况下
|
|
|
|
|
|
if (SizeType::AreaTarget == pSATracker->m_SizeMode)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 计算跟踪面目标质心
|
|
|
|
|
|
calculateCentroid(img, &ObjStatus, m_LockingPipe->ObjectFilter.fGray);
|
|
|
|
|
|
|
|
|
|
|
|
// 面目标跟踪错误判定相关信息统计,AI识别率+位移信息统计
|
|
|
|
|
|
SkyTrackFalse_Process(img, p_GLB_Input, &ObjStatus, m_LockingPipe);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (SizeType::SmallTarget == pSATracker->m_SizeMode || SizeType::DimTarget == pSATracker->m_SizeMode)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 如果是小目标,需要单独计算的内容
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 对空目标类别判定处理
|
|
|
|
|
|
SkyClassify_Process(img, &ObjStatus, m_LockingPipe, pSATracker->m_SizeMode);
|
|
|
|
|
|
|
|
|
|
|
|
// 背景监控
|
|
|
|
|
|
pBkgMonitor->BKM_BkgMonitor(img, p_GLB_Input, pSATracker->m_GrayMode, pSATracker->m_TSA_Input.crCenterRect, &ObjStatus);
|
|
|
|
|
|
skyControlInfo.m_bMemoryTrackOcc = pBkgMonitor->g_GLB_bInterferenceMem; // 过竿判定遮挡状态传递
|
|
|
|
|
|
|
|
|
|
|
|
// SA跟踪器更新目标表观特性模型
|
|
|
|
|
|
pSATracker->TO_RecordObjFeatures(&mTargetFusion, p_GLB_Input);
|
|
|
|
|
|
m_TSky_Output.m_bComplexEnv = pBkgMonitor->g_GLB_bComplexEnv; // 复杂背景透传到输出
|
|
|
|
|
|
m_TSky_Output.m_bInterferenceMem = pBkgMonitor->g_GLB_bInterferenceMem; // 过竿遮挡标记透传到输出
|
|
|
|
|
|
|
|
|
|
|
|
// 跟踪器局部的检测器结果清空
|
|
|
|
|
|
memset(pSATracker->m_Target_Array, 0, sizeof(TARGET_OBJECT) * pSATracker->m_nTargetNum);
|
|
|
|
|
|
pSATracker->m_nTargetNum = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
//// KCF特性监控
|
|
|
|
|
|
//if (pKCFTracker && mTrakingPara.Sky_bEnableKCF)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// // 获取KCF响应值监控
|
|
|
|
|
|
// KcfRespHistory* kcfStatus = &g_kcfRespVec;
|
|
|
|
|
|
// // 统计监控信息
|
|
|
|
|
|
// SINT32 nCount = MIN(KCFHistLen, kcfStatus->Cnt);
|
|
|
|
|
|
|
|
|
|
|
|
// PIPE_FEATURE_FLUC kcfStatus_Peak;
|
|
|
|
|
|
// TO_CalcStdOfArray(kcfStatus->kcf_peak, KCFHistLen, kcfStatus->ind, nCount, &kcfStatus_Peak);
|
|
|
|
|
|
// PIPE_FEATURE_FLUC kcfStatus_Psr;
|
|
|
|
|
|
// TO_CalcStdOfArray(kcfStatus->kcf_psr, KCFHistLen, kcfStatus->ind, nCount, &kcfStatus_Psr);
|
|
|
|
|
|
// PIPE_FEATURE_FLUC kcfStatus_apce;
|
|
|
|
|
|
// TO_CalcStdOfArray(kcfStatus->kcf_apce, KCFHistLen, kcfStatus->ind, nCount, &kcfStatus_apce);
|
|
|
|
|
|
|
|
|
|
|
|
// // 信息融合
|
|
|
|
|
|
// FLOAT32 Prob_Peak = EVENT_ProbCalc(kcfStatus->kcf_peak_curr, kcfStatus_Peak.fMean, kcfStatus_Peak.fStd);
|
|
|
|
|
|
|
|
|
|
|
|
// FLOAT32 Prob_Psr = EVENT_ProbCalc(kcfStatus->kcf_psr_curr, kcfStatus_Psr.fMean, kcfStatus_Psr.fStd);
|
|
|
|
|
|
|
|
|
|
|
|
// FLOAT32 Prob_Apce = EVENT_ProbCalc(kcfStatus->kcf_apce_curr, kcfStatus_apce.fMean, kcfStatus_apce.fStd);
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
// 遮挡决策
|
|
|
|
|
|
|
|
|
|
|
|
// 跟踪判错
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 跟踪失败,解锁
|
|
|
|
|
|
Cancle();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 返回跟踪状态
|
|
|
|
|
|
return SkyTrkState;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 对空强制记忆跟踪
|
|
|
|
|
|
TrackUnlockState SkyTracker::MemTrack(GD_VIDEO_FRAME_S img, GLB_INPUT* g_GLB_Input, API_MOT_PIPE* g_GLB_PipeProc, ARIDLL_PARMA* g_stArithPara, GLB_SCEN_MODE m_type)
|
|
|
|
|
|
{
|
|
|
|
|
|
SkyTrkState = Locked_Losting; // 对空(决策)跟踪器的跟踪状态
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OBJECTSTATUS* pObjStatus = &this->ObjStatus;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 取管道运动模型
|
|
|
|
|
|
FilterMeanNL stMotionMod_mean = m_LockingPipe->stMotionMod_mean;
|
|
|
|
|
|
pObjStatus->ptPos.x = stMotionMod_mean.crnObjPrediRtLong.cx;
|
|
|
|
|
|
pObjStatus->ptPos.y = stMotionMod_mean.crnObjPrediRtLong.cy;
|
|
|
|
|
|
pObjStatus->sfAglSpeed.vx = m_LockingPipe->sfAglSpeed.vx;
|
|
|
|
|
|
pObjStatus->sfAglSpeed.vy = m_LockingPipe->sfAglSpeed.vy;
|
|
|
|
|
|
|
|
|
|
|
|
// 更新目标角度值
|
|
|
|
|
|
pObjStatus->afAngle = stMotionMod_mean.ObjAglListsLong.arfPredict.afAngle;
|
|
|
|
|
|
|
|
|
|
|
|
// 直接预测并更新决策跟踪器
|
|
|
|
|
|
pObjStatus->unFrmId = g_GLB_Input->unFrmId;
|
|
|
|
|
|
pObjStatus->unTotalCnt++;
|
|
|
|
|
|
pObjStatus->unTrackedCnt++;
|
|
|
|
|
|
pObjStatus->unContiTrackedCnt++;
|
|
|
|
|
|
pObjStatus->unContiLostCnt++;
|
|
|
|
|
|
pObjStatus->bObjMiss = FALSE;
|
|
|
|
|
|
//更新目标丢失/跟踪失败标志
|
|
|
|
|
|
pObjStatus->bObjLost = TRUE;
|
|
|
|
|
|
|
|
|
|
|
|
//更新目标位置
|
|
|
|
|
|
POINT32F pfPosPrePre = pObjStatus->ptPosPre;
|
|
|
|
|
|
pObjStatus->ptPosPre = pObjStatus->ptPos;
|
|
|
|
|
|
|
|
|
|
|
|
pObjStatus->ptPosFilter.x = (pObjStatus->ptPosPre.x + pObjStatus->sfSpeed.vx + pObjStatus->ptPos.x) / 2;
|
|
|
|
|
|
pObjStatus->ptPosFilter.y = (pObjStatus->ptPosPre.y + pObjStatus->sfSpeed.vy + pObjStatus->ptPos.y) / 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//更新目标尺寸
|
|
|
|
|
|
pObjStatus->sfSize.s = pObjStatus->sfSize.w * pObjStatus->sfSize.h;
|
|
|
|
|
|
pObjStatus->fObjPxlsCnt = pObjStatus->sfSize.s;
|
|
|
|
|
|
|
|
|
|
|
|
//更新目标速度
|
|
|
|
|
|
pObjStatus->sfSpeed.vx = (pObjStatus->ptPos.x - pfPosPrePre.x) / 2;
|
|
|
|
|
|
pObjStatus->sfSpeed.vy = (pObjStatus->ptPos.y - pfPosPrePre.y) / 2;
|
|
|
|
|
|
|
|
|
|
|
|
// 结果输出
|
|
|
|
|
|
memcpy(&m_TSky_Output.ObjectStatusDesc, pObjStatus, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
|
|
|
|
|
|
return SkyTrkState;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SkyTracker::Cancle()
|
|
|
|
|
|
{
|
|
|
|
|
|
PIPE* pPipe = m_LockingPipe;
|
|
|
|
|
|
|
|
|
|
|
|
if (pPipe)
|
|
|
|
|
|
{
|
|
|
|
|
|
pPipe->bTrackingPipe = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pKCFTracker->KCF_CleanUpObjectTracker(); // 清空KCF跟踪结果
|
|
|
|
|
|
|
|
|
|
|
|
pBkgMonitor->BKM_CleanUpResult(); // 清空背景监控结果
|
|
|
|
|
|
|
|
|
|
|
|
memset(&pSATracker->m_ObjStatus, 0, sizeof(OBJECTSTATUS)); // 小面跟踪结果清空
|
|
|
|
|
|
memset(&ObjStatus, 0, sizeof(OBJECTSTATUS)); // 对空决策结果清空
|
|
|
|
|
|
|
|
|
|
|
|
// 类别判定监控信息清空
|
|
|
|
|
|
memset(pipeClassifyInfo, 0, sizeof(PipeMainClassifyInfo));
|
|
|
|
|
|
|
|
|
|
|
|
// 主跟踪目标状态信息清空
|
|
|
|
|
|
memset(&SkyTrkStatusInfo, 0, sizeof(PipeMainStatusInfo));
|
|
|
|
|
|
|
|
|
|
|
|
m_TSky_Output.m_SizeMode = SizeType::unKnown; // 输出目标尺寸类型为未知
|
|
|
|
|
|
m_TSky_Output.m_nTargetNum = 0; // 局部目标检测结果重置为0
|
|
|
|
|
|
m_TSky_Output.m_nMatcherNum = 0; // 模板匹配结果重置为0
|
|
|
|
|
|
|
|
|
|
|
|
// 跟踪阶段局部区域单帧目标检测结果
|
|
|
|
|
|
memset(&m_TSky_Output.mTrakingPara_Output, 0, sizeof(Param_SkyTracker));
|
|
|
|
|
|
memset(&m_TSky_Output.ObjectStatusTST, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
memset(&m_TSky_Output.ObjectStatusCEND, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
memset(&m_TSky_Output.ObjectStatusKCF, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
memset(&m_TSky_Output.ObjectStatusDesc, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SkyTracker::SetMemTrack(bool bMemFlag)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_bSetMemoryTrack = bMemFlag;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SkyTracker::SetSkyParam(Param_SkyTracker * stSkyParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
mTrakingPara.Sky_bEnableMatcher = stSkyParam->Sky_bEnableMatcher;
|
|
|
|
|
|
mTrakingPara.Sky_bUseAIDet = stSkyParam->Sky_bUseAIDet;
|
|
|
|
|
|
mTrakingPara.Sky_nUseAIDetFeq = stSkyParam->Sky_nUseAIDetFeq;
|
|
|
|
|
|
mTrakingPara.Sky_nTrackMemFrmNum = stSkyParam->Sky_nTrackMemFrmNum;
|
|
|
|
|
|
|
|
|
|
|
|
//mTrakingPara.Sky_bEnableTrackSA = stSkyParam->Sky_bEnableTrackSA;
|
|
|
|
|
|
//mTrakingPara.Sky_bEnableKCF = stSkyParam->Sky_bEnableKCF; // 内部自动调整关闭,因为清空了kcf信息,强制打开可能会导致程序崩溃,不建议设置kcf算法开关
|
|
|
|
|
|
|
|
|
|
|
|
pSATracker->m_TSA_Param.Sky_bUseAIDet = stSkyParam->Sky_bUseAIDet;
|
|
|
|
|
|
pSATracker->m_TSA_Param.nUseAIDetFeq = stSkyParam->Sky_nUseAIDetFeq;
|
|
|
|
|
|
|
|
|
|
|
|
skyControlInfo.nTrackMemFrmNum = mTrakingPara.Sky_nTrackMemFrmNum;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Param_SkyTracker SkyTracker::GetSkyParam()
|
|
|
|
|
|
{
|
|
|
|
|
|
return mTrakingPara;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CENTERRECT SkyTracker::getSATracker_SrBox()
|
|
|
|
|
|
{
|
|
|
|
|
|
return pSATracker->m_TSA_output.crCenterRect;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CENTERRECT SkyTracker::getKCFTracker_SrBox()
|
|
|
|
|
|
{
|
|
|
|
|
|
return pKCFTracker->KCF_GetSrBox();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SizeType SkyTracker::getSATracker_SizeType()
|
|
|
|
|
|
{
|
|
|
|
|
|
return pSATracker->m_SizeMode;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TARGET_OBJECT* SkyTracker::getTrackerSATargetList(SINT32& num)
|
|
|
|
|
|
{
|
|
|
|
|
|
num = MAX(pSATracker->m_nTargetNum, 0);
|
|
|
|
|
|
return pSATracker->m_Target_Array;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SkyTracker::TrackDecision(GD_VIDEO_FRAME_S img, GLB_INPUT* p_GLB_Input)
|
|
|
|
|
|
{
|
|
|
|
|
|
UBYTE8 ubSuccessFlag = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
// 决策计算
|
|
|
|
|
|
DecPolicy policy = Decision(img);
|
|
|
|
|
|
|
|
|
|
|
|
// 执行决策结果
|
|
|
|
|
|
ubSuccessFlag = ApplyDecision(policy, img, p_GLB_Input);
|
|
|
|
|
|
|
|
|
|
|
|
// 跟踪错误判断,算法内部判断主动解锁
|
|
|
|
|
|
if (SkyTrkStatusInfo.nAbnormalCnt > 10)
|
|
|
|
|
|
{
|
|
|
|
|
|
SkyTrkState = Unlock_ArithTrackFalse;
|
|
|
|
|
|
ubSuccessFlag = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 若KCF和CEND都找到了目标,且此时发现长时轨迹预测偏差较大,直接清空长时轨迹
|
|
|
|
|
|
FilterMeanNL * pFilter = &m_LockingPipe->stMotionMod_mean;
|
|
|
|
|
|
if (mTrakingPara.Sky_bEnableKCF && mTrakingPara.Sky_bEnableTrackSA)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pKCFTracker->GetTrackeStatus()->fConfidence > 0.5 && pSATracker->m_ObjStatus.fConfidence > 0.4)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pFilter->nObjTrackLostCntLong > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
pFilter->ObjAglListsLong.nCnt = 0;
|
|
|
|
|
|
pFilter->ObjAglListsLong.nEnd = 0;
|
|
|
|
|
|
//g_GLB_stOutput.ObjAglListsLong.nStep = GLB_FRM_FREQ / 4;
|
|
|
|
|
|
//g_GLB_stOutput.ObjAglListsLong.nListSize = GLB_OBJTRACK_LONG;
|
|
|
|
|
|
//g_GLB_stOutput.ObjAglListsLong.parHistoryList = (ANGLE_R*)DSP_GLB_pObjAglListsLong;
|
|
|
|
|
|
memset(pFilter->ObjAglListsLong.parHistoryList, 0, sizeof(ANGLE_R) * GLB_OBJTRACK_LEN);
|
|
|
|
|
|
memset(&pFilter->ObjAglListsLong.arfFilter, 0, sizeof(ANGLE_R));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(&m_TSky_Output.ObjectStatusDesc, &ObjStatus, sizeof(OBJECTSTATUS)); // 对空跟踪决策结果透传
|
|
|
|
|
|
|
|
|
|
|
|
return ubSuccessFlag;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DecPolicy SkyTracker::Decision(GD_VIDEO_FRAME_S img)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 默认全部保持,不做处理
|
|
|
|
|
|
DecPolicy policy = { Act::Remain };
|
|
|
|
|
|
// 仅运行检测跟踪器的决策流程,包含小目标和面目标逻辑一致
|
|
|
|
|
|
if (mTrakingPara.Sky_bEnableTrackSA && !mTrakingPara.Sky_bEnableKCF)
|
|
|
|
|
|
{
|
|
|
|
|
|
policy.Act_SATracker = Act::Credit;//取SA
|
|
|
|
|
|
}
|
|
|
|
|
|
// 同时开启管道跟踪器与KCF,表明当前为面目标融合跟踪
|
|
|
|
|
|
else if (mTrakingPara.Sky_bEnableTrackSA && mTrakingPara.Sky_bEnableKCF)
|
|
|
|
|
|
{
|
|
|
|
|
|
policy = TO_TrackDecisionOf_KCF_CEND(img);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 仅开启KCF
|
|
|
|
|
|
else if (!mTrakingPara.Sky_bEnableTrackSA && mTrakingPara.Sky_bEnableKCF)
|
|
|
|
|
|
{
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Credit;//取KCF
|
|
|
|
|
|
}
|
|
|
|
|
|
// 跟踪器全关
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//pass
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return policy;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SkyTracker::ApplyDecision(DecPolicy policy, GD_VIDEO_FRAME_S img, GLB_INPUT* p_GLB_Input)
|
|
|
|
|
|
{
|
|
|
|
|
|
UBYTE8 ubSuccessFlag = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
UINT16* pSrc = (UINT16*)img.u64VirAddr[0];
|
|
|
|
|
|
SINT32 nWidth = img.u32Width;
|
|
|
|
|
|
SINT32 nHeight = img.u32Height;
|
|
|
|
|
|
|
|
|
|
|
|
// SA Tracker
|
|
|
|
|
|
OBJECTSTATUS* pObjStatusSA = &pSATracker->m_ObjStatus; // 小面跟踪决策输出
|
|
|
|
|
|
// 错误保护
|
|
|
|
|
|
if (policy.Act_SATracker == Act::Credit && policy.Act_KCFTracker == Act::Credit)
|
|
|
|
|
|
{
|
|
|
|
|
|
policy.Act_SATracker = Act::Reset;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 先输出决策跟踪结果
|
|
|
|
|
|
if (policy.Act_SATracker == Act::Credit)
|
|
|
|
|
|
{
|
|
|
|
|
|
memcpy(&ObjStatus, pObjStatusSA, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
// 将SA的匹配目标直接给mTargetFusion
|
|
|
|
|
|
mTargetFusion = pSATracker->m_MatchedTarget;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (policy.Act_KCFTracker == Act::Credit)
|
|
|
|
|
|
{
|
|
|
|
|
|
// KCF 模型更新
|
|
|
|
|
|
if (pKCFTracker->GetTrackeStatus()->unContiLostCnt < 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
//20171218,更新kcf模板
|
|
|
|
|
|
pKCFTracker->KCF_ModelUpdate(img);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 直接取KCF跟踪结果
|
|
|
|
|
|
memcpy(&ObjStatus, pKCFTracker->GetTrackeStatus(), sizeof(OBJECTSTATUS));
|
|
|
|
|
|
|
|
|
|
|
|
// 质心中心定位结果拷贝到输出
|
|
|
|
|
|
//ObjStatus.ptCentroid.x = pObjStatusSA->ptCentroid.x;
|
|
|
|
|
|
//ObjStatus.ptCentroid.y = pObjStatusSA->ptCentroid.y;
|
|
|
|
|
|
|
|
|
|
|
|
// AI尺寸结果拷贝到KCF对应位置
|
|
|
|
|
|
ObjStatus.snAIDetSize.w = pObjStatusSA->snAIDetSize.w;
|
|
|
|
|
|
ObjStatus.snAIDetSize.h = pObjStatusSA->snAIDetSize.h;
|
|
|
|
|
|
ObjStatus.snAIDetSize.s = pObjStatusSA->snAIDetSize.s;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 未采信任何跟踪器
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
TrackUnlockState KCFTrkState = pKCFTracker->GetKcfTrkStatus(); // KCF的跟踪状态
|
|
|
|
|
|
TrackUnlockState SATrkState = pSATracker->SATrkState; // SATrack的跟踪状态
|
|
|
|
|
|
if (Unlock_MemTimeOver == KCFTrkState && Unlock_MemTimeOver == SATrkState)
|
|
|
|
|
|
{
|
|
|
|
|
|
SkyTrkState = Unlock_MemTimeOver;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SkyTrkState = Unlock_MemOutFOV;
|
|
|
|
|
|
}
|
|
|
|
|
|
//更新目标计数器
|
|
|
|
|
|
ObjStatus.unTrackedCnt++;
|
|
|
|
|
|
ObjStatus.unContiTrackedCnt = 0;
|
|
|
|
|
|
ObjStatus.unContiLostCnt++;
|
|
|
|
|
|
//决策跟踪器解锁
|
|
|
|
|
|
ObjStatus.bObjMiss = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 返回跟踪失败标记
|
|
|
|
|
|
ubSuccessFlag = FALSE;
|
|
|
|
|
|
return ubSuccessFlag;
|
|
|
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// 类别输出决策
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
SkyClassify_Desci(p_GLB_Input, pObjStatusSA);
|
|
|
|
|
|
|
|
|
|
|
|
// 输出送显
|
|
|
|
|
|
m_TSky_Output.ObjectStatusDesc.unClsType = ObjStatus.unClsType;
|
|
|
|
|
|
m_TSky_Output.ObjectStatusDesc.emClsSrc = ObjStatus.emClsSrc;
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// SA执行决策重置
|
|
|
|
|
|
if (policy.Act_SATracker == Act::Reset)
|
|
|
|
|
|
{
|
|
|
|
|
|
pSATracker->Reset(&ObjStatus, true, img, nWidth, nHeight, p_GLB_Input);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (policy.Act_SATracker == Act::Adjust)
|
|
|
|
|
|
{
|
|
|
|
|
|
pSATracker->Reset(&ObjStatus, false, img, nWidth, nHeight, p_GLB_Input);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//pass
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// KCF执行决策重置
|
|
|
|
|
|
if (policy.Act_KCFTracker == Act::Reset)
|
|
|
|
|
|
{
|
|
|
|
|
|
pKCFTracker->KCF_Reset(&ObjStatus, true, img, p_GLB_Input);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (policy.Act_KCFTracker == Act::Adjust)
|
|
|
|
|
|
{
|
|
|
|
|
|
pKCFTracker->KCF_Reset(&ObjStatus, false, img, p_GLB_Input);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//pass
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//// AID monitor 监控提供最佳重捕信息后,对KCF和小面进行重启
|
|
|
|
|
|
//MASTERAIDMONITOR* p_masterMonitor = Ai_DMonitor->getAIDMasterInfo();
|
|
|
|
|
|
//if (p_masterMonitor->nBestArrestId >= 0)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// NEIBOR* pNeibor = &p_masterMonitor->nNeiborInfo[p_masterMonitor->nBestArrestId];
|
|
|
|
|
|
// ObjStatus.ptPos.x = pNeibor->rsCurrentBox.x + pNeibor->rsCurrentBox.w / 2;
|
|
|
|
|
|
// ObjStatus.ptPos.y = pNeibor->rsCurrentBox.y + pNeibor->rsCurrentBox.h / 2;
|
|
|
|
|
|
// ObjStatus.sfSize.w = pNeibor->rsCurrentBox.w;
|
|
|
|
|
|
// ObjStatus.sfSize.h = pNeibor->rsCurrentBox.h;
|
|
|
|
|
|
|
|
|
|
|
|
// // 初始化目标响应及相似度信息
|
|
|
|
|
|
// pKCFTracker->KCF_Reset(&ObjStatus, true, img, p_GLB_Input);
|
|
|
|
|
|
// pSATracker->Reset(&ObjStatus, true, img, nWidth, nHeight, p_GLB_Input);
|
|
|
|
|
|
|
|
|
|
|
|
// // 重捕成功后参数重置
|
|
|
|
|
|
// Ai_DMonitor->initPara();
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Remain; // 重置状态恢复
|
|
|
|
|
|
policy.Act_SATracker = Act::Remain; // 重置状态恢复
|
|
|
|
|
|
|
|
|
|
|
|
ubSuccessFlag = !ObjStatus.bObjMiss;
|
|
|
|
|
|
|
|
|
|
|
|
return ubSuccessFlag;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SkyTracker::SetTrackModeAuto(GD_VIDEO_FRAME_S img, GLB_INPUT* p_GLB_Input)
|
|
|
|
|
|
{
|
|
|
|
|
|
UBYTE8* pSmall2Area_Target = (UBYTE8*)pSATracker->TO_pSmall2Area_Target_counter;
|
|
|
|
|
|
OBJECTSTATUS* pObjStatus = &ObjStatus;//上一帧跟踪结果
|
|
|
|
|
|
|
|
|
|
|
|
UINT16* pSrc = (UINT16*)img.u64VirAddr[0];
|
|
|
|
|
|
SINT32 nWidth = img.u32Width;
|
|
|
|
|
|
SINT32 nHeight = img.u32Height;
|
|
|
|
|
|
|
|
|
|
|
|
SINT16 i = 0;
|
|
|
|
|
|
SINT16 nCount = 0;
|
|
|
|
|
|
// 待融合跟踪器结果
|
|
|
|
|
|
OBJECTSTATUS* pObjStatusKCF = pKCFTracker->GetTrackeStatus();
|
|
|
|
|
|
OBJECTSTATUS* pObjStatusSA = &pSATracker->m_ObjStatus;
|
|
|
|
|
|
|
|
|
|
|
|
CENTERRECT32F crfCandiRect;
|
|
|
|
|
|
FLOAT32 fObjWHRatio = pObjStatus->sfSize.w / pObjStatus->sfSize.h;
|
|
|
|
|
|
SINT32 nNewPipeId = -1;
|
|
|
|
|
|
//POINT32F ptfObjPos;
|
|
|
|
|
|
//SIZE32F sfObjSize;
|
|
|
|
|
|
|
|
|
|
|
|
// 强制记忆跟踪期间,不切换目标跟踪器类型
|
|
|
|
|
|
//if (g_GLB_Force_MemTrack || g_GLB_bInterferenceMem || g_GLB_MainHControl || (g_GLB_TargetMissileCrose_EO == GLB_MT_CROSS))
|
|
|
|
|
|
//{
|
|
|
|
|
|
// return;
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
//// 复杂场景丢失目标,也不切换//20230604
|
|
|
|
|
|
if (pBkgMonitor->g_GLB_bComplexEnv)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果小面目标跟踪未开,直接返回
|
|
|
|
|
|
if (!mTrakingPara.Sky_bEnableTrackSA)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//小目标跟踪切面目标跟踪
|
|
|
|
|
|
if (pSATracker->m_SizeMode == SmallTarget)
|
|
|
|
|
|
{
|
|
|
|
|
|
//若目标尺寸大于阈值,则开启KCF跟踪、关闭小目标跟踪
|
|
|
|
|
|
if ((pObjStatus->fObjPxlsCnt >= mTrakingPara.nSmallObjSizeMax
|
|
|
|
|
|
|| pObjStatus->sfSize.w >= 7 || pObjStatus->sfSize.h >= 7)
|
|
|
|
|
|
&& ((pObjStatusSA->unContiLostCnt > 0) ||
|
|
|
|
|
|
(pObjStatus->fObjPxlsCnt >= mTrakingPara.nSmallObjSizeMax * 2.0)))
|
|
|
|
|
|
{
|
|
|
|
|
|
pSmall2Area_Target[pSATracker->g_GLB_S2ATagCnt] = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
pSmall2Area_Target[pSATracker->g_GLB_S2ATagCnt] = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
pSATracker->g_GLB_S2ATagCnt = (pSATracker->g_GLB_S2ATagCnt + 1) % GLB_TRACK_SMALL2FACE_CNT;
|
|
|
|
|
|
|
|
|
|
|
|
//统计变大次数,若超过阈值,则切换算法
|
|
|
|
|
|
nCount = 0;
|
|
|
|
|
|
for (i = 0; i < GLB_TRACK_SMALL2FACE_CNT; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nCount += pSmall2Area_Target[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果TST即将超过记忆帧数还没有发现目标(即将解锁),此时直接切换到面目标试试
|
|
|
|
|
|
BBOOL bLostTST = FALSE;
|
|
|
|
|
|
BBOOL bFindAreaTarget = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
|
if (pObjStatusSA->unContiLostCnt > 10 &&
|
|
|
|
|
|
!(this->m_bSetMemoryTrack))
|
|
|
|
|
|
{
|
|
|
|
|
|
bLostTST = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
// 判断CEND单一目标跟踪,表明无干扰场景
|
|
|
|
|
|
SINT32 nCrossTarget = pSATracker->getInterfereAreaTargteNum(rc);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 如果面目标检测器检测到1个目标,且小目标跟踪器丢失目标,可能是切换的最佳时机
|
|
|
|
|
|
if (nCrossTarget > 0 && (ObjStatus.unContiLostCnt > 0) || (pObjStatus->sfSize.w >= 7 || pObjStatus->sfSize.h >= 7))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 面目标检测到目标,需要更新特性。因为TST模板大小限制,可能丢失目标尺度
|
|
|
|
|
|
TARGET_OBJECT* ptTargetArr = (TARGET_OBJECT*)pSATracker->m_Target_Array;
|
|
|
|
|
|
TARGET_OBJECT* ptTarget = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
// 查找离跟踪中心最近的面目标
|
|
|
|
|
|
FLOAT32 nDistMin = FLOAT32(nWidth * nHeight);
|
|
|
|
|
|
SINT32 nIndex = -1;
|
|
|
|
|
|
for (SINT32 i = 0; i < pSATracker->m_nTargetNum; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
FLOAT32 dist = ABS(ptTargetArr[i].pfCenPos.x - pObjStatusSA->ptPos.x) *
|
|
|
|
|
|
ABS(ptTargetArr[i].pfCenPos.y - pObjStatusSA->ptPos.y);
|
|
|
|
|
|
if (dist < nDistMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
nDistMin = dist;
|
|
|
|
|
|
nIndex = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (nIndex >= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
ptTarget = &ptTargetArr[nIndex];
|
|
|
|
|
|
if (ABS(ptTarget->pfCenPos.x - pObjStatusSA->ptPos.x) <= 3 &&
|
|
|
|
|
|
ABS(ptTarget->pfCenPos.y - pObjStatusSA->ptPos.y) <= 3 &&
|
|
|
|
|
|
(ptTarget->snSize.w >= 6 || ptTarget->snSize.h >= 6)
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
bFindAreaTarget = true;//标记面目标跟踪成功
|
|
|
|
|
|
// 重新设置跟踪初始化值
|
|
|
|
|
|
pObjStatus->unContiLostCnt = 0;
|
|
|
|
|
|
pObjStatus->fObjPxlsCnt = FLOAT32(MAX((UINT32)mTrakingPara.nSmallObjSizeMax, ptTarget->unObjPxlsCnt));
|
|
|
|
|
|
pObjStatus->sfSize.w = FLOAT32(MAX(8, ptTarget->snSize.w));
|
|
|
|
|
|
pObjStatus->sfSize.h = FLOAT32(MAX(8, ptTarget->snSize.h));
|
|
|
|
|
|
//// 重置跟踪管道特性,防止被拒绝
|
|
|
|
|
|
//if (g_GLB_stOutput.nPriorPipeId >= 0)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// PIPE* pPipe = &pPipeArray[g_GLB_stOutput.nPriorPipeId];
|
|
|
|
|
|
// memset(pPipe, 0, sizeof(PIPE));
|
|
|
|
|
|
// PIPE_AddObjToSpecifiedEmptyPipe(pPipe, g_GLB_stOutput.nPriorPipeId, ptTarget);
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (nCount >= GLB_TRACK_SMALL2FACE_THRES && bFindAreaTarget) //以338A对空抗干扰数据--双机小目标交错为例
|
|
|
|
|
|
{
|
|
|
|
|
|
crfCandiRect.cx = pObjStatus->ptPos.x;
|
|
|
|
|
|
crfCandiRect.cy = pObjStatus->ptPos.y;
|
|
|
|
|
|
crfCandiRect.w = pObjStatus->sfSize.w;
|
|
|
|
|
|
crfCandiRect.h = pObjStatus->sfSize.h;
|
|
|
|
|
|
crfCandiRect.s = crfCandiRect.w * crfCandiRect.h;
|
|
|
|
|
|
|
|
|
|
|
|
pKCFTracker->KCF_InitObjectParameters(img, m_LockingPipe, p_GLB_Input);
|
|
|
|
|
|
mTrakingPara.Sky_bEnableKCF = true;
|
|
|
|
|
|
|
|
|
|
|
|
// SA跟踪器置于面目标
|
|
|
|
|
|
pSATracker->m_SizeMode = SizeType::AreaTarget;
|
|
|
|
|
|
|
|
|
|
|
|
//小目标和面目标相互切换计数器清零
|
|
|
|
|
|
pSATracker->g_GLB_S2ATagCnt = 0;
|
|
|
|
|
|
memset(pSmall2Area_Target, 0, sizeof(UBYTE8) * GLB_TRACK_SMALL2FACE_CNT);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//正常(中/大)目标跟踪
|
|
|
|
|
|
if (pSATracker->m_SizeMode == AreaTarget)
|
|
|
|
|
|
{
|
|
|
|
|
|
//若目标尺寸小于阈值,则开启小目标跟踪、关闭KCF跟踪
|
|
|
|
|
|
SINT32 nFaceObjPxlsMin = MAX(mTrakingPara.nSmallObjSizeMax, 25/*pSATracker->*/);
|
|
|
|
|
|
if ((pObjStatus->fObjPxlsCnt < nFaceObjPxlsMin - 8 || (pObjStatus->sfSize.w < 5 && pObjStatus->sfSize.h < 5))
|
|
|
|
|
|
&& ((pObjStatusSA->unContiLostCnt > 0) || pObjStatus->fObjPxlsCnt < nFaceObjPxlsMin))
|
|
|
|
|
|
{
|
|
|
|
|
|
pSmall2Area_Target[pSATracker->g_GLB_S2ATagCnt] = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
pSmall2Area_Target[pSATracker->g_GLB_S2ATagCnt] = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
pSATracker->g_GLB_S2ATagCnt = (pSATracker->g_GLB_S2ATagCnt + 1) % GLB_TRACK_SMALL2FACE_CNT;
|
|
|
|
|
|
|
|
|
|
|
|
//统计变大次数,若超过阈值,则切换算法
|
|
|
|
|
|
nCount = 0;
|
|
|
|
|
|
for (i = 0; i < GLB_TRACK_SMALL2FACE_CNT; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nCount += pSmall2Area_Target[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// S726属于逼近型跟踪器,正常跟踪不会出现面目标转小目标,将GLB_TRACK_SMALL2FACE_THRES 调整为7 by wcw04046 @ 2021/12/01
|
|
|
|
|
|
if (nCount >= GLB_TRACK_SMALL2FACE_THRES)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
//初始化TST跟踪算法
|
|
|
|
|
|
//pSATracker->Init(pSrc, nWidth, nHeight, pxlType, m_LockingPipe, g_GLB_Input);
|
|
|
|
|
|
pKCFTracker->KCF_CleanUpObjectTracker();
|
|
|
|
|
|
|
|
|
|
|
|
//清空CEND、KCF跟踪算法
|
|
|
|
|
|
memset(pObjStatusSA, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
memset(pObjStatusKCF, 0, sizeof(OBJECTSTATUS));
|
|
|
|
|
|
|
|
|
|
|
|
//小目标和面目标相互切换计数器清零
|
|
|
|
|
|
pSATracker->g_GLB_S2ATagCnt = 0;
|
|
|
|
|
|
memset(pSmall2Area_Target, 0, sizeof(UBYTE8) * GLB_TRACK_SMALL2FACE_CNT);
|
|
|
|
|
|
|
|
|
|
|
|
pSATracker->m_SizeMode = SmallTarget;//切到小目标模式
|
|
|
|
|
|
|
|
|
|
|
|
mTrakingPara.Sky_bEnableKCF = false;//关闭KCF
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
POINT16S* SkyTracker::GetDST_MaxPoint_Sky()
|
|
|
|
|
|
{
|
|
|
|
|
|
return pSATracker->getDSTmodule()->getMaxPoint();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DecPolicy SkyTracker::TO_TrackDecisionOf_KCF_CEND(GD_VIDEO_FRAME_S img)
|
|
|
|
|
|
{
|
|
|
|
|
|
DecPolicy policy = { Act::Remain };
|
|
|
|
|
|
|
|
|
|
|
|
OBJECTSTATUS* pObjStatus = &ObjStatus;
|
|
|
|
|
|
OBJECTSTATUS* pObjStatusKCF = pKCFTracker->GetTrackeStatus();
|
|
|
|
|
|
OBJECTSTATUS* pObjStatusCEND = &pSATracker->m_ObjStatus;
|
|
|
|
|
|
|
|
|
|
|
|
BBOOL bSameObjCendKCF = false;//CEND与KCF结果的是否为同一个目标
|
|
|
|
|
|
FLOAT32 fSizeSameCendKCF = 0.0f; //CEND与KCF的目标尺寸重合率
|
|
|
|
|
|
FLOAT32 fWHDiffCendKCF = 0.0f; //CEND与KCF的目标宽高差异
|
|
|
|
|
|
SIZE32F snObjRadius = { 0 }; //目标半径
|
|
|
|
|
|
FLOAT32 fObjWHRatio = 0.0; //目标宽高比
|
|
|
|
|
|
SINT32 i = 0;
|
|
|
|
|
|
SINT32 nBkgAbnormal = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//20171206,统计背景区域异常块个数
|
|
|
|
|
|
//for (i = 0; i < GLB_OBJ_BKG_NUM; i++)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// if (g_GLB_bObj8BkgStatus[i])
|
|
|
|
|
|
// {
|
|
|
|
|
|
// nBkgAbnormal++;
|
|
|
|
|
|
// }
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//上一帧目标结果:尺寸半径、目标矩形、宽高比
|
|
|
|
|
|
snObjRadius.w = pObjStatus->sfSize.w / 2.0f;
|
|
|
|
|
|
snObjRadius.h = pObjStatus->sfSize.h / 2.0f;
|
|
|
|
|
|
fObjWHRatio = pObjStatus->sfSize.w / pObjStatus->sfSize.h;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//判断CEND与KCF结果的是否为同一个目标,计算重合率、相似度
|
|
|
|
|
|
bSameObjCendKCF = TO_IsCoincideObj(pObjStatusCEND->ptPos, pObjStatusCEND->sfSize,
|
|
|
|
|
|
pObjStatusKCF->ptPos, pObjStatusKCF->sfSize, &fSizeSameCendKCF, &fWHDiffCendKCF);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 判断CEND单一目标跟踪,表明无干扰场景
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 nCrossTarget = pSATracker->getInterfereAreaTargteNum(rc);
|
|
|
|
|
|
|
|
|
|
|
|
// 先处理有跟踪器解锁情况(两个跟踪器都解锁)
|
|
|
|
|
|
if (pObjStatusCEND->bObjMiss && pObjStatusKCF->bObjMiss)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 直接退出,谁也不信
|
|
|
|
|
|
return policy;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pObjStatusCEND->bObjMiss)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 采信KCF
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Credit;
|
|
|
|
|
|
policy.Act_SATracker = Act::Reset;
|
|
|
|
|
|
return policy;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (pObjStatusKCF->bObjMiss)
|
|
|
|
|
|
{
|
|
|
|
|
|
//采信SA
|
|
|
|
|
|
policy.Act_SATracker = Act::Credit;
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Reset;
|
|
|
|
|
|
return policy;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 以下处理都未跟丢情形
|
|
|
|
|
|
|
|
|
|
|
|
// STATUS-1:均稳跟
|
|
|
|
|
|
if (pObjStatusCEND->unContiLostCnt == 0 && pObjStatusKCF->unContiLostCnt == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 跟踪相同位置,且简单场景下,取CEND
|
|
|
|
|
|
if (!pBkgMonitor->g_GLB_bComplexEnv && bSameObjCendKCF)
|
|
|
|
|
|
{
|
|
|
|
|
|
//采信SA,但不重置KCF,只调整位置
|
|
|
|
|
|
policy.Act_SATracker = Act::Credit;
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Adjust;
|
|
|
|
|
|
g_GLB_nTrackDecisionCnt++;
|
|
|
|
|
|
// 1.附近没有目标且跟踪偏离,隔5帧重置一次KCF(更苛刻条件下)
|
|
|
|
|
|
// 2.CEND检出稳定的尺寸条件下,每20帧重置1次KCF
|
|
|
|
|
|
if (
|
|
|
|
|
|
((1 == nCrossTarget && fSizeSameCendKCF < 0.7f && g_GLB_nTrackDecisionCnt > 5)
|
|
|
|
|
|
|| (pObjStatusCEND->fConfidence > 0.8f && nBkgAbnormal <= 2
|
|
|
|
|
|
&& g_GLB_nTrackDecisionCnt > 20 && pObjStatusCEND->sfSize.s < 300))
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Reset;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (g_GLB_nTrackDecisionCnt > 20)
|
|
|
|
|
|
{
|
|
|
|
|
|
g_GLB_nTrackDecisionCnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
// 其余情况取KCF,并重置CEND
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
policy.Act_SATracker = Act::Adjust;
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Credit;
|
|
|
|
|
|
g_GLB_nTrackDecisionCnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// STATUS-2:SA记忆
|
|
|
|
|
|
if (pObjStatusCEND->unContiLostCnt > 0 && pObjStatusKCF->unContiLostCnt == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
//SA对学习依赖不高,随时重置无影响
|
|
|
|
|
|
policy.Act_SATracker = Act::Adjust;
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Credit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// STATUS-3:KCF记忆
|
|
|
|
|
|
if (pObjStatusKCF->unContiLostCnt > 0 && pObjStatusCEND->unContiLostCnt == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
policy.Act_SATracker = Act::Credit;
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Adjust;
|
|
|
|
|
|
// KCF不轻易重置
|
|
|
|
|
|
if (pObjStatusKCF->unContiLostCnt > 5 && pObjStatusCEND->unContiTrackedCnt > 5)
|
|
|
|
|
|
{
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Reset;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// STATUS-4:均记忆,取KCF
|
|
|
|
|
|
if (pObjStatusKCF->unContiLostCnt > 0 && pObjStatusCEND->unContiLostCnt > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
policy.Act_SATracker = Act::Reset;
|
|
|
|
|
|
policy.Act_KCFTracker = Act::Credit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return policy;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
///*
|
|
|
|
|
|
//* 将跟踪器结果输出为管道目标信息,不要丢特征,否则可能导致SA跟踪器特征突变一直无法跟踪
|
|
|
|
|
|
//*/
|
|
|
|
|
|
//bool SkyTracker::UpdateTracker2Pipe(GLB_INPUT* g_GLB_Input, PIPE* pPipeOut)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// PIPE* pPipe = pPipeOut;
|
|
|
|
|
|
//
|
|
|
|
|
|
// // 总帧数+1
|
|
|
|
|
|
// pPipe->unTotalCnt++;
|
|
|
|
|
|
//
|
|
|
|
|
|
// // 目标丢失
|
|
|
|
|
|
// if (ObjStatus.unContiLostCnt > 0)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// //标记管道丢失
|
|
|
|
|
|
// pPipe->bLost = true;
|
|
|
|
|
|
// pPipe->unLostCnt++;
|
|
|
|
|
|
// pPipe->unContinueExistCnt = 0;
|
|
|
|
|
|
// ////当管道目标超过N次(连续)没被检测到时,清空管道。
|
|
|
|
|
|
// //if (pPipe->unLostCnt >= (UINT32)(nPipeFOVLostCnt))
|
|
|
|
|
|
// //{
|
|
|
|
|
|
// // //标记跟踪失败
|
|
|
|
|
|
// // ubSuccessFlag = FALSE;
|
|
|
|
|
|
// // return ubSuccessFlag;
|
|
|
|
|
|
// //}
|
|
|
|
|
|
// }
|
|
|
|
|
|
// // 目标更新
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// //获取在当前帧中查找到的最相似目标
|
|
|
|
|
|
// //KCF获得的目标只有位置和尺度信息
|
|
|
|
|
|
// TARGET_OBJECT Target = { 0 };
|
|
|
|
|
|
// Target.unFrmID = g_GLB_Input->unFrmId;
|
|
|
|
|
|
// Target.bObject = true;
|
|
|
|
|
|
// Target.pfCenPos = ObjStatus.ptPos;
|
|
|
|
|
|
// //ptTarget.pnMaxPos = ptTarget.pfCenPos;
|
|
|
|
|
|
// Target.afAngle = ObjStatus.afAngle;
|
|
|
|
|
|
// Target.fMatchConf = ObjStatus.fConfidence;
|
|
|
|
|
|
//
|
|
|
|
|
|
// // 尺度,重要,KCF和SA之间除位置外唯一的切换特征
|
|
|
|
|
|
// Target.snSize.w = ObjStatus.sfSize.w;
|
|
|
|
|
|
// Target.snSize.h = ObjStatus.sfSize.h;
|
|
|
|
|
|
// Target.snSize.s = ObjStatus.sfSize.s;
|
|
|
|
|
|
// Target.nObjTypeSrc = ObjStatus.nObjTypeSrc;
|
|
|
|
|
|
// Target.unObjPxlsCnt = ObjStatus.fObjPxlsCnt;
|
|
|
|
|
|
//
|
|
|
|
|
|
// // 如果对空小面目标跟踪器已经检出目标,且是融合决策目标,直接加入管道
|
|
|
|
|
|
// if (mTargetFusion.bObject)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// Target = mTargetFusion;
|
|
|
|
|
|
// }
|
|
|
|
|
|
//
|
|
|
|
|
|
// // 将跟踪决策目标加入管道
|
|
|
|
|
|
// PIPE_AddObjToOccupiedPipe(pPipe, pPipe->nPipeID, &Target, 0, g_GLB_Input);
|
|
|
|
|
|
// }
|
|
|
|
|
|
//
|
|
|
|
|
|
// return true;
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
//20180305,统计数组的标准差
|
|
|
|
|
|
void SkyTracker::CalcStdOfArrayStatus(FLOAT32* pfArray, SINT32 nTotalLen, SINT32 nEnd,
|
|
|
|
|
|
SINT32 nCountLen, PIPE_FEATURE_FLUC* pstPipeFeature)
|
|
|
|
|
|
{
|
|
|
|
|
|
//统计极值、均值、方差
|
|
|
|
|
|
FLOAT32 fMinValue = 1e6;
|
|
|
|
|
|
FLOAT32 fMaxValue = -1e6;
|
|
|
|
|
|
DOUBLE64 dMean = 0.0f;
|
|
|
|
|
|
DOUBLE64 dVariance = 0.0f; //方差
|
|
|
|
|
|
SINT32 i = 0;
|
|
|
|
|
|
FLOAT32 fValue = 0.0f;
|
|
|
|
|
|
//FLOAT32 fStd = 0.0f; //标准差
|
|
|
|
|
|
SINT32 nIndex = 0; //数组下标
|
|
|
|
|
|
FLOAT32 fNormalizedArray[TRACK_STATUS_DEPTH_MAX] = { 0 }; //归一化后的数组
|
|
|
|
|
|
//FLOAT32 fRange = 0.0f; //数组值域范围
|
|
|
|
|
|
|
|
|
|
|
|
//防错,如果统计长度大于总数组长度,则直接返回-1(异常)
|
|
|
|
|
|
if (nCountLen > TRACK_STATUS_DEPTH_MAX)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < nCountLen; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = (nEnd - i + nTotalLen) % nTotalLen;
|
|
|
|
|
|
fValue = pfArray[nIndex];
|
|
|
|
|
|
|
|
|
|
|
|
//有效值存入归一化数组
|
|
|
|
|
|
fNormalizedArray[i] = fValue;
|
|
|
|
|
|
|
|
|
|
|
|
//最大最小值统计
|
|
|
|
|
|
fMinValue = MIN(fMinValue, fValue);
|
|
|
|
|
|
fMaxValue = MAX(fMaxValue, fValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//归一化数组并统计均值和方差累加
|
|
|
|
|
|
for (i = 0; i < nCountLen; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
fValue = fNormalizedArray[i];
|
|
|
|
|
|
|
|
|
|
|
|
//背景灰度及灰度平方累加
|
|
|
|
|
|
dMean += (DOUBLE64)fValue;
|
|
|
|
|
|
dVariance += (DOUBLE64)fValue * fValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算均值、方差
|
|
|
|
|
|
dMean = dMean / (DOUBLE64)(MAX(nCountLen, 1));
|
|
|
|
|
|
dVariance = dVariance / (DOUBLE64)(MAX(nCountLen, 1));
|
|
|
|
|
|
dVariance -= dMean * dMean;
|
|
|
|
|
|
pstPipeFeature->fMean = (FLOAT32)dMean;
|
|
|
|
|
|
pstPipeFeature->fStd = (FLOAT32)sqrt(dVariance);
|
|
|
|
|
|
pstPipeFeature->fMin = fMinValue;
|
|
|
|
|
|
pstPipeFeature->fMax = fMaxValue;
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SkyTracker::SkyTrackFalse_Process(GD_VIDEO_FRAME_S img, GLB_INPUT* p_GLB_Input, OBJECTSTATUS* ObjStatus, PIPE* m_LockingPipe)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (FALSE == SkyTrkStatusInfo.bOccupy)
|
|
|
|
|
|
{
|
|
|
|
|
|
SkyTrkStatusInfo.bOccupy = TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SkyTrkStatusInfo.nCountNum += 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 角度位置信息
|
|
|
|
|
|
if (1 == SkyTrkStatusInfo.nCountNum)
|
|
|
|
|
|
{
|
|
|
|
|
|
SkyTrkStatusInfo.fPosAngle = ObjStatus->afAngle;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FLOAT32 disX = ABS(DEGLIM(SkyTrkStatusInfo.fPosAngle.fAz - ObjStatus->afAngle.fAz)) / p_GLB_Input->stCamera.fAglReso;
|
|
|
|
|
|
FLOAT32 disY = ABS(DEGLIM(SkyTrkStatusInfo.fPosAngle.fPt - ObjStatus->afAngle.fPt)) / p_GLB_Input->stCamera.fAglReso;
|
|
|
|
|
|
SkyTrkStatusInfo.fMoveDis[SkyTrkStatusInfo.ubEnd] = sqrt(POW2(disX) + POW2(disY));
|
|
|
|
|
|
|
|
|
|
|
|
if (SkyTrkStatusInfo.nCountNum > 2 * p_GLB_Input->unFreq) // 单次计数满更新数据
|
|
|
|
|
|
{
|
|
|
|
|
|
SkyTrkStatusInfo.nAIDetNum = 0;
|
|
|
|
|
|
SkyTrkStatusInfo.ubEnd = (++SkyTrkStatusInfo.ubEnd) % TRACK_STATUS_DEPTH_MAX;
|
|
|
|
|
|
SkyTrkStatusInfo.nCountNum = SkyTrkStatusInfo.nCountNum % (2 * p_GLB_Input->unFreq);
|
|
|
|
|
|
SkyTrkStatusInfo.nSavedNum = (++SkyTrkStatusInfo.nSavedNum) % TRACK_STATUS_DEPTH_MAX;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 识别信息统计
|
|
|
|
|
|
if (ObjStatus->snAIDetSize.w > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
SkyTrkStatusInfo.nAIDetNum += 1;
|
|
|
|
|
|
SkyTrkStatusInfo.fAIDetRatio[SkyTrkStatusInfo.ubEnd] = 1.0f * SkyTrkStatusInfo.nAIDetNum / SkyTrkStatusInfo.nCountNum;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PIPE_FEATURE_FLUC DetFeatureB = { 0 };
|
|
|
|
|
|
|
|
|
|
|
|
PIPE_FEATURE_FLUC MoveFeatureB = { 0 };
|
|
|
|
|
|
|
|
|
|
|
|
// 累计存满6次,开始分析当前跟踪目标是否出错
|
|
|
|
|
|
if (SkyTrkStatusInfo.nSavedNum > 3 && SkyTrkStatusInfo.nCountNum > p_GLB_Input->unFreq)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 识别率变化
|
|
|
|
|
|
CalcStdOfArrayStatus(SkyTrkStatusInfo.fAIDetRatio, TRACK_STATUS_DEPTH_MAX, (SkyTrkStatusInfo.ubEnd - 2) % TRACK_STATUS_DEPTH_MAX,
|
|
|
|
|
|
SkyTrkStatusInfo.nSavedNum - 1, &DetFeatureB);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 位移量变化
|
|
|
|
|
|
CalcStdOfArrayStatus(SkyTrkStatusInfo.fMoveDis, TRACK_STATUS_DEPTH_MAX, (SkyTrkStatusInfo.ubEnd - 2) % TRACK_STATUS_DEPTH_MAX,
|
|
|
|
|
|
SkyTrkStatusInfo.nSavedNum - 1, &MoveFeatureB);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 跟踪异常判断条件
|
|
|
|
|
|
if (DetFeatureB.fMean > 0.65 && SkyTrkStatusInfo.fAIDetRatio[SkyTrkStatusInfo.ubEnd] <= 0.05 &&
|
|
|
|
|
|
MoveFeatureB.fMean > 100 && SkyTrkStatusInfo.fMoveDis[SkyTrkStatusInfo.ubEnd] <= 20)
|
|
|
|
|
|
{
|
|
|
|
|
|
SkyTrkStatusInfo.nAbnormalCnt += 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|