📄 track.cpp
字号:
// Track.cpp: implementation of the CTrack class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Track.h"
#include <math.h>
#include <mmsystem.h>
#include "ZXDib.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTrack::CTrack()
{
m_pBitmapInput= NULL; //输入图像:
m_pBitmapInput_SecondLevel = NULL;//输入图像的降低分辨率图象
m_pBitmapTemplate = NULL; //模板图像指针
m_pBitmapTemplate_SecondLevel = NULL;
m_pBitmapTarget= NULL; //目标图像指针
m_pEigenSpace = NULL; //特征空间指针
m_pEigenSpace_SecondLevel= NULL; //金字塔抽层后的特征空间指针
m_dDelt=0.0;
m_nNumberOfTotalEigenVectors =0;
m_nNumberOfSelectedEigenVectors=0;
m_dwTargetWidth =0;
m_dwTargetHeight =0;
m_dwBitmapInputWidth = 0;
m_dwBitmapInputHeight = 0;
m_pEigenSpace_SecondLevel = NULL;
m_pEigenSpace = NULL;
m_pBitmapInput = NULL;
m_pBitmapTemplate = NULL;
m_pBitmapTemplateRelation = NULL;
m_ppResultImage = NULL;
m_ppResultImage=NULL;
m_pOutPutTargetImage=NULL;
m_dGradationOffset = 0;
}
CTrack::~CTrack()
{
//释放内存:
if(!m_pEigenSpace) delete m_pEigenSpace;
if(!m_pEigenSpace_SecondLevel) delete m_pEigenSpace_SecondLevel;
if(!m_pBitmapInput) delete m_pBitmapInput; //输入图像:
if(!m_pBitmapInput_SecondLevel) delete m_pBitmapInput_SecondLevel ;
if(!m_pBitmapTemplate) delete m_pBitmapTemplate; //模板图像指针
if(!m_pBitmapTemplate_SecondLevel)
delete m_pBitmapTemplate_SecondLevel;
if(!m_pBitmapTarget) delete m_pBitmapTarget; //目标图像指针
if(!m_pBitmapTemplateRelation) delete m_pBitmapTemplateRelation;
if(!m_ppResultImage) delete m_ppResultImage;
if(!m_pOutPutTargetImage) delete m_pOutPutTargetImage;
}
/////////////////////////////////////////////////////
//
// 设置和文件相关的信息
// 所有跟踪的初始化信息,全部在此函数内完成
//
/////////////////////////////////////////////////////
bool CTrack::TrackSet(double *pEigenSpaceSet,double *pEigenSapceSecondLevelSet,
int nEigenSpaceVectorNumberSet,double *pBitmapTemplateSet,
DWORD dwTargetHeightSet,DWORD dwTargetWidthSet,
DWORD dwBitmapInputHeightSet,DWORD dwBitmapInputWidthSet,
double dDeltSet,
int nPyramidLevelSet,
int nMaxIterateTimesSet,
double dTemplateUpdatePowerSet,
TRACK_TYPE TrackTypeSet,
TRACK_TEPLATE_UPDATE_TYPE TemplateUpdateTypeSet,
double a_Set[6])
{
//装入特征空间:
if(m_pEigenSpace) delete m_pEigenSpace;
m_pEigenSpace = pEigenSpaceSet;
if(m_pEigenSpace_SecondLevel) delete m_pEigenSpace_SecondLevel;
m_pEigenSpace_SecondLevel = pEigenSapceSecondLevelSet;
//设置采用的特征向量个数:
m_nNumberOfSelectedEigenVectors = nEigenSpaceVectorNumberSet;
//设置目标大小
m_dwTargetWidth = dwTargetWidthSet;
m_dwTargetHeight = dwTargetHeightSet;
//装入模板::并0均值化处理
if(TrackTypeSet==TT_AFFINE)
{
m_pBitmapTemplate = pBitmapTemplateSet;
ZeroMean(m_pBitmapTemplate,m_dwTargetWidth*m_dwTargetHeight,m_dTempalteGradationOffset);
PyramidSampleImage(m_dwTargetHeight,m_dwTargetWidth,m_pBitmapTemplate,m_pBitmapTemplate_SecondLevel);
}else
{
m_pBitmapTemplate = NULL;
m_pBitmapTemplate_SecondLevel = NULL;
m_dTempalteGradationOffset = 0;
}
//设置输入图像大小:
m_dwBitmapInputWidth = dwBitmapInputWidthSet;
m_dwBitmapInputHeight = dwBitmapInputHeightSet;
//参数
m_dDelt = dDeltSet;
m_nPyramidLevel = nPyramidLevelSet;
m_nMaxIterateTimes = nMaxIterateTimesSet;
m_dTemplateUpdatePower = dTemplateUpdatePowerSet;
//跟踪方式和模板更新方式:
TrackType = TrackTypeSet;
TemplateUpdateType = TemplateUpdateTypeSet;
////======以下部分为初始化部分:===============
for(int i=0;i<6;i++)
{
a[i]=a_last[i]=a_Set[i];
a_add[i]= 0;
}
return true;
}
////////////////////////////////////////////////////////////
//
// 得到当前参数所对应的边框:
//
////////////////////////////////////////////////////////////
bool CTrack::GetRect(CPoint * pPoint)
{
if(!pPoint) return FALSE;
double x,y,x_center,y_center;
x_center = (double)(m_dwTargetWidth)/2;
y_center = (double)(m_dwTargetHeight)/2;
a[1] += 1; a[5] += 1;
/////////////// 0 //////////
x = a[0] - x_center*a[1] + y_center*a[2] ;
y = a[3] - x_center*a[4] + y_center*a[5] ;
pPoint[0].y = (int) (y+0.5);
pPoint[0].x = (int) (x+0.5);
//////////// 1 //////////////
x = a[0] + x_center*a[1] + y_center*a[2] ;
y = a[3] + x_center*a[4] + y_center*a[5] ;
pPoint[1].y = (int) (y+0.5);
pPoint[1].x = (int) (x+0.5);
///////////// 2 ///////////////
x = a[0] + x_center*a[1] - y_center*a[2] ;
y = a[3] + x_center*a[4] - y_center*a[5] ;
pPoint[2].y = (int) (y+0.5);
pPoint[2].x = (int) (x+0.5);
////////// 3 ////////////////
x = a[0] - x_center*a[1] - y_center*a[2] ;
y = a[3] - x_center*a[4] - y_center*a[5] ;
pPoint[3].y = (int) (y+0.5);
pPoint[3].x = (int) (x+0.5);
a[1] -= 1; a[5] -= 1;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// 计算当前金字塔层的I,到输入图像中抠取目标区域
//
/////////////////////////////////////////////////////////////////////////////////////////////////
bool CTrack::SampleTargetWithAffineParameter(int level,double* a_set,double *&pTargetOut)
{
double x,y,temp,x1,x2,x3,y1,y2,y3;
int nFactor = 1<<level;
m_dwTargetWidth /= nFactor;
m_dwTargetHeight/= nFactor;
double x_center = m_dwTargetWidth/2;
double y_center = m_dwTargetHeight/2;
int dMagnifyX,dMagnifyY;
dMagnifyY = nFactor;
dMagnifyX = nFactor;
DWORD position,i,j,position_l=0,dwObjectSize_now=m_dwTargetHeight*m_dwTargetWidth,dwImageWidth_now = m_dwBitmapInputWidth*nFactor;
double x_addition;
double y_addition;
if(pTargetOut) delete pTargetOut;
pTargetOut = new double [m_dwTargetWidth*m_dwTargetHeight];
//================有效性检测========================
if(a_set[1]*a_set[1]+a_set[4]*a_set[4] <0.001 || a_set[2]*a_set[2]+a_set[5]*a_set[5] <0.001)
{
// AfxMessageBox("在采集当前选择框所覆盖的目标区时,区域瞬间变得太小!");
// dwTargetWindowWidth *= nFactor; dwTargetWindowHeight*= nFactor;
// return FALSE;
}
if(a_set[1]*a_set[1]+a_set[4]*a_set[4] >9 || a_set[2]*a_set[2]+a_set[5]*a_set[5] >9)
{
// AfxMessageBox("在采集当前选择框所覆盖的目标区时,区域瞬间变得太大!");
// dwTargetWindowWidth *= nFactor; dwTargetWindowHeight*= nFactor;
// return FALSE;
}
//检测匹配框是否出界:(检测四个顶点是否出界)
x = (a_set[0]-x_center*a_set[1]-y_center*a_set[2] -x_center)*nFactor;// + m_CenterX;
x1 = (a_set[0]+x_center*a_set[1]-y_center*a_set[2] +x_center)*nFactor;// + m_CenterX;
x2 = (a_set[0]-x_center*a_set[1]+y_center*a_set[2] -x_center)*nFactor;// + m_CenterX;
x3 = (a_set[0]+x_center*a_set[1]+y_center*a_set[2] +x_center)*nFactor;// + m_CenterX;
y = (a_set[3]-x_center*a_set[4]-y_center*a_set[5] -y_center)*nFactor;// + m_CenterY;
y1 = (a_set[3]+x_center*a_set[4]-y_center*a_set[5] -y_center)*nFactor;// + m_CenterY;
y2 = (a_set[3]-x_center*a_set[4]+y_center*a_set[5] +y_center)*nFactor;// + m_CenterY;
y3 = (a_set[3]+x_center*a_set[4]+y_center*a_set[5] +y_center)*nFactor;// + m_CenterY;
if(x<2||x1<2||x2<2||x3<2|| x>m_dwBitmapInputWidth-2||x1>m_dwBitmapInputWidth-2||x2>m_dwBitmapInputWidth-2||x3>m_dwBitmapInputWidth-2|| y<2||y1<2||y2<2||y3<2|| y1>m_dwBitmapInputHeight-2||y2>m_dwBitmapInputHeight-2||y3>m_dwBitmapInputHeight-2||y>m_dwBitmapInputHeight-2 )
{
// AfxMessageBox("在采集当前选择框所覆盖的目标区时,发生越界!");
m_dwTargetWidth *= nFactor; m_dwTargetHeight*= nFactor;
return FALSE;
}
double x_Left;
double y_Left;
//仿射变换,上中心偏移量
x_Left = (a_set[0] -x_center*a_set[1] -y_center*a_set[2] -x_center)*nFactor;// + m_CenterX ;
y_Left = (a_set[3] -x_center*a_set[4] -y_center*a_set[5] -y_center)*nFactor;// + m_CenterY ;
x_addition = (a_set[1]+1)*nFactor;
y_addition = (a_set[4])*nFactor;
//采集目标图象
for(j=0; j<m_dwTargetHeight; j++)
{
x = x_Left;
y = y_Left;
x_Left += (a_set[2])*nFactor;
y_Left += (a_set[5]+1)*nFactor;
for(i=0; i<m_dwTargetWidth; i++)
{
//计算当前点在输入图像中的位置
position = (int)(y) * m_dwBitmapInputWidth + (int)(x);
/////采集该点处的灰度值
//抽样:在2*2临域内采用内插法:
temp = m_pBitmapInput[position] - (m_pBitmapInput[position] - m_pBitmapInput[position+1])* (x-(int)x);
position += m_dwBitmapInputWidth;
temp -= (temp-(m_pBitmapInput[position] - (m_pBitmapInput[position] - m_pBitmapInput[position+1])* (x-(int)x)))*(y-(int)y);
//插值结果赋给相应的标准化目标点:
pTargetOut[position_l] = temp;
position_l ++;//计算下一个点
x += x_addition;
y += y_addition;
}
}
m_dwTargetWidth *= nFactor;
m_dwTargetHeight*= nFactor;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// 计算当前金字塔层的I,到输入图像中抠取目标区域
//
/////////////////////////////////////////////////////////////////////////////////////////////////
bool CTrack::SampleTargetWithAffineParameter(int level,double* a_set,BYTE *&pTargetOut)
{
double x,y,temp,x1,x2,x3,y1,y2,y3;
int nFactor = 1<<level;
m_dwTargetWidth /= nFactor;
m_dwTargetHeight/= nFactor;
double x_center = m_dwTargetWidth/2;//((double)dwTargetWindowWidth)/(2*nFactor);
double y_center = m_dwTargetHeight/2;//((double)dwTargetWindowWidth)/(2*nFactor);
int dMagnifyX,dMagnifyY;
dMagnifyY = nFactor;
dMagnifyX = nFactor;
DWORD position,i,j,position_l=0,dwObjectSize_now=m_dwTargetHeight*m_dwTargetWidth,dwImageWidth_now = m_dwBitmapInputWidth*nFactor;
double x_addition;
double y_addition;
if(pTargetOut) delete pTargetOut;
pTargetOut = new BYTE [m_dwTargetWidth*m_dwTargetHeight];
//================有效性检测========================
if(a_set[1]*a_set[1]+a_set[4]*a_set[4] <0.001 || a_set[2]*a_set[2]+a_set[5]*a_set[5] <0.001)
{
// AfxMessageBox("在采集当前选择框所覆盖的目标区时,区域瞬间变得太小!");
// dwTargetWindowWidth *= nFactor; dwTargetWindowHeight*= nFactor;
// return FALSE;
}
if(a_set[1]*a_set[1]+a_set[4]*a_set[4] >9 || a_set[2]*a_set[2]+a_set[5]*a_set[5] >9)
{
// AfxMessageBox("在采集当前选择框所覆盖的目标区时,区域瞬间变得太大!");
// dwTargetWindowWidth *= nFactor; dwTargetWindowHeight*= nFactor;
// return FALSE;
}
//检测匹配框是否出界:(检测四个顶点是否出界)
x = (a_set[0]-x_center*a_set[1]-y_center*a_set[2] -x_center)*nFactor;// + m_CenterX;
x1 = (a_set[0]+x_center*a_set[1]-y_center*a_set[2] +x_center)*nFactor;// + m_CenterX;
x2 = (a_set[0]-x_center*a_set[1]+y_center*a_set[2] -x_center)*nFactor;// + m_CenterX;
x3 = (a_set[0]+x_center*a_set[1]+y_center*a_set[2] +x_center)*nFactor;// + m_CenterX;
y = (a_set[3]-x_center*a_set[4]-y_center*a_set[5] -y_center)*nFactor;// + m_CenterY;
y1 = (a_set[3]+x_center*a_set[4]-y_center*a_set[5] -y_center)*nFactor;// + m_CenterY;
y2 = (a_set[3]-x_center*a_set[4]+y_center*a_set[5] +y_center)*nFactor;// + m_CenterY;
y3 = (a_set[3]+x_center*a_set[4]+y_center*a_set[5] +y_center)*nFactor;// + m_CenterY;
if(x<2||x1<2||x2<2||x3<2|| x>m_dwBitmapInputWidth-2||x1>m_dwBitmapInputWidth-2||x2>m_dwBitmapInputWidth-2||x3>m_dwBitmapInputWidth-2|| y<2||y1<2||y2<2||y3<2|| y1>m_dwBitmapInputHeight-2||y2>m_dwBitmapInputHeight-2||y3>m_dwBitmapInputHeight-2||y>m_dwBitmapInputHeight-2 )
{
// AfxMessageBox("在采集当前选择框所覆盖的目标区时,发生越界!");
m_dwTargetWidth *= nFactor; m_dwTargetHeight*= nFactor;
return FALSE;
}
double x_Left;
double y_Left;
//仿射变换,上中心偏移量
x_Left = (a_set[0] -x_center*a_set[1] -y_center*a_set[2] -x_center)*nFactor;// + m_CenterX ;
y_Left = (a_set[3] -x_center*a_set[4] -y_center*a_set[5] -y_center)*nFactor;// + m_CenterY ;
x_addition = (a_set[1]+1)*nFactor;
y_addition = (a_set[4])*nFactor;
//采集目标图象
for(j=0; j<m_dwTargetHeight; j++)
{
x = x_Left;
y = y_Left;
x_Left += (a_set[2])*nFactor;
y_Left += (a_set[5]+1)*nFactor;
for(i=0; i<m_dwTargetWidth; i++)
{
//计算当前点在输入图像中的位置
position = (int)(y) * m_dwBitmapInputWidth + (int)(x);
/////采集该点处的灰度值
//抽样:在2*2临域内采用内插法:
temp = m_pBitmapInput[position] - (m_pBitmapInput[position] - m_pBitmapInput[position+1])* (x-(int)x);
position += m_dwBitmapInputWidth;
temp -= (temp-(m_pBitmapInput[position] - (m_pBitmapInput[position] - m_pBitmapInput[position+1])* (x-(int)x)))*(y-(int)y);
//插值结果赋给相应的标准化目标点:
pTargetOut[position_l] = (int)temp;
position_l ++;//计算下一个点
x += x_addition;
y += y_addition;
}
}
m_dwTargetWidth *= nFactor;
m_dwTargetHeight*= nFactor;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -