⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 track.cpp

📁 利用web camera对目标进行特征跟踪的程序 对于初学机器视觉的有些帮助
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 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 + -