|
|
|
|
|
#include "Arith_Detector.h"
|
|
|
|
|
|
|
|
|
|
|
|
// 增加标准化算法模块
|
|
|
|
|
|
#include "Arith_CoordModule.h"
|
|
|
|
|
|
#include <thread>
|
|
|
|
|
|
using std::thread;
|
|
|
|
|
|
|
|
|
|
|
|
Detectors::Detectors(SINT32 nWidth, SINT32 nHeight, CENTERRECT mmCenterRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
pDST_Module = API_DetectSmallObj::Create(nWidth, nHeight, mmCenterRect);
|
|
|
|
|
|
pDAT_Module = API_DetectAreaObj::Create(nWidth, nHeight, mmCenterRect);
|
|
|
|
|
|
|
|
|
|
|
|
// 最大处理DT_TARGET_MAX_NUM个目标
|
|
|
|
|
|
m_Target_Array = new TARGET_OBJECT[DT_TARGET_MAX_NUM];
|
|
|
|
|
|
|
|
|
|
|
|
nSysStatus = GLB_STATUS_SEARCH;//默认状态
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Detectors::Detectors(SINT32 nWidth, SINT32 nHeight)
|
|
|
|
|
|
{
|
|
|
|
|
|
pDST_Module = API_DetectSmallObj::Create(nWidth, nHeight);
|
|
|
|
|
|
pDAT_Module = API_DetectAreaObj::Create(nWidth, nHeight);
|
|
|
|
|
|
|
|
|
|
|
|
// 最大处理DT_TARGET_MAX_NUM个目标
|
|
|
|
|
|
m_Target_Array = new TARGET_OBJECT[DT_TARGET_MAX_NUM];
|
|
|
|
|
|
|
|
|
|
|
|
m_FrmObjsCnt = 0;
|
|
|
|
|
|
|
|
|
|
|
|
nSysStatus = GLB_STATUS_SEARCH;//默认状态
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Detectors::~Detectors()
|
|
|
|
|
|
{
|
|
|
|
|
|
API_DetectSmallObj::Destroy(pDST_Module);
|
|
|
|
|
|
API_DetectAreaObj::Destroy(pDAT_Module);
|
|
|
|
|
|
delete m_Target_Array;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BBOOL Detectors::Init(SINT32 nWidth, SINT32 nHeight, CENTERRECT mmCenterRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
pDST_Module = API_DetectSmallObj::Create(nWidth, nHeight, mmCenterRect);
|
|
|
|
|
|
pDAT_Module = API_DetectAreaObj::Create(nWidth, nHeight, mmCenterRect);
|
|
|
|
|
|
|
|
|
|
|
|
// 最大处理DT_TARGET_MAX_NUM个目标
|
|
|
|
|
|
m_Target_Array = new TARGET_OBJECT[DT_TARGET_MAX_NUM];
|
|
|
|
|
|
|
|
|
|
|
|
nSysStatus = GLB_STATUS_SEARCH;//默认状态
|
|
|
|
|
|
|
|
|
|
|
|
m_FrmObjsCnt = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 检测器参数初始化
|
|
|
|
|
|
mDetPara.bEnableDetcetSmallTarget = true;
|
|
|
|
|
|
mDetPara.bEnableDetcetAreaTarget = true;
|
|
|
|
|
|
mDetPara.bEnableDetcetDimTarget = false;
|
|
|
|
|
|
mDetPara.fSmallDetectGDK = 7.0; //适配3315,避免小目标过多
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
void Detectors::ClearTargetsArray()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_Target_Array)
|
|
|
|
|
|
{
|
|
|
|
|
|
memset(m_Target_Array,0,sizeof(TARGET_OBJECT) * DT_TARGET_MAX_NUM);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 Detectors::Detect(GD_VIDEO_FRAME_S img, CENTERRECT mmCenterRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 类型检查
|
|
|
|
|
|
if (img.enPixelFormat != GD_PIXEL_FORMAT_GRAY_Y16 && GD_PIXEL_FORMAT_GRAY_Y8 != img.enPixelFormat)
|
|
|
|
|
|
{
|
|
|
|
|
|
ClearTargetsArray();
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//UINT16* pSrc = (UINT16*)img.u64VirAddr[0];
|
|
|
|
|
|
SINT32 nWidth = img.u32Width;
|
|
|
|
|
|
SINT32 nHeight = img.u32Height;
|
|
|
|
|
|
|
|
|
|
|
|
thread t1;
|
|
|
|
|
|
thread t2;
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化小目标队列
|
|
|
|
|
|
t1 = std::thread(&API_DetectSmallObj::Detect, pDST_Module, img, nWidth, nHeight, mmCenterRect, GLB_STATUS_SEARCH);//创建小目标处理线程
|
|
|
|
|
|
t2 = std::thread(&API_DetectAreaObj::Detect, pDAT_Module, img, nWidth, nHeight, mmCenterRect, GLB_STATUS_SEARCH);//创建面目标处理线程
|
|
|
|
|
|
|
|
|
|
|
|
//// 检测线程同步
|
|
|
|
|
|
t1.join();
|
|
|
|
|
|
t2.join();
|
|
|
|
|
|
|
|
|
|
|
|
// cv::Mat src(nHeight,nWidth,CV_8UC1);
|
|
|
|
|
|
// UINT16* pY16 = (UINT16*)pSrc;
|
|
|
|
|
|
// for (size_t i = 0; i < nHeight * nWidth; i++)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// src.data[i] = pY16[i];
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// cv::imshow("src",src);
|
|
|
|
|
|
// cv::waitKey(1);
|
|
|
|
|
|
|
|
|
|
|
|
// 将小目标队列拷贝进输出队列
|
|
|
|
|
|
SINT32 nSmallTargetNum = pDST_Module->GetTargetNum();
|
|
|
|
|
|
memcpy(m_Target_Array, pDST_Module->GetTargetArray(), nSmallTargetNum * sizeof(TARGET_OBJECT));
|
|
|
|
|
|
|
|
|
|
|
|
//拷贝面目标检测队列,截断拷贝
|
|
|
|
|
|
SINT32 nCpNum = MIN(DT_TARGET_MAX_NUM - nSmallTargetNum,pDAT_Module->GetTargetNum());
|
|
|
|
|
|
memcpy(&m_Target_Array[nSmallTargetNum], pDAT_Module->GetTargetArray(), nCpNum * sizeof(TARGET_OBJECT));
|
|
|
|
|
|
|
|
|
|
|
|
//小、面目标原地合并
|
|
|
|
|
|
m_FrmObjsCnt = MergeSmallAndAreaTarget(m_Target_Array, nSmallTargetNum, nCpNum, 9 ,GLB_STATUS::GLB_STATUS_SEARCH);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return m_FrmObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 Detectors::Detect(GD_VIDEO_FRAME_S img)
|
|
|
|
|
|
{
|
|
|
|
|
|
CENTERRECT mmCenterRect = { SINT16(img.u32Width / 2),SINT16(img.u32Height / 2),SINT16(img.u32Width) ,SINT16(img.u32Height) };
|
|
|
|
|
|
return Detect(img, mmCenterRect);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
POINT16S* Detectors::GetDST_MaxPoint()
|
|
|
|
|
|
{
|
|
|
|
|
|
return pDST_Module->getMaxPoint();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 Detectors::ImportExternTargets(TARGET_OBJECT* pTargetList, SINT32 nNum)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 清空输出队列
|
|
|
|
|
|
memset(m_Target_Array, 0, sizeof(TARGET_OBJECT) * DT_TARGET_MAX_NUM);
|
|
|
|
|
|
// 外部目标复制到输出队列
|
|
|
|
|
|
memcpy(m_Target_Array, pTargetList, nNum * sizeof(TARGET_OBJECT));
|
|
|
|
|
|
|
|
|
|
|
|
m_FrmObjsCnt = nNum;
|
|
|
|
|
|
|
|
|
|
|
|
return nNum;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Detectors::SetParam(Param_SkyDetect para)
|
|
|
|
|
|
{
|
|
|
|
|
|
pDST_Module->setDstDetState(para.bEnableDetcetSmallTarget); // 小目标检测开关设置
|
|
|
|
|
|
pDST_Module->setDstParm(¶); // 小目标检测参数设置
|
|
|
|
|
|
|
|
|
|
|
|
pDAT_Module->setDatDetState(para.bEnableDetcetAreaTarget); // 面目标检测开关设置
|
|
|
|
|
|
pDAT_Module->setDatParm(¶); // 面目标检测参数设置
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Param_SkyDetect Detectors::GetParam()
|
|
|
|
|
|
{
|
|
|
|
|
|
Param_SkyDetect para = { 0 };
|
|
|
|
|
|
|
|
|
|
|
|
// 小目标参数查询
|
|
|
|
|
|
para.bEnableDetcetSmallTarget = pDST_Module->getDstDetState();
|
|
|
|
|
|
|
|
|
|
|
|
DST_PARAMETERS* pDST_stPara = pDST_Module->GetDstParm();
|
|
|
|
|
|
para.fSmallDetectGDK = pDST_stPara->fgdk;
|
|
|
|
|
|
para.fDimGdk = pDST_stPara->fDimGdk;
|
|
|
|
|
|
para.nDetectGrayType = pDST_stPara->nDetectGrayType;
|
|
|
|
|
|
|
|
|
|
|
|
// 面目标参数查询
|
|
|
|
|
|
para.bEnableDetcetAreaTarget = pDAT_Module->getDatDetState();
|
|
|
|
|
|
DAT_PARAMETERS* pDAT_stPara = pDAT_Module->GetDatParm();
|
|
|
|
|
|
|
|
|
|
|
|
para.nGrayThresMinBright = pDAT_stPara->nGrayThresMinBright;
|
|
|
|
|
|
para.nGrayThresMinDark = pDAT_stPara->nGrayThresMinDark;
|
|
|
|
|
|
|
|
|
|
|
|
para.fAreaDetectGradDiffThre = pDAT_stPara->nGradThresMin;
|
|
|
|
|
|
|
|
|
|
|
|
para.nDSmpScale = pDAT_stPara->nDSmpScale;
|
|
|
|
|
|
|
|
|
|
|
|
//if (pDAT_stPara->nDetectGrayType != para.nDetectGrayType)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// spdlog::warn("{:08d}Small and area det nGrayType is not same.", 12);
|
|
|
|
|
|
//}
|
|
|
|
|
|
return para;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TARGET_OBJECT* Detectors::GetTargetArray()
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_Target_Array;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Detectors::RemoveLabelTarget(RECT32S box)
|
|
|
|
|
|
{
|
|
|
|
|
|
int Disthre = MAX((box.w + box.h), 7);
|
|
|
|
|
|
int cx = box.x + box.w / 2;
|
|
|
|
|
|
int cy = box.y + box.h / 2;
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < m_FrmObjsCnt; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
TARGET_OBJECT* tTarget = &m_Target_Array[i];
|
|
|
|
|
|
Disthre = MIN(20, Disthre);
|
|
|
|
|
|
// 基于中心点距离
|
|
|
|
|
|
if (ABS(tTarget->pfCenPos.x - cx) + ABS(tTarget->pfCenPos.y - cy) < Disthre)
|
|
|
|
|
|
{
|
|
|
|
|
|
tTarget->bObject = false;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:SO_MergeSmallAndAreaTarget()
|
|
|
|
|
|
* 功能描述:合并目标数组中重合的小目标和面目标
|
|
|
|
|
|
* 输入参数:UINT16 *pSrc -- 原始图像
|
|
|
|
|
|
* SINT32 nWidth -- 图像宽度
|
|
|
|
|
|
* SINT32 nHeight -- 图像高度
|
|
|
|
|
|
* TARGET_OBJECT *ptTargetArray-- 单帧目标数组
|
|
|
|
|
|
* SINT32 nSmallObjsCnt -- 单帧目标数组中的小目标个数
|
|
|
|
|
|
* SINT32 nAreaObjsCnt -- 单帧目标数组中的面目标个数
|
|
|
|
|
|
* 输出参数:TARGET_OBJECT *ptTargetArray-- 小目标和面目标合并后的目标数组
|
|
|
|
|
|
* 返 回 值:nTargetNum -- 小目标和面目标合并后的目标数目
|
|
|
|
|
|
* 调用关系:
|
|
|
|
|
|
* 其它说明:单帧目标数组中目标排列顺序:nSmallObjsCnt个小目标+nAreaObjsCnt个面目标
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
SINT16 MergeSmallAndAreaTarget(TARGET_OBJECT *ptTargetArray, SINT32 nSmallObjsCnt, SINT32 nAreaObjsCnt, SINT32 nCombineDist, GLB_STATUS nSysStatus)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 i = 0;
|
|
|
|
|
|
SINT32 j = 0;
|
|
|
|
|
|
SINT32 k = 0;
|
|
|
|
|
|
TARGET_OBJECT *ptSmallTarget = NULL;
|
|
|
|
|
|
TARGET_OBJECT *ptAreaTarget = NULL;
|
|
|
|
|
|
SINT32 nXDistance = 0;
|
|
|
|
|
|
SINT32 nYDistance = 0;
|
|
|
|
|
|
SINT32 nObjsCnt = (nSmallObjsCnt + nAreaObjsCnt);
|
|
|
|
|
|
SINT32 nMaxPntsDis = 0; //20181205,小目标极值点距离(绝对值)
|
|
|
|
|
|
SINT32 nObjCombineDist = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (GLB_STATUS_TRACK != nSysStatus)
|
|
|
|
|
|
{
|
|
|
|
|
|
nObjCombineDist = MAX(nCombineDist, 20);//合并阈值保护
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
nObjCombineDist = nCombineDist;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//20170905,目标个数为0,直接返回
|
|
|
|
|
|
//20170303,跟踪且复杂场景下不合并,否则导致合并后影响最优管道目标判断,尤其在穿云时小目标跟踪稳定,合并后相似度反而不如云干扰
|
|
|
|
|
|
//if (nObjsCnt < 1 || g_GLB_bComplexEnv)
|
|
|
|
|
|
//20180926,跟踪期间不合并,容易导致真实小目标被合并算法进记忆
|
|
|
|
|
|
//20181205,考虑跟踪期间的小小目标合并
|
|
|
|
|
|
if (nObjsCnt == 0 /*|| GLB_STATUS_TRACK == nSysStatus*/)
|
|
|
|
|
|
{
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//20171206,全遍历,防止漏合并
|
|
|
|
|
|
for (i = 0; i < nObjsCnt; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
ptAreaTarget = &ptTargetArray[i];
|
|
|
|
|
|
|
|
|
|
|
|
//20170314: 防错,跳过空目标
|
|
|
|
|
|
if (!ptAreaTarget->bObject)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//20171206,全遍历,防止漏合并
|
|
|
|
|
|
for (j = 0; j < nObjsCnt; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (i == j)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
ptSmallTarget = &ptTargetArray[j];
|
|
|
|
|
|
|
|
|
|
|
|
//20170314: 防错,跳过空目标
|
|
|
|
|
|
if (!ptSmallTarget->bObject)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//20161112,仅合并灰度类型相同的目标
|
|
|
|
|
|
if (ptAreaTarget->nObjTypeGray == ptSmallTarget->nObjTypeGray)
|
|
|
|
|
|
{
|
|
|
|
|
|
//20140905: 若两个目标的矩形框有交集,也合并
|
|
|
|
|
|
SINT32 nCombineDist = 1;
|
|
|
|
|
|
BBOOL bBoxClose = true;
|
|
|
|
|
|
if ((ptAreaTarget->mrnRect.minX < ptSmallTarget->mrnRect.minX && ptAreaTarget->mrnRect.maxX < ptSmallTarget->mrnRect.minX - nCombineDist)
|
|
|
|
|
|
|| (ptAreaTarget->mrnRect.maxX > ptSmallTarget->mrnRect.maxX && ptAreaTarget->mrnRect.minX > ptSmallTarget->mrnRect.maxX + nCombineDist)
|
|
|
|
|
|
|| (ptAreaTarget->mrnRect.minY < ptSmallTarget->mrnRect.minY && ptAreaTarget->mrnRect.maxY < ptSmallTarget->mrnRect.minY - nCombineDist)
|
|
|
|
|
|
|| (ptAreaTarget->mrnRect.maxY > ptSmallTarget->mrnRect.maxY && ptAreaTarget->mrnRect.minY > ptSmallTarget->mrnRect.maxY + nCombineDist))
|
|
|
|
|
|
{
|
|
|
|
|
|
bBoxClose = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
bBoxClose = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算面目标与小目标之间的距离
|
|
|
|
|
|
nXDistance = ABS((SINT32)(ptAreaTarget->pfCenPos.x - ptSmallTarget->pfCenPos.x));
|
|
|
|
|
|
nYDistance = ABS((SINT32)(ptAreaTarget->pfCenPos.y - ptSmallTarget->pfCenPos.y));
|
|
|
|
|
|
BBOOL bDistClose = false;
|
|
|
|
|
|
if (nXDistance < nObjCombineDist
|
|
|
|
|
|
&& nYDistance < nObjCombineDist)
|
|
|
|
|
|
{
|
|
|
|
|
|
bDistClose = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//矩形交叠或距离过近,则合并,取大者
|
|
|
|
|
|
if (bBoxClose || bDistClose)
|
|
|
|
|
|
{
|
|
|
|
|
|
//20161209,如果两个目标极值点与中心点均很近,则合并至面目标
|
|
|
|
|
|
SINT32 nDeltetID = i;
|
|
|
|
|
|
FLOAT32 fCenPntDistAB = 0.0f;
|
|
|
|
|
|
SINT32 nMaxPntDistAB = 0;
|
|
|
|
|
|
SINT32 nThres = nObjCombineDist * nObjCombineDist;
|
|
|
|
|
|
|
|
|
|
|
|
//计算A、B点中心点和极值点距离
|
|
|
|
|
|
fCenPntDistAB = (ptAreaTarget->pfCenPos.x - ptSmallTarget->pfCenPos.x) * (ptAreaTarget->pfCenPos.x - ptSmallTarget->pfCenPos.x);
|
|
|
|
|
|
fCenPntDistAB += (ptAreaTarget->pfCenPos.y - ptSmallTarget->pfCenPos.y) * (ptAreaTarget->pfCenPos.y - ptSmallTarget->pfCenPos.y);
|
|
|
|
|
|
nMaxPntDistAB = (ptAreaTarget->pnMaxPos.x - ptSmallTarget->pnMaxPos.x) * (ptAreaTarget->pnMaxPos.x - ptSmallTarget->pnMaxPos.x);
|
|
|
|
|
|
nMaxPntDistAB += (ptAreaTarget->pnMaxPos.y - ptSmallTarget->pnMaxPos.y) * (ptAreaTarget->pnMaxPos.y - ptSmallTarget->pnMaxPos.y);
|
|
|
|
|
|
|
|
|
|
|
|
if (fCenPntDistAB < nThres && nMaxPntDistAB < nThres)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 nSizeDiffW = ptSmallTarget->snSize.w - ptAreaTarget->snSize.w;
|
|
|
|
|
|
SINT32 nSizeDiffH = ptSmallTarget->snSize.h - ptAreaTarget->snSize.h;
|
|
|
|
|
|
if (fCenPntDistAB < 3 && ABS(nSizeDiffW) < 3 && ABS(nSizeDiffH) < 3)
|
|
|
|
|
|
{
|
|
|
|
|
|
nDeltetID = j;//重复目标
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//20170221,若小目标的宽或高大于7,才合并,为了小目标逼近过程中平滑过渡到面目标,防止跟踪局部
|
|
|
|
|
|
if (ptSmallTarget->nObjTypeSize > GLB_OBJ_SIZE_SMALL)
|
|
|
|
|
|
{
|
|
|
|
|
|
//20181206,仅在搜索阶段合并
|
|
|
|
|
|
if (GLB_STATUS_TRACK != nSysStatus || ((GLB_STATUS_TRACK == nSysStatus)
|
|
|
|
|
|
&& ptAreaTarget->nObjTypeSize == GLB_OBJ_SIZE_SMALL
|
|
|
|
|
|
&& (ptAreaTarget->snSize.w > 7 || ptAreaTarget->snSize.h > 7)))
|
|
|
|
|
|
//if (GLB_STATUS_SEARCH == nSysStatus)
|
|
|
|
|
|
{
|
|
|
|
|
|
memcpy(ptAreaTarget, ptSmallTarget, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
ptAreaTarget->nObjTypeSize = GLB_OBJ_SIZE_MIDDLE; //更新目标类型:临界目标
|
|
|
|
|
|
nDeltetID = j;
|
|
|
|
|
|
|
|
|
|
|
|
//20170326,更新合并标志
|
|
|
|
|
|
//20181206,仅在搜索阶段合并
|
|
|
|
|
|
//if (GLB_STATUS_TRACK == nSysStatus)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// g_GLB_bMergeSmallAndArea = true;
|
|
|
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//20170311,否则不合并
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (ptAreaTarget->nObjTypeSize > GLB_OBJ_SIZE_SMALL)
|
|
|
|
|
|
{
|
|
|
|
|
|
//20181206,仅在搜索阶段合并
|
|
|
|
|
|
if (GLB_STATUS_SEARCH == nSysStatus ||
|
|
|
|
|
|
(GLB_STATUS_TRACK == nSysStatus
|
|
|
|
|
|
&& ptSmallTarget->nObjTypeSize == GLB_OBJ_SIZE_SMALL
|
|
|
|
|
|
&& (ptSmallTarget->snSize.w > 7 || ptSmallTarget->snSize.h > 7)))
|
|
|
|
|
|
//if (GLB_STATUS_SEARCH == nSysStatus)
|
|
|
|
|
|
{
|
|
|
|
|
|
memcpy(ptSmallTarget, ptAreaTarget, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
ptSmallTarget->nObjTypeSize = GLB_OBJ_SIZE_MIDDLE; //更新目标类型:临界目标
|
|
|
|
|
|
nDeltetID = i;
|
|
|
|
|
|
|
|
|
|
|
|
//20170326,更新合并标志
|
|
|
|
|
|
//20181206,仅在搜索阶段合并
|
|
|
|
|
|
//if (GLB_STATUS_TRACK == nSysStatus)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// g_GLB_bMergeSmallAndArea = true;
|
|
|
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//20170311,否则不合并
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//20181205,考虑小小目标合并
|
|
|
|
|
|
nMaxPntsDis = ABS(ptSmallTarget->pnMaxPos.x - ptAreaTarget->pnMaxPos.x) +
|
|
|
|
|
|
ABS(ptSmallTarget->pnMaxPos.y - ptAreaTarget->pnMaxPos.y);
|
|
|
|
|
|
|
|
|
|
|
|
//20181206,仅考虑简单背景的情况,防止目标和云等背景合并
|
|
|
|
|
|
if (/*!g_GLB_bComplexEnv && */GLB_STATUS_TRACK == nSysStatus && nMaxPntsDis < 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ptSmallTarget->unObjPxlsCnt > ptAreaTarget->unObjPxlsCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
memcpy(ptAreaTarget, ptSmallTarget, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
nDeltetID = j;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
memcpy(ptSmallTarget, ptAreaTarget, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
nDeltetID = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 增加小小目标合并的情况,因为加入了双极值点的算法,前端没有能力处理极值点不接近而目标框接近的情况。
|
|
|
|
|
|
else if (/*!g_GLB_bComplexEnv && */GLB_STATUS_TRACK != nSysStatus && nMaxPntsDis < 9)
|
|
|
|
|
|
{
|
|
|
|
|
|
memcpy(ptSmallTarget, ptAreaTarget, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
nDeltetID = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//跳过,不合并
|
|
|
|
|
|
//continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (k = nDeltetID + 1; k < nObjsCnt; k++)
|
|
|
|
|
|
{
|
|
|
|
|
|
ptTargetArray[k - 1] = ptTargetArray[k];
|
|
|
|
|
|
}
|
|
|
|
|
|
memset(&ptTargetArray[nObjsCnt - 1], 0, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
nObjsCnt--;
|
|
|
|
|
|
i--;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//暂不处理
|
|
|
|
|
|
} //end of "if (fCenPntDistAB < nThres && nMaxPntDistAB < nThres)"
|
|
|
|
|
|
} //end of "if (bBoxClose || bDistClose)"
|
|
|
|
|
|
} //end of "if (ptAreaTarget->nObjTypeGray == ptSmallTarget->nObjTypeGray)"
|
|
|
|
|
|
} //end of "for (j = i + 1; j < nObjsCnt; j++)"
|
|
|
|
|
|
} // end of "for (i = 0; i < nObjsCnt - 1; i++)"
|
|
|
|
|
|
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:Sort_TargetArray(SINT32 nObjsNum)
|
|
|
|
|
|
* 功能描述:将目标检测结果进行排序
|
|
|
|
|
|
* 输入参数:SINT32 nObjsNum -- 目标检测个数
|
|
|
|
|
|
DetectCenterX -- 目标检测中心X
|
|
|
|
|
|
DetectCenterY -- 目标检测中心Y
|
|
|
|
|
|
* 输出参数:无
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void Sort_TargetArray(TARGET_OBJECT* ptTargetArray,SINT32 nObjsNum, FLOAT32 DetectCenterX, FLOAT32 DetectCenterY)
|
|
|
|
|
|
{
|
|
|
|
|
|
FLOAT32 DistA = 0.0;
|
|
|
|
|
|
FLOAT32 DistB = 0.0;
|
|
|
|
|
|
TARGET_OBJECT ptTargetArrayTemp;
|
|
|
|
|
|
for (int i = 0; i < nObjsNum - 1; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int j = i; j < nObjsNum; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//根据各个目标检测结果与检测中心点的距离进行排序
|
|
|
|
|
|
DistA = (ptTargetArray[i].pfCenPos.x - DetectCenterX) * (ptTargetArray[i].pfCenPos.x - DetectCenterX)
|
|
|
|
|
|
+ (ptTargetArray[i].pfCenPos.y - DetectCenterY) * (ptTargetArray[i].pfCenPos.y - DetectCenterY);
|
|
|
|
|
|
DistB = (ptTargetArray[j].pfCenPos.x - DetectCenterX) * (ptTargetArray[j].pfCenPos.x - DetectCenterX)
|
|
|
|
|
|
+ (ptTargetArray[j].pfCenPos.y - DetectCenterY) * (ptTargetArray[j].pfCenPos.y - DetectCenterY);
|
|
|
|
|
|
if (DistA > DistB)
|
|
|
|
|
|
{
|
|
|
|
|
|
ptTargetArrayTemp = ptTargetArray[i];
|
|
|
|
|
|
memcpy(&ptTargetArray[i], &ptTargetArray[j], sizeof(TARGET_OBJECT));
|
|
|
|
|
|
memcpy(&ptTargetArray[j], &ptTargetArrayTemp, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 MergeAIAndSATarget(TARGET_OBJECT* ptTargetArray,SINT32 nObjsCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(nObjsCnt == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 i = 0;
|
|
|
|
|
|
SINT32 j = 0;
|
|
|
|
|
|
SINT32 k = 0;
|
|
|
|
|
|
SINT32 nXDistance = 0;
|
|
|
|
|
|
SINT32 nYDistance = 0;
|
|
|
|
|
|
|
|
|
|
|
|
TARGET_OBJECT* pT1 = NULL;
|
|
|
|
|
|
TARGET_OBJECT* pT2 = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 nObjCombineDist = 5;
|
|
|
|
|
|
|
|
|
|
|
|
//20171206,全遍历,防止漏合并
|
|
|
|
|
|
for (i = 0; i < nObjsCnt; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
pT1 = &ptTargetArray[i];
|
|
|
|
|
|
|
|
|
|
|
|
//20170314: 防错,跳过空目标
|
|
|
|
|
|
if (!pT1->bObject)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//20171206,全遍历,防止漏合并
|
|
|
|
|
|
for (j = 0; j < nObjsCnt; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (i == j)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
pT2 = &ptTargetArray[j];
|
|
|
|
|
|
|
|
|
|
|
|
//20170314: 防错,跳过空目标
|
|
|
|
|
|
if (!pT2->bObject)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//仅合并传统算法目标与AI目标
|
|
|
|
|
|
if(pT1->unClsType == pT2->unClsType)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//20140905: 若两个目标的矩形框有交集,也合并
|
|
|
|
|
|
SINT32 nCombineDist = 1;
|
|
|
|
|
|
BBOOL bBoxClose = true;
|
|
|
|
|
|
if ((pT2->mrnRect.minX < pT1->mrnRect.minX && pT2->mrnRect.maxX < pT1->mrnRect.minX - nCombineDist)
|
|
|
|
|
|
|| (pT2->mrnRect.maxX > pT1->mrnRect.maxX && pT2->mrnRect.minX > pT1->mrnRect.maxX + nCombineDist)
|
|
|
|
|
|
|| (pT2->mrnRect.minY < pT1->mrnRect.minY && pT2->mrnRect.maxY < pT1->mrnRect.minY - nCombineDist)
|
|
|
|
|
|
|| (pT2->mrnRect.maxY > pT1->mrnRect.maxY && pT2->mrnRect.minY > pT1->mrnRect.maxY + nCombineDist))
|
|
|
|
|
|
{
|
|
|
|
|
|
bBoxClose = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
bBoxClose = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算面目标与小目标之间的距离
|
|
|
|
|
|
nXDistance = ABS((SINT32)(pT2->pfCenPos.x - pT1->pfCenPos.x));
|
|
|
|
|
|
nYDistance = ABS((SINT32)(pT2->pfCenPos.y - pT1->pfCenPos.y));
|
|
|
|
|
|
BBOOL bDistClose = false;
|
|
|
|
|
|
if (nXDistance < nObjCombineDist
|
|
|
|
|
|
&& nYDistance < nObjCombineDist)
|
|
|
|
|
|
{
|
|
|
|
|
|
bDistClose = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//矩形交叠或距离过近,则合并,取大者
|
|
|
|
|
|
if (bBoxClose || bDistClose)
|
|
|
|
|
|
{
|
|
|
|
|
|
//20161209,如果两个目标极值点与中心点均很近,则合并至面目标
|
|
|
|
|
|
SINT32 nDeltetID = i;
|
|
|
|
|
|
FLOAT32 fCenPntDistAB = 0.0f;
|
|
|
|
|
|
SINT32 nMaxPntDistAB = 0;
|
|
|
|
|
|
SINT32 nThres = nObjCombineDist * nObjCombineDist;
|
|
|
|
|
|
|
|
|
|
|
|
//计算A、B点中心点距离
|
|
|
|
|
|
fCenPntDistAB = (pT2->pfCenPos.x - pT1->pfCenPos.x) * (pT2->pfCenPos.x - pT1->pfCenPos.x);
|
|
|
|
|
|
fCenPntDistAB += (pT2->pfCenPos.y - pT1->pfCenPos.y) * (pT2->pfCenPos.y - pT1->pfCenPos.y);
|
|
|
|
|
|
|
|
|
|
|
|
if (fCenPntDistAB < nThres)
|
|
|
|
|
|
{
|
|
|
|
|
|
nDeltetID = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 执行合并
|
|
|
|
|
|
for (int k = nDeltetID + 1; k < nObjsCnt; k++)
|
|
|
|
|
|
{
|
|
|
|
|
|
ptTargetArray[k - 1] = ptTargetArray[k];
|
|
|
|
|
|
}
|
|
|
|
|
|
memset(&ptTargetArray[nObjsCnt - 1], 0, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
nObjsCnt--;
|
|
|
|
|
|
i--;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|