/*********版权所有(C)2014,武汉高德红外股份有限公司*************** * 文件名称:Arith_BkgMonitor.cpp * 文件标识:背景监控 * 内容摘要:目标跟踪的过程中,监控目标周围的背景的均值和方差变化,提高跟踪的抗干扰能力 * 其它说明:"Arith_BkgMonitor"的函数、全局变量、宏定义,统一前缀为简写"BKM"。 * 当前版本:固化V2.0 * 创建作者:MSSu * 创建日期:2015.03.16 * * 修改记录1: * 修改日期:2015.04.20 * 版 本 号:固化V2.0 * 修 改 人:MSSu * 修改内容:算法整理及优化。 * 修改记录2:… *******************************************************************/ #include "Arith_ImgOperate.h" #include "Arith_Detector.h" #include "Arith_BkgMonitor.h" #include "Arith_TrackSAObj.h" #include BkgMonitor::BkgMonitor() { memset(g_GLB_bObj8BkgStatus, 0, sizeof(BBOOL) * GLB_OBJ_BKG_NUM); //20170227Whao,目标跟踪时8邻域方差异常标志 g_GLB_bComplexEnv = FALSE; //20170301,连续退出复杂环境帧计数及进入复杂环境标志 g_GLB_bCrossInterference = FALSE; //20170603,wsa,场景分析:判断是否有交错目标干扰 g_GLB_bMultiObj = FALSE; //20170301,连续多目标帧计数及标志 g_GLB_bMultiObjMerge = FALSE; //20170306,多目标合并标志位 g_GLB_bInterferenceMem = FALSE; //20170217Whao,干扰进记忆跟踪标志位和干扰方向 g_GLB_bInfrnDirection = GLB_INFRN_DIR_NONE; //20170217Whao,干扰进记忆跟踪标志位和干扰方向 g_GLB_nObj8BkgArrayIndex = 0; //20170220Whao,目标跟踪时8邻域背景监控均值与方差数据记录的数组当前下标 g_GLB_nObj8BkgFrames = 0; //20170220Whao,目标跟踪时8邻域背景监控均值与方差数据记录的总帧数 g_GLB_nExitInfrnMemCnt = 0; //20170302Whao,退出干扰进记忆跟踪帧计数 g_GLB_nMultiObjCnt = 0; //20170301,连续多目标帧计数及标志 g_GLB_nExitComplexEnv = 0; //20170301,连续退出复杂环境帧计数及进入复杂环境标志【DSP-B核移植】 g_GLB_nCrossInterferenceCnt = 0; //20170603,wsa,场景分析:交错目标干扰时目标逼近计数器 g_GLB_bObjGrayMean = 0.0; //20170216Whao,目标跟踪时目标4邻域均值【DSP-B核移植】 g_GLB_NearEdge = FALSE; bJudgeBkgMean = FALSE; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //背景监控空间 memset(mrnBkgBlks, 0, 8 * sizeof(MINMAXRECT32S)); //目标跟踪时8邻域框 memset(DSP_GLB_Obj8BkgMeanArray, 0, sizeof(FLOAT32) * GLB_OBJ_BKG_FRM_NUM * GLB_OBJ_BKG_NUM);//目标跟踪时8邻域背景均值数组 memset(DSP_GLB_Obj8BkgStdArray, 0, sizeof(FLOAT32) * GLB_OBJ_BKG_FRM_NUM * GLB_OBJ_BKG_NUM);//目标跟踪时8邻域背景标准差数组 } BkgMonitor::~BkgMonitor() { } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //////////////////////////////////////////////////////////////////////////////// //--函数定义 //////////////////////////////////////////////////////////////////////////////// /********************************************************** * 函数名称:BKM_BkgMonitor() * 功能描述:对目标8邻域区域进行监控 * 输入参数:PIXELTYPE *pFrame * SINT32 nWidth -- 图像宽度 * SINT32 nHeight -- 图像高度 * CENTERRECT crnObjRect -- 目标矩形 * SPEED32F AngleSpeed -- 角速度 * 输出参数:g_GLB_bComplexEnv * g_GLB_bInterferenceMem * 返 回 值:无 * 调用关系:无 * 其它说明:无 **********************************************************/ /************************************* * Method: BKM_BkgMonitor() * Function Description: * CreateData: 2025/2/18 * Input Param: GD_VIDEO_FRAME_S img -- 原始图像 * Input Param: GLB_INPUT * p_GLB_Input -- 随帧输入参数 * Input Param: GrayType nTrackGrayType -- 亮暗目标类型 * Input Param: CENTERRECT crCenterRect -- 搜索区域矩形 * Input Param: OBJECTSTATUS * pTrackStatus -- 跟踪状态结构体 * Output Param: * Return: void * Call Relation: * Other Description: *************************************/ void BkgMonitor::BKM_BkgMonitor(GD_VIDEO_FRAME_S img, GLB_INPUT* p_GLB_Input, GrayType nTrackGrayType, CENTERRECT crCenterRect, OBJECTSTATUS* pTrackStatus) { //20170216,监控目标的8邻域区域 MINMAXRECT32S mrnObj; //目标跟踪矩形 OBJECTMONITOR ObjectMONI; //目标场景监控信息 SINT16 nObjOutRadius = 5; //目标扩展半径,防止背景点包含目标点计算得出的均值和标准差有偏差 SINT16 nObjCenterX = 0; //目标中心点X坐标 SINT16 nObjCenterY = 0; //目标中心点Y坐标 SINT16 nObjWidth = 0; //目标中心点X坐标 SINT16 nObjHeight = 0; //目标中心点Y坐标 DOUBLE64 dGrayMean = 0.0f; SINT16 nCnt = 0; SINT16 i = 0; SINT16 j = 0; SINT16 nBkgWRadius = 0; //目标场景监控半径 SINT16 nBkgHRadius = 0; //目标场景监控半径 CENTERRECT crnObjRect = { 0 }; SINT32 nWidth = img.u32Width; SINT32 nHeight = img.u32Height; crnObjRect.cx = (SINT16)pTrackStatus->ptPos.x; crnObjRect.cy = (SINT16)pTrackStatus->ptPos.y; crnObjRect.w = MAX((SINT16)pTrackStatus->sfSize.w, 8); crnObjRect.h = MAX((SINT16)pTrackStatus->sfSize.h, 8); nBkgWRadius = (SINT16)(MAX(crnObjRect.w * 0.75, (crCenterRect.w - crnObjRect.w) / 2)); nBkgHRadius = (SINT16)(MAX(crnObjRect.h * 0.75, (crCenterRect.h - crnObjRect.h) / 2)); nObjCenterX = crnObjRect.cx; nObjCenterY = crnObjRect.cy; nObjWidth = crnObjRect.w; nObjHeight = crnObjRect.h; //20171208,这样取值对于形状姿态不规律的目标,可能取到背景区域 mrnObj.minX = MAX(0, MIN(nObjCenterX - nObjWidth / 2 - nObjOutRadius, nWidth - 1)); mrnObj.maxX = MAX(0, MIN(nObjCenterX + nObjWidth / 2 + nObjOutRadius, nWidth - 1)); mrnObj.minY = MAX(0, MIN(nObjCenterY - nObjHeight / 2 - nObjOutRadius, nHeight - 1)); mrnObj.maxY = MAX(0, MIN(nObjCenterY + nObjHeight / 2 + nObjOutRadius, nHeight - 1)); #if 0 // 计算区域的左上角坐标 int minX = mrnObj.minX; int minY = mrnObj.minY; // 计算扣取区域的宽度和高度 int width = nObjWidth; int height = nObjHeight; // 计算扣取区域在原始图像中的偏移量 int offset = minY * nWidth + minX; // 构造 cv::Mat 对象 cv::Mat croppedImage(height, width, CV_8UC1); for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { croppedImage.at(i, j) = ((UBYTE8*)img.u64VirAddr[0])[(i + minY)* nWidth + minX + j]; } } #endif // 计算目标区域的均值 for (j = mrnObj.minY; j <= mrnObj.maxY; j++) { for (i = mrnObj.minX; i <= mrnObj.maxX; i++) { //dGrayMean += pFrame[j * nWidth + i]; if (GD_PIXEL_FORMAT_GRAY_Y8 == img.enPixelFormat) { dGrayMean += ((UBYTE8*)img.u64VirAddr[0])[j * nWidth + i]; } else { dGrayMean += ((UINT16*)img.u64VirAddr[0])[j * nWidth + i]; } nCnt++; } } g_GLB_bObjGrayMean = FLOAT32(dGrayMean / nCnt); // 对目标8邻域区域进行监控 BKM_CalObjBkgMonitor(img, nWidth, nHeight, mrnObj, nBkgWRadius, nBkgHRadius, &ObjectMONI, nTrackGrayType, pTrackStatus->sfAglSpeed, (FLOAT32*)DSP_GLB_Obj8BkgMeanArray, (FLOAT32*)DSP_GLB_Obj8BkgStdArray); //区域场景分析,主要针对过杆 //20170221Whao,监控数组大于10以后才进行处理 //20170303Whao,仅对低空时判定过杆(伺服俯仰角<10°) if ((g_GLB_nObj8BkgFrames > GLB_OBJ_BKG_FRM_NUM - 1) /*&& g_SERVO_stInput.fPitching < GLB_INFRN_PT_THRES*/) { BKM_AnalyzeBkg(p_GLB_Input, g_GLB_bObjGrayMean, (FLOAT32*)DSP_GLB_Obj8BkgMeanArray, (FLOAT32*)DSP_GLB_Obj8BkgStdArray, pTrackStatus); } else { g_GLB_bInterferenceMem = false; g_GLB_bInfrnDirection = GLB_INFRN_DIR_NONE; } } /********************************************************** * 函数名称:BKM_CleanUpResult() * 功能描述:清空场景监控结果 * 输入参数: * 输出参数: * 返 回 值:无 * 调用关系:无 * 其它说明:无 **********************************************************/ void BkgMonitor::BKM_CleanUpResult() { //20170220Whao,清空场景监控结果 memset(mrnBkgBlks, 0, 8 * sizeof(MINMAXRECT32S)); memset(&DSP_GLB_Obj8BkgMeanArray, 0, GLB_OBJ_BKG_FRM_NUM * GLB_OBJ_BKG_NUM * sizeof(FLOAT32));//目标跟踪时8邻域背景均值数组 memset(&DSP_GLB_Obj8BkgStdArray, 0, GLB_OBJ_BKG_FRM_NUM * GLB_OBJ_BKG_NUM * sizeof(FLOAT32)); //目标跟踪时8邻域背景标准差数组 memset(&g_GLB_bObj8BkgStatus, 0, GLB_OBJ_BKG_NUM * sizeof(BBOOL)); //目标跟踪时8邻域背景监控方差的变化趋势矩阵 g_GLB_nObj8BkgArrayIndex = 0; g_GLB_nObj8BkgFrames = 0; g_GLB_bInterferenceMem = false; g_GLB_nExitInfrnMemCnt = 0; g_GLB_bInfrnDirection = GLB_INFRN_DIR_NONE; bJudgeBkgMean = false; //20170603,清空交错干扰标志位和计数器 g_GLB_bCrossInterference = false; g_GLB_nCrossInterferenceCnt = 0; //20170301,清空多目标计数及标志 g_GLB_nMultiObjCnt = 0; g_GLB_bMultiObj = false; //20170306,清空多目标合并标志位 g_GLB_bMultiObjMerge = false; //20170301,清空连续退出复杂环境帧计数及进入复杂环境标志 g_GLB_nExitComplexEnv = 0; g_GLB_bComplexEnv = false; } /********************************************************** * 函数名称:TO_CalObjBkgMonitor() * 功能描述:对目标8邻域区域进行监控 * 输入参数:PIXELTYPE *pFrame -- 原始图像 * SINT32 nWidth -- 图像宽度 * SINT32 nHeight -- 图像高度 * MINMAXRECT32S mrnObj -- 目标矩形 * SINT32 nBkgRadius -- 邻域背景半径 * UBYTE8 nDetectGrayType -- 目标检测的灰度类型 * SPEED32F AngleSpeed -- 角速度 * 输出参数:OBJECTMONITOR *objSNR -- 目标场景监控结构体指针 * FLOAT32 *pdObj8BkgMeanArray-- 目标跟踪时8邻域背景监控均值 * FLOAT32 *pdObj8BkgStdArray -- 目标跟踪时8邻域背景监控方差 * 返 回 值:无 * 调用关系:无 * 其它说明:无 **********************************************************/ void BkgMonitor::BKM_CalObjBkgMonitor(GD_VIDEO_FRAME_S img, SINT32 nWidth, SINT32 nHeight, MINMAXRECT32S mrnObj, SINT32 nBkgWRadius, SINT32 nBkgHRadius, OBJECTMONITOR *objSNR, GrayType nDetectGrayType, SPEED32F AngleSpeed, FLOAT32 *pdObj8BkgMeanArray, FLOAT32 *pdObj8BkgStdArray) { SINT32 i, j, k; SINT32 nBGValue, nBGCnt; //背景点灰度、背景点计数 double dBGMean, dBGStd; //背景均值、方差 MINMAXRECT32S mrnBkg; //背景区域矩形 SINT32 nLineIndex, nIndex; FLOAT32 fGrayMax, fGrayMin, fGrayMean; SINT32 nGrayCnt; SINT32 CenterX, CenterY; //20170220,获取帧间的下标 if (g_GLB_nObj8BkgFrames < GLB_OBJ_BKG_FRM_NUM - 1) { g_GLB_nObj8BkgArrayIndex = g_GLB_nObj8BkgFrames; } else { g_GLB_nObj8BkgArrayIndex = g_GLB_nObj8BkgFrames % GLB_OBJ_BKG_FRM_NUM; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++ //获取目标灰度值极值、均值【重复计算】及其坐标 nLineIndex = mrnObj.minY * nWidth; CenterX = (mrnObj.minX + mrnObj.maxX) >> 1; CenterY = (mrnObj.minY + mrnObj.maxY) >> 1; //objSNR->ObjGray = pFrame[CenterY * nWidth + CenterX]; if (GD_PIXEL_FORMAT_GRAY_Y8 == img.enPixelFormat) { objSNR->ObjGray = ((UBYTE8*)img.u64VirAddr[0])[CenterY * nWidth + CenterX]; } else { objSNR->ObjGray = ((UINT16*)img.u64VirAddr[0])[CenterY * nWidth + CenterX]; } fGrayMax = objSNR->ObjGray; fGrayMin = objSNR->ObjGray; fGrayMean = 0.0f; nGrayCnt = 0; for (i = mrnObj.minY; i <= mrnObj.maxY; i++) { for (j = mrnObj.minX; j <= mrnObj.maxX; j++) { nIndex = nLineIndex + j; //目标灰度均值 //fGrayMean += (FLOAT32)(pFrame[nIndex]); if (GD_PIXEL_FORMAT_GRAY_Y8 == img.enPixelFormat) { fGrayMean += ((UBYTE8*)img.u64VirAddr[0])[nIndex]; } else { fGrayMean += ((UINT16*)img.u64VirAddr[0])[nIndex]; } nGrayCnt++; } nLineIndex += nWidth; } if (nGrayCnt > 0) { fGrayMean /= nGrayCnt; } //根据检测类型,获取目标灰度极值 //亮目标 if (GrayType::BrightTarget == nDetectGrayType) { objSNR->ObjGray = fGrayMax; objSNR->ObjGrayMean = fGrayMean; } //暗目标 else if (GrayType::DarkTarget == nDetectGrayType) { objSNR->ObjGray = fGrayMin; objSNR->ObjGrayMean = fGrayMean; } //亮暗全检测 else { objSNR->ObjGray = fGrayMean; objSNR->ObjGrayMean = fGrayMean; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++ //统计背景均值、方差:划分为0-上、1-右上、2-右、3-右下、4-下、5-左下、6-左、7-左上8个背景区域 //计算背景窗口边界 mrnBkg.minX = MAX(0, MIN(mrnObj.minX - nBkgWRadius, nWidth - 1)); mrnBkg.maxX = MAX(0, MIN(mrnObj.maxX + nBkgWRadius, nWidth - 1)); mrnBkg.minY = MAX(0, MIN(mrnObj.minY - nBkgHRadius, nHeight - 1)); mrnBkg.maxY = MAX(0, MIN(mrnObj.maxY + nBkgHRadius, nHeight - 1)); //20170303,【防错】如果目标运动到图像边界,则方差数组和均值数组清零 if ((0 == mrnObj.minX) || (0 == mrnObj.minY) || ((nWidth - 1) == mrnObj.maxX) || ((nWidth - 1) == mrnObj.maxY)) { for (i = 0; i < GLB_OBJ_BKG_NUM; i++) { nIndex = g_GLB_nObj8BkgArrayIndex * GLB_OBJ_BKG_NUM + i; pdObj8BkgMeanArray[nIndex] = 0.0; pdObj8BkgStdArray[nIndex] = 0.0; } } else { //MSSu, 20170607: 以下代码可简化到一个for循环内执行,先保存每个每个背景区域的边界矩形数组即可。 //背景区域0-上 mrnBkgBlks[0] = mrnObj; mrnBkgBlks[0].minY = mrnBkg.minY; mrnBkgBlks[0].maxY = mrnObj.minY - 1; //背景区域1-右上 mrnBkgBlks[1] = mrnBkgBlks[0]; mrnBkgBlks[1].minX = mrnObj.maxX + 1; mrnBkgBlks[1].maxX = mrnBkg.maxX; //背景区域2-右 mrnBkgBlks[2] = mrnObj; mrnBkgBlks[2].minX = mrnBkgBlks[1].minX; mrnBkgBlks[2].maxX = mrnBkgBlks[1].maxX; //背景区域3-右下 mrnBkgBlks[3] = mrnBkgBlks[2]; mrnBkgBlks[3].minY = mrnObj.maxY + 1; mrnBkgBlks[3].maxY = mrnBkg.maxY; //背景区域4-下 mrnBkgBlks[4] = mrnObj; mrnBkgBlks[4].minY = mrnBkgBlks[3].minY; mrnBkgBlks[4].maxY = mrnBkgBlks[3].maxY; //背景区域5-左下 mrnBkgBlks[5] = mrnBkgBlks[4]; mrnBkgBlks[5].minX = mrnBkg.minX; mrnBkgBlks[5].maxX = mrnObj.minX - 1; #if 0 // 计算区域的左上角坐标 int minX = mrnBkgBlks[5].minX; int minY = mrnBkgBlks[5].minY; // 计算扣取区域的宽度和高度 int width = mrnBkgBlks[5].maxX - mrnBkgBlks[5].minX; int height = mrnBkgBlks[5].maxY - mrnBkgBlks[5].minY; // 计算扣取区域在原始图像中的偏移量 int offset = minY * nWidth + minX; // 构造 cv::Mat 对象 cv::Mat region5(height, width, CV_8UC1); for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { region5.at(i, j) = ((UBYTE8*)img.u64VirAddr[0])[(i + minY) * nWidth + minX + j]; } } #endif //背景区域6-左 mrnBkgBlks[6] = mrnObj; mrnBkgBlks[6].minX = mrnBkgBlks[5].minX; mrnBkgBlks[6].maxX = mrnBkgBlks[5].maxX; //背景区域7-左上 mrnBkgBlks[7] = mrnBkgBlks[6]; mrnBkgBlks[7].minY = mrnBkgBlks[0].minY; mrnBkgBlks[7].maxY = mrnBkgBlks[0].maxY; //遍历每个背景分块,抛掉最大值、最小值 for (k = 0; k < GLB_OBJ_BKG_NUM; k++) { //统计背景均值、方差 double dBlkMin = 1e6; double dBlkMax = 1e-6; nBGCnt = 0; dBGMean = 0; dBGStd = 0; nLineIndex = mrnBkgBlks[k].minY * nWidth; for (i = mrnBkgBlks[k].minY; i <= mrnBkgBlks[k].maxY; i++) { for (j = mrnBkgBlks[k].minX; j <= mrnBkgBlks[k].maxX; j++) { nIndex = nLineIndex + j; //nBGValue = pFrame[nIndex]; if (GD_PIXEL_FORMAT_GRAY_Y8 == img.enPixelFormat) { nBGValue = ((UBYTE8*)img.u64VirAddr[0])[nIndex]; } else { nBGValue = ((UINT16*)img.u64VirAddr[0])[nIndex]; } //背景灰度及灰度平方累加 dBGMean += (double)nBGValue; dBGStd += (double)nBGValue * nBGValue; nBGCnt++; dBlkMin = MIN(dBlkMin, nBGValue); dBlkMax = MAX(dBlkMax, nBGValue); } nLineIndex += nWidth; } //计算上背景均值、方差 nIndex = g_GLB_nObj8BkgArrayIndex * GLB_OBJ_BKG_NUM + k; dBGMean -= (dBlkMin + dBlkMax); dBGStd -= (dBlkMin * dBlkMin + dBlkMax * dBlkMax); nBGCnt -= 2; pdObj8BkgMeanArray[nIndex] = FLOAT32( dBGMean / (double)nBGCnt); pdObj8BkgStdArray[nIndex] = FLOAT32(dBGStd / (double)nBGCnt); pdObj8BkgStdArray[nIndex] -= pdObj8BkgMeanArray[nIndex] * pdObj8BkgMeanArray[nIndex]; } } //20170227,更新邻域背景是否异常状态,如分割不准确导致的方差异常 BKM_UpdateObjBkgStatus(pdObj8BkgStdArray); //BKM_UpdateObjBkgMean(pdObj8BkgMeanArray); //20170220,帧数累加 g_GLB_nObj8BkgFrames++; } /********************************************************** * 函数名称:BKM_AnalyzeBkg() * 功能描述:目标背景区域场景分析,过杆分析 * 输入参数:SPEED32F AngleSpeed -- 角速度 * DOUBLE64 bObjGrayMean -- 目标灰度均值 * DOUBLE64 *pdObj8BkgMeanArray-- 目标跟踪时8邻域背景监控均值 * DOUBLE64 *pdObj8BkgStdArray -- 目标跟踪时8邻域背景监控方差 * 输出参数:无 * 返 回 值:无 * 调用关系:无 * 其它说明:无 **********************************************************/ void BkgMonitor::BKM_AnalyzeBkg(GLB_INPUT* p_GLB_Input, FLOAT32 bObjGrayMean, FLOAT32 *pdObj8BkgMeanArray, FLOAT32 *pdObj8BkgStdArray, OBJECTSTATUS* pTrackStatus) { SINT32 i; SINT16 nValidCnt = 0; //判别有效性计数 BBOOL bJudgeBkgStd = false; //判别背景区域方差可转自动跟踪标志位 SINT32 nStdThreshold = 5000; //2500; //方差预警阈值 SINT32 nIndexCurrFrm = g_GLB_nObj8BkgArrayIndex * GLB_OBJ_BKG_NUM; //10 FLOAT32 fSpeedThresh = 0.0025f; //目标过杆判断速度阈值 20161216141048目标过杆速度为0.029 SPEED32F AngleSpeed = pTrackStatus->sfAglSpeed; //20170301,如果已经判断在过云,则不进行过杆判断,防止已经在过云过程中进此条件进记忆跟踪 //20170302,【屏蔽】过杆优先级更高 if (g_GLB_bComplexEnv) { return; } // 调整可见光的方差阈值 if (GLB_VIDEO_TYPE::GLB_VIDEO_VL == p_GLB_Input->unVideoSrc) { nStdThreshold = 500; } // 单帧分左右会受到预测不准确,目标特征的影响 FLOAT32 leftMean = (pdObj8BkgMeanArray[nIndexCurrFrm + 5] + pdObj8BkgMeanArray[nIndexCurrFrm + 6] + pdObj8BkgMeanArray[nIndexCurrFrm + 7]) / 3; FLOAT32 rightMean = (pdObj8BkgMeanArray[nIndexCurrFrm + 1] + pdObj8BkgMeanArray[nIndexCurrFrm + 2] + pdObj8BkgMeanArray[nIndexCurrFrm + 3]) / 3; //过杆判断 if (!g_GLB_bInterferenceMem) { //20170302,水平过杆 if (fabs(AngleSpeed.vx) > fabs(AngleSpeed.vy)) { //水平过杆方向判断 //20171207,过杆判断采用速度阈值,防止静止的目标判断为过杆 if(AngleSpeed.vx < -fSpeedThresh) { //目标向左运动,判断左侧三个邻域的均值和方差,若左+左上或左+左下的梯度值大于预警阈值 g_GLB_bInfrnDirection = GLB_INFRN_DIR_LEFT; //判断前方有杆,提前进记忆跟踪 if ((pdObj8BkgStdArray[nIndexCurrFrm + 7] > nStdThreshold && pdObj8BkgStdArray[nIndexCurrFrm + 6] > nStdThreshold) || (pdObj8BkgStdArray[nIndexCurrFrm + 6] > nStdThreshold && pdObj8BkgStdArray[nIndexCurrFrm + 5] > nStdThreshold)) { //置干扰进记忆跟踪标志为真 g_GLB_bInterferenceMem = true; } //单凭借方差在轮廓不清晰的背景,无法准确判断,需要结合背景灰度(默认可见光为暗目标) if (GLB_VIDEO_TYPE::GLB_VIDEO_VL == p_GLB_Input->unVideoSrc) { if (rightMean - leftMean > 20) { g_GLB_bInterferenceMem = true; } } else { } } //else //20171207,过杆判断采用速度阈值,防止静止的目标判断为过杆 if (AngleSpeed.vx > fSpeedThresh) { //目标向右运动,判断右侧三个邻域的均值和方差,若左+左上或左+左下的梯度值大于预警阈值 g_GLB_bInfrnDirection = GLB_INFRN_DIR_RIGHT; //判断前方有杆,提前进记忆跟踪 if ((pdObj8BkgStdArray[nIndexCurrFrm + 1] > nStdThreshold && pdObj8BkgStdArray[nIndexCurrFrm + 2] > nStdThreshold) || (pdObj8BkgStdArray[nIndexCurrFrm + 2] > nStdThreshold && pdObj8BkgStdArray[nIndexCurrFrm + 3] > nStdThreshold)) { //置干扰进记忆跟踪标志为真 g_GLB_bInterferenceMem = true; } //单凭借方差在轮廓不清晰的背景,无法准确判断,需要结合背景灰度(默认可见光为暗目标) if (GLB_VIDEO_TYPE::GLB_VIDEO_VL == p_GLB_Input->unVideoSrc) { if (leftMean - rightMean > 20) { g_GLB_bInterferenceMem = true; } } else { } } } // //不考虑垂直方向过杆,避免云层干扰 // else // { // //垂直方向判断 // if (AngleSpeed.vy < 0) // { // //目标向下运动,判断下侧三个邻域的均值和方差,若下+左下或下+右下的梯度值大于预警阈值 // //判断下方有杆,提前进记忆跟踪 // if ((pdObj8BkgStdArray[nIndexCurrFrm + 3] > nStdThreshold // && pdObj8BkgStdArray[nIndexCurrFrm + 4] > nStdThreshold) // || (pdObj8BkgStdArray[nIndexCurrFrm + 4] > nStdThreshold // && pdObj8BkgStdArray[nIndexCurrFrm + 5] > nStdThreshold)) // { // //置干扰进记忆跟踪标志为真 // g_GLB_bInterferenceMem = true; // g_GLB_bInfrnDirection = GLB_INFRN_DIR_DOWN; // } // } // else // { // //目标向上运动,判断下侧三个邻域的均值和方差,若上+左上或上+右上的梯度值大于预警阈值 // //判断上方有杆,提前进记忆跟踪 // if ((pdObj8BkgStdArray[nIndexCurrFrm + 7] > nStdThreshold // && pdObj8BkgStdArray[nIndexCurrFrm + 0] > nStdThreshold) // || (pdObj8BkgStdArray[nIndexCurrFrm + 0] > nStdThreshold // && pdObj8BkgStdArray[nIndexCurrFrm + 1] > nStdThreshold)) // { // //置干扰进记忆跟踪标志为真 // g_GLB_bInterferenceMem = true; // g_GLB_bInfrnDirection = GLB_INFRN_DIR_UP; // } // } // } } //解除干扰,置干扰进记忆跟踪标志为假 if (g_GLB_bInterferenceMem) { ////背景区域均值均小于目标均值,【这里考虑的是亮目标过杆】 //for (i = 0; i < GLB_OBJ_BKG_NUM; i++) //{ // if (bObjGrayMean > pdObj8BkgMeanArray[nIndexCurrFrm + i]) // { // nValidCnt++; // } //} if (GLB_INFRN_DIR_RIGHT == g_GLB_bInfrnDirection) { //水平运动时,目标的上三背景区域方差或者下三背景区域方差均小于阈值,即场景趋于平坦 if ((pdObj8BkgStdArray[nIndexCurrFrm + 0] < nStdThreshold && pdObj8BkgStdArray[nIndexCurrFrm + 1] < nStdThreshold) || (pdObj8BkgStdArray[nIndexCurrFrm + 4] < nStdThreshold && pdObj8BkgStdArray[nIndexCurrFrm + 3] < nStdThreshold)) { bJudgeBkgStd = true; } if (GLB_VIDEO_TYPE::GLB_VIDEO_VL == p_GLB_Input->unVideoSrc) { // 暗目标向右出遮挡区域 if (pdObj8BkgMeanArray[nIndexCurrFrm + 7] + 20 < pdObj8BkgMeanArray[nIndexCurrFrm + 1] || pdObj8BkgMeanArray[nIndexCurrFrm + 5] + 20 < pdObj8BkgMeanArray[nIndexCurrFrm + 3]) { bJudgeBkgMean = true; } } else { if (pdObj8BkgMeanArray[nIndexCurrFrm + 7] > pdObj8BkgMeanArray[nIndexCurrFrm + 1] + 100 || pdObj8BkgMeanArray[nIndexCurrFrm + 5] > pdObj8BkgMeanArray[nIndexCurrFrm + 3] + 100) { bJudgeBkgMean = true; } } } else if (GLB_INFRN_DIR_LEFT == g_GLB_bInfrnDirection) { //水平运动时,目标的上三背景区域方差或者下三背景区域方差均小于阈值,即场景趋于平坦 if ((pdObj8BkgStdArray[nIndexCurrFrm + 0] < nStdThreshold && pdObj8BkgStdArray[nIndexCurrFrm + 7] < nStdThreshold) || (pdObj8BkgStdArray[nIndexCurrFrm + 5] < nStdThreshold && pdObj8BkgStdArray[nIndexCurrFrm + 4] < nStdThreshold)) { bJudgeBkgStd = true; } if (GLB_VIDEO_TYPE::GLB_VIDEO_VL == p_GLB_Input->unVideoSrc) { if (pdObj8BkgMeanArray[nIndexCurrFrm + 7] > pdObj8BkgMeanArray[nIndexCurrFrm + 1] + 20 || pdObj8BkgMeanArray[nIndexCurrFrm + 5] > pdObj8BkgMeanArray[nIndexCurrFrm + 3] + 20) { bJudgeBkgMean = true; } } else { if (pdObj8BkgMeanArray[nIndexCurrFrm + 7] + 100 < pdObj8BkgMeanArray[nIndexCurrFrm + 1] || pdObj8BkgMeanArray[nIndexCurrFrm + 5] + 100 < pdObj8BkgMeanArray[nIndexCurrFrm + 3]) { bJudgeBkgMean = true; } } } //20170414,暂不判断垂直运动 // else if (GLB_INFRN_DIR_DOWN == g_GLB_bInfrnDirection || GLB_INFRN_DIR_UP == g_GLB_bInfrnDirection) // { // //垂直运动时,目标的左三背景区域方差或者右三背景区域方差均小于阈值,即场景趋于平坦 // if ((pdObj8BkgStdArray[nIndexCurrFrm + 5] < nStdThreshold // && pdObj8BkgStdArray[nIndexCurrFrm + 6] < nStdThreshold // && pdObj8BkgStdArray[nIndexCurrFrm + 7] < nStdThreshold) // || (pdObj8BkgStdArray[nIndexCurrFrm + 3] < nStdThreshold // && pdObj8BkgStdArray[nIndexCurrFrm + 2] < nStdThreshold // && pdObj8BkgStdArray[nIndexCurrFrm + 1] < nStdThreshold)) // { // //除了考虑目标左右背景之外,上下背景方差用来区别进入干扰和退出干扰 // if (pdObj8BkgStdArray[nIndexCurrFrm + 0] < nStdThreshold // && pdObj8BkgStdArray[nIndexCurrFrm + 4] < nStdThreshold) // { // bJudgeBkgStd = true; // } // } // } else { //暂不处理 } //20170914,wsa,对20161201_170642_2进行测试发现6400帧过杆时,由于面目标偏离预测位置一点点,导致计算 //出来的背景(包含真实目标区域)方差并不是很准,不满足方差条件导致无法退出干扰,改进时加入相似度判别 //若均值和方差条件均满足可转自动跟踪情况,置标志位为假 if (bJudgeBkgMean && bJudgeBkgStd || pTrackStatus->unContiLostCnt > p_GLB_Input->unFreq * 3) { g_GLB_nExitInfrnMemCnt++; if (g_GLB_nExitInfrnMemCnt > GLB_EXIT_INFRN_MEM_CNT) { g_GLB_bInterferenceMem = false; bJudgeBkgMean = false; g_GLB_nExitInfrnMemCnt = 0; g_GLB_bInfrnDirection = GLB_INFRN_DIR_NONE; } } else { g_GLB_nExitInfrnMemCnt = 0; //g_GLB_bInfrnDirection = GLB_INFRN_DIR_NONE; } } } /********************************************************** * 函数名称:BKM_UpdateObjBkgStatus() * 功能描述:更新邻域背景是否异常状态,如分割不准确导致的方差异常 * 输入参数:FLOAT32 *pdObj8BkgStdArray -- 目标跟踪时8邻域背景监控方差 * 输出参数:无 * 返 回 值:无 * 调用关系:无 * 其它说明:无 **********************************************************/ void BkgMonitor::BKM_UpdateObjBkgStatus(FLOAT32 *pdObj8BkgStdArray) { FLOAT32 ardMeanOf8BkgStd[GLB_OBJ_BKG_FRM_NUM] = {0.0}; //方差的均值,10帧 SINT32 i, j; SINT32 nAbnormalCnt = 0; //异常帧计数器 FLOAT32 dBGMean = 0.0; //均值 FLOAT32 dBGValue = 0.0; //当前值 FLOAT32 dAbnormalStdThres = 2000; //超过阈值2000直接视为异常 //20170301,如果已经判断在过杆,则不进行过杆云判断,过杆优先级更高 if (g_GLB_bInterferenceMem) { return; } //若不满10帧不进行变化趋势计算 if (g_GLB_nObj8BkgFrames < GLB_OBJ_BKG_FRM_NUM - 1) { return; } //计算最近10帧背景方差的均值 //MSSu, 20170307: 此处重复计算。可在每帧保存背景块方差时,直接计算好 for (j = 0; j < GLB_OBJ_BKG_FRM_NUM; j++) { dBGMean = 0.0; //遍历每帧记录 for (i = 0; i < GLB_OBJ_BKG_NUM; i++) { //当前值,求和 dBGValue = pdObj8BkgStdArray[j * GLB_OBJ_BKG_NUM + i]; dBGMean += (FLOAT32)dBGValue; } ardMeanOf8BkgStd[j] = dBGMean / GLB_OBJ_BKG_NUM; } //分别比较8块邻域和背景方差的差异,找出异常背景块 for (i = 0; i < GLB_OBJ_BKG_NUM; i++) { nAbnormalCnt = 0; for (j = 0; j < GLB_OBJ_BKG_FRM_NUM; j++) { if (pdObj8BkgStdArray[j * GLB_OBJ_BKG_NUM + i] > 1.5 * ardMeanOf8BkgStd[j]) { nAbnormalCnt++; } } //10帧的异常帧数超过5帧且大于阈值则认为该背景块异常 if (nAbnormalCnt > 0.5 * GLB_OBJ_BKG_FRM_NUM || pdObj8BkgStdArray[g_GLB_nObj8BkgArrayIndex * GLB_OBJ_BKG_NUM + i] > dAbnormalStdThres) { g_GLB_bObj8BkgStatus[i] = GLB_OBJ_BKG_STD_ABNORMAL; } else { g_GLB_bObj8BkgStatus[i] = GLB_OBJ_BKG_STD_NORMAL; } } //// 判断接近强边缘,此时异常块大概率呈现一边倒趋势,至少出现连续3个true //for (SINT32 i = 0; i < GLB_OBJ_BKG_NUM; i++) //{ // SINT32 BLK1 = i; // SINT32 BLK2 = (i + 1) % GLB_OBJ_BKG_NUM; // SINT32 BLK3 = (i + 2) % GLB_OBJ_BKG_NUM; // if (g_GLB_bObj8BkgStatus[BLK1] + g_GLB_bObj8BkgStatus[BLK2] + g_GLB_bObj8BkgStatus[BLK3] == 3) // { // int a = 0; // } //} //20170228,若背景环境复杂,如鱼鳞状云,8邻域区域有一半方差异常,不进行合并 SINT16 nAbnormalBlkCnt = 0; //异常背景块计数 //统计异常背景块个数 for (i = 0; i < GLB_OBJ_BKG_NUM; i++) { if (g_GLB_bObj8BkgStatus[i]) { nAbnormalBlkCnt++; } } //更新复杂场景标志位及退出复杂场景帧计数 if (nAbnormalBlkCnt > GLB_OBJ_BKG_NUM / 2 - 1) { //退出复杂场景帧数清零 g_GLB_nExitComplexEnv = 0; //进入复杂场景第一帧,复杂场景标志位置为真 if (!g_GLB_bComplexEnv) { g_GLB_bComplexEnv = true; } ////人工调整一次分割阈值,保证目标与背景的区分度 //if (g_DAT_stPara.nGrayThresMinBright < DAT_GRAY_THRES_MAX) //{ // g_DAT_stPara.nGrayThresMinBright = (g_DAT_stPara.nGrayThresMinBright + DAT_GRAY_THRES_MAX) / 2; //} //if (g_DAT_stPara.nGrayThresMinDark < DAT_GRAY_THRES_MAX) //{ // g_DAT_stPara.nGrayThresMinDark = (g_DAT_stPara.nGrayThresMinDark + DAT_GRAY_THRES_MAX) / 2; //} //if (g_DAT_stPara.nGradThresMin < DAT_GRAD_THRES_MAX) //{ // g_DAT_stPara.nGradThresMin = (g_DAT_stPara.nGradThresMin + DAT_GRAD_THRES_MAX) / 2; //} } else { //累计退出复杂场景帧计数 g_GLB_nExitComplexEnv++; //若帧计数超过阈值,则异常环境标志位置为假 if (g_GLB_nExitComplexEnv > GLB_EXIT_CMPLX_ENV_CNT && g_GLB_bComplexEnv) { g_GLB_bComplexEnv = false; ////人工调整一次分割阈值,保证目标分割的完整性 //if (g_DAT_stPara.nGrayThresMinBright > DAT_GRAY_THRES_MIN) //{ // g_DAT_stPara.nGrayThresMinBright = DAT_GRAY_THRES_MIN; //} //if (g_DAT_stPara.nGrayThresMinDark > DAT_GRAY_THRES_MIN) //{ // g_DAT_stPara.nGrayThresMinDark = DAT_GRAY_THRES_MIN; //} //if (g_DAT_stPara.nGradThresMin > DAT_GRAD_THRES_MIN) //{ // g_DAT_stPara.nGradThresMin = DAT_GRAD_THRES_MIN; //} } } } void BkgMonitor::BKM_UpdateObjBkgMean(FLOAT32* pdObj8BkgMeanArray) { FLOAT32 ardMeanOf8BkgGray[GLB_OBJ_BKG_NUM] = { 0.0 }; //灰度的均值,8个方向 SINT32 i, j; SINT32 nAbnormalCnt = 0; //异常帧计数器 FLOAT32 dBGMean = 0.0; //均值 FLOAT32 dBGValue = 0.0; //当前值 FLOAT32 dAbnormalStdThres = 2000; //超过阈值2000直接视为异常 ////20170301,如果已经判断在过杆,则不进行过杆云判断,过杆优先级更高 //if (g_GLB_bInterferenceMem) //{ // return; //} //若不满10帧不进行变化趋势计算 if (g_GLB_nObj8BkgFrames < GLB_OBJ_BKG_FRM_NUM - 1) { return; } //每个块计算连续10帧灰度的均值 for (i = 0; i < GLB_OBJ_BKG_NUM; i++) { dBGMean = 0.0; for (j = 0; j < GLB_OBJ_BKG_FRM_NUM; j++) { dBGValue = pdObj8BkgMeanArray[i + j * GLB_OBJ_BKG_FRM_NUM]; dBGMean += (FLOAT32)dBGValue; } ardMeanOf8BkgGray[i] = dBGMean / GLB_OBJ_BKG_FRM_NUM; } ////分别比较8块邻域和背景方差的差异,找出异常背景块 //for (i = 0; i < GLB_OBJ_BKG_NUM; i++) //{ // nAbnormalCnt = 0; // for (j = 0; j < GLB_OBJ_BKG_FRM_NUM; j++) // { // if (pdObj8BkgStdArray[j * GLB_OBJ_BKG_NUM + i] > 1.5 * ardMeanOf8BkgStd[j]) // { // nAbnormalCnt++; // } // } // //10帧的异常帧数超过5帧且大于阈值则认为该背景块异常 // if (nAbnormalCnt > 0.5 * GLB_OBJ_BKG_FRM_NUM // || pdObj8BkgStdArray[g_GLB_nObj8BkgArrayIndex * GLB_OBJ_BKG_NUM + i] > dAbnormalStdThres) // { // g_GLB_bObj8BkgStatus[i] = GLB_OBJ_BKG_STD_ABNORMAL; // } // else // { // g_GLB_bObj8BkgStatus[i] = GLB_OBJ_BKG_STD_NORMAL; // } //} ////20170228,若背景环境复杂,如鱼鳞状云,8邻域区域有一半方差异常,不进行合并 //SINT16 nAbnormalBlkCnt = 0; //异常背景块计数 ////统计异常背景块个数 //for (i = 0; i < GLB_OBJ_BKG_NUM; i++) //{ // if (g_GLB_bObj8BkgStatus[i]) // { // nAbnormalBlkCnt++; // } //} ////更新复杂场景标志位及退出复杂场景帧计数 //if (nAbnormalBlkCnt > GLB_OBJ_BKG_NUM / 2 - 1) //{ // //退出复杂场景帧数清零 // g_GLB_nExitComplexEnv = 0; // //进入复杂场景第一帧,复杂场景标志位置为真 // if (!g_GLB_bComplexEnv) // { // g_GLB_bComplexEnv = true; // } //} //else //{ // //累计退出复杂场景帧计数 // g_GLB_nExitComplexEnv++; // //若帧计数超过阈值,则异常环境标志位置为假 // if (g_GLB_nExitComplexEnv > GLB_EXIT_CMPLX_ENV_CNT && g_GLB_bComplexEnv) // { // g_GLB_bComplexEnv = false; // } //} } /********************************************************** * 函数名称:BKM_MergeMultiTarget() * 功能描述:合并目标数组中重合的面目标 * 输入参数:TARGET_OBJECT *ptTargetArray-- 单帧目标数组 * SINT32 nObjsCnt -- 单帧目标数组中的目标个数 * 输出参数:TARGET_OBJECT *ptTargetArray-- 目标合并后的目标数组 * 返 回 值:nTargetNum -- 目标合并后的目标数目 * 调用关系: * 其它说明: **********************************************************/ //SINT16 BKM_MergeMultiTarget(TARGET_OBJECT *ptTargetArray, SINT32 nObjsCnt) //{ // SINT32 i = 0; // SINT32 j = 0; // SINT32 k = 0; // TARGET_OBJECT *ptOtherTarget = NULL; // TARGET_OBJECT *ptCurrentTarget = NULL; // //SINT32 nXDistance = 0; // //SINT32 nYDistance = 0; // SINT16 nDist = 0; //两个目标框间的最小距离 // SINT16 nMinDistThres = 2 * g_DAT_stPara.nDSmpScale; //合并的最小距离阈值【DSP移植注意B核g_DAT_stPara.nDSmpScale的赋值】 // SINT32 nDeltetID = 0; //待删除目标下标 // // //初始化多目标合并标志 // g_GLB_bMultiObjMerge = false; // // //仅一个目标或者无最优管道目标直接返回 // if (nObjsCnt < 2) // { // return nObjsCnt; // } // // for (i = 0; i < nObjsCnt - 1; i++) // { // //候选目标 // ptCurrentTarget = &ptTargetArray[i]; // // for (j = i + 1; j < nObjsCnt; j++) // { // //待合并目标 // ptOtherTarget = &ptTargetArray[j]; // // //计算两个目标框间的最小距离 // nDist = IMGO_CalcDistOfTwoRect(ptCurrentTarget->mrnRect, ptOtherTarget->mrnRect); // // //距离大于阈值不合并 // if (nDist > nMinDistThres) // { // continue; // } // else // { // //更新多目标合并标志位 // g_GLB_bMultiObjMerge = true; // // //更新合并后的目标信息,包括目标矩形,中心点坐标,尺寸和像素点个数,【灰度值和目标类型暂未更新】 // ptCurrentTarget->mrnRect.minX = MIN(ptCurrentTarget->mrnRect.minX, ptOtherTarget->mrnRect.minX); // ptCurrentTarget->mrnRect.minY = MIN(ptCurrentTarget->mrnRect.minY, ptOtherTarget->mrnRect.minY); // ptCurrentTarget->mrnRect.maxX = MAX(ptCurrentTarget->mrnRect.maxX, ptOtherTarget->mrnRect.maxX); // ptCurrentTarget->mrnRect.maxY = MAX(ptCurrentTarget->mrnRect.maxY, ptOtherTarget->mrnRect.maxY); // ptCurrentTarget->pfCenPos.x = (FLOAT32)(ptCurrentTarget->mrnRect.minX + ptCurrentTarget->mrnRect.maxX) / 2.0f; // ptCurrentTarget->pfCenPos.y = (FLOAT32)(ptCurrentTarget->mrnRect.minY + ptCurrentTarget->mrnRect.maxY) / 2.0f; // ptCurrentTarget->snSize.w = ptCurrentTarget->mrnRect.maxX - ptCurrentTarget->mrnRect.minX + 1; // ptCurrentTarget->snSize.h = ptCurrentTarget->mrnRect.maxY - ptCurrentTarget->mrnRect.minY + 1; // ptCurrentTarget->snSize.s = ptCurrentTarget->snSize.w * ptCurrentTarget->snSize.h; // ptCurrentTarget->unObjPxlsCnt = ptCurrentTarget->unObjPxlsCnt + ptOtherTarget->unObjPxlsCnt; // // //删除被合并的目标 // for (k = j + 1; k < nObjsCnt; k++) // { // ptTargetArray[k-1] = ptTargetArray[k]; // } // memset(&ptTargetArray[nObjsCnt-1], 0, sizeof(TARGET_OBJECT)); // nObjsCnt--; // i--; // break; // } // } // } // // return nObjsCnt; //} // /********************************************************** * 函数名称:BKM_MultiObjMonitor() * 功能描述:多目标监控,监控待跟踪目标周围是否存在相邻的目标 * 输入参数:BYTE8 bTargetIndex -- 目标编号 * TARGET_OBJECT *ptTargetArray-- 单帧目标数组 * SINT32 nObjsCnt -- 目标个数 * 输出参数:无 * 返 回 值:BBOOL bMultiObj -- 是否多目标(一个目标被分割成多个) * 调用关系:无 * 其它说明:无 **********************************************************/ //BBOOL BKM_MultiObjMonitor(BYTE8 bTargetIndex, TARGET_OBJECT *ptTargetArray, SINT32 nObjsCnt) //{ // BBOOL bMultiObj = false; // SINT32 i = 0; // SINT32 nNonNeighborObjCnt = 0; //不相邻目标计数器 // TARGET_OBJECT *ptOtherTarget = NULL; // TARGET_OBJECT *ptPipeTarget = NULL; // SINT16 nDist = 0; //两个目标框间的最小距离 // SINT16 nMinDistThres = 3; //合并的最小距离阈值 // // //仅一个目标或者无最优管道目标直接返回 // if (nObjsCnt < 2 || -1 == bTargetIndex) // { // //清零帧数并返回 // g_GLB_nMultiObjCnt = 0; // return bMultiObj; // } // // //候选管道目标 // ptPipeTarget = &ptTargetArray[bTargetIndex]; // // for (i = 0; i < nObjsCnt; i++) // { // //跳过候选目标 // if (i == bTargetIndex) // { // continue; // } // // ptOtherTarget = &ptTargetArray[i]; // // //计算两个目标框间的最小距离 // nDist = IMGO_CalcDistOfTwoRect(ptPipeTarget->mrnRect, ptOtherTarget->mrnRect); // // //距离大于阈值不合并 // if (nDist > nMinDistThres) // { // nNonNeighborObjCnt++; // continue; // } // else // { // //20170302,累加多目标帧数,这里仅存在距离小于阈值的目标时认为是多目标 // g_GLB_nMultiObjCnt++; // if (g_GLB_nMultiObjCnt > GLB_MULTI_OBJ_MAX_CNT) // { // bMultiObj = true; // } // break; // } // } // // //如果均为不相邻目标,则视为多目标为假,帧数清零 // if (nNonNeighborObjCnt == nObjsCnt - 1) // { // g_GLB_nMultiObjCnt = 0; // } // // return bMultiObj; //}