|
|
|
|
|
/*********版权所有(C)2017,武汉高德红外股份有限公司***************
|
|
|
|
|
|
* 文件名称:Arith_DetectAreaObj.h
|
|
|
|
|
|
* 文件标识:面目标检测
|
|
|
|
|
|
* 内容摘要:基于灰度特征+梯度特征+Ostu阈值分割的面目标检测
|
|
|
|
|
|
* 其它说明:"DetectAreaObj"的函数、全局变量、宏定义,统一前缀为简写"DAT"。
|
|
|
|
|
|
* 当前版本:《面目标检测标准化V1.0》
|
|
|
|
|
|
* 创建作者:zy
|
|
|
|
|
|
* 创建日期:2017.11.13
|
|
|
|
|
|
*******************************************************************/
|
|
|
|
|
|
#include "Arith_DetectAreaObj.h"
|
|
|
|
|
|
#include "Arith_ImgOperate.h"
|
|
|
|
|
|
#include "Arith_DetectAreaObj.h"
|
|
|
|
|
|
#include "API_DetectSAObj.h"
|
|
|
|
|
|
//#include "../Version.h"
|
|
|
|
|
|
#include "opencv2/opencv.hpp"
|
|
|
|
|
|
|
|
|
|
|
|
API_DetectAreaObj * API_DetectAreaObj::Create(SINT32 nWidth, SINT32 nHeight)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new DetectAreaObj(nWidth,nHeight);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
API_DetectAreaObj * API_DetectAreaObj::Create(SINT32 nWidth, SINT32 nHeight, CENTERRECT mmCenterRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new DetectAreaObj(nWidth,nHeight,mmCenterRect);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void API_DetectAreaObj::Destroy(API_DetectAreaObj * obj)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TARGET_OBJECT CreateNewTarget(GD_VIDEO_FRAME_S img, SINT32 nWidth, SINT32 nHeight, RECT32S bbox, SINT32 unFrmId)
|
|
|
|
|
|
{
|
|
|
|
|
|
MINMAXRECT32S mrnObjRect;
|
|
|
|
|
|
OBJECTSNR objSNR;
|
|
|
|
|
|
TARGET_OBJECT tNewTarget = { 0 };
|
|
|
|
|
|
TARGET_OBJECT* pNewTarget = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
POINT32F ptfObjPos = { 0 };
|
|
|
|
|
|
ptfObjPos.x = FLOAT32(bbox.x + bbox.w / 2);
|
|
|
|
|
|
ptfObjPos.y = FLOAT32(bbox.y + bbox.h / 2);
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算目标边界矩形
|
|
|
|
|
|
mrnObjRect.minY = MAX(0, MIN((SINT32)(bbox.y), nHeight - 1));
|
|
|
|
|
|
mrnObjRect.maxY = MAX(0, MIN((SINT32)(bbox.y + bbox.h), nHeight - 1));
|
|
|
|
|
|
mrnObjRect.minX = MAX(0, MIN((SINT32)(bbox.x), nWidth - 1));
|
|
|
|
|
|
mrnObjRect.maxX = MAX(0, MIN((SINT32)(bbox.x + bbox.w), nWidth - 1));
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//新建目标
|
|
|
|
|
|
memset(&tNewTarget, 0, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
tNewTarget.bObject = true;
|
|
|
|
|
|
tNewTarget.unFrmID = unFrmId;
|
|
|
|
|
|
tNewTarget.pfCenPos = ptfObjPos;
|
|
|
|
|
|
tNewTarget.pnMaxPos.x = (SINT16)(ptfObjPos.x);
|
|
|
|
|
|
tNewTarget.pnMaxPos.y = (SINT16)(ptfObjPos.y);
|
|
|
|
|
|
tNewTarget.mrnRect.minY = (SINT16)(mrnObjRect.minY);
|
|
|
|
|
|
tNewTarget.mrnRect.maxY = (SINT16)(mrnObjRect.maxY);
|
|
|
|
|
|
tNewTarget.mrnRect.minX = (SINT16)(mrnObjRect.minX);
|
|
|
|
|
|
tNewTarget.mrnRect.maxX = (SINT16)(mrnObjRect.maxX);
|
|
|
|
|
|
tNewTarget.snSize.w = (SINT16)(bbox.w);
|
|
|
|
|
|
tNewTarget.snSize.h = (SINT16)(bbox.h);
|
|
|
|
|
|
tNewTarget.snSize.s = (SINT32)(bbox.w * bbox.h);
|
|
|
|
|
|
tNewTarget.unObjPxlsCnt = (SINT32)(tNewTarget.snSize.s);
|
|
|
|
|
|
|
|
|
|
|
|
//计算目标的背景均值、背景标准差、SNR
|
|
|
|
|
|
memset(&objSNR, 0, sizeof(OBJECTSNR));
|
|
|
|
|
|
DAT_CalRectObjSNR_IMG(img, nWidth, nHeight, mrnObjRect, 3, &objSNR, DAT_DETECT_OBJ_TYPE_ALL);
|
|
|
|
|
|
tNewTarget.pxObjGray = (UINT16)objSNR.ObjGray;
|
|
|
|
|
|
tNewTarget.nObjTypeSize = GLB_OBJ_SIZE_FACE;
|
|
|
|
|
|
tNewTarget.nObjTypeGray = objSNR.fSNR > 0.0f ? GLB_OBJ_GRAY_BRIGHT : GLB_OBJ_GRAY_DARK;
|
|
|
|
|
|
tNewTarget.fBGMean = objSNR.BGMean;
|
|
|
|
|
|
tNewTarget.fBGStd = objSNR.BGStd;
|
|
|
|
|
|
tNewTarget.fSNR = objSNR.fSNR;
|
|
|
|
|
|
|
|
|
|
|
|
return tNewTarget;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DetectAreaObj::DetectAreaObj(int nWidth, int nHeight)
|
|
|
|
|
|
{
|
|
|
|
|
|
DAT_pxDetectArea = NULL;
|
|
|
|
|
|
DAT_pnMagArry = NULL;
|
|
|
|
|
|
DAT_pFlagHasSearch = NULL;
|
|
|
|
|
|
DAT_fGradX = NULL;
|
|
|
|
|
|
DAT_fGradY = NULL;
|
|
|
|
|
|
DAT_pxDetectAreaIntegral = NULL;
|
|
|
|
|
|
DAT_pBinary_Mag = NULL;
|
|
|
|
|
|
DAT_pBinary_Gray = NULL;
|
|
|
|
|
|
DAT_pBinary_GrayNew = NULL;
|
|
|
|
|
|
DAT_DIFF = NULL;
|
|
|
|
|
|
DAT_pxDetectAreaGradIntegral = NULL;
|
|
|
|
|
|
m_DAT_bInitialize = FALSE;
|
|
|
|
|
|
m_FrmObjsCnt = 0;
|
|
|
|
|
|
|
|
|
|
|
|
CENTERRECT mmCenterRect;
|
|
|
|
|
|
mmCenterRect.cx = nWidth / 2;
|
|
|
|
|
|
mmCenterRect.cy = nHeight / 2;
|
|
|
|
|
|
mmCenterRect.w = nWidth;
|
|
|
|
|
|
mmCenterRect.h = nHeight;
|
|
|
|
|
|
mmCenterRect.s = nWidth * nHeight;
|
|
|
|
|
|
Init(nWidth, nHeight, mmCenterRect);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DetectAreaObj::DetectAreaObj(int nWidth, int nHeight, CENTERRECT mmCenterRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
DAT_pxDetectArea = NULL;
|
|
|
|
|
|
DAT_pnMagArry = NULL;
|
|
|
|
|
|
DAT_pFlagHasSearch = NULL;
|
|
|
|
|
|
DAT_fGradX = NULL;
|
|
|
|
|
|
DAT_fGradY = NULL;
|
|
|
|
|
|
DAT_pxDetectAreaIntegral = NULL;
|
|
|
|
|
|
DAT_pBinary_Mag = NULL;
|
|
|
|
|
|
DAT_pBinary_Gray = NULL;
|
|
|
|
|
|
DAT_pBinary_GrayNew = NULL;
|
|
|
|
|
|
DAT_DIFF = NULL;
|
|
|
|
|
|
DAT_pxDetectAreaGradIntegral = NULL;
|
|
|
|
|
|
m_DAT_bInitialize = FALSE;
|
|
|
|
|
|
m_FrmObjsCnt = 0;
|
|
|
|
|
|
Init(nWidth, nHeight, mmCenterRect);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DetectAreaObj::~DetectAreaObj()
|
|
|
|
|
|
{
|
|
|
|
|
|
DAT_ReleaseMemory();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DetectAreaObj::Init(SINT32 nWidth, SINT32 nHeight, CENTERRECT mmCenterRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
DAT_Initialization(nWidth, nHeight, mmCenterRect);
|
|
|
|
|
|
m_FrmObjsCnt = 0;
|
|
|
|
|
|
bEnableAreaObjDetect = true;
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int DetectAreaObj::GetAreaSegInfo(GD_VIDEO_FRAME_S img, CENTERRECT mmCenterRect, GLB_STATUS nStatus, PixcelsCnt *pCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
int landsNum = DAT_ObjectAreaSeg(img, mmCenterRect, nStatus, pCnt);
|
|
|
|
|
|
return landsNum;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int DetectAreaObj::Detect(GD_VIDEO_FRAME_S img, CENTERRECT mmCenterRect, SINT32 nObjCombineDist, GLB_STATUS nStatus)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!bEnableAreaObjDetect)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_FrmObjsCnt = 0;
|
|
|
|
|
|
return ERR_UNInit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (GLB_STATUS::GLB_STATUS_TRACK == nStatus)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (0 == nObjCombineDist)
|
|
|
|
|
|
{
|
|
|
|
|
|
nObjCombineDist = m_DAT_stPara.nObjCombineDist;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
nObjCombineDist = m_DAT_stPara.nObjCombineDist;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_DAT_stInput.crnSrRect = mmCenterRect;
|
|
|
|
|
|
|
|
|
|
|
|
m_FrmObjsCnt = DAT_DetectAreaTarget(img, nStatus, nObjCombineDist);
|
|
|
|
|
|
|
|
|
|
|
|
return m_FrmObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TARGET_OBJECT* DetectAreaObj::GetTargetArray()
|
|
|
|
|
|
{
|
|
|
|
|
|
return DAT_Target;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OBJECTSTATUS* DetectAreaObj::GetTargetMatched()
|
|
|
|
|
|
{
|
|
|
|
|
|
return &m_DatTrkTarget;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 DetectAreaObj::GetTargetNum()
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_FrmObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DetectAreaObj::SetTargetNum(SINT32 num)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_FrmObjsCnt = num;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BBOOL DetectAreaObj::getDatDetState()
|
|
|
|
|
|
{
|
|
|
|
|
|
return bEnableAreaObjDetect;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DetectAreaObj::setDatDetState(BBOOL bEnableState)
|
|
|
|
|
|
{
|
|
|
|
|
|
bEnableAreaObjDetect = bEnableState;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DAT_PARAMETERS* DetectAreaObj::GetDatParm()
|
|
|
|
|
|
{
|
|
|
|
|
|
return &m_DAT_stPara;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DAT_OUTPUT* DetectAreaObj::getDAT_stOutput()
|
|
|
|
|
|
{
|
|
|
|
|
|
return &m_DAT_stOutput;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DetectAreaObj::setDatParm(Param_SkyDetect* param)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nDetectGrayType = param->nDetectGrayType;
|
|
|
|
|
|
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinBright = param->nGrayThresMinBright;
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinDark = param->nGrayThresMinDark;
|
|
|
|
|
|
m_DAT_stPara.nGradThresMin = param->fAreaDetectGradDiffThre;
|
|
|
|
|
|
m_DAT_stPara.nDSmpScale = param->nDSmpScale;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DAT_INPUT* DetectAreaObj::getDatInput()
|
|
|
|
|
|
{
|
|
|
|
|
|
return &m_DAT_stInput;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DetectAreaObj::DAT_MallocMemory(SINT32 nWidth, SINT32 nHeight, CENTERRECT mmCenterRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
DAT_ReleaseMemory();
|
|
|
|
|
|
// 处理尺寸,控制默认大小,并波门自适应时考虑该大小
|
|
|
|
|
|
DAT_CENTER_REGION_SIZE = DAT_SEARCH_RGN_H * DAT_SEARCH_RGN_W;
|
|
|
|
|
|
DAT_pxDetectArea = new UINT16[DAT_CENTER_REGION_SIZE];
|
|
|
|
|
|
DAT_pnMagArry = new UINT16[DAT_CENTER_REGION_SIZE];
|
|
|
|
|
|
DAT_pFlagHasSearch = new UBYTE8[DAT_CENTER_REGION_SIZE];
|
|
|
|
|
|
DAT_fGradX = new SINT16[DAT_TARGET_PXLS_MAX];
|
|
|
|
|
|
DAT_fGradY = new SINT16[DAT_TARGET_PXLS_MAX];
|
|
|
|
|
|
DAT_pxDetectAreaIntegral = new SINT32[DAT_CENTER_REGION_SIZE];
|
|
|
|
|
|
DAT_pBinary_Mag = new UBYTE8[DAT_CENTER_REGION_SIZE];
|
|
|
|
|
|
DAT_pBinary_Gray = new UBYTE8[DAT_CENTER_REGION_SIZE];
|
|
|
|
|
|
DAT_pBinary_GrayNew = new UBYTE8[DAT_CENTER_REGION_SIZE];
|
|
|
|
|
|
DAT_DIFF = new SINT32[DAT_CENTER_REGION_SIZE];
|
|
|
|
|
|
DAT_pxDetectAreaGradIntegral = new SINT32[DAT_CENTER_REGION_SIZE];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DetectAreaObj::DAT_ReleaseMemory()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DAT_pxDetectArea)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_pxDetectArea;
|
|
|
|
|
|
DAT_pxDetectArea = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (DAT_pnMagArry)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_pnMagArry;
|
|
|
|
|
|
DAT_pnMagArry = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (DAT_pFlagHasSearch)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_pFlagHasSearch;
|
|
|
|
|
|
DAT_pFlagHasSearch = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (DAT_fGradX)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_fGradX;
|
|
|
|
|
|
DAT_fGradX = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (DAT_fGradY)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_fGradY;
|
|
|
|
|
|
DAT_fGradY = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (DAT_pxDetectAreaIntegral)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_pxDetectAreaIntegral;
|
|
|
|
|
|
DAT_pxDetectAreaIntegral = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (DAT_pBinary_Mag)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_pBinary_Mag;
|
|
|
|
|
|
DAT_pBinary_Mag = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (DAT_pBinary_Gray)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_pBinary_Gray;
|
|
|
|
|
|
DAT_pBinary_Gray = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (DAT_pBinary_GrayNew)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_pBinary_GrayNew;
|
|
|
|
|
|
DAT_pBinary_GrayNew = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (DAT_DIFF)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_DIFF;
|
|
|
|
|
|
DAT_DIFF = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (DAT_pxDetectAreaGradIntegral)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] DAT_pxDetectAreaGradIntegral;
|
|
|
|
|
|
DAT_pxDetectAreaGradIntegral = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cv::Mat Array2Mat_uchar(const unsigned char* array, int cols, int rows)
|
|
|
|
|
|
{
|
|
|
|
|
|
cv::Mat img(rows, cols, CV_8UC1);
|
|
|
|
|
|
for (int i = 0; i < rows; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int j = 0; j < cols; ++j)
|
|
|
|
|
|
{
|
|
|
|
|
|
img.at<uchar>(i, j) = array[i * cols + j];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return img;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_DetectAreaTarget()
|
|
|
|
|
|
* 功能描述:基于区域连通的面目标检测
|
|
|
|
|
|
* 输入参数:UINT16 *pSrc -- 原始图像
|
|
|
|
|
|
* SINT32 nWidth -- 图像宽度
|
|
|
|
|
|
* SINT32 nHeight -- 图像高度
|
|
|
|
|
|
* GLB_STATUS nStatus -- 标识当前检测算法的用途(搜索的检测、跟踪的检测)
|
|
|
|
|
|
* 输出参数:无
|
|
|
|
|
|
* 返 回 值:SINT32 nObjsCnt -- 单帧检测的目标数量
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:根据目标大小,进行了3倍降采样操作,
|
|
|
|
|
|
可以根据实际需要修改是否进行降采样,并修改内存空间
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
SINT32 DetectAreaObj::DAT_DetectAreaTarget(GD_VIDEO_FRAME_S img, GLB_STATUS nStatus, SINT32 nObjCombineDist)
|
|
|
|
|
|
{
|
|
|
|
|
|
TARGET_OBJECT* ptTargetArray = (TARGET_OBJECT*)DAT_Target_Temp;
|
|
|
|
|
|
TARGET_OBJECT* ptTargetArrayCombine = (TARGET_OBJECT*)DAT_Target_Combine;
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 nObjsCnt = 0;
|
|
|
|
|
|
SIZE32S snSrDSmp;
|
|
|
|
|
|
SIZE32S snSrDSmpInt;
|
|
|
|
|
|
CENTERRECT crnSrRect; //搜索区域中心矩形
|
|
|
|
|
|
MINMAXRECT32S mmrSrRect;//搜索区域边界矩形
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 nWidth = img.u32Width;
|
|
|
|
|
|
SINT32 nHeight = img.u32Height;
|
|
|
|
|
|
// 未初始化报错
|
|
|
|
|
|
if (!m_DAT_bInitialize)
|
|
|
|
|
|
{
|
|
|
|
|
|
return ERR_UNInit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
cv::Mat data1 = Array2Mat_uchar(img.u64VirAddr[0], nWidth, nHeight);
|
|
|
|
|
|
|
|
|
|
|
|
cv::imshow("imput", data1);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//初始化单帧检测算法输出结果
|
|
|
|
|
|
DAT_CleanUpFrameDetectOutput();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算搜索区域在图像上的矩形范围(设置下限为64*64)
|
|
|
|
|
|
SINT32 nDATUnvalidBorder = MAX(m_DAT_stInput.nGrayRadius, m_DAT_stInput.nGradRadius) + 1;
|
|
|
|
|
|
crnSrRect = m_DAT_stInput.crnSrRect;
|
|
|
|
|
|
|
|
|
|
|
|
//m_DAT_stPara.nDSmpScale = 8;
|
|
|
|
|
|
// 计算合适的降采样倍数,如果是在搜索阶段,默认4倍降采样;如果是在跟踪阶段,则需要依据质心跟踪目标的尺寸,动态计算降采样倍数
|
|
|
|
|
|
|
|
|
|
|
|
//判断目标变化趋势,若尺寸大于阈值,则进行目标变大帧计数
|
|
|
|
|
|
if (nStatus == GLB_STATUS_TRACK)
|
|
|
|
|
|
{
|
|
|
|
|
|
FLOAT32 sSize = MAX(m_DatTrkTarget.sfSize.s, 0.58f * m_DatTrkTarget.snAIDetSize.s); // AI检测尺寸本身偏大,内部有效像素更少,乘以一个估计权重
|
|
|
|
|
|
if (sSize >= 3000)
|
|
|
|
|
|
{
|
|
|
|
|
|
GLB_Dat16SampleCnt++;
|
|
|
|
|
|
GLB_Dat8SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat4SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat2SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat1SampleCnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (sSize >= 900)
|
|
|
|
|
|
{
|
|
|
|
|
|
GLB_Dat16SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat8SampleCnt++;
|
|
|
|
|
|
GLB_Dat4SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat2SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat1SampleCnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (sSize < 900 && sSize >= 250)
|
|
|
|
|
|
{
|
|
|
|
|
|
GLB_Dat16SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat8SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat4SampleCnt++;
|
|
|
|
|
|
GLB_Dat2SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat1SampleCnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (sSize < 250 && sSize >= 100)
|
|
|
|
|
|
{
|
|
|
|
|
|
GLB_Dat16SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat8SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat4SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat2SampleCnt++;
|
|
|
|
|
|
GLB_Dat1SampleCnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
GLB_Dat16SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat8SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat4SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat2SampleCnt = 0;
|
|
|
|
|
|
GLB_Dat1SampleCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//目标降采样调整的帧连续计数器
|
|
|
|
|
|
if (GLB_Dat16SampleCnt > 5)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nDSmpScale = 16;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_Dat8SampleCnt > 5)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nDSmpScale = 8;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_Dat4SampleCnt > 5)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nDSmpScale = 4;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_Dat2SampleCnt > 5)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nDSmpScale = 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_Dat1SampleCnt > 5)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nDSmpScale = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
////自动调整降采样倍数
|
|
|
|
|
|
//if (nStatus != GLB_STATUS_TRACK)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// //根据参考区域大小调整降采样倍数, 计算降采样后参考区域大小
|
|
|
|
|
|
// if (crnSrRect.s < 128 * 128)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// m_DAT_stPara.nDSmpScale = 2;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// m_DAT_stPara.nDSmpScale = 4;
|
|
|
|
|
|
// }
|
|
|
|
|
|
//}
|
|
|
|
|
|
//else
|
|
|
|
|
|
if (nStatus == GLB_STATUS_TRACK) // 跟踪阶段根据降采样倍数,扩大检测的波门范围
|
|
|
|
|
|
{
|
|
|
|
|
|
if (16 == m_DAT_stPara.nDSmpScale)
|
|
|
|
|
|
{
|
|
|
|
|
|
crnSrRect.w = (SINT16)(crnSrRect.w * 4);
|
|
|
|
|
|
crnSrRect.h = (SINT16)(crnSrRect.h * 4);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (8 == m_DAT_stPara.nDSmpScale)
|
|
|
|
|
|
{
|
|
|
|
|
|
crnSrRect.w = (SINT16)(crnSrRect.w * 3);
|
|
|
|
|
|
crnSrRect.h = (SINT16)(crnSrRect.h * 3);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (4 == m_DAT_stPara.nDSmpScale)
|
|
|
|
|
|
{
|
|
|
|
|
|
crnSrRect.w = (SINT16)(crnSrRect.w * 2);
|
|
|
|
|
|
crnSrRect.h = (SINT16)(crnSrRect.h * 2);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (2 == m_DAT_stPara.nDSmpScale)
|
|
|
|
|
|
{
|
|
|
|
|
|
crnSrRect.w = (SINT16)(crnSrRect.w);
|
|
|
|
|
|
crnSrRect.h = (SINT16)(crnSrRect.h);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//不处理
|
|
|
|
|
|
}
|
|
|
|
|
|
m_DAT_stOutput.crCenterRect = crnSrRect;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//不处理
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 根据固定模板限制降采样倍数最小值
|
|
|
|
|
|
FLOAT32 s_input = crnSrRect.w * crnSrRect.h;
|
|
|
|
|
|
FLOAT32 min_ratio = floor(sqrt(s_input / DAT_CENTER_REGION_SIZE)) + 1;
|
|
|
|
|
|
|
|
|
|
|
|
m_DAT_stPara.nDSmpScale = MAX(m_DAT_stPara.nDSmpScale, min_ratio);
|
|
|
|
|
|
|
|
|
|
|
|
//边界限制
|
|
|
|
|
|
crnSrRect.w = MAX(crnSrRect.w, DAT_SEARCH_RGN_W_MIN + nDATUnvalidBorder * m_DAT_stPara.nDSmpScale);
|
|
|
|
|
|
crnSrRect.h = MAX(crnSrRect.h, DAT_SEARCH_RGN_W_MIN + nDATUnvalidBorder * m_DAT_stPara.nDSmpScale);
|
|
|
|
|
|
crnSrRect.w = MIN(crnSrRect.w, nWidth - 2);
|
|
|
|
|
|
crnSrRect.h = MIN(crnSrRect.h, nHeight - 2);
|
|
|
|
|
|
crnSrRect.s = crnSrRect.w * crnSrRect.h;
|
|
|
|
|
|
IMGO_CenRect16S2MMRect32S(crnSrRect, &mmrSrRect, nWidth, nHeight);
|
|
|
|
|
|
|
|
|
|
|
|
//边界限制
|
|
|
|
|
|
mmrSrRect.minX = MAX(1, MIN(mmrSrRect.minX, nWidth - 2));
|
|
|
|
|
|
mmrSrRect.maxX = MAX(1, MIN(mmrSrRect.maxX, nWidth - 2));
|
|
|
|
|
|
mmrSrRect.minY = MAX(1, MIN(mmrSrRect.minY, nHeight - 2));
|
|
|
|
|
|
mmrSrRect.maxY = MAX(1, MIN(mmrSrRect.maxY, nHeight - 2));
|
|
|
|
|
|
|
|
|
|
|
|
//更新搜索区域矩形
|
|
|
|
|
|
IMGO_MMRect32S2CenRect16S(mmrSrRect, &crnSrRect);
|
|
|
|
|
|
|
|
|
|
|
|
//MSSu, 20150609: 防止越界
|
|
|
|
|
|
if ((crnSrRect.w <= 1) || (crnSrRect.h <= 1))
|
|
|
|
|
|
{
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算降采样图像尺寸
|
|
|
|
|
|
snSrDSmp.w = (crnSrRect.w) / m_DAT_stPara.nDSmpScale;
|
|
|
|
|
|
snSrDSmp.h = (crnSrRect.h) / m_DAT_stPara.nDSmpScale;
|
|
|
|
|
|
snSrDSmp.s = snSrDSmp.w * snSrDSmp.h;
|
|
|
|
|
|
|
|
|
|
|
|
//计算积分图尺寸
|
|
|
|
|
|
snSrDSmpInt.w = snSrDSmp.w + 1;
|
|
|
|
|
|
snSrDSmpInt.h = snSrDSmp.h + 1;
|
|
|
|
|
|
snSrDSmpInt.s = snSrDSmpInt.w * snSrDSmpInt.h;
|
|
|
|
|
|
|
|
|
|
|
|
//记录算法结果
|
|
|
|
|
|
m_DAT_stOutput.snSrDSmp = snSrDSmp;
|
|
|
|
|
|
m_DAT_stOutput.mmrSrRect = mmrSrRect;
|
|
|
|
|
|
m_DAT_stOutput.snSrDSmpInt = snSrDSmpInt;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//提取搜索区域图像,二倍降采样后,存入m_DAT_stOutput.pnSrDSmpImg
|
|
|
|
|
|
//20171213,面目标检测不采用抽点的方式二倍降采样
|
|
|
|
|
|
IMGO_GDSGetSubMMRectDownSample(img, nWidth, nHeight,
|
|
|
|
|
|
m_DAT_stOutput.pnSrDSmpImg, mmrSrRect, m_DAT_stPara.nDSmpScale);
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算降采样后搜索区域图像pnSrDSmpImg上各点的梯度幅值pnGradMag
|
|
|
|
|
|
//20171110zy:m_DAT_stOutput.pnGradMag图像大小 和 snSrDSmp.w一样,h不一定一样大
|
|
|
|
|
|
IMGO_CalcGradImg(m_DAT_stOutput.pnSrDSmpImg, snSrDSmp.w, snSrDSmp.h, m_DAT_stOutput.pnGradMag);
|
|
|
|
|
|
|
|
|
|
|
|
//计算梯度积分图
|
|
|
|
|
|
IMGO_CalcIntegralImg(m_DAT_stOutput.pnGradMag, snSrDSmp,
|
|
|
|
|
|
m_DAT_stOutput.pnGradInt, m_DAT_stOutput.snSrDSmpInt);
|
|
|
|
|
|
|
|
|
|
|
|
//梯度分割
|
|
|
|
|
|
DAT_GradSegmentation(m_DAT_stOutput.pnGradMag, snSrDSmp, m_DAT_stOutput.pnGradInt,
|
|
|
|
|
|
snSrDSmpInt, m_DAT_stInput.nGradRadius, m_DAT_stInput.nGradRadiusTG,
|
|
|
|
|
|
m_DAT_stPara.nGradThresMin, m_DAT_stOutput.pnGradBinary);
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算灰度积分图
|
|
|
|
|
|
IMGO_CalcIntegralImg(m_DAT_stOutput.pnSrDSmpImg, snSrDSmp,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayInt, m_DAT_stOutput.snSrDSmpInt);
|
|
|
|
|
|
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32* pnTgBgDiff = (SINT32*)DAT_DIFF;
|
|
|
|
|
|
|
|
|
|
|
|
//20161115,计算背景目标灰度残差图
|
|
|
|
|
|
DAT_CalcTgBgDiff(m_DAT_stOutput.pnSrDSmpImg, snSrDSmp, m_DAT_stOutput.pnGrayInt,
|
|
|
|
|
|
snSrDSmpInt, m_DAT_stInput.nGrayRadius, m_DAT_stInput.nGrayRadiusTG, pnTgBgDiff);
|
|
|
|
|
|
|
|
|
|
|
|
DAT_GraySegmentation(snSrDSmp, m_DAT_stInput.nGrayRadius, m_DAT_stPara.nGrayThresMinBright, m_DAT_stOutput.pnGrayBinary, pnTgBgDiff, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//亮目标分割
|
|
|
|
|
|
nObjsCnt = DAT_ObjsSegmentation(m_DAT_stOutput.pnSrDSmpImg,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayBinary, m_DAT_stOutput.pnGradBinary, snSrDSmp,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayInt, m_DAT_stOutput.pnGradInt, snSrDSmpInt,
|
|
|
|
|
|
m_DAT_stInput.snSrBlksNum, m_DAT_stPara.nDSmpScale, mmrSrRect,
|
|
|
|
|
|
ptTargetArray, m_DAT_stPara.nFrmObjsMax, img.enPixelFormat);
|
|
|
|
|
|
|
|
|
|
|
|
//亮目标合并
|
|
|
|
|
|
nObjsCnt = DAT_MergeObjs(ptTargetArray, ptTargetArrayCombine,
|
|
|
|
|
|
m_DAT_stPara.nFrmObjsMax, nObjsCnt, nObjCombineDist);
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
// 显示结果
|
|
|
|
|
|
|
|
|
|
|
|
//if (/*g_GLB_stPara.nStatus == GLB_STATUS_TRACK*/1)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cv::Mat TmpGrayBinary(snSrDSmp.h, snSrDSmp.w, CV_8UC1, DAT_pBinary_Gray);
|
|
|
|
|
|
cv::Mat TmpGradBinary(snSrDSmp.h, snSrDSmp.w, CV_8UC1, DAT_pBinary_Mag);
|
|
|
|
|
|
// for (int iH = 0; iH < snSrDSmp.h; iH++)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// memcpy(TmpGrayBinary.data + (iH * DAT_CENTER_REGION_W), g_DAT_stOutput.pnGrayBinary + (iH * snSrDSmp.w), snSrDSmp.w * sizeof(UBYTE8));
|
|
|
|
|
|
// memcpy(TmpGradBinary.data + (iH * DAT_CENTER_REGION_W), g_DAT_stOutput.pnGradBinary + (iH * snSrDSmp.w), snSrDSmp.w * sizeof(UBYTE8));
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
TmpGrayBinary = TmpGrayBinary * 255;
|
|
|
|
|
|
TmpGradBinary = TmpGradBinary * 255;
|
|
|
|
|
|
|
|
|
|
|
|
cv::resize(TmpGrayBinary, TmpGrayBinary, cv::Size(), m_DAT_stPara.nDSmpScale, m_DAT_stPara.nDSmpScale);
|
|
|
|
|
|
cv::resize(TmpGradBinary, TmpGradBinary, cv::Size(), m_DAT_stPara.nDSmpScale, m_DAT_stPara.nDSmpScale);
|
|
|
|
|
|
|
|
|
|
|
|
cv::Mat FuseImg(m_DAT_stPara.nDSmpScale * snSrDSmp.h, m_DAT_stPara.nDSmpScale * snSrDSmp.w, CV_8UC3);
|
|
|
|
|
|
std::vector<cv::Mat> planes;
|
|
|
|
|
|
cv::split(FuseImg, planes);
|
|
|
|
|
|
planes.at(0) = TmpGrayBinary;
|
|
|
|
|
|
planes.at(2) = TmpGradBinary;
|
|
|
|
|
|
planes.at(1) = 0;
|
|
|
|
|
|
cv::merge(planes, FuseImg);
|
|
|
|
|
|
|
|
|
|
|
|
for (int nIndex = 0; nIndex < nObjsCnt; nIndex++)
|
|
|
|
|
|
{
|
|
|
|
|
|
cv::Rect ret(ptTargetArray[nIndex].mrnRect.minX, ptTargetArray[nIndex].mrnRect.minY,
|
|
|
|
|
|
(ptTargetArray[nIndex].mrnRect.maxX - ptTargetArray[nIndex].mrnRect.minX),
|
|
|
|
|
|
(ptTargetArray[nIndex].mrnRect.maxY - ptTargetArray[nIndex].mrnRect.minY));
|
|
|
|
|
|
cv::rectangle(FuseImg, ret, cv::Scalar(0, 255, 0));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cv::imshow("分割结果:灰度(B)_梯度(R)", FuseImg);
|
|
|
|
|
|
cv::imshow("灰度分割结果", TmpGrayBinary);
|
|
|
|
|
|
cv::imshow("梯度分割结果", TmpGradBinary);
|
|
|
|
|
|
cv::waitKey(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_DARK == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32* pnTgBgDiff = (SINT32*)DAT_DIFF;
|
|
|
|
|
|
|
|
|
|
|
|
//20161115,计算背景目标灰度残差图
|
|
|
|
|
|
DAT_CalcTgBgDiff(m_DAT_stOutput.pnSrDSmpImg, snSrDSmp, m_DAT_stOutput.pnGrayInt,
|
|
|
|
|
|
snSrDSmpInt, m_DAT_stInput.nGrayRadius, m_DAT_stInput.nGrayRadiusTG, pnTgBgDiff);
|
|
|
|
|
|
|
|
|
|
|
|
DAT_GraySegmentation(snSrDSmp, m_DAT_stInput.nGrayRadius, m_DAT_stPara.nGrayThresMinDark, m_DAT_stOutput.pnGrayBinary, pnTgBgDiff, true);
|
|
|
|
|
|
|
|
|
|
|
|
//暗目标分割
|
|
|
|
|
|
nObjsCnt = DAT_ObjsSegmentation(m_DAT_stOutput.pnSrDSmpImg,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayBinary, m_DAT_stOutput.pnGradBinary, snSrDSmp,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayInt, m_DAT_stOutput.pnGradInt, snSrDSmpInt,
|
|
|
|
|
|
m_DAT_stInput.snSrBlksNum, m_DAT_stPara.nDSmpScale, mmrSrRect,
|
|
|
|
|
|
ptTargetArray, m_DAT_stPara.nFrmObjsMax, img.enPixelFormat);
|
|
|
|
|
|
|
|
|
|
|
|
//暗目标合并
|
|
|
|
|
|
nObjsCnt = DAT_MergeObjs(ptTargetArray, ptTargetArrayCombine,
|
|
|
|
|
|
m_DAT_stPara.nFrmObjsMax, nObjsCnt, nObjCombineDist);
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
// 显示结果
|
|
|
|
|
|
|
|
|
|
|
|
//if (/*g_GLB_stPara.nStatus == GLB_STATUS_TRACK*/1)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cv::Mat TmpGrayBinary(snSrDSmp.h, snSrDSmp.w, CV_8UC1, DAT_pBinary_Gray);
|
|
|
|
|
|
cv::Mat TmpGradBinary(snSrDSmp.h, snSrDSmp.w, CV_8UC1, DAT_pBinary_Mag);
|
|
|
|
|
|
// for (int iH = 0; iH < snSrDSmp.h; iH++)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// memcpy(TmpGrayBinary.data + (iH * DAT_CENTER_REGION_W), g_DAT_stOutput.pnGrayBinary + (iH * snSrDSmp.w), snSrDSmp.w * sizeof(UBYTE8));
|
|
|
|
|
|
// memcpy(TmpGradBinary.data + (iH * DAT_CENTER_REGION_W), g_DAT_stOutput.pnGradBinary + (iH * snSrDSmp.w), snSrDSmp.w * sizeof(UBYTE8));
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
TmpGrayBinary = TmpGrayBinary * 255;
|
|
|
|
|
|
TmpGradBinary = TmpGradBinary * 255;
|
|
|
|
|
|
|
|
|
|
|
|
cv::resize(TmpGrayBinary, TmpGrayBinary, cv::Size(), m_DAT_stPara.nDSmpScale, m_DAT_stPara.nDSmpScale);
|
|
|
|
|
|
cv::resize(TmpGradBinary, TmpGradBinary, cv::Size(), m_DAT_stPara.nDSmpScale, m_DAT_stPara.nDSmpScale);
|
|
|
|
|
|
|
|
|
|
|
|
cv::Mat FuseImg(m_DAT_stPara.nDSmpScale * snSrDSmp.h, m_DAT_stPara.nDSmpScale * snSrDSmp.w, CV_8UC3);
|
|
|
|
|
|
std::vector<cv::Mat> planes;
|
|
|
|
|
|
cv::split(FuseImg, planes);
|
|
|
|
|
|
planes.at(0) = TmpGrayBinary;
|
|
|
|
|
|
planes.at(2) = TmpGradBinary;
|
|
|
|
|
|
planes.at(1) = 0;
|
|
|
|
|
|
cv::merge(planes, FuseImg);
|
|
|
|
|
|
|
|
|
|
|
|
for (int nIndex = 0; nIndex < nObjsCnt; nIndex++)
|
|
|
|
|
|
{
|
|
|
|
|
|
cv::Rect ret(ptTargetArray[nIndex].mrnRect.minX, ptTargetArray[nIndex].mrnRect.minY,
|
|
|
|
|
|
(ptTargetArray[nIndex].mrnRect.maxX - ptTargetArray[nIndex].mrnRect.minX),
|
|
|
|
|
|
(ptTargetArray[nIndex].mrnRect.maxY - ptTargetArray[nIndex].mrnRect.minY));
|
|
|
|
|
|
cv::rectangle(FuseImg, ret, cv::Scalar(0, 255, 0));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cv::imshow("分割结果:灰度(B)_梯度(R)", FuseImg);
|
|
|
|
|
|
cv::imshow("灰度分割结果", TmpGrayBinary);
|
|
|
|
|
|
cv::imshow("梯度分割结果", TmpGradBinary);
|
|
|
|
|
|
cv::waitKey(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 nFrmBrightObjCnt = 0;
|
|
|
|
|
|
SINT32 nFrmDarkObjCnt = 0;
|
|
|
|
|
|
SINT32* pnTgBgDiff = (SINT32*)DAT_DIFF;
|
|
|
|
|
|
|
|
|
|
|
|
//20161112Whao,初始化亮暗目标数组
|
|
|
|
|
|
TARGET_OBJECT* ptDATResultBright = (TARGET_OBJECT*)DAT_Target_Bright;
|
|
|
|
|
|
TARGET_OBJECT* ptDATResultDark = (TARGET_OBJECT*)DAT_Target_DARK;
|
|
|
|
|
|
memset(ptDATResultBright, 0, sizeof(TARGET_OBJECT) * DAT_TARGET_NUM_MAX);
|
|
|
|
|
|
memset(ptDATResultDark, 0, sizeof(TARGET_OBJECT) * DAT_TARGET_NUM_MAX);
|
|
|
|
|
|
|
|
|
|
|
|
//20161112,先执行亮目标灰度
|
|
|
|
|
|
m_DAT_stPara.nDetectGrayType = GLB_OBJ_GRAY_BRIGHT;
|
|
|
|
|
|
|
|
|
|
|
|
//20161115,计算背景目标灰度残差图
|
|
|
|
|
|
DAT_CalcTgBgDiff(m_DAT_stOutput.pnSrDSmpImg, snSrDSmp, m_DAT_stOutput.pnGrayInt,
|
|
|
|
|
|
snSrDSmpInt, m_DAT_stInput.nGrayRadius, m_DAT_stInput.nGrayRadiusTG, pnTgBgDiff);
|
|
|
|
|
|
|
|
|
|
|
|
//亮目标灰度分割
|
|
|
|
|
|
DAT_GraySegmentation(snSrDSmp, m_DAT_stInput.nGrayRadius, m_DAT_stPara.nGrayThresMinBright, m_DAT_stOutput.pnGrayBinary, pnTgBgDiff, true);
|
|
|
|
|
|
|
|
|
|
|
|
//亮目标分割
|
|
|
|
|
|
nFrmBrightObjCnt = DAT_ObjsSegmentation(m_DAT_stOutput.pnSrDSmpImg,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayBinary, m_DAT_stOutput.pnGradBinary, snSrDSmp,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayInt, m_DAT_stOutput.pnGradInt, snSrDSmpInt,
|
|
|
|
|
|
m_DAT_stInput.snSrBlksNum, m_DAT_stPara.nDSmpScale, mmrSrRect,
|
|
|
|
|
|
ptTargetArray, m_DAT_stPara.nFrmObjsMax, img.enPixelFormat);
|
|
|
|
|
|
|
|
|
|
|
|
//亮目标合并
|
|
|
|
|
|
nFrmBrightObjCnt = DAT_MergeObjs(ptTargetArray, ptTargetArrayCombine,
|
|
|
|
|
|
m_DAT_stPara.nFrmObjsMax, nFrmBrightObjCnt, nObjCombineDist);
|
|
|
|
|
|
|
|
|
|
|
|
//复制面目标结果到共享空间(DSP双核移植时使用)
|
|
|
|
|
|
TARGET_OBJECT* ptDATResultBrightTmp = (TARGET_OBJECT*)DAT_Target_Temp;
|
|
|
|
|
|
memcpy(ptDATResultBright, ptDATResultBrightTmp, nFrmBrightObjCnt * sizeof(TARGET_OBJECT));
|
|
|
|
|
|
|
|
|
|
|
|
//初始化单帧目标数组
|
|
|
|
|
|
memset(ptTargetArray, 0, sizeof(TARGET_OBJECT) * DAT_TARGET_NUM_MAX);
|
|
|
|
|
|
memset(ptTargetArrayCombine, 0, sizeof(TARGET_OBJECT) * DAT_TARGET_NUM_MAX);
|
|
|
|
|
|
memset(m_DAT_stOutput.pnGrayBinary, 0, sizeof(UBYTE8) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
memset(pnTgBgDiff, 0, sizeof(SINT16) * DAT_CENTER_REGION_SIZE); //初始化背景残差图数组
|
|
|
|
|
|
|
|
|
|
|
|
//20161112,再执行暗目标灰度分割
|
|
|
|
|
|
m_DAT_stPara.nDetectGrayType = GLB_OBJ_GRAY_DARK;
|
|
|
|
|
|
|
|
|
|
|
|
//计算暗目标与背景残差图
|
|
|
|
|
|
DAT_CalcTgBgDiff(m_DAT_stOutput.pnSrDSmpImg, snSrDSmp, m_DAT_stOutput.pnGrayInt,
|
|
|
|
|
|
snSrDSmpInt, m_DAT_stInput.nGrayRadius, m_DAT_stInput.nGrayRadiusTG, pnTgBgDiff);
|
|
|
|
|
|
|
|
|
|
|
|
//暗目标灰度分割
|
|
|
|
|
|
DAT_GraySegmentation(snSrDSmp, m_DAT_stInput.nGrayRadius, m_DAT_stPara.nGrayThresMinDark, m_DAT_stOutput.pnGrayBinary, pnTgBgDiff, true);
|
|
|
|
|
|
|
|
|
|
|
|
//暗目标分割
|
|
|
|
|
|
nFrmDarkObjCnt = DAT_ObjsSegmentation(m_DAT_stOutput.pnSrDSmpImg,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayBinary, m_DAT_stOutput.pnGradBinary, snSrDSmp,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayInt, m_DAT_stOutput.pnGradInt, snSrDSmpInt,
|
|
|
|
|
|
m_DAT_stInput.snSrBlksNum, m_DAT_stPara.nDSmpScale, mmrSrRect,
|
|
|
|
|
|
ptTargetArray, m_DAT_stPara.nFrmObjsMax, img.enPixelFormat);
|
|
|
|
|
|
|
|
|
|
|
|
//暗目标合并
|
|
|
|
|
|
nFrmDarkObjCnt = DAT_MergeObjs(ptTargetArray, ptTargetArrayCombine,
|
|
|
|
|
|
m_DAT_stPara.nFrmObjsMax, nFrmDarkObjCnt, nObjCombineDist);
|
|
|
|
|
|
|
|
|
|
|
|
//复制暗面目标结果
|
|
|
|
|
|
TARGET_OBJECT* ptDATResultDarkTmp = (TARGET_OBJECT*)DAT_Target_Temp;
|
|
|
|
|
|
memcpy(ptDATResultDark, ptDATResultDarkTmp, nFrmDarkObjCnt * sizeof(TARGET_OBJECT));
|
|
|
|
|
|
|
|
|
|
|
|
//20161112,合并检测结果
|
|
|
|
|
|
nObjsCnt = DAT_MergeTargets(ptDATResultBright, ptDATResultDark, nFrmBrightObjCnt, nFrmDarkObjCnt, m_DAT_stPara.nFrmObjsMax);
|
|
|
|
|
|
|
|
|
|
|
|
//20171110zy: 还原灰度检测类型,不与小目标检测类型相关联
|
|
|
|
|
|
m_DAT_stPara.nDetectGrayType = GLB_OBJ_GRAY_ALL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//复制面目标结果到共享空间(DSP双核移植时使用)
|
|
|
|
|
|
TARGET_OBJECT* ptDATResult = (TARGET_OBJECT*)DAT_Target;
|
|
|
|
|
|
TARGET_OBJECT* ptDATResulTemp = (TARGET_OBJECT*)DAT_Target_Temp;
|
|
|
|
|
|
memcpy(ptDATResult, ptDATResulTemp, nObjsCnt * sizeof(TARGET_OBJECT));
|
|
|
|
|
|
|
|
|
|
|
|
// 导出分割图
|
|
|
|
|
|
m_DAT_stOutput.DAT_pBinary_Gray = DAT_pBinary_Gray;
|
|
|
|
|
|
m_DAT_stOutput.DAT_pBinary_Mag = DAT_pBinary_Mag;
|
|
|
|
|
|
|
|
|
|
|
|
// 显式输出目标个数
|
|
|
|
|
|
m_DAT_stOutput.nFrmObjsCnt = nObjsCnt;
|
|
|
|
|
|
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void dfs(unsigned char* grid, int nr, int nc, int r, int c)
|
|
|
|
|
|
{
|
|
|
|
|
|
grid[r * nc + c] = '\0';
|
|
|
|
|
|
if (r - 1 >= 0 && grid[(r - 1) * nc + c] == '\x1') dfs(grid, nr, nc, r - 1, c);
|
|
|
|
|
|
if (r + 1 < nr && grid[(r + 1) * nc + c] == '\x1') dfs(grid, nr, nc, r + 1, c);
|
|
|
|
|
|
if (c - 1 >= 0 && grid[r * nc + (c - 1)] == '\x1') dfs(grid, nr, nc, r, c - 1);
|
|
|
|
|
|
if (c + 1 < nc && grid[r * nc + (c + 1)] == '\x1') dfs(grid, nr, nc, r, c + 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int numIslands(unsigned char* grid, int nr, int nc)
|
|
|
|
|
|
{
|
|
|
|
|
|
int num_islands = 0;
|
|
|
|
|
|
for (int r = 0; r < nr; ++r)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int c = 0; c < nc; ++c)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (grid[r * nc + c] == '\x1')
|
|
|
|
|
|
{
|
|
|
|
|
|
++num_islands;
|
|
|
|
|
|
dfs(grid, nr, nc, r, c);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return num_islands;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int numPixcels(unsigned char* grid, int nr, int nc, int* holeXpixcel, int* holeYpixcel)
|
|
|
|
|
|
{
|
|
|
|
|
|
int num_pixcel = 0;
|
|
|
|
|
|
*holeXpixcel = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 统计行孔洞数
|
|
|
|
|
|
for (int r = 0; r < nr; ++r)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool len_start = false;
|
|
|
|
|
|
bool len_end = true;
|
|
|
|
|
|
int lineXPixcel = 0;
|
|
|
|
|
|
int stepXPixcel = 0;
|
|
|
|
|
|
for (int c = 0; c < nc; ++c)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (grid[r * nc + c] == '\x1')
|
|
|
|
|
|
{
|
|
|
|
|
|
num_pixcel++;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (len_start == false && grid[r * nc + c] == '\x1')
|
|
|
|
|
|
{
|
|
|
|
|
|
len_start = true;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (true == len_start)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (grid[r * nc + c] == '\0')
|
|
|
|
|
|
{
|
|
|
|
|
|
stepXPixcel += 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (stepXPixcel > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
lineXPixcel += stepXPixcel;
|
|
|
|
|
|
stepXPixcel = 0;
|
|
|
|
|
|
len_start = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
(*holeXpixcel) += lineXPixcel;
|
|
|
|
|
|
}
|
|
|
|
|
|
//统计列孔洞数
|
|
|
|
|
|
for (int c = 0; c < nc; ++c)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool col_start = false;
|
|
|
|
|
|
bool col_end = true;
|
|
|
|
|
|
int lineYPixcel = 0;
|
|
|
|
|
|
int stepYPixcel = 0;
|
|
|
|
|
|
for (int r = 0; r < nr; ++r)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (col_start == false && grid[r * nc + c] == '\x1')
|
|
|
|
|
|
{
|
|
|
|
|
|
col_start = true;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (true == col_start)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (grid[r * nc + c] == '\0')
|
|
|
|
|
|
{
|
|
|
|
|
|
stepYPixcel += 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (stepYPixcel > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
lineYPixcel += stepYPixcel;
|
|
|
|
|
|
stepYPixcel = 0;
|
|
|
|
|
|
col_start = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
(*holeYpixcel) += lineYPixcel;
|
|
|
|
|
|
}
|
|
|
|
|
|
return num_pixcel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_DetectAreaTarget()
|
|
|
|
|
|
* 功能描述:基于区域连通的面目标检测
|
|
|
|
|
|
* 输入参数:UINT16 *pSrc -- 原始图像
|
|
|
|
|
|
CENTERRECT crnSrRect; //搜索区域中心矩形
|
|
|
|
|
|
* GLB_STATUS nStatus -- 标识当前检测算法的用途(搜索的检测、跟踪的检测)
|
|
|
|
|
|
* 输出参数:无
|
|
|
|
|
|
* 返 回 值:SINT32 nObjsCnt -- 单帧检测的目标数量
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:根据目标大小,进行了3倍降采样操作,
|
|
|
|
|
|
可以根据实际需要修改是否进行降采样,并修改内存空间
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
SINT32 DetectAreaObj::DAT_ObjectAreaSeg(GD_VIDEO_FRAME_S img, CENTERRECT crnSrRect, GLB_STATUS nStatus, PixcelsCnt* pCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 nObjsCnt = 0;
|
|
|
|
|
|
SIZE32S snSrDSmp;
|
|
|
|
|
|
SIZE32S snSrDSmpInt;
|
|
|
|
|
|
MINMAXRECT32S mmrSrRect;//搜索区域边界矩形
|
|
|
|
|
|
SINT32 nDSmpScale = 1;
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 landsNum = 0;
|
|
|
|
|
|
|
|
|
|
|
|
//SINT32 numPixcel = 0;
|
|
|
|
|
|
//SINT32 holeXpixcel = 0; // x方向孔洞数
|
|
|
|
|
|
//SINT32 holeYpixcel = 0; // y方向孔洞数
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
cv::Mat data1 = Array2Mat_uchar(img.u64VirAddr[0], nWidth, nHeight);
|
|
|
|
|
|
|
|
|
|
|
|
cv::imshow("imput", data1);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算搜索区域在图像上的矩形范围(设置下限为64*64)
|
|
|
|
|
|
SINT32 nDATUnvalidBorder = MAX(m_DAT_stInput.nGrayRadius, m_DAT_stInput.nGradRadius) + 1;
|
|
|
|
|
|
//crnSrRect = m_DAT_stInput.crnSrRect;
|
|
|
|
|
|
|
|
|
|
|
|
//判断目标变化趋势,若尺寸大于阈值,则进行目标变大帧计数
|
|
|
|
|
|
if (nStatus != GLB_STATUS_TRACK)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//边界限制
|
|
|
|
|
|
crnSrRect.w = MAX(crnSrRect.w, DAT_SEARCH_RGN_W_MIN + nDATUnvalidBorder * nDSmpScale);
|
|
|
|
|
|
crnSrRect.h = MAX(crnSrRect.h, DAT_SEARCH_RGN_W_MIN + nDATUnvalidBorder * nDSmpScale);
|
|
|
|
|
|
crnSrRect.w = MIN(crnSrRect.w, (SINT32)img.u32Width - 2);
|
|
|
|
|
|
crnSrRect.h = MIN(crnSrRect.h, (SINT32)img.u32Height - 2);
|
|
|
|
|
|
crnSrRect.s = crnSrRect.w * crnSrRect.h;
|
|
|
|
|
|
IMGO_CenRect16S2MMRect32S(crnSrRect, &mmrSrRect, img.u32Width, img.u32Height);
|
|
|
|
|
|
|
|
|
|
|
|
//边界限制
|
|
|
|
|
|
mmrSrRect.minX = MAX(1, MIN(mmrSrRect.minX, (SINT32)img.u32Width - 2));
|
|
|
|
|
|
mmrSrRect.maxX = MAX(1, MIN(mmrSrRect.maxX, (SINT32)img.u32Width - 2));
|
|
|
|
|
|
mmrSrRect.minY = MAX(1, MIN(mmrSrRect.minY, (SINT32)img.u32Height - 2));
|
|
|
|
|
|
mmrSrRect.maxY = MAX(1, MIN(mmrSrRect.maxY, (SINT32)img.u32Height - 2));
|
|
|
|
|
|
|
|
|
|
|
|
//更新搜索区域矩形
|
|
|
|
|
|
IMGO_MMRect32S2CenRect16S(mmrSrRect, &crnSrRect);
|
|
|
|
|
|
|
|
|
|
|
|
//MSSu, 20150609: 防止越界
|
|
|
|
|
|
if ((crnSrRect.w <= 1) || (crnSrRect.h <= 1))
|
|
|
|
|
|
{
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算降采样图像尺寸
|
|
|
|
|
|
snSrDSmp.w = crnSrRect.w;
|
|
|
|
|
|
snSrDSmp.h = crnSrRect.h;
|
|
|
|
|
|
snSrDSmp.s = snSrDSmp.w * snSrDSmp.h;
|
|
|
|
|
|
|
|
|
|
|
|
//计算积分图尺寸
|
|
|
|
|
|
snSrDSmpInt.w = snSrDSmp.w + 1;
|
|
|
|
|
|
snSrDSmpInt.h = snSrDSmp.h + 1;
|
|
|
|
|
|
snSrDSmpInt.s = snSrDSmpInt.w * snSrDSmpInt.h;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//提取搜索区域图像,二倍降采样后,存入m_DAT_stOutput.pnSrDSmpImgNew
|
|
|
|
|
|
//20171213,面目标检测不采用抽点的方式二倍降采样
|
|
|
|
|
|
IMGO_GDSGetSubMMRectDownSample(img, img.u32Width, img.u32Height,
|
|
|
|
|
|
m_DAT_stOutput.pnSrDSmpImg, mmrSrRect, nDSmpScale);
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算灰度积分图
|
|
|
|
|
|
IMGO_CalcIntegralImg(m_DAT_stOutput.pnSrDSmpImg, snSrDSmp,
|
|
|
|
|
|
m_DAT_stOutput.pnGrayInt, snSrDSmpInt);
|
|
|
|
|
|
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32* pnTgBgDiff = (SINT32*)DAT_DIFF;
|
|
|
|
|
|
|
|
|
|
|
|
//20161115,计算背景目标灰度残差图
|
|
|
|
|
|
DAT_CalcTgBgDiff(m_DAT_stOutput.pnSrDSmpImg, snSrDSmp, m_DAT_stOutput.pnGrayInt,
|
|
|
|
|
|
snSrDSmpInt, m_DAT_stInput.nGrayRadius, m_DAT_stInput.nGrayRadiusTG, pnTgBgDiff);
|
|
|
|
|
|
|
|
|
|
|
|
DAT_GraySegmentation(snSrDSmp, m_DAT_stInput.nGrayRadius, m_DAT_stPara.nGrayThresMinBright, DAT_pBinary_GrayNew, pnTgBgDiff, false);
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
cv::Mat TmpGrayBinary(snSrDSmp.h, snSrDSmp.w, CV_8UC1);
|
|
|
|
|
|
memcpy(TmpGrayBinary.data, DAT_pBinary_GrayNew, snSrDSmp.h * snSrDSmp.w * sizeof(UBYTE8));
|
|
|
|
|
|
TmpGrayBinary = TmpGrayBinary * 255;
|
|
|
|
|
|
|
|
|
|
|
|
cv::imshow("灰度分割结果", TmpGrayBinary);
|
|
|
|
|
|
cv::waitKey(1);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
pCnt->nObjCnt = numPixcels(DAT_pBinary_GrayNew, snSrDSmp.h, snSrDSmp.w, &pCnt->nObjXHoleCnt, &pCnt->nObjYHoleCnt);
|
|
|
|
|
|
|
|
|
|
|
|
landsNum = numIslands(DAT_pBinary_GrayNew, snSrDSmp.h, snSrDSmp.w);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_DARK == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32* pnTgBgDiff = (SINT32*)DAT_DIFF;
|
|
|
|
|
|
|
|
|
|
|
|
//20161115,计算背景目标灰度残差图
|
|
|
|
|
|
DAT_CalcTgBgDiff(m_DAT_stOutput.pnSrDSmpImg, snSrDSmp, m_DAT_stOutput.pnGrayInt,
|
|
|
|
|
|
snSrDSmpInt, m_DAT_stInput.nGrayRadius, m_DAT_stInput.nGrayRadiusTG, pnTgBgDiff);
|
|
|
|
|
|
|
|
|
|
|
|
DAT_GraySegmentation(snSrDSmp, m_DAT_stInput.nGrayRadius, m_DAT_stPara.nGrayThresMinDark, DAT_pBinary_GrayNew, pnTgBgDiff, false);
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
cv::Mat TmpGrayBinary(snSrDSmp.h, snSrDSmp.w, CV_8UC1);
|
|
|
|
|
|
memcpy(TmpGrayBinary.data, DAT_pBinary_GrayNew, snSrDSmp.h * snSrDSmp.w * sizeof(UBYTE8));
|
|
|
|
|
|
TmpGrayBinary = TmpGrayBinary * 255;
|
|
|
|
|
|
|
|
|
|
|
|
cv::imshow("灰度分割结果", TmpGrayBinary);
|
|
|
|
|
|
cv::waitKey(1);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
pCnt->nObjCnt = numPixcels(DAT_pBinary_GrayNew, snSrDSmp.h, snSrDSmp.w, &pCnt->nObjXHoleCnt, &pCnt->nObjYHoleCnt);
|
|
|
|
|
|
landsNum = numIslands(DAT_pBinary_GrayNew, snSrDSmp.h, snSrDSmp.w);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return landsNum;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_Initialization()
|
|
|
|
|
|
* 功能描述:算法初始化
|
|
|
|
|
|
* 输入参数:无
|
|
|
|
|
|
* 输出参数:无
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:无
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void DetectAreaObj::DAT_Initialization(SINT32 nWidth, SINT32 nHeight, CENTERRECT mmCenterRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//初始化算法输入
|
|
|
|
|
|
//搜索区域
|
|
|
|
|
|
m_DAT_stInput.crnSrRect.cx = (SINT16)(mmCenterRect.cx); //搜索区域中心点cx
|
|
|
|
|
|
m_DAT_stInput.crnSrRect.cy = (SINT16)(mmCenterRect.cy); //搜索区域中心点cy
|
|
|
|
|
|
m_DAT_stInput.crnSrRect.w = mmCenterRect.w; //搜索区域宽度w
|
|
|
|
|
|
m_DAT_stInput.crnSrRect.h = mmCenterRect.h; //搜索区域高度h
|
|
|
|
|
|
m_DAT_stInput.crnSrRect.s = mmCenterRect.w * mmCenterRect.h;
|
|
|
|
|
|
|
|
|
|
|
|
//梯度分块尺寸
|
|
|
|
|
|
m_DAT_stInput.nGradRadius = DAT_GRAD_BLK_RADIUS;
|
|
|
|
|
|
m_DAT_stInput.nGradRadiusTG = DAT_GRAD_BLK_RADIUS_TG;
|
|
|
|
|
|
m_DAT_stInput.snGradBlkSize.w = m_DAT_stInput.nGradRadius * 2 + 1;
|
|
|
|
|
|
m_DAT_stInput.snGradBlkSize.h = m_DAT_stInput.snGradBlkSize.w;
|
|
|
|
|
|
m_DAT_stInput.snGradBlkSize.s = m_DAT_stInput.snGradBlkSize.w * m_DAT_stInput.snGradBlkSize.h;
|
|
|
|
|
|
|
|
|
|
|
|
//灰度分块尺寸
|
|
|
|
|
|
m_DAT_stInput.nGrayRadius = DAT_GRAY_BLK_RADIUS;
|
|
|
|
|
|
m_DAT_stInput.nGrayRadiusTG = DAT_GRAY_BLK_RADIUS_TG;
|
|
|
|
|
|
m_DAT_stInput.snGrayBlkSize.w = m_DAT_stInput.nGrayRadius * 2 + 1;
|
|
|
|
|
|
m_DAT_stInput.snGrayBlkSize.h = m_DAT_stInput.snGrayBlkSize.w;
|
|
|
|
|
|
m_DAT_stInput.snGrayBlkSize.s = m_DAT_stInput.snGrayBlkSize.w * m_DAT_stInput.snGrayBlkSize.h;
|
|
|
|
|
|
|
|
|
|
|
|
//搜索区域分块个数
|
|
|
|
|
|
m_DAT_stInput.snSrBlksNum.w = DAT_SR_RGN_BLKS_NUM_W;
|
|
|
|
|
|
m_DAT_stInput.snSrBlksNum.h = DAT_SR_RGN_BLKS_NUM_H;
|
|
|
|
|
|
m_DAT_stInput.snSrBlksNum.s = DAT_SR_RGN_BLKS_NUM;
|
|
|
|
|
|
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//初始化算法参数
|
|
|
|
|
|
//
|
|
|
|
|
|
m_DAT_stPara.nDetectGrayType = GLB_OBJ_GRAY_ALL; // 默认检测亮/暗目标
|
|
|
|
|
|
m_DAT_stPara.nFrmObjsMax = DAT_TARGET_NUM_MAX;
|
|
|
|
|
|
m_DAT_stPara.nDSmpScale = DAT_DSAMPLE_SCALE; // 默认降采样倍数
|
|
|
|
|
|
m_DAT_stPara.nGradThresMin = DAT_GRAD_THRES_MIN;
|
|
|
|
|
|
m_DAT_stPara.nObjSizeMin = DAT_TARGET_PXLS_MIN;
|
|
|
|
|
|
m_DAT_stPara.nObjSizeMax = DAT_TARGET_PXLS_MAX;
|
|
|
|
|
|
m_DAT_stPara.nObjWidthMax = DAT_TARGET_WIDTH_MAX;
|
|
|
|
|
|
m_DAT_stPara.nObjHeightMax = DAT_TARGET_HEIGHT_MAX;
|
|
|
|
|
|
m_DAT_stPara.fObjWHRatioMin = 0.2f;
|
|
|
|
|
|
m_DAT_stPara.fObjWHRatioMax = 5.0f;
|
|
|
|
|
|
m_DAT_stPara.fObjRectRatioMin = 0.3f;
|
|
|
|
|
|
m_DAT_stPara.nObjBkgGrayDiffMin = 10;
|
|
|
|
|
|
m_DAT_stPara.fBkgGrayDiffCoeff = 0.35f;
|
|
|
|
|
|
m_DAT_stPara.fgdk = DAT_OBJ_SNR_MIN;
|
|
|
|
|
|
m_DAT_stPara.nObjCombineDist = 11;
|
|
|
|
|
|
|
|
|
|
|
|
//20161113Whao,亮暗目标两套阈值
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinBright = DAT_GRAY_THRES_BRIGHT_MIN;
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinDark = DAT_GRAY_THRES_DARK_MIN;
|
|
|
|
|
|
|
|
|
|
|
|
//面目标检测去虚警开关(上位机软件界面可调)
|
|
|
|
|
|
m_DAT_stPara.bUseDeFA_ObjVarMin = 1;
|
|
|
|
|
|
m_DAT_stPara.bUseDeFA_Size = 1;
|
|
|
|
|
|
m_DAT_stPara.bUseDeFA_WHRatio = 1;
|
|
|
|
|
|
m_DAT_stPara.bUseDeFA_RectRatio = 1;
|
|
|
|
|
|
m_DAT_stPara.bUseDeFA_BTGrayMin = 0;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
|
|
|
|
|
|
// 内存申请
|
|
|
|
|
|
DAT_MallocMemory(nWidth, nHeight, mmCenterRect);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//初始化算法输出结果
|
|
|
|
|
|
memset(&m_DAT_stOutput, 0, sizeof(DAT_OUTPUT));
|
|
|
|
|
|
//初始化灰度图指针
|
|
|
|
|
|
m_DAT_stOutput.pnSrDSmpImg = (UINT16*)DAT_pxDetectArea;
|
|
|
|
|
|
m_DAT_stOutput.pnGrayBinary = (UBYTE8*)DAT_pBinary_Gray;
|
|
|
|
|
|
m_DAT_stOutput.pnGrayInt = (SINT32*)DAT_pxDetectAreaIntegral;
|
|
|
|
|
|
|
|
|
|
|
|
//m_DAT_stOutput.pnSrDSmpImgNew = (UINT16*)DAT_pxDetectAreaNew;
|
|
|
|
|
|
|
|
|
|
|
|
//初始化梯度图指针
|
|
|
|
|
|
m_DAT_stOutput.pnGradMag = (UINT16*)DAT_pnMagArry;
|
|
|
|
|
|
m_DAT_stOutput.pnGradBinary = (UBYTE8*)DAT_pBinary_Mag;
|
|
|
|
|
|
m_DAT_stOutput.pnGradInt = (SINT32*)DAT_pxDetectAreaGradIntegral;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//初始化单帧检测算法输出结果
|
|
|
|
|
|
DAT_CleanUpFrameDetectOutput();
|
|
|
|
|
|
|
|
|
|
|
|
//算法初始化标记
|
|
|
|
|
|
m_DAT_bInitialize = TRUE; //DAT算法初始化标志。1-初始化,0-不初始化。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_CleanUpFrameDetectOutput()
|
|
|
|
|
|
* 功能描述:初始化单帧检测算法输出结果
|
|
|
|
|
|
* 输入参数:无
|
|
|
|
|
|
* 输出参数:无
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:无
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void DetectAreaObj::DAT_CleanUpFrameDetectOutput(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
//初始化灰度图指针
|
|
|
|
|
|
memset(m_DAT_stOutput.pnSrDSmpImg, 0, sizeof(UINT16) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
memset(m_DAT_stOutput.pnGrayBinary, 0, sizeof(UBYTE8) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
memset(m_DAT_stOutput.pnGrayInt, 0, sizeof(SINT32) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
//初始化梯度图指针
|
|
|
|
|
|
memset(m_DAT_stOutput.pnGradMag, 0, sizeof(UINT16) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
memset(m_DAT_stOutput.pnGradBinary, 0, sizeof(UBYTE8) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
memset(m_DAT_stOutput.pnGradInt, 0, sizeof(SINT32) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
//初始化单帧目标数组
|
|
|
|
|
|
TARGET_OBJECT* ptTargetArray = (TARGET_OBJECT*)DAT_Target;
|
|
|
|
|
|
TARGET_OBJECT* ptTargetArrayTemp = (TARGET_OBJECT*)DAT_Target_Temp;
|
|
|
|
|
|
TARGET_OBJECT* ptTargetArrayCombine = (TARGET_OBJECT*)DAT_Target_Combine;
|
|
|
|
|
|
memset(ptTargetArray, 0, sizeof(TARGET_OBJECT) * DAT_TARGET_NUM_MAX);
|
|
|
|
|
|
memset(ptTargetArrayTemp, 0, sizeof(TARGET_OBJECT) * DAT_TARGET_NUM_MAX);
|
|
|
|
|
|
memset(ptTargetArrayCombine, 0, sizeof(TARGET_OBJECT) * DAT_TARGET_NUM_MAX);
|
|
|
|
|
|
|
|
|
|
|
|
//20161116,初始化灰度残差图
|
|
|
|
|
|
SINT32* pnTgBgDiff = (SINT32*)DAT_DIFF;
|
|
|
|
|
|
memset(pnTgBgDiff, 0, sizeof(SINT32) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_GradSegmentation()
|
|
|
|
|
|
* 功能描述:梯度分割
|
|
|
|
|
|
* 输入参数:UINT16 *pnImg -- 输入图像
|
|
|
|
|
|
* SIZE32S snImgSize -- 输入图像尺寸
|
|
|
|
|
|
* SINT32 *pnIntImg -- 输入图像积分图
|
|
|
|
|
|
* SIZE32S snIntImgSize-- 积分图尺寸
|
|
|
|
|
|
* SINT32 nRadius -- 邻域半径
|
|
|
|
|
|
* SINT32 nRadiusTG -- 目标半径
|
|
|
|
|
|
* SINT32 nThresMin -- 分割阈值下限
|
|
|
|
|
|
* 输出参数:UBYTE8 *pnBinary -- 二值化图像
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:在输入图像上,查找与邻域背景均值差异满足阈值的点,作为二值化分割点。
|
|
|
|
|
|
* 1)减少计算复杂度:边界不处理,将有效计算区域向内缩小邻域矩形块半径(nRadius)个像素。
|
|
|
|
|
|
* 2)利用积分图g,求(m,n)、(i,j)所成矩形内的像素值累加和:
|
|
|
|
|
|
* RectSum = g(m,n) - g(m,j)
|
|
|
|
|
|
* -g(i,n) + g(i,j)
|
|
|
|
|
|
* 3)固定分割阈值:为nThresMin
|
|
|
|
|
|
* 4)输入图像(i,j)点,对应于积分图像上的(i+1,j+1)点。
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void DetectAreaObj::DAT_GradSegmentation(UINT16* pnImg, SIZE32S snImgSize,
|
|
|
|
|
|
SINT32* pnIntImg, SIZE32S snIntImgSize,
|
|
|
|
|
|
SINT32 nRadius, SINT32 nRadiusTG, SINT32 nThresMin,
|
|
|
|
|
|
UBYTE8* pnBinary)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 i, j;
|
|
|
|
|
|
SINT32 nBorder = 1; //不处理的边界大小
|
|
|
|
|
|
SINT32 nUnvalid = nRadius + nBorder;//无效区域(不处理)的总大小
|
|
|
|
|
|
SINT32 nDiameter = 2 * nRadius + 1; //邻域直径
|
|
|
|
|
|
SINT32 nTGSize = (2 * nRadiusTG + 1) * (2 * nRadiusTG + 1); //目标矩形像素个数
|
|
|
|
|
|
SINT32 nBlkSize = nDiameter * nDiameter - nTGSize; //邻域矩形像素个数(去除目标矩形)
|
|
|
|
|
|
SINT32 nLine = 0; //当前点行起始坐标(输入图像、二值化图像)
|
|
|
|
|
|
SINT32 nBlkFirstLn = 0; //邻域起始行坐标(积分图)
|
|
|
|
|
|
SINT32 nBlkLastLn = 0; //邻域末尾行坐标(积分图)
|
|
|
|
|
|
SINT32 nTGFirstLn = 0; //目标起始行坐标(积分图)
|
|
|
|
|
|
SINT32 nTGLastLn = 0; //目标末尾行坐标(积分图)
|
|
|
|
|
|
SINT32 nCurrId = 0; //当前点图像坐标(输入图像、二值化图像)
|
|
|
|
|
|
SINT32 nCurrValue = 0; //当前像素值(输入图像)
|
|
|
|
|
|
SINT32 nBlkMean = 0; //邻域均值(积分图)
|
|
|
|
|
|
SINT32 nTGSum = 0; //目标像素值之和(积分图)
|
|
|
|
|
|
SINT32 nTGMean = 0; //目标均值(积分图)
|
|
|
|
|
|
MINMAXRECT32S mrnRectValid; //有效计算区域矩形
|
|
|
|
|
|
MINMAXRECT32S mrnIntBlkRect;//邻域块矩形(积分图)
|
|
|
|
|
|
MINMAXRECT32S mrnIntTGRect; //目标矩形(积分图)
|
|
|
|
|
|
SINT16 nMaxIters = DAT_MAX_SEG_TIMES;
|
|
|
|
|
|
|
|
|
|
|
|
//20161113Whao,计算的总有效点数
|
|
|
|
|
|
UBYTE8 nIter = 0; //迭代次数
|
|
|
|
|
|
SINT32 nTotalPnts = 0; //总的点数
|
|
|
|
|
|
SINT32 nValidPnts = 0; //二値化为1的有效点数
|
|
|
|
|
|
FLOAT32 fValidRatio = 0.0f; //二值分割后的有效点占比
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算有效区域矩形
|
|
|
|
|
|
mrnRectValid.minX = nUnvalid;
|
|
|
|
|
|
mrnRectValid.maxX = snImgSize.w - 1 - nUnvalid;
|
|
|
|
|
|
mrnRectValid.minY = nUnvalid;
|
|
|
|
|
|
mrnRectValid.maxY = snImgSize.h - 1 - nUnvalid;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//初始化背景邻域块矩形、起始及末尾行坐标
|
|
|
|
|
|
mrnIntBlkRect.minY = mrnRectValid.minY - nRadius;
|
|
|
|
|
|
mrnIntBlkRect.maxY = mrnRectValid.minY + 1 + nRadius;
|
|
|
|
|
|
mrnIntBlkRect.minX = mrnRectValid.minX - nRadius;
|
|
|
|
|
|
mrnIntBlkRect.maxX = mrnRectValid.minX + 1 + nRadius;
|
|
|
|
|
|
nBlkFirstLn = mrnIntBlkRect.minY * snIntImgSize.w;
|
|
|
|
|
|
nBlkLastLn = mrnIntBlkRect.maxY * snIntImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//初始化目标矩形、起始及末尾行坐标
|
|
|
|
|
|
mrnIntTGRect.minY = mrnRectValid.minY - nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.maxY = mrnRectValid.minY + 1 + nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.minX = mrnRectValid.minX - nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.maxX = mrnRectValid.minX + 1 + nRadiusTG;
|
|
|
|
|
|
nTGFirstLn = mrnIntTGRect.minY * snIntImgSize.w;
|
|
|
|
|
|
nTGLastLn = mrnIntTGRect.maxY * snIntImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//20161113Whao,计算的总有效点数
|
|
|
|
|
|
nTotalPnts = (mrnRectValid.maxY - mrnRectValid.minY + 1) * (mrnRectValid.maxX - mrnRectValid.minX + 1);
|
|
|
|
|
|
|
|
|
|
|
|
for (nIter = 0; nIter < nMaxIters; nIter++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//20161113,重置二値化结果数组
|
|
|
|
|
|
memset(pnBinary, 0, sizeof(UBYTE8) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
nValidPnts = 0;
|
|
|
|
|
|
nLine = mrnRectValid.minY * snImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//初始化背景邻域块矩形、起始及末尾行坐标
|
|
|
|
|
|
mrnIntBlkRect.minY = mrnRectValid.minY - nRadius;
|
|
|
|
|
|
mrnIntBlkRect.maxY = mrnRectValid.minY + 1 + nRadius;
|
|
|
|
|
|
mrnIntBlkRect.minX = mrnRectValid.minX - nRadius;
|
|
|
|
|
|
mrnIntBlkRect.maxX = mrnRectValid.minX + 1 + nRadius;
|
|
|
|
|
|
nBlkFirstLn = mrnIntBlkRect.minY * snIntImgSize.w;
|
|
|
|
|
|
nBlkLastLn = mrnIntBlkRect.maxY * snIntImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//初始化目标矩形、起始及末尾行坐标
|
|
|
|
|
|
mrnIntTGRect.minY = mrnRectValid.minY - nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.maxY = mrnRectValid.minY + 1 + nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.minX = mrnRectValid.minX - nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.maxX = mrnRectValid.minX + 1 + nRadiusTG;
|
|
|
|
|
|
nTGFirstLn = mrnIntTGRect.minY * snIntImgSize.w;
|
|
|
|
|
|
nTGLastLn = mrnIntTGRect.maxY * snIntImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//在梯度图上,查找与邻域背景均值差异满足阈值的点,作为二值化特征点。
|
|
|
|
|
|
//注:积分图pnIntImg比原始图像pnImg扩大了1行(上侧)、1列(左侧),
|
|
|
|
|
|
nLine = mrnRectValid.minY * snImgSize.w;
|
|
|
|
|
|
for (i = mrnRectValid.minY; i <= mrnRectValid.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnRectValid.minX; j <= mrnRectValid.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//当前点坐标、像素值(输入图像、二值化图像)
|
|
|
|
|
|
nCurrId = nLine + j;
|
|
|
|
|
|
nCurrValue = pnImg[nCurrId];
|
|
|
|
|
|
|
|
|
|
|
|
//计算目标均值
|
|
|
|
|
|
nTGSum = pnIntImg[nTGFirstLn + mrnIntTGRect.minX]
|
|
|
|
|
|
- pnIntImg[nTGFirstLn + mrnIntTGRect.maxX]
|
|
|
|
|
|
- pnIntImg[nTGLastLn + mrnIntTGRect.minX]
|
|
|
|
|
|
+ pnIntImg[nTGLastLn + mrnIntTGRect.maxX];
|
|
|
|
|
|
nTGMean = nTGSum / nTGSize;
|
|
|
|
|
|
|
|
|
|
|
|
//计算邻域均值(去除目标矩形后)
|
|
|
|
|
|
nBlkMean = pnIntImg[nBlkFirstLn + mrnIntBlkRect.minX]
|
|
|
|
|
|
- pnIntImg[nBlkFirstLn + mrnIntBlkRect.maxX]
|
|
|
|
|
|
- pnIntImg[nBlkLastLn + mrnIntBlkRect.minX]
|
|
|
|
|
|
+ pnIntImg[nBlkLastLn + mrnIntBlkRect.maxX];
|
|
|
|
|
|
nBlkMean = (nBlkMean - nTGSum) / nBlkSize;
|
|
|
|
|
|
|
|
|
|
|
|
//将梯度值比背景梯度均值大nThresMin的像素标记为显著点
|
|
|
|
|
|
if (nTGMean - nBlkMean > nThresMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
pnBinary[nCurrId] = DAT_FLAG_BINARY;
|
|
|
|
|
|
nValidPnts++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//更新邻域块矩形(积分图)X坐标范围
|
|
|
|
|
|
mrnIntBlkRect.minX++;
|
|
|
|
|
|
mrnIntBlkRect.maxX++;
|
|
|
|
|
|
|
|
|
|
|
|
//更新目标矩形(积分图)X坐标范围
|
|
|
|
|
|
mrnIntTGRect.minX++;
|
|
|
|
|
|
mrnIntTGRect.maxX++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//更新当前点行起始坐标(输入图像、二值化图像)
|
|
|
|
|
|
nLine += snImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//邻域块矩形(积分图)Y坐标范围、X坐标范围
|
|
|
|
|
|
mrnIntBlkRect.minY++;
|
|
|
|
|
|
mrnIntBlkRect.maxY++;
|
|
|
|
|
|
mrnIntBlkRect.minX = mrnRectValid.minX - nRadius;
|
|
|
|
|
|
mrnIntBlkRect.maxX = mrnRectValid.minX + 1 + nRadius;
|
|
|
|
|
|
nBlkFirstLn += snIntImgSize.w;
|
|
|
|
|
|
nBlkLastLn += snIntImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//目标矩形(积分图)Y坐标范围、X坐标范围
|
|
|
|
|
|
mrnIntTGRect.minY++;
|
|
|
|
|
|
mrnIntTGRect.maxY++;
|
|
|
|
|
|
mrnIntTGRect.minX = mrnRectValid.minX - nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.maxX = mrnRectValid.minX + 1 + nRadiusTG;
|
|
|
|
|
|
nTGFirstLn += snIntImgSize.w;
|
|
|
|
|
|
nTGLastLn += snIntImgSize.w;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 20171107zy:对超大面目标不进行有效点的判断
|
|
|
|
|
|
//20161113Whao,如果有效点数在阈值范围内跳出,否则调整分割阈值
|
|
|
|
|
|
fValidRatio = (FLOAT32)nValidPnts / (FLOAT32)nTotalPnts;
|
|
|
|
|
|
if (fValidRatio > DAT_MIN_GRAD_SEG_RATIO && fValidRatio < DAT_MAX_GRAD_SEG_RATIO)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGradThresMin = nThresMin;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (fValidRatio < DAT_MIN_GRAD_SEG_RATIO)
|
|
|
|
|
|
{
|
|
|
|
|
|
nThresMin = (nThresMin + DAT_GRAD_THRES_MIN) / 2;
|
|
|
|
|
|
nThresMin = MAX(nThresMin, DAT_GRAD_THRES_MIN);
|
|
|
|
|
|
if (DAT_GRAD_THRES_MIN == nThresMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGradThresMin = nThresMin;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (fValidRatio > DAT_MAX_GRAD_SEG_RATIO)
|
|
|
|
|
|
{
|
|
|
|
|
|
nThresMin = (nThresMin + DAT_GRAD_THRES_MAX) / 2;
|
|
|
|
|
|
nThresMin = MIN(nThresMin, DAT_GRAD_THRES_MAX);
|
|
|
|
|
|
if (DAT_GRAD_THRES_MAX == nThresMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGradThresMin = nThresMin;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//不处理
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//20161113Whao,更新梯度分割阈值
|
|
|
|
|
|
m_DAT_stPara.nGradThresMin = nThresMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_CalcTgBgDiff()
|
|
|
|
|
|
* 功能描述:计算目标背景差异图
|
|
|
|
|
|
* 输入参数:UINT16 *pFrame -- 输入图像
|
|
|
|
|
|
* SIZE32S snImgSize -- 输入图像尺寸
|
|
|
|
|
|
* SINT32 *pnIntImg -- 输入图像积分图
|
|
|
|
|
|
* SIZE32S snIntImgSize-- 积分图尺寸
|
|
|
|
|
|
* SINT32 nRadius -- 邻域半径
|
|
|
|
|
|
* SINT32 nRadiusTG -- 目标半径
|
|
|
|
|
|
* SINT32 nThresMin -- 分割阈值下限
|
|
|
|
|
|
* 输出参数:UBYTE8 *pnBinary -- 二值化图像
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:在输入图像上,查找与邻域背景均值差异满足阈值的点,作为二值化分割点。
|
|
|
|
|
|
* 1)减少计算复杂度:边界不处理,将有效计算区域向内缩小邻域矩形块半径(nRadius)个像素。
|
|
|
|
|
|
* 2)利用积分图g,求(m,n)、(i,j)所成矩形内的像素值累加和:
|
|
|
|
|
|
* RectSum = g(m,n) - g(m,j)
|
|
|
|
|
|
* -g(i,n) + g(i,j)
|
|
|
|
|
|
* 3)固定分割阈值:为nThresMin
|
|
|
|
|
|
* 4)输入图像(i,j)点,对应于积分图像上的(i+1,j+1)点。
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void DetectAreaObj::DAT_CalcTgBgDiff(UINT16* pFrame, SIZE32S snImgSize,
|
|
|
|
|
|
SINT32* pnIntImg, SIZE32S snIntImgSize,
|
|
|
|
|
|
SINT32 nRadius, SINT32 nRadiusTG,
|
|
|
|
|
|
SINT32* pnTgBgDiff)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 i, j;
|
|
|
|
|
|
SINT32 nBorder = 1; //不处理的边界大小
|
|
|
|
|
|
SINT32 nUnvalid = nRadius + nBorder;//无效区域(不处理)的总大小
|
|
|
|
|
|
SINT32 nDiameter = 2 * nRadius + 1; //邻域直径
|
|
|
|
|
|
SINT32 nTGSize = (2 * nRadiusTG + 1) * (2 * nRadiusTG + 1); //目标矩形像素个数
|
|
|
|
|
|
SINT32 nBlkSize = nDiameter * nDiameter - nTGSize; //邻域矩形像素个数(去除目标矩形)
|
|
|
|
|
|
SINT32 nLine = 0; //当前点行起始坐标(输入图像、二值化图像)
|
|
|
|
|
|
SINT32 nBlkFirstLn = 0; //邻域起始行坐标(积分图)
|
|
|
|
|
|
SINT32 nBlkLastLn = 0; //邻域末尾行坐标(积分图)
|
|
|
|
|
|
SINT32 nTGFirstLn = 0; //目标起始行坐标(积分图)
|
|
|
|
|
|
SINT32 nTGLastLn = 0; //目标末尾行坐标(积分图)
|
|
|
|
|
|
SINT32 nCurrId = 0; //当前点图像坐标(输入图像、二值化图像)
|
|
|
|
|
|
SINT32 nCurrValue = 0; //当前像素值(输入图像)
|
|
|
|
|
|
SINT32 nBlkMean = 0; //邻域均值(积分图)
|
|
|
|
|
|
SINT32 nTGSum = 0; //目标像素值之和(积分图)
|
|
|
|
|
|
SINT32 nTGMean = 0; //目标均值(积分图)
|
|
|
|
|
|
SINT32 nImgMean = 0; //图像均值(输入图像)
|
|
|
|
|
|
MINMAXRECT32S mrnRectValid; //有效计算区域矩形
|
|
|
|
|
|
MINMAXRECT32S mrnIntBlkRect;//邻域块矩形(积分图)
|
|
|
|
|
|
MINMAXRECT32S mrnIntTGRect; //目标矩形(积分图)
|
|
|
|
|
|
|
|
|
|
|
|
//20161113Whao,计算的总有效点数
|
|
|
|
|
|
//UBYTE8 nIter = 0; //迭代次数
|
|
|
|
|
|
//SINT32 nTotalPnts = 0; //总的点数
|
|
|
|
|
|
//SINT32 nValidPnts = 0; //二値化为1的有效点数
|
|
|
|
|
|
//FLOAT32 fValidRatio = 0.0f; //二值分割后的有效点占比
|
|
|
|
|
|
|
|
|
|
|
|
//20161114Whao,计算邻域上下左右均值
|
|
|
|
|
|
SINT32 nBlkMeanUp = 0; //上邻域均值
|
|
|
|
|
|
SINT32 nBlkMeanDown = 0; //上邻域均值
|
|
|
|
|
|
SINT32 nBlkMeanLeft = 0; //上邻域均值
|
|
|
|
|
|
SINT32 nBlkMeanRight = 0; //上邻域均值
|
|
|
|
|
|
SINT32 nBlkSizeUp = 0; //上邻域矩形像素个数
|
|
|
|
|
|
SINT32 nBlkSizeDown = 0; //上邻域矩形像素个数
|
|
|
|
|
|
SINT32 nBlkSizeLeft = 0; //上邻域矩形像素个数
|
|
|
|
|
|
SINT32 nBlkSizeRight = 0; //上邻域矩形像素个数
|
|
|
|
|
|
SINT32 BlkMeanArray[4] = { 0 };
|
|
|
|
|
|
SINT32* pnBlkMeanArray = BlkMeanArray;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算全图均值
|
|
|
|
|
|
nImgMean = pnIntImg[snIntImgSize.s - 1] / snImgSize.s;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算有效区域矩形
|
|
|
|
|
|
mrnRectValid.minX = nUnvalid;
|
|
|
|
|
|
mrnRectValid.maxX = snImgSize.w - 1 - nUnvalid;
|
|
|
|
|
|
mrnRectValid.minY = nUnvalid;
|
|
|
|
|
|
mrnRectValid.maxY = snImgSize.h - 1 - nUnvalid;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//初始化背景邻域块矩形、起始及末尾行坐标
|
|
|
|
|
|
mrnIntBlkRect.minY = mrnRectValid.minY - nRadius;
|
|
|
|
|
|
mrnIntBlkRect.maxY = mrnRectValid.minY + 1 + nRadius;
|
|
|
|
|
|
mrnIntBlkRect.minX = mrnRectValid.minX - nRadius;
|
|
|
|
|
|
mrnIntBlkRect.maxX = mrnRectValid.minX + 1 + nRadius;
|
|
|
|
|
|
nBlkFirstLn = mrnIntBlkRect.minY * snIntImgSize.w;
|
|
|
|
|
|
nBlkLastLn = mrnIntBlkRect.maxY * snIntImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//初始化目标矩形、起始及末尾行坐标
|
|
|
|
|
|
mrnIntTGRect.minY = mrnRectValid.minY - nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.maxY = mrnRectValid.minY + 1 + nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.minX = mrnRectValid.minX - nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.maxX = mrnRectValid.minX + 1 + nRadiusTG;
|
|
|
|
|
|
nTGFirstLn = mrnIntTGRect.minY * snIntImgSize.w;
|
|
|
|
|
|
nTGLastLn = mrnIntTGRect.maxY * snIntImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//在梯度图上,查找与邻域背景均值差异满足阈值的点,作为二值化特征点。
|
|
|
|
|
|
//注:积分图pnIntImg比原始图像pnImg扩大了1行(上侧)、1列(左侧),
|
|
|
|
|
|
nLine = mrnRectValid.minY * snImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//20161115,上下左右邻域点个数仅计算一次
|
|
|
|
|
|
nBlkSizeUp = (mrnIntTGRect.minY - mrnIntBlkRect.minY)
|
|
|
|
|
|
* (mrnIntTGRect.maxX - mrnIntTGRect.minX);
|
|
|
|
|
|
nBlkSizeDown = nBlkSizeUp;
|
|
|
|
|
|
nBlkSizeLeft = nBlkSizeUp;
|
|
|
|
|
|
nBlkSizeRight = nBlkSizeUp;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//20161115,计算目标背景残差图
|
|
|
|
|
|
for (i = mrnRectValid.minY; i <= mrnRectValid.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnRectValid.minX; j <= mrnRectValid.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//当前点坐标、像素值(输入图像、二值化图像)
|
|
|
|
|
|
nCurrId = nLine + j;
|
|
|
|
|
|
nCurrValue = pFrame[nCurrId];
|
|
|
|
|
|
|
|
|
|
|
|
//计算上背景邻域
|
|
|
|
|
|
nBlkMeanUp = pnIntImg[nBlkFirstLn + mrnIntTGRect.minX]
|
|
|
|
|
|
- pnIntImg[nTGFirstLn + mrnIntTGRect.minX]
|
|
|
|
|
|
- pnIntImg[nBlkFirstLn + mrnIntTGRect.maxX]
|
|
|
|
|
|
+ pnIntImg[nTGFirstLn + mrnIntTGRect.maxX];
|
|
|
|
|
|
|
|
|
|
|
|
nBlkMeanUp = nBlkMeanUp / nBlkSizeUp;
|
|
|
|
|
|
pnBlkMeanArray[0] = nBlkMeanUp;
|
|
|
|
|
|
|
|
|
|
|
|
//计算下背景邻域 ok
|
|
|
|
|
|
nBlkMeanDown = pnIntImg[nTGLastLn + mrnIntTGRect.minX]
|
|
|
|
|
|
- pnIntImg[nTGLastLn + mrnIntTGRect.maxX]
|
|
|
|
|
|
- pnIntImg[nBlkLastLn + mrnIntTGRect.minX]
|
|
|
|
|
|
+ pnIntImg[nBlkLastLn + mrnIntTGRect.maxX];
|
|
|
|
|
|
|
|
|
|
|
|
nBlkMeanDown = nBlkMeanDown / nBlkSizeDown;
|
|
|
|
|
|
pnBlkMeanArray[1] = nBlkMeanDown;
|
|
|
|
|
|
|
|
|
|
|
|
//计算左背景邻域 ok
|
|
|
|
|
|
nBlkMeanLeft = pnIntImg[nTGFirstLn + mrnIntBlkRect.minX]
|
|
|
|
|
|
- pnIntImg[nTGFirstLn + mrnIntTGRect.minX]
|
|
|
|
|
|
- pnIntImg[nTGLastLn + mrnIntBlkRect.minX]
|
|
|
|
|
|
+ pnIntImg[nTGLastLn + mrnIntTGRect.minX];
|
|
|
|
|
|
|
|
|
|
|
|
nBlkMeanLeft = nBlkMeanLeft / nBlkSizeLeft;
|
|
|
|
|
|
pnBlkMeanArray[2] = nBlkMeanLeft;
|
|
|
|
|
|
|
|
|
|
|
|
//计算右背景邻域 ok
|
|
|
|
|
|
nBlkMeanRight = pnIntImg[nTGFirstLn + mrnIntTGRect.maxX]
|
|
|
|
|
|
- pnIntImg[nTGFirstLn + mrnIntBlkRect.maxX]
|
|
|
|
|
|
- pnIntImg[nTGLastLn + mrnIntTGRect.maxX]
|
|
|
|
|
|
+ pnIntImg[nTGLastLn + mrnIntBlkRect.maxX];
|
|
|
|
|
|
|
|
|
|
|
|
nBlkMeanRight = nBlkMeanRight / nBlkSizeRight;
|
|
|
|
|
|
pnBlkMeanArray[3] = nBlkMeanRight;
|
|
|
|
|
|
|
|
|
|
|
|
//20161114,排序取次小值
|
|
|
|
|
|
if (GLB_OBJ_GRAY_DARK == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
nBlkMean = FindMinOfFour(pnBlkMeanArray);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 20171016zy: 仅筛选特别亮的点
|
|
|
|
|
|
nBlkMean = FindMaxOfFour(pnBlkMeanArray);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//不处理
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pnTgBgDiff[nCurrId] = nCurrValue - nBlkMean;
|
|
|
|
|
|
|
|
|
|
|
|
//更新邻域块矩形(积分图)X坐标范围
|
|
|
|
|
|
mrnIntBlkRect.minX++;
|
|
|
|
|
|
mrnIntBlkRect.maxX++;
|
|
|
|
|
|
|
|
|
|
|
|
//更新目标矩形(积分图)X坐标范围
|
|
|
|
|
|
mrnIntTGRect.minX++;
|
|
|
|
|
|
mrnIntTGRect.maxX++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//更新当前点行起始坐标(输入图像、二值化图像)
|
|
|
|
|
|
nLine += snImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//邻域块矩形(积分图)Y坐标范围、X坐标范围
|
|
|
|
|
|
mrnIntBlkRect.minY++;
|
|
|
|
|
|
mrnIntBlkRect.maxY++;
|
|
|
|
|
|
mrnIntBlkRect.minX = mrnRectValid.minX - nRadius;
|
|
|
|
|
|
mrnIntBlkRect.maxX = mrnRectValid.minX + 1 + nRadius;
|
|
|
|
|
|
nBlkFirstLn = mrnIntBlkRect.minY * snIntImgSize.w;
|
|
|
|
|
|
nBlkLastLn = mrnIntBlkRect.maxY * snIntImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//目标矩形(积分图)Y坐标范围、X坐标范围
|
|
|
|
|
|
mrnIntTGRect.minY++;
|
|
|
|
|
|
mrnIntTGRect.maxY++;
|
|
|
|
|
|
mrnIntTGRect.minX = mrnRectValid.minX - nRadiusTG;
|
|
|
|
|
|
mrnIntTGRect.maxX = mrnRectValid.minX + 1 + nRadiusTG;
|
|
|
|
|
|
nTGFirstLn += snIntImgSize.w;
|
|
|
|
|
|
nTGLastLn += snIntImgSize.w;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_GraySegmentation()
|
|
|
|
|
|
* 功能描述:灰度分割
|
|
|
|
|
|
* 输入参数:UINT16 *pFrame -- 输入图像
|
|
|
|
|
|
* SIZE32S snImgSize -- 输入图像尺寸
|
|
|
|
|
|
* SINT32 *pnIntImg -- 输入图像积分图
|
|
|
|
|
|
* SIZE32S snIntImgSize-- 积分图尺寸
|
|
|
|
|
|
* SINT32 nRadius -- 邻域半径
|
|
|
|
|
|
* SINT32 nRadiusTG -- 目标半径
|
|
|
|
|
|
* SINT32 nThresMin -- 分割阈值下限
|
|
|
|
|
|
* 输出参数:UBYTE8 *pnBinary -- 二值化图像
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:在输入图像上,查找与邻域背景均值差异满足阈值的点,作为二值化分割点。
|
|
|
|
|
|
* 1)减少计算复杂度:边界不处理,将有效计算区域向内缩小邻域矩形块半径(nRadius)个像素。
|
|
|
|
|
|
* 2)利用积分图g,求(m,n)、(i,j)所成矩形内的像素值累加和:
|
|
|
|
|
|
* RectSum = g(m,n) - g(m,j)
|
|
|
|
|
|
* -g(i,n) + g(i,j)
|
|
|
|
|
|
* 3)固定分割阈值:为nThresMin
|
|
|
|
|
|
* 4)输入图像(i,j)点,对应于积分图像上的(i+1,j+1)点。
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void DetectAreaObj::DAT_GraySegmentation(SIZE32S snImgSize, SINT32 nRadius, SINT32 nThresMin,
|
|
|
|
|
|
UBYTE8* pnBinary, SINT32* pnTgBgDiff, BBOOL changeDetParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 i, j;
|
|
|
|
|
|
SINT32 nBorder = 1; //不处理的边界大小
|
|
|
|
|
|
SINT32 nUnvalid = nRadius + nBorder;//无效区域(不处理)的总大小
|
|
|
|
|
|
SINT32 nLine = 0; //当前点行起始坐标(输入图像、二值化图像)
|
|
|
|
|
|
SINT32 nCurrId = 0; //当前点图像坐标(输入图像、二值化图像)
|
|
|
|
|
|
MINMAXRECT32S mrnRectValid; //有效计算区域矩形
|
|
|
|
|
|
SINT16 nMaxIters = DAT_MAX_SEG_TIMES; //最大迭代次数
|
|
|
|
|
|
|
|
|
|
|
|
//20161113Whao,计算的总有效点数
|
|
|
|
|
|
UBYTE8 nIter = 0; //迭代次数
|
|
|
|
|
|
SINT32 nTotalPnts = 0; //总的点数
|
|
|
|
|
|
SINT32 nValidPnts = 0; //二値化为1的有效点数
|
|
|
|
|
|
FLOAT32 fValidRatio = 0.0f; //二值分割后的有效点占比
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//计算有效区域矩形
|
|
|
|
|
|
mrnRectValid.minX = nUnvalid;
|
|
|
|
|
|
mrnRectValid.maxX = snImgSize.w - 1 - nUnvalid;
|
|
|
|
|
|
mrnRectValid.minY = nUnvalid;
|
|
|
|
|
|
mrnRectValid.maxY = snImgSize.h - 1 - nUnvalid;
|
|
|
|
|
|
|
|
|
|
|
|
//20161113Whao,计算的总有效点数
|
|
|
|
|
|
nTotalPnts = (mrnRectValid.maxY - mrnRectValid.minY + 1) * (mrnRectValid.maxX - mrnRectValid.minX + 1);
|
|
|
|
|
|
|
|
|
|
|
|
nLine = mrnRectValid.minY * snImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//在梯度图上,查找与邻域背景均值差异满足阈值的点,作为二值化特征点。
|
|
|
|
|
|
//注:积分图pnIntImg比原始图像pnImg扩大了1行(上侧)、1列(左侧),
|
|
|
|
|
|
//20161113Whao,增加最大迭代次数和有效点占比判断
|
|
|
|
|
|
for (nIter = 0; nIter < nMaxIters; nIter++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//20161113,重置二値化结果数组
|
|
|
|
|
|
memset(pnBinary, 0, sizeof(UBYTE8) * DAT_CENTER_REGION_SIZE);
|
|
|
|
|
|
nValidPnts = 0;
|
|
|
|
|
|
nLine = mrnRectValid.minY * snImgSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
for (i = mrnRectValid.minY; i <= mrnRectValid.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnRectValid.minX; j <= mrnRectValid.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//当前点坐标、像素值(输入图像、二值化图像)
|
|
|
|
|
|
nCurrId = nLine + j;
|
|
|
|
|
|
|
|
|
|
|
|
//将灰度值比背景均值大nThresMin的像素标记为显著点
|
|
|
|
|
|
//MSSu, 20150513: 面目标增加暗目标检测模式
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pnTgBgDiff[nCurrId] > nThresMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
pnBinary[nCurrId] = DAT_FLAG_BINARY;
|
|
|
|
|
|
nValidPnts++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_DARK == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pnTgBgDiff[nCurrId] < -nThresMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
pnBinary[nCurrId] = DAT_FLAG_BINARY; //DAT_FLAG_BINARY_DARK;
|
|
|
|
|
|
nValidPnts++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//if (ABS(nCurrValue - nBlkMean) > nThresMin)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// pnBinary[nCurrId] = DAT_FLAG_BINARY;
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
//不处理
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//更新当前点行起始坐标(输入图像、二值化图像)
|
|
|
|
|
|
nLine += snImgSize.w;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//跟踪状态不调整分割阈值(老版本)
|
|
|
|
|
|
//==========20171017zy: 跟踪状态下,也进行分割阈值的调整,注释下面=============
|
|
|
|
|
|
//if (GLB_STATUS_TRACK == m_GLB_stPara.nStatus)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// break;
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
// 20171107zy: 添加超大面目标限制,超不面目标不进行有效点判断
|
|
|
|
|
|
//20161113Whao,如果有效点数在阈值范围内跳出,否则调整分割阈值
|
|
|
|
|
|
if (false == changeDetParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fValidRatio = (FLOAT32)nValidPnts / (FLOAT32)nTotalPnts;
|
|
|
|
|
|
if (fValidRatio > DAT_MIN_GRAY_SEG_RATIO && fValidRatio < DAT_MAX_GRAY_SEG_RATIO)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinBright = nThresMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinDark = nThresMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (fValidRatio < DAT_MIN_GRAY_SEG_RATIO)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
nThresMin = (SINT32)(0.7 * nThresMin + 0.3 * DAT_GRAY_THRES_BRIGHT_MIN);
|
|
|
|
|
|
nThresMin = MAX(nThresMin, DAT_GRAY_THRES_BRIGHT_MIN);
|
|
|
|
|
|
if (DAT_GRAY_THRES_BRIGHT_MIN == nThresMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinBright = nThresMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
nThresMin = (SINT32)(0.7 * nThresMin + 0.3 * DAT_GRAY_THRES_DARK_MIN);
|
|
|
|
|
|
nThresMin = MAX(nThresMin, DAT_GRAY_THRES_DARK_MIN);
|
|
|
|
|
|
if (DAT_GRAY_THRES_DARK_MIN == nThresMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinDark = nThresMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (fValidRatio > DAT_MAX_GRAY_SEG_RATIO)
|
|
|
|
|
|
{
|
|
|
|
|
|
//nThresMin = (nThresMin + DAT_GRAY_THRES_MAX) / 2;
|
|
|
|
|
|
// 20171016zy 修改迭代阈值的变化比例
|
|
|
|
|
|
nThresMin = (SINT32)(0.7 * nThresMin + 0.3 * DAT_GRAY_THRES_MAX);
|
|
|
|
|
|
nThresMin = MIN(nThresMin, DAT_GRAY_THRES_MAX);
|
|
|
|
|
|
if (DAT_GRAY_THRES_MAX == nThresMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinBright = nThresMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinDark = nThresMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//不处理
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (true == changeDetParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
//20161113Whao,更新亮暗目标分割阈值
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinBright = nThresMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
m_DAT_stPara.nGrayThresMinDark = nThresMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_ObjsSegmentation()
|
|
|
|
|
|
* 功能描述:目标分割
|
|
|
|
|
|
* 输入参数:UINT16 *pFrame -- 原始图像(降采样后)
|
|
|
|
|
|
* UBYTE8 *pnGrayBinary -- 灰度二值图(降采样后)
|
|
|
|
|
|
* UBYTE8 *pnGradBinary -- 梯度二值图(降采样后)
|
|
|
|
|
|
* SIZE32S snImgSize -- 输入图像尺寸(降采样后)
|
|
|
|
|
|
* SINT32 *pnGrayInt -- 灰度积分图
|
|
|
|
|
|
* SINT32 *pnGradInt -- 梯度积分图
|
|
|
|
|
|
* SIZE32S snIntSize -- 积分图尺寸
|
|
|
|
|
|
* SIZE32S snBlksNum -- 分块个数
|
|
|
|
|
|
* SINT32 nDSmpScale -- 降采样倍数
|
|
|
|
|
|
* MINMAXRECT32S mrnSrRect -- 搜索区域矩形(原始图像)
|
|
|
|
|
|
* SINT32 nFrmObjsMax -- 单帧检测目标的最大个数
|
|
|
|
|
|
* 输出参数:TARGET_OBJECT *ptTargetArray-- 当前帧目标检测结果数组
|
|
|
|
|
|
* 返 回 值:SINT32 nObjsCnt -- 单帧检测的目标数量
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:在2倍降采样图像上检测目标,再还原回原始图像位置及大小。
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
SINT32 DetectAreaObj::DAT_ObjsSegmentation(UINT16* pFrame, UBYTE8* pnGrayBinary,
|
|
|
|
|
|
UBYTE8* pnGradBinary, SIZE32S snImgSize,
|
|
|
|
|
|
SINT32* pnGrayInt, SINT32* pnGradInt, SIZE32S snIntSize,
|
|
|
|
|
|
SIZE32S snBlksNum, SINT32 nDSmpScale, MINMAXRECT32S mrnSrRect,
|
|
|
|
|
|
TARGET_OBJECT* ptTargetArray, SINT32 nFrmObjsMax, GD_PIXEL_FORMAT_E enPixelFormat)
|
|
|
|
|
|
{
|
|
|
|
|
|
MINMAXRECT32S* pmrnBlksRect = (MINMAXRECT32S*)DAT_pmrnBlksRect;
|
|
|
|
|
|
UBYTE8* pnFlagHasSr = (UBYTE8*)DAT_pFlagHasSearch;
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 k, i, j;
|
|
|
|
|
|
SINT32 nObjsCnt = 0;
|
|
|
|
|
|
SIZE32S snBlksNumNew = snBlksNum;
|
|
|
|
|
|
MINMAXRECT32S mrnRect;
|
|
|
|
|
|
SINT32 nLine, nIndex;
|
|
|
|
|
|
TARGET_OBJECT tTarget; //记录单个目标
|
|
|
|
|
|
//BBOOL bSuccessFlag = FALSE;
|
|
|
|
|
|
//BBOOL bStop = FALSE;
|
|
|
|
|
|
BBOOL bTarget = FALSE;
|
|
|
|
|
|
FLOAT32 fDSmpRatio = 1.0f / (nDSmpScale * nDSmpScale);
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//初始化
|
|
|
|
|
|
memset(ptTargetArray, 0, nFrmObjsMax * sizeof(TARGET_OBJECT));
|
|
|
|
|
|
memset(pnFlagHasSr, 0, snImgSize.s * sizeof(UBYTE8));
|
|
|
|
|
|
|
|
|
|
|
|
//限制更新分块个数为奇数
|
|
|
|
|
|
snBlksNumNew.w = (0 == snBlksNumNew.w % 2) ? snBlksNumNew.w + 1 : snBlksNumNew.w;
|
|
|
|
|
|
snBlksNumNew.w = MIN(snBlksNumNew.w, DAT_SR_RGN_BLKS_NUM_W);
|
|
|
|
|
|
snBlksNumNew.h = snBlksNumNew.w;
|
|
|
|
|
|
snBlksNumNew.s = snBlksNumNew.w * snBlksNumNew.h;
|
|
|
|
|
|
m_DAT_stInput.snSrBlksNum = snBlksNumNew;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//对搜索区域进行分块
|
|
|
|
|
|
//分块的目的:因目标个数有限制,优先检测图像中心的目标
|
|
|
|
|
|
DAT_SetSearchBlks(snImgSize, snBlksNumNew, pmrnBlksRect);
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//目标分割(优先检测图像中心块)
|
|
|
|
|
|
for (k = 0; k < snBlksNumNew.s; k++)
|
|
|
|
|
|
{
|
|
|
|
|
|
mrnRect = pmrnBlksRect[k];
|
|
|
|
|
|
nLine = mrnRect.minY * snImgSize.w;
|
|
|
|
|
|
for (i = mrnRect.minY; i <= mrnRect.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnRect.minX; j <= mrnRect.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//计算当前像素坐标
|
|
|
|
|
|
nIndex = nLine + j;
|
|
|
|
|
|
|
|
|
|
|
|
//MSSu, 20150514: 弱目标检测时,灰度、梯度二值点取并集,否则取交集
|
|
|
|
|
|
BBOOL bSeedPt = FALSE;
|
|
|
|
|
|
if ((DAT_FLAG_BINARY == pnGrayBinary[nIndex]
|
|
|
|
|
|
&& DAT_FLAG_BINARY == pnGradBinary[nIndex])
|
|
|
|
|
|
&& DAT_FLAG_CONNECTED != pnFlagHasSr[nIndex])
|
|
|
|
|
|
{
|
|
|
|
|
|
bSeedPt = TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//若当前点为二值化点,且未被归类,则将其作为种子点,进行连通域搜索
|
|
|
|
|
|
if (bSeedPt)
|
|
|
|
|
|
{
|
|
|
|
|
|
//目标初始化为空
|
|
|
|
|
|
memset(&tTarget, 0, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
//区域连通
|
|
|
|
|
|
//MSSu, 20150608: 连通像素个数阈值*0.8,目的:防止计算量过大。
|
|
|
|
|
|
DAT_GetConnectedArea(pFrame, pnGrayBinary, pnGradBinary,
|
|
|
|
|
|
pnFlagHasSr, snImgSize.w, snImgSize.h, j, i,
|
|
|
|
|
|
(SINT32)(m_DAT_stPara.nObjSizeMax * fDSmpRatio * 0.8), &tTarget);
|
|
|
|
|
|
|
|
|
|
|
|
//目标确认
|
|
|
|
|
|
bTarget = DAT_IsTarget(pFrame, snImgSize, pnGrayInt,
|
|
|
|
|
|
pnGradInt, snIntSize, &tTarget, enPixelFormat);
|
|
|
|
|
|
|
|
|
|
|
|
//若确认为目标,则加入面目标数组
|
|
|
|
|
|
if (bTarget)
|
|
|
|
|
|
{
|
|
|
|
|
|
//标记为真实目标
|
|
|
|
|
|
tTarget.bObject = TRUE;
|
|
|
|
|
|
|
|
|
|
|
|
//记录帧编号 (全局耦合)
|
|
|
|
|
|
//tTarget.unFrmID = m_GLB_stInput.stParaLn.unFrmId;
|
|
|
|
|
|
|
|
|
|
|
|
// 适应目标识别算法的加入,传统检测无法获取目标类型,此处约定目标类别ID置为DT_TARGET_CLS_ID,置信度为1
|
|
|
|
|
|
tTarget.unClsType = DT_TARGET_CLS_ID;
|
|
|
|
|
|
tTarget.fDetConf = 1.0;
|
|
|
|
|
|
tTarget.nObjTypeSrc = ObjSrc::Arith_DAT;
|
|
|
|
|
|
|
|
|
|
|
|
//更新目标位置,还原到原始图像坐标系
|
|
|
|
|
|
tTarget.pfCenPos.x = (tTarget.pfCenPos.x) * nDSmpScale + mrnSrRect.minX + (nDSmpScale >> 1);
|
|
|
|
|
|
tTarget.pfCenPos.y = (tTarget.pfCenPos.y) * nDSmpScale + mrnSrRect.minY + (nDSmpScale >> 1);
|
|
|
|
|
|
tTarget.pnMaxPos.x = (SINT16)(tTarget.pnMaxPos.x * nDSmpScale + mrnSrRect.minX);
|
|
|
|
|
|
tTarget.pnMaxPos.y = (SINT16)(tTarget.pnMaxPos.y * nDSmpScale + mrnSrRect.minY);
|
|
|
|
|
|
tTarget.mrnRect.minX = tTarget.mrnRect.minX * nDSmpScale + mrnSrRect.minX;
|
|
|
|
|
|
//tTarget.mrnRect.maxX = tTarget.mrnRect.maxX * nDSmpScale + mrnSrRect.minX;
|
|
|
|
|
|
//20161207,还原回去最小值指向原始长度的第一个点,最大值指向原始长度的最后一个点
|
|
|
|
|
|
tTarget.mrnRect.maxX = tTarget.mrnRect.maxX * nDSmpScale + mrnSrRect.minX + nDSmpScale - 1;
|
|
|
|
|
|
tTarget.mrnRect.minY = tTarget.mrnRect.minY * nDSmpScale + mrnSrRect.minY;
|
|
|
|
|
|
//tTarget.mrnRect.maxY = tTarget.mrnRect.maxY * nDSmpScale + mrnSrRect.minY;
|
|
|
|
|
|
tTarget.mrnRect.maxY = tTarget.mrnRect.maxY * nDSmpScale + mrnSrRect.minY + nDSmpScale - 1;
|
|
|
|
|
|
|
|
|
|
|
|
//更新目标大小
|
|
|
|
|
|
tTarget.snSize.w *= nDSmpScale;
|
|
|
|
|
|
tTarget.snSize.h *= nDSmpScale;
|
|
|
|
|
|
tTarget.snSize.s *= (nDSmpScale * nDSmpScale);
|
|
|
|
|
|
tTarget.unObjPxlsCnt *= (nDSmpScale * nDSmpScale);
|
|
|
|
|
|
|
|
|
|
|
|
//标记目标类型
|
|
|
|
|
|
tTarget.nObjTypeSize = GLB_OBJ_SIZE_FACE;
|
|
|
|
|
|
tTarget.nObjTypeGray = (tTarget.fSNR > 0.0f) ? GLB_OBJ_GRAY_BRIGHT : GLB_OBJ_GRAY_DARK;
|
|
|
|
|
|
|
|
|
|
|
|
// //计算目标的方位角、俯仰角 (全局耦合)
|
|
|
|
|
|
// tTarget.afAngle.fAz = SERVO_CalcObjAzimuth(tTarget.pfCenPos.x,
|
|
|
|
|
|
// m_GLB_stInput.stParaLn.snImgSize.w,
|
|
|
|
|
|
// m_SERVO_stInput.fAzimuth, m_SERVO_stInput.fResolAz);
|
|
|
|
|
|
// tTarget.afAngle.fPt = SERVO_CalcObjPitching(tTarget.pfCenPos.y,
|
|
|
|
|
|
// m_GLB_stInput.stParaLn.snImgSize.h,
|
|
|
|
|
|
// m_SERVO_stInput.fPitching, m_SERVO_stInput.fResolPt);
|
|
|
|
|
|
|
|
|
|
|
|
//将目标加入单帧目标数组
|
|
|
|
|
|
ptTargetArray[nObjsCnt] = tTarget;
|
|
|
|
|
|
nObjsCnt++;
|
|
|
|
|
|
|
|
|
|
|
|
//目标个数达上限,则终止检测
|
|
|
|
|
|
if (nFrmObjsMax == nObjsCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//更新下一行起始坐标
|
|
|
|
|
|
nLine += snImgSize.w;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//目标个数达上限,则终止检测
|
|
|
|
|
|
if (nObjsCnt > nFrmObjsMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_SetSearchBlks()
|
|
|
|
|
|
* 功能描述:对搜索区域进行分块,将最中心的块放在数组首位
|
|
|
|
|
|
* 输入参数:SIZE32S snImgSize -- 输入图像尺寸(降采样后)
|
|
|
|
|
|
* SIZE32S snBlksNum -- 分块个数
|
|
|
|
|
|
* 输出参数:MINMAXRECT32S *pmrnBlksRect -- 分块矩形坐标数组
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:3*3分块顺序: 5*5分块顺序:
|
|
|
|
|
|
* 5 1 6 21 13 9 14 22
|
|
|
|
|
|
* 4 0 2 20 5 1 6 15
|
|
|
|
|
|
* 8 3 7 12 4 0 2 10
|
|
|
|
|
|
* 19 8 3 7 16
|
|
|
|
|
|
* 24 18 11 17 23
|
|
|
|
|
|
* 更多块排序效果,参见:SVN\Arith_Object_Detect_Recognise\S231-光电跟踪系统
|
|
|
|
|
|
* \trunk\src\S231_matlab_BlksSort\BlksSort.m
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void DetectAreaObj::DAT_SetSearchBlks(SIZE32S snImgSize, SIZE32S snBlksNum, MINMAXRECT32S* pmrnBlksRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 i, j, k;
|
|
|
|
|
|
SINT32 nBlkId;
|
|
|
|
|
|
SINT32 nBlkWidth = snImgSize.w / snBlksNum.w;//分块宽度
|
|
|
|
|
|
SINT32 nBlkHeight = snImgSize.h / snBlksNum.h;//分块高度
|
|
|
|
|
|
SINT32 nCenBiggerW = nBlkWidth / 4; //中间分块扩大比例
|
|
|
|
|
|
SINT32 nCenBiggerH = nBlkHeight / 4; //中间分块扩大比例
|
|
|
|
|
|
SINT32 nCenBlkW = nBlkWidth + nCenBiggerW; //中间分块宽度
|
|
|
|
|
|
SINT32 nCenBlkH = nBlkHeight + nCenBiggerH; //中间分块高度
|
|
|
|
|
|
SINT32 nOtherBlksW = (snImgSize.w - nCenBlkW) / (snBlksNum.w - 1); //其它分块宽度
|
|
|
|
|
|
SINT32 nOtherBlksH = (snImgSize.h - nCenBlkH) / (snBlksNum.h - 1); //其它分块宽度
|
|
|
|
|
|
SINT32 nCenBlkIdX = snBlksNum.w / 2; //中间分块位置X
|
|
|
|
|
|
SINT32 nCenBlkIdY = snBlksNum.h / 2; //中间分块位置Y
|
|
|
|
|
|
MINMAXRECT32S mrnRectTop, mrnRectBottom, mrnRectLeft, mrnRectRight;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//第0子块(正中间)
|
|
|
|
|
|
pmrnBlksRect[0].minY = MAX(0, MIN(nCenBlkIdY * nOtherBlksH, snImgSize.h - 1));
|
|
|
|
|
|
pmrnBlksRect[0].maxY = MAX(0, MIN(snImgSize.h - pmrnBlksRect[0].minY, snImgSize.h - 1));
|
|
|
|
|
|
pmrnBlksRect[0].minX = MAX(0, MIN(nCenBlkIdX * nOtherBlksW, snImgSize.w - 1));
|
|
|
|
|
|
pmrnBlksRect[0].maxX = MAX(0, MIN(snImgSize.w - pmrnBlksRect[0].minX, snImgSize.w - 1));
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//其它分块:从中间向外扩展
|
|
|
|
|
|
nBlkId = 1;
|
|
|
|
|
|
for (k = 1; k <= nCenBlkIdX; k++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//------------------------------
|
|
|
|
|
|
//正上方
|
|
|
|
|
|
i = nCenBlkIdY - k;
|
|
|
|
|
|
j = nCenBlkIdX;
|
|
|
|
|
|
mrnRectTop.minY = MAX(pmrnBlksRect[0].minY - k * nOtherBlksH, 0);
|
|
|
|
|
|
mrnRectTop.maxY = MAX(mrnRectTop.minY + nOtherBlksH - 1, 0);
|
|
|
|
|
|
mrnRectTop.minX = pmrnBlksRect[0].minX;
|
|
|
|
|
|
mrnRectTop.maxX = pmrnBlksRect[0].maxX;
|
|
|
|
|
|
pmrnBlksRect[nBlkId] = mrnRectTop;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//正右方
|
|
|
|
|
|
i = nCenBlkIdY;
|
|
|
|
|
|
j = nCenBlkIdX + k;
|
|
|
|
|
|
mrnRectRight.minY = pmrnBlksRect[0].minY;
|
|
|
|
|
|
mrnRectRight.maxY = pmrnBlksRect[0].maxY;
|
|
|
|
|
|
mrnRectRight.minX = MIN(pmrnBlksRect[0].maxX + (k - 1) * nOtherBlksW + 1, snImgSize.w - 1);
|
|
|
|
|
|
mrnRectRight.maxX = MIN(mrnRectRight.minX + nOtherBlksW - 1, snImgSize.w - 1);
|
|
|
|
|
|
if (k == nCenBlkIdX)
|
|
|
|
|
|
{
|
|
|
|
|
|
mrnRectRight.maxX = snImgSize.w - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
pmrnBlksRect[nBlkId] = mrnRectRight;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//正下方
|
|
|
|
|
|
i = nCenBlkIdY + k;
|
|
|
|
|
|
j = nCenBlkIdX;
|
|
|
|
|
|
mrnRectBottom.minY = MIN(pmrnBlksRect[0].maxY + (k - 1) * nOtherBlksH + 1, snImgSize.h - 1);
|
|
|
|
|
|
mrnRectBottom.maxY = MIN(mrnRectBottom.minY + nOtherBlksH - 1, snImgSize.h - 1);
|
|
|
|
|
|
mrnRectBottom.minX = pmrnBlksRect[0].minX;
|
|
|
|
|
|
mrnRectBottom.maxX = pmrnBlksRect[0].maxX;
|
|
|
|
|
|
if (k == nCenBlkIdX)
|
|
|
|
|
|
{
|
|
|
|
|
|
mrnRectBottom.maxY = snImgSize.h - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pmrnBlksRect[nBlkId] = mrnRectBottom;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//正左方
|
|
|
|
|
|
i = nCenBlkIdY;
|
|
|
|
|
|
j = nCenBlkIdX - k;
|
|
|
|
|
|
mrnRectLeft.minY = pmrnBlksRect[0].minY;
|
|
|
|
|
|
mrnRectLeft.maxY = pmrnBlksRect[0].maxY;
|
|
|
|
|
|
mrnRectLeft.minX = MAX(pmrnBlksRect[0].minX - k * nOtherBlksW, 0);
|
|
|
|
|
|
mrnRectLeft.maxX = MAX(mrnRectLeft.minX + nOtherBlksW - 1, 0);
|
|
|
|
|
|
pmrnBlksRect[nBlkId] = mrnRectLeft;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------
|
|
|
|
|
|
//其它
|
|
|
|
|
|
for (j = 1; j < k; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//上行其它列(左右对称)
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectTop.minY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = mrnRectTop.maxY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = pmrnBlksRect[0].minX - j * nOtherBlksW;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = pmrnBlksRect[nBlkId].minX + nOtherBlksW - 1;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectTop.minY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = mrnRectTop.maxY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = pmrnBlksRect[0].maxX + (j - 1) * nOtherBlksW + 1;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = pmrnBlksRect[nBlkId].minX + nOtherBlksW - 1;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//右列其它行(上下对称)
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectRight.minY - j * nOtherBlksH;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = pmrnBlksRect[nBlkId].minY + nOtherBlksH - 1;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = mrnRectRight.minX;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = mrnRectRight.maxX;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectRight.maxY + (j - 1) * nOtherBlksH + 1;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = pmrnBlksRect[nBlkId].minY + nOtherBlksH - 1;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = mrnRectRight.minX;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = mrnRectRight.maxX;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//下行其它列(左右对称)
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectBottom.minY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = mrnRectBottom.maxY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = pmrnBlksRect[0].maxX + (j - 1) * nOtherBlksW + 1;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = pmrnBlksRect[nBlkId].minX + nOtherBlksW - 1;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectBottom.minY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = mrnRectBottom.maxY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = pmrnBlksRect[0].minX - j * nOtherBlksW;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = pmrnBlksRect[nBlkId].minX + nOtherBlksW - 1;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//左列其它行(上下对称)
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectLeft.maxY + (j - 1) * nOtherBlksH + 1;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = pmrnBlksRect[nBlkId].minY + nOtherBlksH - 1;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = mrnRectLeft.minX;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = mrnRectLeft.maxX;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectLeft.minY - j * nOtherBlksH;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = pmrnBlksRect[nBlkId].minY + nOtherBlksH - 1;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = mrnRectLeft.minX;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = mrnRectLeft.maxX;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------
|
|
|
|
|
|
//左上角
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectTop.minY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = mrnRectTop.maxY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = mrnRectLeft.minX;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = mrnRectLeft.maxX;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//右上角
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectTop.minY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = mrnRectTop.maxY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = mrnRectRight.minX;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = mrnRectRight.maxX;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//右下角
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectBottom.minY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = mrnRectBottom.maxY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = mrnRectRight.minX;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = mrnRectRight.maxX;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
|
|
|
|
|
|
//左下角
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minY = mrnRectBottom.minY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxY = mrnRectBottom.maxY;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].minX = mrnRectLeft.minX;
|
|
|
|
|
|
pmrnBlksRect[nBlkId].maxX = mrnRectLeft.maxX;
|
|
|
|
|
|
nBlkId++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_GetConnectedArea()
|
|
|
|
|
|
* 功能描述:对每个种子点进行区域连通,得到1个目标
|
|
|
|
|
|
* 输入参数:UINT16 *pFrame -- 输入待区域连通的图像
|
|
|
|
|
|
* UBYTE8 *pnGrayBi -- 输入图像的二值化结果
|
|
|
|
|
|
* UBYTE8 *pnFlagHasSr -- 标记每个像素点是否被归类的图像
|
|
|
|
|
|
* SINT32 nWidth -- 输入图像宽度
|
|
|
|
|
|
* SINT32 nHeight -- 输入图像高度
|
|
|
|
|
|
* SINT32 nSeedX -- 种子点的X坐标
|
|
|
|
|
|
* SINT32 nSeedY -- 种子点的Y坐标
|
|
|
|
|
|
* SINT32 nPxlsThresMax -- 最大像素个数阈值
|
|
|
|
|
|
* 输出参数:TARGET_OBJECT *ptTarget -- 目标像素阈值下限
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:无
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void DetectAreaObj::DAT_GetConnectedArea(UINT16* pFrame, UBYTE8* pnGrayBi, UBYTE8* pnGradBi,
|
|
|
|
|
|
UBYTE8* pnFlagHasSr, SINT32 nWidth, SINT32 nHeight,
|
|
|
|
|
|
SINT32 nSeedX, SINT32 nSeedY, SINT32 nPxlsThresMax,
|
|
|
|
|
|
TARGET_OBJECT* ptTarget)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT16* pnGrowQueX = (SINT16*)DAT_fGradX;
|
|
|
|
|
|
SINT16* pnGrowQueY = (SINT16*)DAT_fGradY;
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 i, j, xx, yy;
|
|
|
|
|
|
SINT32 nStart = 0; //定义堆栈的起点和终点/当nStart=nEnd, 表示堆栈中只有一个点
|
|
|
|
|
|
SINT32 nEnd = 0;
|
|
|
|
|
|
SINT32 nFilterHalf = 1;
|
|
|
|
|
|
BBOOL bConnAdd = FALSE;
|
|
|
|
|
|
//UBYTE8 *pBinaryValue = NULL;
|
|
|
|
|
|
UBYTE8* pFlagSearch = NULL;
|
|
|
|
|
|
SINT32 nPos = 0;
|
|
|
|
|
|
SINT32 nSeedPos = nSeedY * nWidth + nSeedX;
|
|
|
|
|
|
SINT32 nGraySum = pFrame[nSeedPos];
|
|
|
|
|
|
UINT16 nGrayMax = pFrame[nSeedPos];
|
|
|
|
|
|
POINT32F pfCenPos = { 0 };
|
|
|
|
|
|
POINT16S pnMaxPos = { 0 };
|
|
|
|
|
|
//OBJECTSNR objSNR = {0};
|
|
|
|
|
|
//MINMAXRECT32S mrnObj = {0};
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//1.把种子点的坐标压入栈
|
|
|
|
|
|
pnGrowQueX[nEnd] = nSeedX;
|
|
|
|
|
|
pnGrowQueY[nEnd] = nSeedY;
|
|
|
|
|
|
|
|
|
|
|
|
//初始化
|
|
|
|
|
|
//pnGrayBi[nSeedPos] = 0;
|
|
|
|
|
|
pnFlagHasSr[nSeedPos] = DAT_FLAG_CONNECTED;
|
|
|
|
|
|
pfCenPos.x += nSeedX;
|
|
|
|
|
|
pfCenPos.y += nSeedY;
|
|
|
|
|
|
pnMaxPos.x = (SINT16)nSeedX;
|
|
|
|
|
|
pnMaxPos.y = (SINT16)nSeedY;
|
|
|
|
|
|
ptTarget->mrnRect.minX = ptTarget->mrnRect.maxX = nSeedX;
|
|
|
|
|
|
ptTarget->mrnRect.minY = ptTarget->mrnRect.maxY = nSeedY;
|
|
|
|
|
|
ptTarget->unObjPxlsCnt = 1;
|
|
|
|
|
|
ptTarget->pxObjGray = pFrame[nSeedPos];
|
|
|
|
|
|
ptTarget->pxObjMaxGray = pFrame[nSeedPos];
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//2.遍历栈
|
|
|
|
|
|
while (nStart <= nEnd)
|
|
|
|
|
|
{
|
|
|
|
|
|
//2.1.当前种子点的坐标
|
|
|
|
|
|
SINT32 nCurrX = pnGrowQueX[nStart];
|
|
|
|
|
|
SINT32 nCurrY = pnGrowQueY[nStart];
|
|
|
|
|
|
|
|
|
|
|
|
//2.3.对当前点的8邻域进行遍历
|
|
|
|
|
|
for (i = -nFilterHalf; i <= nFilterHalf; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = -nFilterHalf; j <= nFilterHalf; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//2.3.1.获取8-邻域象素的坐标
|
|
|
|
|
|
xx = nCurrX + j;
|
|
|
|
|
|
yy = nCurrY + i;
|
|
|
|
|
|
|
|
|
|
|
|
//2.3.2.邻域搜索
|
|
|
|
|
|
if ((xx < nWidth)
|
|
|
|
|
|
&& (xx >= 0)
|
|
|
|
|
|
&& (yy < nHeight)
|
|
|
|
|
|
&& (yy >= 0)
|
|
|
|
|
|
&& !(0 == j && 0 == i))//不越界,且不为中心点
|
|
|
|
|
|
{
|
|
|
|
|
|
//2.3.2.1.获取指针
|
|
|
|
|
|
nPos = nWidth * yy + xx;
|
|
|
|
|
|
//pBinaryValue = pnGrayBi;
|
|
|
|
|
|
pFlagSearch = pnFlagHasSr;
|
|
|
|
|
|
|
|
|
|
|
|
//2.3.2.2.标记已搜索过的点
|
|
|
|
|
|
if (DAT_FLAG_CONNECTED == pFlagSearch[nPos])
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
pFlagSearch[nPos] = DAT_FLAG_CONNECTED;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//2.3.2.4.若该点为二值化点,或与最近已压栈点的灰度差小于阈值,则将该点加入栈
|
|
|
|
|
|
bConnAdd = FALSE;
|
|
|
|
|
|
if (DAT_FLAG_BINARY == pnGrayBi[nPos] /*|| DAT_FLAG_BINARY == pnGradBi[nPos]*/)
|
|
|
|
|
|
{
|
|
|
|
|
|
bConnAdd = TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 横向
|
|
|
|
|
|
//if (j = -nFilterHalf || j <= nFilterHalf)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// if()
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bConnAdd)
|
|
|
|
|
|
{
|
|
|
|
|
|
//堆栈的尾部指针后移一位
|
|
|
|
|
|
nEnd++;
|
|
|
|
|
|
|
|
|
|
|
|
//目标过大:栈将发生溢出,不再继续搜索该连通域
|
|
|
|
|
|
if (nEnd >= nPxlsThresMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
goto EndConnect;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//2.3.2.4.3.把被归类的点从二值化点中清除
|
|
|
|
|
|
//MSSu, 20150409: 不清除
|
|
|
|
|
|
//pnGrayBi[nPos] = DAT_FLAG_NONBINARY;
|
|
|
|
|
|
|
|
|
|
|
|
//2.3.2.4.4.象素(xx,yy) 压入栈
|
|
|
|
|
|
pnGrowQueX[nEnd] = xx;
|
|
|
|
|
|
pnGrowQueY[nEnd] = yy;
|
|
|
|
|
|
|
|
|
|
|
|
//2.3.2.4.5.更新目标的边界
|
|
|
|
|
|
ptTarget->mrnRect.minY = MIN(ptTarget->mrnRect.minY, yy);
|
|
|
|
|
|
ptTarget->mrnRect.maxY = MAX(ptTarget->mrnRect.maxY, yy);
|
|
|
|
|
|
ptTarget->mrnRect.minX = MIN(ptTarget->mrnRect.minX, xx);
|
|
|
|
|
|
ptTarget->mrnRect.maxX = MAX(ptTarget->mrnRect.maxX, xx);
|
|
|
|
|
|
|
|
|
|
|
|
//2.3.2.4.6.目标形心、大小累计
|
|
|
|
|
|
pfCenPos.x += xx;
|
|
|
|
|
|
pfCenPos.y += yy;
|
|
|
|
|
|
//ptTarget->pfCenPos.x += xx;
|
|
|
|
|
|
//ptTarget->pfCenPos.y += yy;
|
|
|
|
|
|
|
|
|
|
|
|
//mww,计算目标灰度值,2014.06.13
|
|
|
|
|
|
nGraySum += pFrame[nPos];
|
|
|
|
|
|
|
|
|
|
|
|
// 面目标计算极值亮度
|
|
|
|
|
|
ptTarget->pxObjMaxGray = MAX(ptTarget->pxObjMaxGray, pFrame[nPos]);
|
|
|
|
|
|
|
|
|
|
|
|
//查找极值点
|
|
|
|
|
|
//20161112Whao,区分亮目标和暗目标
|
|
|
|
|
|
if (((GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType) && (pFrame[nPos] > nGrayMax))
|
|
|
|
|
|
|| ((GLB_OBJ_GRAY_DARK == m_DAT_stPara.nDetectGrayType) && (pFrame[nPos] < nGrayMax)))
|
|
|
|
|
|
{
|
|
|
|
|
|
nGrayMax = pFrame[nPos];
|
|
|
|
|
|
pnMaxPos.x = xx;
|
|
|
|
|
|
pnMaxPos.y = yy;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//目标像素个数累加
|
|
|
|
|
|
ptTarget->unObjPxlsCnt++;
|
|
|
|
|
|
}//end of if(*pnGrayBi==255)...
|
|
|
|
|
|
}//end of if( (xx < nWidth) && (xx>=0) && (yy<nHeight) && (yy>=0) )...
|
|
|
|
|
|
}//end of for (j = -nFilterHalf; j <= nFilterHalf; j++)...
|
|
|
|
|
|
}//end of for (i = -nFilterHalf; i <= nFilterHalf; i++)...
|
|
|
|
|
|
|
|
|
|
|
|
//2.4.指向下一个当前点
|
|
|
|
|
|
nStart++;
|
|
|
|
|
|
|
|
|
|
|
|
}//end of while(nStart <= nEnd)...
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
EndConnect:
|
|
|
|
|
|
//3.计算目标形心、大小
|
|
|
|
|
|
if (ptTarget->unObjPxlsCnt > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
//计算目标形心
|
|
|
|
|
|
ptTarget->pfCenPos.x = pfCenPos.x / ptTarget->unObjPxlsCnt;
|
|
|
|
|
|
ptTarget->pfCenPos.y = pfCenPos.y / ptTarget->unObjPxlsCnt;
|
|
|
|
|
|
|
|
|
|
|
|
//计算目标极大值
|
|
|
|
|
|
ptTarget->pnMaxPos.x = (SINT16)pnMaxPos.x;
|
|
|
|
|
|
ptTarget->pnMaxPos.y = (SINT16)pnMaxPos.y;
|
|
|
|
|
|
|
|
|
|
|
|
//计算目标灰度均值
|
|
|
|
|
|
ptTarget->pxObjGray = (UINT16)(nGraySum / ptTarget->unObjPxlsCnt);
|
|
|
|
|
|
|
|
|
|
|
|
//计算目标宽高、大小(矩形面积)
|
|
|
|
|
|
ptTarget->snSize.w = ptTarget->mrnRect.maxX - ptTarget->mrnRect.minX + 1;
|
|
|
|
|
|
ptTarget->snSize.h = ptTarget->mrnRect.maxY - ptTarget->mrnRect.minY + 1;
|
|
|
|
|
|
ptTarget->snSize.s = ptTarget->snSize.h * ptTarget->snSize.w;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_IsTarget()
|
|
|
|
|
|
* 功能描述:目标确认
|
|
|
|
|
|
* 输入参数:UINT16 *pFrame -- 原始图像
|
|
|
|
|
|
* SIZE32S snImgSize -- 输入图像尺寸(降采样后)
|
|
|
|
|
|
* SINT32 *pnGrayInt -- 灰度积分图
|
|
|
|
|
|
* SINT32 *pnGradInt -- 梯度积分图
|
|
|
|
|
|
* SIZE32S snIntSize -- 积分图尺寸
|
|
|
|
|
|
* TARGET_OBJECT *ptTarget -- 待确认目标
|
|
|
|
|
|
* 输出参数:无
|
|
|
|
|
|
* 返 回 值:1-是目标,0-不是目标。
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:无
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
BBOOL DetectAreaObj::DAT_IsTarget(UINT16* pnSrDSmpImg, SIZE32S snImgSize, SINT32* pnGrayInt,
|
|
|
|
|
|
SINT32* pnGradInt, SIZE32S snIntSize, TARGET_OBJECT* ptTarget, GD_PIXEL_FORMAT_E enPixelFormat)
|
|
|
|
|
|
{
|
|
|
|
|
|
BBOOL bTarget = TRUE;
|
|
|
|
|
|
FLOAT32 fWHRatio; //宽高比
|
|
|
|
|
|
FLOAT32 fRectRatio; //矩形度
|
|
|
|
|
|
MINMAXRECT32S mrnObj; //目标矩形
|
|
|
|
|
|
MINMAXRECT32S mrnBkg; //背景矩形
|
|
|
|
|
|
MINMAXRECT32S mrnBkgBlk;//背景分块矩形
|
|
|
|
|
|
OBJECTSNR objSNR; //目标SNR结构体
|
|
|
|
|
|
SINT32 nObjBigger; //目标矩形扩展大小
|
|
|
|
|
|
SINT32 nBkgBigger; //背景矩形扩展大小
|
|
|
|
|
|
SINT32 nBkgPxlsCnt; //背景分块矩形内的像素个数
|
|
|
|
|
|
SINT32 nBkgMeanT = 0, nBkgMeanB = 0, nBkgMeanL = 0, nBkgMeanR = 0; //背景分块均值
|
|
|
|
|
|
SINT32 nBkgMaxVeri, nBkgMaxHori; //背景水平、垂直方向最大值
|
|
|
|
|
|
SINT32 nBkgMinVeri, nBkgMinHori; //背景水平、垂直方向最大值
|
|
|
|
|
|
SINT32 nDiffThresV, nDiffThresH; //水平、垂直方向灰度差阈值
|
|
|
|
|
|
SINT32 unObjPxlsCntReal;//目标实际像素个数
|
|
|
|
|
|
SIZE16S snObjSizeReal; //目标实际尺寸
|
|
|
|
|
|
|
|
|
|
|
|
BBOOL bEnableDeFABySize = m_DAT_stPara.bUseDeFA_Size;
|
|
|
|
|
|
BBOOL bEnableDeFAByWHR = m_DAT_stPara.bUseDeFA_WHRatio;
|
|
|
|
|
|
BBOOL bEnableDeFAByRR = m_DAT_stPara.bUseDeFA_RectRatio;
|
|
|
|
|
|
BBOOL bEnableDeFAByGrayDiff = m_DAT_stPara.bUseDeFA_BTGrayMin;
|
|
|
|
|
|
BBOOL bEnableDeFaByObjStd = m_DAT_stPara.bUseDeFA_ObjVarMin;
|
|
|
|
|
|
BBOOL bEnableDeFABySNR = false; //20171017飞机穿云过程中,SNR过小,易排除真实目标,改为FALSE
|
|
|
|
|
|
BBOOL bAtSkyLandLine = FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//目标矩形
|
|
|
|
|
|
nObjBigger = MIN(MAX(3, (MIN(ptTarget->snSize.w, ptTarget->snSize.h) >> 2)), 6);
|
|
|
|
|
|
mrnObj.minX = MAX(0, MIN(ptTarget->mrnRect.minX - nObjBigger, snImgSize.w - 1));
|
|
|
|
|
|
mrnObj.maxX = MAX(0, MIN(ptTarget->mrnRect.maxX + nObjBigger, snImgSize.w - 1));
|
|
|
|
|
|
mrnObj.minY = MAX(0, MIN(ptTarget->mrnRect.minY - nObjBigger, snImgSize.h - 1));
|
|
|
|
|
|
mrnObj.maxY = MAX(0, MIN(ptTarget->mrnRect.maxY + nObjBigger, snImgSize.h - 1));
|
|
|
|
|
|
|
|
|
|
|
|
//背景矩形
|
|
|
|
|
|
nBkgBigger = MIN(MAX(3, (MIN(ptTarget->snSize.w, ptTarget->snSize.h) >> 2)), 10);
|
|
|
|
|
|
mrnBkg.minX = MAX(0, MIN(mrnObj.minX - nBkgBigger, snImgSize.w - 1));
|
|
|
|
|
|
mrnBkg.maxX = MAX(0, MIN(mrnObj.maxX + nBkgBigger, snImgSize.w - 1));
|
|
|
|
|
|
mrnBkg.minY = MAX(0, MIN(mrnObj.minY - nBkgBigger, snImgSize.h - 1));
|
|
|
|
|
|
mrnBkg.maxY = MAX(0, MIN(mrnObj.maxY + nBkgBigger, snImgSize.h - 1));
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//目标大小限制
|
|
|
|
|
|
if (bEnableDeFABySize) // 20171107zy:对超大目标不进行大小限制
|
|
|
|
|
|
{
|
|
|
|
|
|
unObjPxlsCntReal = ptTarget->unObjPxlsCnt * m_DAT_stPara.nDSmpScale * m_DAT_stPara.nDSmpScale;
|
|
|
|
|
|
snObjSizeReal.w = ptTarget->snSize.w * m_DAT_stPara.nDSmpScale;
|
|
|
|
|
|
snObjSizeReal.h = ptTarget->snSize.h * m_DAT_stPara.nDSmpScale;
|
|
|
|
|
|
snObjSizeReal.s = snObjSizeReal.w * snObjSizeReal.h;
|
|
|
|
|
|
if (unObjPxlsCntReal < m_DAT_stPara.nObjSizeMin
|
|
|
|
|
|
|| unObjPxlsCntReal > m_DAT_stPara.nObjSizeMax
|
|
|
|
|
|
|| snObjSizeReal.w > m_DAT_stPara.nObjWidthMax
|
|
|
|
|
|
|| snObjSizeReal.h > m_DAT_stPara.nObjHeightMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//目标宽高比限制
|
|
|
|
|
|
if (bEnableDeFAByWHR)
|
|
|
|
|
|
{
|
|
|
|
|
|
fWHRatio = (FLOAT32)ptTarget->snSize.w / ptTarget->snSize.h;
|
|
|
|
|
|
if (fWHRatio < m_DAT_stPara.fObjWHRatioMin
|
|
|
|
|
|
|| fWHRatio > m_DAT_stPara.fObjWHRatioMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//目标矩形度限制(只有红外适应做矩形度限制)
|
|
|
|
|
|
if (bEnableDeFAByRR && GD_PIXEL_FORMAT_GRAY_Y16 == enPixelFormat)
|
|
|
|
|
|
{
|
|
|
|
|
|
fRectRatio = (FLOAT32)ptTarget->unObjPxlsCnt / ptTarget->snSize.s;
|
|
|
|
|
|
if (fRectRatio < m_DAT_stPara.fObjRectRatioMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//目标、背景均值灰度差限制
|
|
|
|
|
|
//20161112Whao,仅对亮目标打开该限制
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType && bEnableDeFAByGrayDiff)
|
|
|
|
|
|
{
|
|
|
|
|
|
//计算背景上分块灰度均值
|
|
|
|
|
|
mrnBkgBlk = mrnBkg;
|
|
|
|
|
|
mrnBkgBlk.maxY = mrnObj.minY - 1;
|
|
|
|
|
|
nBkgPxlsCnt = (mrnBkgBlk.maxY - mrnBkgBlk.minY + 1) * (mrnBkgBlk.maxX - mrnBkgBlk.minX + 1);
|
|
|
|
|
|
if (0 == nBkgPxlsCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
return bTarget;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
nBkgMeanT = IMGO_CalcIntegralInMMRect(pnGrayInt, snIntSize, mrnBkgBlk) / nBkgPxlsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算背景下分块灰度均值
|
|
|
|
|
|
mrnBkgBlk = mrnBkg;
|
|
|
|
|
|
mrnBkgBlk.minY = mrnObj.maxY + 1;
|
|
|
|
|
|
nBkgPxlsCnt = (mrnBkgBlk.maxY - mrnBkgBlk.minY + 1) * (mrnBkgBlk.maxX - mrnBkgBlk.minX + 1);
|
|
|
|
|
|
if (0 == nBkgPxlsCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
return bTarget;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
nBkgMeanB = IMGO_CalcIntegralInMMRect(pnGrayInt, snIntSize, mrnBkgBlk) / nBkgPxlsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算背景左分块灰度均值
|
|
|
|
|
|
mrnBkgBlk = mrnBkg;
|
|
|
|
|
|
mrnBkgBlk.maxX = mrnObj.minX - 1;
|
|
|
|
|
|
nBkgPxlsCnt = (mrnBkgBlk.maxY - mrnBkgBlk.minY + 1) * (mrnBkgBlk.maxX - mrnBkgBlk.minX + 1);
|
|
|
|
|
|
if (0 == nBkgPxlsCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
return bTarget;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
nBkgMeanL = IMGO_CalcIntegralInMMRect(pnGrayInt, snIntSize, mrnBkgBlk) / nBkgPxlsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算背景右分块灰度均值
|
|
|
|
|
|
mrnBkgBlk = mrnBkg;
|
|
|
|
|
|
mrnBkgBlk.minX = mrnObj.maxX + 1;
|
|
|
|
|
|
nBkgPxlsCnt = (mrnBkgBlk.maxY - mrnBkgBlk.minY + 1) * (mrnBkgBlk.maxX - mrnBkgBlk.minX + 1);
|
|
|
|
|
|
if (0 == nBkgPxlsCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
return bTarget;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
nBkgMeanR = IMGO_CalcIntegralInMMRect(pnGrayInt, snIntSize, mrnBkgBlk) / nBkgPxlsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//若目标灰度与垂直方向背景最大灰度的差值,小于(上下背景灰度差异*系数),则认为是虚警。
|
|
|
|
|
|
//MSSu, 20150513: 面目标增加暗目标检测模式
|
|
|
|
|
|
//MSSu, 20150515: S231外场实验远距离目标在天地线附近,垂直方向最大值与目标的灰度较接近
|
|
|
|
|
|
// 因此,垂直方向最大值取上下背景的最小值。
|
|
|
|
|
|
//nBkgMaxVeri = MAX(nBkgMeanT, nBkgMeanB);
|
|
|
|
|
|
if (nBkgMeanT > nBkgMeanB)
|
|
|
|
|
|
{
|
|
|
|
|
|
nBkgMaxVeri = nBkgMeanB;
|
|
|
|
|
|
// bAtSkyLandLine = TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
nBkgMaxVeri = MAX(nBkgMeanT, nBkgMeanB);
|
|
|
|
|
|
}
|
|
|
|
|
|
nBkgMinVeri = MIN(nBkgMeanT, nBkgMeanB);
|
|
|
|
|
|
nDiffThresV = (SINT32)(ABS(nBkgMeanT - nBkgMeanB) * m_DAT_stPara.fBkgGrayDiffCoeff);
|
|
|
|
|
|
nDiffThresV = MAX(nDiffThresV, m_DAT_stPara.nObjBkgGrayDiffMin);
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ptTarget->pxObjGray - nBkgMaxVeri < nDiffThresV)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_DARK == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ptTarget->pxObjGray - nBkgMinVeri > -nDiffThresV)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_ALL == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (((ptTarget->pxObjGray > nBkgMaxVeri)
|
|
|
|
|
|
&& ptTarget->pxObjGray - nBkgMaxVeri < nDiffThresV)
|
|
|
|
|
|
|| ((ptTarget->pxObjGray < nBkgMinVeri)
|
|
|
|
|
|
&& (ptTarget->pxObjGray - nBkgMinVeri > -nDiffThresV)))
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//若目标灰度与水平方向背景最大灰度的差值,小于(左右背景灰度差异*系数),则认为是虚警。
|
|
|
|
|
|
//MSSu, 20150513: 面目标增加暗目标检测模式
|
|
|
|
|
|
nBkgMaxHori = MAX(nBkgMeanL, nBkgMeanR);
|
|
|
|
|
|
nBkgMinHori = MIN(nBkgMeanL, nBkgMeanR);
|
|
|
|
|
|
nDiffThresH = (SINT32)(ABS(nBkgMeanL - nBkgMeanR) * m_DAT_stPara.fBkgGrayDiffCoeff);
|
|
|
|
|
|
nDiffThresH = MAX(nDiffThresH, m_DAT_stPara.nObjBkgGrayDiffMin);
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ptTarget->pxObjGray - nBkgMaxHori < nDiffThresH)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_DARK == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ptTarget->pxObjGray - nBkgMinHori > -nDiffThresH)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_ALL == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (((ptTarget->pxObjGray > nBkgMaxHori)
|
|
|
|
|
|
&& ptTarget->pxObjGray - nBkgMaxHori < nDiffThresH)
|
|
|
|
|
|
|| ((ptTarget->pxObjGray < nBkgMinHori)
|
|
|
|
|
|
&& (ptTarget->pxObjGray - nBkgMinHori > -nDiffThresH)))
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//仅对确认为目标的,计算SNR
|
|
|
|
|
|
if (!bTarget)
|
|
|
|
|
|
{
|
|
|
|
|
|
return bTarget;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//目标SNR限制
|
|
|
|
|
|
//计算目标的背景均值、背景标准差、SNR
|
|
|
|
|
|
memset(&objSNR, 0, sizeof(OBJECTSNR));
|
|
|
|
|
|
DAT_CalRectObjSNR_UINT16(pnSrDSmpImg, snImgSize.w, snImgSize.h, mrnObj, nBkgBigger, &objSNR, m_DAT_stPara.nDetectGrayType);
|
|
|
|
|
|
ptTarget->fBGMean = objSNR.BGMean;
|
|
|
|
|
|
ptTarget->fBGStd = objSNR.BGStd;
|
|
|
|
|
|
ptTarget->fSNR = objSNR.fSNR;
|
|
|
|
|
|
ptTarget->fObjStd = objSNR.ObjStd;
|
|
|
|
|
|
ptTarget->fGrayNeighbor[0] = nBkgMeanT;
|
|
|
|
|
|
ptTarget->fGrayNeighbor[1] = nBkgMeanB;
|
|
|
|
|
|
ptTarget->fGrayNeighbor[2] = nBkgMeanL;
|
|
|
|
|
|
ptTarget->fGrayNeighbor[3] = nBkgMeanR;
|
|
|
|
|
|
//20161112Whao,仅对亮目标打开该限制
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType && bEnableDeFABySNR && !bAtSkyLandLine)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ptTarget->fSNR < m_DAT_stPara.fgdk)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_DARK == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ptTarget->fSNR > -m_DAT_stPara.fgdk)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_ALL == m_DAT_stPara.nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (fabs(ptTarget->fSNR) < m_DAT_stPara.fgdk)
|
|
|
|
|
|
{
|
|
|
|
|
|
bTarget = FALSE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bEnableDeFaByObjStd && ((ptTarget->fObjStd / (ptTarget->unObjPxlsCnt + 0.001)) < 3 && ptTarget->unObjPxlsCnt > 4))
|
|
|
|
|
|
{
|
|
|
|
|
|
//bTarget = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return bTarget;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_MergeObjs()
|
|
|
|
|
|
* 功能描述:目标合并
|
|
|
|
|
|
* 输入参数:TARGET_OBJECT *ptTargetArray -- 目标数组指针
|
|
|
|
|
|
* TARGET_OBJECT *ptTargetArrayCombine -- 用于合并的临时目标数组指针
|
|
|
|
|
|
* SINT32 nFrmObjsMax -- 单帧检测目标的最大个数
|
|
|
|
|
|
* SIZE32S nObjsCnt -- 输入目标个数
|
|
|
|
|
|
* SINT32 nObjsCombineDist -- 目标合并距离
|
|
|
|
|
|
* 输出参数:TARGET_OBJECT *ptTargetArr -- 目标数组指针
|
|
|
|
|
|
* 返 回 值:SINT32 nObjsCntNew -- 合并后目标个数
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:合并后的最终目标数组,拷贝到*ptTargetArray中返回。
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
SINT32 DetectAreaObj::DAT_MergeObjs(TARGET_OBJECT* ptTargetArray, TARGET_OBJECT* ptTargetArrayCombine,
|
|
|
|
|
|
SINT32 nFrmObjsMax, SINT32 nObjsCnt, SINT32 nObjsCombineDist)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 i, j;
|
|
|
|
|
|
SINT32 nObjsCntNew = 0; //合并后目标个数
|
|
|
|
|
|
TARGET_OBJECT* pTargetA = NULL;
|
|
|
|
|
|
TARGET_OBJECT* pTargetB = NULL;
|
|
|
|
|
|
MINMAXRECT mrnRectA, mrnRectB;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//判断面目标检测数目是否为零或仅有1个目标
|
|
|
|
|
|
if (nObjsCnt < 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
return nObjsCnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//初始化
|
|
|
|
|
|
memcpy(ptTargetArrayCombine, ptTargetArray, nObjsCnt * sizeof(TARGET_OBJECT));
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//遍历已检测的目标
|
|
|
|
|
|
for (i = 0; i < nObjsCnt; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//A目标
|
|
|
|
|
|
pTargetA = &ptTargetArrayCombine[i];
|
|
|
|
|
|
mrnRectA = pTargetA->mrnRect;
|
|
|
|
|
|
|
|
|
|
|
|
//A目标已被合并,则跳过
|
|
|
|
|
|
if (!pTargetA->bObject)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//搜索与A邻近的目标
|
|
|
|
|
|
for (j = i + 1; j < nObjsCnt; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//B目标
|
|
|
|
|
|
pTargetB = &ptTargetArrayCombine[j];
|
|
|
|
|
|
mrnRectB = pTargetB->mrnRect;
|
|
|
|
|
|
|
|
|
|
|
|
//若A、B两个目标距离很近,更新目标大小和位置
|
|
|
|
|
|
if ((mrnRectA.minX < mrnRectB.minX && mrnRectA.maxX < mrnRectB.minX - nObjsCombineDist)
|
|
|
|
|
|
|| (mrnRectA.maxX > mrnRectB.maxX && mrnRectA.minX > mrnRectB.maxX + nObjsCombineDist)
|
|
|
|
|
|
|| (mrnRectA.minY < mrnRectB.minY && mrnRectA.maxY < mrnRectB.minY - nObjsCombineDist)
|
|
|
|
|
|
|| (mrnRectA.maxY > mrnRectB.maxY && mrnRectA.minY > mrnRectB.maxY + nObjsCombineDist))
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//20161113跟踪过程中对重合的目标不合并
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//将B目标合并到A目标中
|
|
|
|
|
|
pTargetA->pfCenPos.x = (pTargetA->pfCenPos.x * pTargetA->unObjPxlsCnt + pTargetB->pfCenPos.x * pTargetB->unObjPxlsCnt);
|
|
|
|
|
|
pTargetA->pfCenPos.x /= (pTargetA->unObjPxlsCnt + pTargetB->unObjPxlsCnt);
|
|
|
|
|
|
pTargetA->pfCenPos.y = (pTargetA->pfCenPos.y * pTargetA->unObjPxlsCnt + pTargetB->pfCenPos.y * pTargetB->unObjPxlsCnt);
|
|
|
|
|
|
pTargetA->pfCenPos.y /= (pTargetA->unObjPxlsCnt + pTargetB->unObjPxlsCnt);
|
|
|
|
|
|
|
|
|
|
|
|
pTargetA->unObjPxlsCnt = pTargetA->unObjPxlsCnt + pTargetB->unObjPxlsCnt;
|
|
|
|
|
|
pTargetA->mrnRect.minX = MIN(mrnRectA.minX, mrnRectB.minX);
|
|
|
|
|
|
pTargetA->mrnRect.maxX = MAX(mrnRectA.maxX, mrnRectB.maxX);
|
|
|
|
|
|
pTargetA->mrnRect.minY = MIN(mrnRectA.minY, mrnRectB.minY);
|
|
|
|
|
|
pTargetA->mrnRect.maxY = MAX(mrnRectA.maxY, mrnRectB.maxY);
|
|
|
|
|
|
pTargetA->snSize.h = pTargetA->mrnRect.maxY - pTargetA->mrnRect.minY + 1;
|
|
|
|
|
|
pTargetA->snSize.w = pTargetA->mrnRect.maxX - pTargetA->mrnRect.minX + 1;
|
|
|
|
|
|
pTargetA->snSize.s = pTargetA->snSize.h * pTargetA->snSize.w;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//更新A目标的方位角、俯仰角 (全局耦合)
|
|
|
|
|
|
//pTargetA->afAngle.fAz = SERVO_CalcObjAzimuth(pTargetA->pfCenPos.x,
|
|
|
|
|
|
// m_GLB_stInput.stParaLn.snImgSize.w,
|
|
|
|
|
|
// m_SERVO_stInput.fAzimuth, m_SERVO_stInput.fResolAz);
|
|
|
|
|
|
//pTargetA->afAngle.fPt = SERVO_CalcObjPitching(pTargetA->pfCenPos.y,
|
|
|
|
|
|
// m_GLB_stInput.stParaLn.snImgSize.h,
|
|
|
|
|
|
// m_SERVO_stInput.fPitching, m_SERVO_stInput.fResolPt);
|
|
|
|
|
|
|
|
|
|
|
|
//清空B目标
|
|
|
|
|
|
memset(pTargetB, 0, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//将临时目标数组ptTargetArrayCombine赋给合并后目标数组ptTargetArray
|
|
|
|
|
|
memset(ptTargetArray, 0, nFrmObjsMax * sizeof(TARGET_OBJECT));
|
|
|
|
|
|
nObjsCntNew = 0;
|
|
|
|
|
|
for (i = 0; i < nObjsCnt; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
pTargetA = &ptTargetArrayCombine[i];
|
|
|
|
|
|
if (pTargetA->bObject)
|
|
|
|
|
|
{
|
|
|
|
|
|
pTargetB = &ptTargetArray[nObjsCntNew++];
|
|
|
|
|
|
memcpy(pTargetB, pTargetA, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nObjsCntNew;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_MergeTargets()
|
|
|
|
|
|
* 功能描述:亮暗目标数组合并
|
|
|
|
|
|
* 输入参数:TARGET_OBJECT *ptDATResultBright -- 亮目标数组指针
|
|
|
|
|
|
* TARGET_OBJECT *ptDATResultDark -- 暗目标数组指针
|
|
|
|
|
|
* SINT32 TnFrmBrightObjCnt -- 亮目标数组个数
|
|
|
|
|
|
* SINT32 nFrmDarkObjCnt -- 暗目标数组个数
|
|
|
|
|
|
* SINT32 nFrmObjsMax -- 单帧检测目标的最大个数
|
|
|
|
|
|
* 输出参数:TARGET_OBJECT *ptTargetArr -- 目标数组指针
|
|
|
|
|
|
* 返 回 值:SINT32 nObjsCntNew -- 合并后目标个数
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:合并后的最终目标数组,拷贝到*ptTargetArray中返回。
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
SINT32 DetectAreaObj::DAT_MergeTargets(TARGET_OBJECT* ptDATResultBright, TARGET_OBJECT* ptDATResultDark,
|
|
|
|
|
|
SINT32 nFrmBrightObjCnt, SINT32 nFrmDarkObjCnt, SINT32 nFrmObjsMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
TARGET_OBJECT* ptTargetArr = (TARGET_OBJECT*)DAT_Target_Temp;
|
|
|
|
|
|
memset(ptTargetArr, 0, sizeof(TARGET_OBJECT) * DAT_TARGET_NUM_MAX);
|
|
|
|
|
|
SINT32 i, j;
|
|
|
|
|
|
FLOAT32 fDistMax = 0.0f; //距离中心的最大值
|
|
|
|
|
|
SINT32 nMaxIndex = 0; //距离中心的最大值的元素下标
|
|
|
|
|
|
SINT32 nIndex = 0; //合并后数组下标
|
|
|
|
|
|
|
|
|
|
|
|
//距离数组
|
|
|
|
|
|
FLOAT32 DistArray[DAT_TARGET_NUM_MAX] = { 0 };
|
|
|
|
|
|
FLOAT32* pfDistArray = DistArray;
|
|
|
|
|
|
FLOAT32 fDist = 0.0f;
|
|
|
|
|
|
|
|
|
|
|
|
SINT32 GLB_CURSORX = m_DAT_stInput.crnSrRect.cx;
|
|
|
|
|
|
SINT32 GLB_CURSORY = m_DAT_stInput.crnSrRect.cy;
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < nFrmBrightObjCnt; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
pfDistArray[nIndex] = (ptDATResultBright[i].pfCenPos.x - GLB_CURSORX) * (ptDATResultBright[i].pfCenPos.x - GLB_CURSORX)
|
|
|
|
|
|
+ (ptDATResultBright[i].pfCenPos.y - GLB_CURSORY) * (ptDATResultBright[i].pfCenPos.y - GLB_CURSORY);
|
|
|
|
|
|
ptTargetArr[nIndex] = ptDATResultBright[i];
|
|
|
|
|
|
if (pfDistArray[nIndex] - fDistMax > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
fDistMax = pfDistArray[nIndex];
|
|
|
|
|
|
nMaxIndex = nIndex;
|
|
|
|
|
|
}
|
|
|
|
|
|
nIndex++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < nFrmDarkObjCnt; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
fDist = (ptDATResultDark[j].pfCenPos.x - GLB_CURSORX) * (ptDATResultDark[j].pfCenPos.x - GLB_CURSORX)
|
|
|
|
|
|
+ (ptDATResultDark[j].pfCenPos.y - GLB_CURSORY) * (ptDATResultDark[j].pfCenPos.y - GLB_CURSORY);
|
|
|
|
|
|
if (nIndex < nFrmObjsMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
pfDistArray[nIndex] = fDist;
|
|
|
|
|
|
ptTargetArr[nIndex] = ptDATResultDark[j];
|
|
|
|
|
|
if (fDist - fDistMax > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
fDistMax = fDist;
|
|
|
|
|
|
nMaxIndex = nIndex;
|
|
|
|
|
|
}
|
|
|
|
|
|
nIndex++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (fDist - fDistMax < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
ptTargetArr[nMaxIndex] = ptDATResultDark[j];
|
|
|
|
|
|
pfDistArray[nMaxIndex] = fDist;
|
|
|
|
|
|
fDistMax = fDist;
|
|
|
|
|
|
|
|
|
|
|
|
//更新距离最大值和最大值的下标
|
|
|
|
|
|
for (i = 0; i < nFrmObjsMax; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pfDistArray[i] - fDistMax > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
fDistMax = pfDistArray[i];
|
|
|
|
|
|
nMaxIndex = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return nIndex;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_CalRectObjSNR_UINT16()
|
|
|
|
|
|
* 功能描述:计算矩形目标SNR
|
|
|
|
|
|
* 输入参数:UINT16 *pFrame -- 原始图像
|
|
|
|
|
|
* SINT32 nWidth -- 图像宽度
|
|
|
|
|
|
* SINT32 nHeight -- 图像高度
|
|
|
|
|
|
* MINMAXRECT32S mrnObj-- 目标矩形坐标
|
|
|
|
|
|
* UBYTE8 nDetectGrayType -- 面目标检测类型 1-只检测亮目标,2-只检测暗目标,3-同时检测亮暗目标
|
|
|
|
|
|
* 输出参数:OBJECTSNR *objSNR -- 目标SNR信息
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:无
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void DAT_CalRectObjSNR_IMG(GD_VIDEO_FRAME_S img, SINT32 nWidth, SINT32 nHeight,
|
|
|
|
|
|
MINMAXRECT32S mrnObj, SINT32 nBkgRadius,
|
|
|
|
|
|
OBJECTSNR* objSNR, UBYTE8 nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 i, j;
|
|
|
|
|
|
SINT32 nBGValue, nBGCnt; //背景点灰度、背景点计数
|
|
|
|
|
|
double dBGMean, dBGStd, dObjStd; //背景均值、方差
|
|
|
|
|
|
MINMAXRECT32S mrnBkg; //背景区域矩形
|
|
|
|
|
|
SINT32 nLineIndex, nIndex;
|
|
|
|
|
|
FLOAT32 fGrayMax, fGrayMin, fGrayMean;
|
|
|
|
|
|
POINT16S ptPntMax, ptPntMin;
|
|
|
|
|
|
SINT32 nGrayCnt;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//获取目标最大灰度值及其坐标
|
|
|
|
|
|
nLineIndex = mrnObj.minY * nWidth;
|
|
|
|
|
|
objSNR->Pnt.x = (mrnObj.minX + mrnObj.maxX) >> 1;
|
|
|
|
|
|
objSNR->Pnt.y = (mrnObj.minY + mrnObj.maxY) >> 1;
|
|
|
|
|
|
//objSNR->ObjGray = pnSrDSmpImg[objSNR->Pnt.y * nWidth + objSNR->Pnt.x];
|
|
|
|
|
|
if (GD_PIXEL_FORMAT_GRAY_Y8 == img.enPixelFormat)
|
|
|
|
|
|
{
|
|
|
|
|
|
objSNR->ObjGray = ((UBYTE8*)img.u64VirAddr[0])[objSNR->Pnt.y * nWidth + objSNR->Pnt.x];
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
objSNR->ObjGray = ((UINT16*)img.u64VirAddr[0])[objSNR->Pnt.y * nWidth + objSNR->Pnt.x];
|
|
|
|
|
|
}
|
|
|
|
|
|
fGrayMax = objSNR->ObjGray;
|
|
|
|
|
|
fGrayMin = objSNR->ObjGray;
|
|
|
|
|
|
ptPntMax = objSNR->Pnt;
|
|
|
|
|
|
ptPntMin = objSNR->Pnt;
|
|
|
|
|
|
fGrayMean = 0.0f;
|
|
|
|
|
|
nGrayCnt = 0;
|
|
|
|
|
|
dObjStd = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (i = mrnObj.minY; i <= mrnObj.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnObj.minX; j <= mrnObj.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
|
|
|
|
|
|
if (GD_PIXEL_FORMAT_GRAY_Y8 == img.enPixelFormat)
|
|
|
|
|
|
{
|
|
|
|
|
|
//最大值
|
|
|
|
|
|
if (((UBYTE8*)img.u64VirAddr[0])[nIndex] > fGrayMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
fGrayMax = (FLOAT32)(((UBYTE8*)img.u64VirAddr[0])[nIndex]);
|
|
|
|
|
|
ptPntMax.x = j;
|
|
|
|
|
|
ptPntMax.y = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//最小值
|
|
|
|
|
|
if (((UBYTE8*)img.u64VirAddr[0])[nIndex] < fGrayMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
fGrayMin = (FLOAT32)(((UBYTE8*)img.u64VirAddr[0])[nIndex]);
|
|
|
|
|
|
ptPntMin.x = j;
|
|
|
|
|
|
ptPntMin.y = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//均值
|
|
|
|
|
|
fGrayMean += (FLOAT32)(((UBYTE8*)img.u64VirAddr[0])[nIndex]);
|
|
|
|
|
|
dObjStd += (FLOAT32)(((UBYTE8*)img.u64VirAddr[0])[nIndex]) * (FLOAT32)(((UBYTE8*)img.u64VirAddr[0])[nIndex]);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//最大值
|
|
|
|
|
|
if (((UINT16*)img.u64VirAddr[0])[nIndex] > fGrayMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
fGrayMax = (FLOAT32)(((UINT16*)img.u64VirAddr[0])[nIndex]);
|
|
|
|
|
|
ptPntMax.x = j;
|
|
|
|
|
|
ptPntMax.y = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//最小值
|
|
|
|
|
|
if (((UINT16*)img.u64VirAddr[0])[nIndex] < fGrayMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
fGrayMin = (FLOAT32)(((UINT16*)img.u64VirAddr[0])[nIndex]);
|
|
|
|
|
|
ptPntMin.x = j;
|
|
|
|
|
|
ptPntMin.y = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//均值
|
|
|
|
|
|
fGrayMean += (FLOAT32)(((UINT16*)img.u64VirAddr[0])[nIndex]);
|
|
|
|
|
|
dObjStd += (FLOAT32)(((UINT16*)img.u64VirAddr[0])[nIndex]) * (FLOAT32)(((UINT16*)img.u64VirAddr[0])[nIndex]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nGrayCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (nGrayCnt > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
fGrayMean /= nGrayCnt;
|
|
|
|
|
|
dObjStd /= nGrayCnt;
|
|
|
|
|
|
dObjStd -= fGrayMean * fGrayMean;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//根据检测类型,获取目标灰度
|
|
|
|
|
|
//亮目标
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
objSNR->ObjGray = fGrayMax;
|
|
|
|
|
|
objSNR->Pnt = ptPntMax;
|
|
|
|
|
|
}
|
|
|
|
|
|
//暗目标
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_DARK == nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
objSNR->ObjGray = fGrayMin;
|
|
|
|
|
|
objSNR->Pnt = ptPntMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
//亮暗全检测
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//MSSu, 20150608: 取目标中心点灰度,屏蔽下面语句
|
|
|
|
|
|
//objSNR->ObjGray = fGrayMean;
|
|
|
|
|
|
//objSNR->Pnt.x = (mrnObj.minX + mrnObj.maxX) >> 1;
|
|
|
|
|
|
//objSNR->Pnt.y = (mrnObj.minY + mrnObj.maxY) >> 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//统计背景均值、方差:划分为上、下、左、右四个背景区域
|
|
|
|
|
|
//计算背景窗口边界
|
|
|
|
|
|
mrnBkg.minX = MAX(0, MIN(mrnObj.minX - nBkgRadius, nWidth - 1));
|
|
|
|
|
|
mrnBkg.maxX = MAX(0, MIN(mrnObj.maxX + nBkgRadius, nWidth - 1));
|
|
|
|
|
|
mrnBkg.minY = MAX(0, MIN(mrnObj.minY - nBkgRadius, nHeight - 1));
|
|
|
|
|
|
mrnBkg.maxY = MAX(0, MIN(mrnObj.maxY + nBkgRadius, nHeight - 1));
|
|
|
|
|
|
|
|
|
|
|
|
//统计背景均值、方差
|
|
|
|
|
|
nBGCnt = 0;
|
|
|
|
|
|
dBGMean = 0;
|
|
|
|
|
|
dBGStd = 0;
|
|
|
|
|
|
|
|
|
|
|
|
//背景区域-上
|
|
|
|
|
|
nLineIndex = mrnBkg.minY * nWidth;
|
|
|
|
|
|
for (i = mrnBkg.minY; i <= mrnObj.minY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnBkg.minX; j <= mrnBkg.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
//nBGValue = pnSrDSmpImg[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++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//背景区域-下
|
|
|
|
|
|
nLineIndex = (mrnObj.maxY + 1) * nWidth;
|
|
|
|
|
|
for (i = mrnObj.maxY + 1; i <= mrnBkg.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnBkg.minX; j <= mrnBkg.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
//nBGValue = pnSrDSmpImg[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++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//背景区域-左
|
|
|
|
|
|
nLineIndex = mrnObj.minY * nWidth;
|
|
|
|
|
|
for (i = mrnObj.minY; i <= mrnObj.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnBkg.minX; j < mrnObj.minX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
//nBGValue = pnSrDSmpImg[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++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//背景区域-右
|
|
|
|
|
|
nLineIndex = mrnObj.minY * nWidth;
|
|
|
|
|
|
for (i = mrnObj.minY; i <= mrnObj.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnObj.maxX + 1; j <= mrnBkg.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
//nBGValue = pnSrDSmpImg[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++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算背景均值、方差
|
|
|
|
|
|
dBGMean /= nBGCnt;
|
|
|
|
|
|
dBGStd /= nBGCnt;
|
|
|
|
|
|
dBGStd -= dBGMean * dBGMean;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//保存目标SNR信息
|
|
|
|
|
|
objSNR->nTGR = (mrnObj.maxX - mrnObj.minX) >> 1;
|
|
|
|
|
|
objSNR->nBGR = nBkgRadius;
|
|
|
|
|
|
objSNR->BGMean = (FLOAT32)dBGMean;
|
|
|
|
|
|
objSNR->BGStd = (FLOAT32)sqrt(dBGStd);
|
|
|
|
|
|
objSNR->fSNR = (0 == objSNR->BGMean || objSNR->BGStd == 0) ? 1e6f : (FLOAT32)((objSNR->ObjGray - objSNR->BGMean) / objSNR->BGStd);
|
|
|
|
|
|
objSNR->ObjStd = (FLOAT32)sqrt(dObjStd);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************
|
|
|
|
|
|
* 函数名称:DAT_CalRectObjSNR_UINT16()
|
|
|
|
|
|
* 功能描述:计算矩形目标SNR
|
|
|
|
|
|
* 输入参数:UINT16 *pFrame -- 原始图像
|
|
|
|
|
|
* SINT32 nWidth -- 图像宽度
|
|
|
|
|
|
* SINT32 nHeight -- 图像高度
|
|
|
|
|
|
* MINMAXRECT32S mrnObj-- 目标矩形坐标
|
|
|
|
|
|
* UBYTE8 nDetectGrayType -- 面目标检测类型 1-只检测亮目标,2-只检测暗目标,3-同时检测亮暗目标
|
|
|
|
|
|
* 输出参数:OBJECTSNR *objSNR -- 目标SNR信息
|
|
|
|
|
|
* 返 回 值:无
|
|
|
|
|
|
* 调用关系:无
|
|
|
|
|
|
* 其它说明:无
|
|
|
|
|
|
**********************************************************/
|
|
|
|
|
|
void DAT_CalRectObjSNR_UINT16(UINT16* pnSrDSmpImg, SINT32 nWidth, SINT32 nHeight,
|
|
|
|
|
|
MINMAXRECT32S mrnObj, SINT32 nBkgRadius,
|
|
|
|
|
|
OBJECTSNR* objSNR, UBYTE8 nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
SINT32 i, j;
|
|
|
|
|
|
SINT32 nBGValue, nBGCnt; //背景点灰度、背景点计数
|
|
|
|
|
|
double dBGMean, dBGStd, dObjStd; //背景均值、方差
|
|
|
|
|
|
MINMAXRECT32S mrnBkg; //背景区域矩形
|
|
|
|
|
|
SINT32 nLineIndex, nIndex;
|
|
|
|
|
|
FLOAT32 fGrayMax, fGrayMin, fGrayMean;
|
|
|
|
|
|
POINT16S ptPntMax, ptPntMin;
|
|
|
|
|
|
SINT32 nGrayCnt;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//获取目标最大灰度值及其坐标
|
|
|
|
|
|
nLineIndex = mrnObj.minY * nWidth;
|
|
|
|
|
|
objSNR->Pnt.x = (mrnObj.minX + mrnObj.maxX) >> 1;
|
|
|
|
|
|
objSNR->Pnt.y = (mrnObj.minY + mrnObj.maxY) >> 1;
|
|
|
|
|
|
objSNR->ObjGray = pnSrDSmpImg[objSNR->Pnt.y * nWidth + objSNR->Pnt.x];
|
|
|
|
|
|
fGrayMax = objSNR->ObjGray;
|
|
|
|
|
|
fGrayMin = objSNR->ObjGray;
|
|
|
|
|
|
ptPntMax = objSNR->Pnt;
|
|
|
|
|
|
ptPntMin = objSNR->Pnt;
|
|
|
|
|
|
fGrayMean = 0.0f;
|
|
|
|
|
|
nGrayCnt = 0;
|
|
|
|
|
|
dObjStd = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (i = mrnObj.minY; i <= mrnObj.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnObj.minX; j <= mrnObj.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
|
|
|
|
|
|
//最大值
|
|
|
|
|
|
if (pnSrDSmpImg[nIndex] > fGrayMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
fGrayMax = (FLOAT32)(pnSrDSmpImg[nIndex]);
|
|
|
|
|
|
ptPntMax.x = j;
|
|
|
|
|
|
ptPntMax.y = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//最小值
|
|
|
|
|
|
if (pnSrDSmpImg[nIndex] < fGrayMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
fGrayMin = (FLOAT32)(pnSrDSmpImg[nIndex]);
|
|
|
|
|
|
ptPntMin.x = j;
|
|
|
|
|
|
ptPntMin.y = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//均值
|
|
|
|
|
|
fGrayMean += (FLOAT32)(pnSrDSmpImg[nIndex]);
|
|
|
|
|
|
dObjStd += (FLOAT32)(pnSrDSmpImg[nIndex]) * (FLOAT32)(pnSrDSmpImg[nIndex]);
|
|
|
|
|
|
nGrayCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (nGrayCnt > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
fGrayMean /= nGrayCnt;
|
|
|
|
|
|
dObjStd /= nGrayCnt;
|
|
|
|
|
|
dObjStd -= fGrayMean * fGrayMean;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//根据检测类型,获取目标灰度
|
|
|
|
|
|
//亮目标
|
|
|
|
|
|
if (GLB_OBJ_GRAY_BRIGHT == nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
objSNR->ObjGray = fGrayMax;
|
|
|
|
|
|
objSNR->Pnt = ptPntMax;
|
|
|
|
|
|
}
|
|
|
|
|
|
//暗目标
|
|
|
|
|
|
else if (GLB_OBJ_GRAY_DARK == nDetectGrayType)
|
|
|
|
|
|
{
|
|
|
|
|
|
objSNR->ObjGray = fGrayMin;
|
|
|
|
|
|
objSNR->Pnt = ptPntMin;
|
|
|
|
|
|
}
|
|
|
|
|
|
//亮暗全检测
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//MSSu, 20150608: 取目标中心点灰度,屏蔽下面语句
|
|
|
|
|
|
//objSNR->ObjGray = fGrayMean;
|
|
|
|
|
|
//objSNR->Pnt.x = (mrnObj.minX + mrnObj.maxX) >> 1;
|
|
|
|
|
|
//objSNR->Pnt.y = (mrnObj.minY + mrnObj.maxY) >> 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//统计背景均值、方差:划分为上、下、左、右四个背景区域
|
|
|
|
|
|
//计算背景窗口边界
|
|
|
|
|
|
mrnBkg.minX = MAX(0, MIN(mrnObj.minX - nBkgRadius, nWidth - 1));
|
|
|
|
|
|
mrnBkg.maxX = MAX(0, MIN(mrnObj.maxX + nBkgRadius, nWidth - 1));
|
|
|
|
|
|
mrnBkg.minY = MAX(0, MIN(mrnObj.minY - nBkgRadius, nHeight - 1));
|
|
|
|
|
|
mrnBkg.maxY = MAX(0, MIN(mrnObj.maxY + nBkgRadius, nHeight - 1));
|
|
|
|
|
|
|
|
|
|
|
|
//统计背景均值、方差
|
|
|
|
|
|
nBGCnt = 0;
|
|
|
|
|
|
dBGMean = 0;
|
|
|
|
|
|
dBGStd = 0;
|
|
|
|
|
|
|
|
|
|
|
|
//背景区域-上
|
|
|
|
|
|
nLineIndex = mrnBkg.minY * nWidth;
|
|
|
|
|
|
for (i = mrnBkg.minY; i <= mrnObj.minY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnBkg.minX; j <= mrnBkg.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
nBGValue = pnSrDSmpImg[nIndex];
|
|
|
|
|
|
|
|
|
|
|
|
//背景灰度及灰度平方累加
|
|
|
|
|
|
dBGMean += (double)nBGValue;
|
|
|
|
|
|
dBGStd += (double)nBGValue * nBGValue;
|
|
|
|
|
|
nBGCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//背景区域-下
|
|
|
|
|
|
nLineIndex = (mrnObj.maxY + 1) * nWidth;
|
|
|
|
|
|
for (i = mrnObj.maxY + 1; i <= mrnBkg.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnBkg.minX; j <= mrnBkg.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
nBGValue = pnSrDSmpImg[nIndex];
|
|
|
|
|
|
|
|
|
|
|
|
//背景灰度及灰度平方累加
|
|
|
|
|
|
dBGMean += (double)nBGValue;
|
|
|
|
|
|
dBGStd += (double)nBGValue * nBGValue;
|
|
|
|
|
|
nBGCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//背景区域-左
|
|
|
|
|
|
nLineIndex = mrnObj.minY * nWidth;
|
|
|
|
|
|
for (i = mrnObj.minY; i <= mrnObj.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnBkg.minX; j < mrnObj.minX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
nBGValue = pnSrDSmpImg[nIndex];
|
|
|
|
|
|
|
|
|
|
|
|
//背景灰度及灰度平方累加
|
|
|
|
|
|
dBGMean += (double)nBGValue;
|
|
|
|
|
|
dBGStd += (double)nBGValue * nBGValue;
|
|
|
|
|
|
nBGCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//背景区域-右
|
|
|
|
|
|
nLineIndex = mrnObj.minY * nWidth;
|
|
|
|
|
|
for (i = mrnObj.minY; i <= mrnObj.maxY; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (j = mrnObj.maxX + 1; j <= mrnBkg.maxX; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nIndex = nLineIndex + j;
|
|
|
|
|
|
nBGValue = pnSrDSmpImg[nIndex];
|
|
|
|
|
|
|
|
|
|
|
|
//背景灰度及灰度平方累加
|
|
|
|
|
|
dBGMean += (double)nBGValue;
|
|
|
|
|
|
dBGStd += (double)nBGValue * nBGValue;
|
|
|
|
|
|
nBGCnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
nLineIndex += nWidth;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//计算背景均值、方差
|
|
|
|
|
|
dBGMean /= nBGCnt;
|
|
|
|
|
|
dBGStd /= nBGCnt;
|
|
|
|
|
|
dBGStd -= dBGMean * dBGMean;
|
|
|
|
|
|
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//保存目标SNR信息
|
|
|
|
|
|
objSNR->nTGR = (mrnObj.maxX - mrnObj.minX) >> 1;
|
|
|
|
|
|
objSNR->nBGR = nBkgRadius;
|
|
|
|
|
|
objSNR->BGMean = (FLOAT32)dBGMean;
|
|
|
|
|
|
objSNR->BGStd = (FLOAT32)sqrt(dBGStd);
|
|
|
|
|
|
objSNR->fSNR = (0 == objSNR->BGMean || objSNR->BGStd == 0) ? 1e6f : (FLOAT32)((objSNR->ObjGray - objSNR->BGMean) / objSNR->BGStd);
|
|
|
|
|
|
objSNR->ObjStd = (FLOAT32)sqrt(dObjStd);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TARGET_OBJECT _CreateNewTarget(UINT16* pFrame, SINT32 nWidth, SINT32 nHeight, RECT32S bbox, SINT32 unFrmId)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// MINMAXRECT32S mrnObjRect;
|
|
|
|
|
|
// OBJECTSNR objSNR;
|
|
|
|
|
|
// TARGET_OBJECT tNewTarget = { 0 };
|
|
|
|
|
|
// TARGET_OBJECT* pNewTarget = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
// POINT32F ptfObjPos = { 0 };
|
|
|
|
|
|
// ptfObjPos.x = FLOAT32(bbox.x + bbox.w / 2);
|
|
|
|
|
|
// ptfObjPos.y = FLOAT32(bbox.y + bbox.h / 2);
|
|
|
|
|
|
// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
// //计算目标边界矩形
|
|
|
|
|
|
// mrnObjRect.minY = MAX(0, MIN((SINT32)(bbox.y), nHeight - 1));
|
|
|
|
|
|
// mrnObjRect.maxY = MAX(0, MIN((SINT32)(bbox.y + bbox.h), nHeight - 1));
|
|
|
|
|
|
// mrnObjRect.minX = MAX(0, MIN((SINT32)(bbox.x), nWidth - 1));
|
|
|
|
|
|
// mrnObjRect.maxX = MAX(0, MIN((SINT32)(bbox.x + bbox.w), nWidth - 1));
|
|
|
|
|
|
|
|
|
|
|
|
// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
// //新建目标
|
|
|
|
|
|
// memset(&tNewTarget, 0, sizeof(TARGET_OBJECT));
|
|
|
|
|
|
// tNewTarget.bObject = true;
|
|
|
|
|
|
// tNewTarget.unFrmID = unFrmId;
|
|
|
|
|
|
// tNewTarget.pfCenPos = ptfObjPos;
|
|
|
|
|
|
// tNewTarget.pnMaxPos.x = (SINT16)(ptfObjPos.x);
|
|
|
|
|
|
// tNewTarget.pnMaxPos.y = (SINT16)(ptfObjPos.y);
|
|
|
|
|
|
// tNewTarget.mrnRect.minY = (SINT16)(mrnObjRect.minY);
|
|
|
|
|
|
// tNewTarget.mrnRect.maxY = (SINT16)(mrnObjRect.maxY);
|
|
|
|
|
|
// tNewTarget.mrnRect.minX = (SINT16)(mrnObjRect.minX);
|
|
|
|
|
|
// tNewTarget.mrnRect.maxX = (SINT16)(mrnObjRect.maxX);
|
|
|
|
|
|
// tNewTarget.snSize.w = (SINT16)(bbox.w);
|
|
|
|
|
|
// tNewTarget.snSize.h = (SINT16)(bbox.h);
|
|
|
|
|
|
// tNewTarget.snSize.s = (SINT32)(bbox.w * bbox.h);
|
|
|
|
|
|
// tNewTarget.unObjPxlsCnt = (SINT32)(tNewTarget.snSize.s);
|
|
|
|
|
|
|
|
|
|
|
|
// //计算目标的背景均值、背景标准差、SNR
|
|
|
|
|
|
// memset(&objSNR, 0, sizeof(OBJECTSNR));
|
|
|
|
|
|
// _DAT_CalRectObjSNR_PIXELTYPE(pFrame, nWidth, nHeight, mrnObjRect,
|
|
|
|
|
|
// 3, &objSNR, DAT_DETECT_OBJ_TYPE_ALL);
|
|
|
|
|
|
// tNewTarget.pxObjGray = (UINT16)objSNR.ObjGray;
|
|
|
|
|
|
// tNewTarget.nObjTypeSize = GLB_OBJ_SIZE_FACE;
|
|
|
|
|
|
// tNewTarget.nObjTypeGray = objSNR.fSNR > 0.0f ? GLB_OBJ_GRAY_BRIGHT : GLB_OBJ_GRAY_DARK;
|
|
|
|
|
|
// tNewTarget.fBGMean = objSNR.BGMean;
|
|
|
|
|
|
// tNewTarget.fBGStd = objSNR.BGStd;
|
|
|
|
|
|
// tNewTarget.fSNR = objSNR.fSNR;
|
|
|
|
|
|
|
|
|
|
|
|
// return tNewTarget;
|
|
|
|
|
|
// }
|