www.pudn.com > 人体步态跟踪识别bate版.rar > BackGround.cpp


// BackGround.cpp: implementation of the CBackGround class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "humantrack.h" 
#include "BackGround.h" 
#include "math.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
CBackGround::CBackGround() 
{ 
	m_hDIB = NULL; 
	m_palDIB = NULL; 
} 
CBackGround::~CBackGround() 
{ 
 
} 
 
/************************************************************************* 
 * \函数名称:  GetFileName() 
 * \输入参数: 
 *   CString	strFilePathName		- 图象的文件名  
 *   int		nCurFrameNum		- 当前帧的图象文件名 
 * \返回值: 
 *   CString			- 返回给定帧数的图象文件名 
 * \说明: 
 *   该函数根据指定文件路径名和当前图象序列的帧数获取图象文件名 
 *   该函数中需要注意的是,只能读取0-999帧图象,图象为bmp格式,且按照 
 *   帧数数字进行存储,例如第一帧图象文件名为×××001.bmp,第33帧图象 
 *   的文件名为×××033.bmp。如果不是bmp文件,则返回"NULL"。 
 * 
 **************************************************************************/ 
 
CString CBackGround::GetFileName(CString strFilePathName, int nCurFrameNum) 
{ 
	//文件的路径名 
	CString strTempFileName; 
 
	int nNumPos=strFilePathName.Find("."); 
	if(nNumPos==-1) 
	{ 
		AfxMessageBox("Please choose a bmp file"); 
		return "NULL"; 
	} 
 
	//表示去掉了扩展名和数字标号的路径名,在这里,限定帧数为0~999,所以采用三位来表示 
	CString strFileNameNoExtNoNum=strFilePathName.Left(nNumPos-3); 
 
	//表示标号的字符串 
	CString strTempNum; 
 
	if(nCurFrameNum<10){ 
		strTempNum.Format("00%d",nCurFrameNum); 
	} 
	else { 
		if(nCurFrameNum<100 &&nCurFrameNum>=10){ 
			strTempNum.Format("0%d",nCurFrameNum); 
		} 
		else{ 
			strTempNum.Format("%d",nCurFrameNum); 
		} 
	} 
	 
	// 得到图象文件名 
	strTempFileName=strFileNameNoExtNoNum+strTempNum+".bmp"; 
	 
	// 返回 
	return strTempFileName; 
} 
 
/************************************************************************* 
 * 
 * \函数名称: 
 *   LoadDibSeq() 
 * 
 * \输入参数: 
 *   CString		strFilePath		- 第一帧图象的文件名  
 *   int		nCurFrameNum		- 当前帧的图象文件名 
 *   int		nTotalFrameNum		- 进行检测的图象帧数 
 *   CDib*		pDib			- 指向返回CDib类的指针 
 * 
 * \返回值: 
 *   BOOL			- 成功则返回TRUE,否则返回FALSE 
 * 
 * \说明: 
 *   该函数根据指定文件路径名和当前图象序列的帧数读取图象数据道pDib中 
 *   该函数中需要注意的是,只能读取0-999帧图象,图象为bmp格式,且按照 
 *   帧数数字进行存储,例如第一帧图象文件名为×××001.bmp,第33帧图象 
 *   的文件名为×××033.bmp。 
 * 
 **************************************************************************/ 
 
BOOL CBackGround::LoadDibSeq() 
{ 
	//一般来讲,程序在处理的过程中需要装载的帧号应该是由外界指定的 
	//当指定的帧号不合法时,就装载当前帧作为默认值 
 
	// 获得当前帧的图象文件名 
	CString strTempFileName; 
	strTempFileName=GetFileName(m_FileName, m_nCurrentFrame); 
	 
	CFile fileOpen; 
     
	fileOpen.Open(_T(strTempFileName),CFile::modeRead); 
 
	m_hDIB = ::ReadDIBFile(fileOpen); 
	 
	LPSTR pDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB); 
	 
	InitDIBData(); 
 
	// 图象的宽度 
	m_ImageWidth= ::DIBWidth(pDIB);	 
	 
	// 图象的高度 
	m_ImageHeight= ::DIBHeight(pDIB); 
 
	return TRUE; 
} 
 
/************************************************************************* 
 * 
 * \函数名称: 
 *   BinaFrameDiff() 
 * 
 * \输入参数: 
 *   unsigned char*	pUnchImg1		- 图象的文件名  
 *   unsigned char*	pUnchImg2		- 当前帧的图象文件名 
 *   int		nWidth 
 *   int		nHeight 
 *   unsigned char*	pUnchResult 
 *   int		nThreshold 
 * 
 * \返回值: 
 *   CString			- 返回给定帧数的图象文件名 
 * 
 * \说明: 
 *   该函数比较pUnchImg1和pUnchImg2两个区域中的内容,如果两个区域内      
 *容的差值的绝对值比Threshold大,则将pUnchResult相应的元素设置为逻辑值1, 
 *用灰度255表示,否则为0,并用灰度0表示 
 * 
 **************************************************************************/ 
 
void CBackGround::BinaFrameDiff(unsigned char *pUnchImg1, unsigned char *pUnchImg2,unsigned char * pUnchResult,int nThreshold) 
{ 
	int nTemp=0; 
	for (int i=0;i nThreshold ? 255:0; 
	}  
	return ; 
} 
 
/************************************************************************* 
 * 
 * \函数名称: 
 *   ErodeFrameDiff() 
 * 
 * \输入参数: 
 *   unsigned char*	pUnchImg1		- 图象数据指针 
 *   int		nWidth			    - 图象宽度 
 *   int		nHeight			    - 图象高度 
 *   int		nErodeHalfWin		- 腐蚀窗口大小的一半 
 *   unsigned char*	pUnchResult		- 结果数据制止 
 *   int		nThreshold		    - 阈值 
 * 
 * \返回值: 
 *   无 
 * 
 * \说明: 
 *   该函数进行腐蚀操作,形态学操作对pUnchImg中的每一点,计算这一点对应的 
 *窗口内的一些参数,然后根据参数结果给这个点设置相应的值. 功能上相当于广义滤波	 
 * 
 **************************************************************************/ 
 
void CBackGround::ErodeFrameDiff(unsigned char *pUnchImg, int nErodeHalfWin, int nErodeThreshold, unsigned char *pUnchResult) 
{ 
    int nHeight=m_ImageHeight; 
	int nWidth=m_ImageWidth; 
	// 搜索整个图象,对图象进行腐蚀处理 
	for (int i=nErodeHalfWin;i= nTotalFrameNum - 1,则说明,已经遍历到最后一帧了 
				if (t >= nTotalFrameNum - 1)	 
					break; 
				 
				// 此时应为此长度的开始 
				segStart = t; 
				 
				while ((t < nTotalFrameNum - 1) && (pUnchTrackBox[t*nFrameSize+offset] == 0))	 
					t++;						 
				 
				// 此长度的结束帧标号 
				segEnd = t - 1; 
				 
				// 获得此连续为0的帧的长度 
				segLen = segEnd +1 -segStart;	 
				 
				// 判断是否为最大长度,是则进行替换 
				if (segLen > largeLen)	{ 
					largeLen = segLen; 
					frameNum = (segEnd + segStart)/2;				 
				} 
			}  
			 
			pnTrackSegLen[offset] = largeLen; 
			pnTrackSegFrame[offset] = frameNum; 
		} 
	} 
	 
	delete []pUnchTrackBox;	pUnchTrackBox=NULL; 
	 
	// 因为对每个象素而言,背景可能出现在不同帧里,此时需要把所有帧调入内存 
	unsigned char* pBuffer = new unsigned char[nTotalFrameNum*(nImageWidth*nImageHeight)]; 
	 
	m_nCurrentFrame=m_nBeginFrame; 
	for (int k=0; k INT_MAX ||::DIBHeight(lpDIB) > INT_MAX) 
	{ 
		::GlobalUnlock((HGLOBAL) m_hDIB); 
		::GlobalFree((HGLOBAL) m_hDIB); 
		m_hDIB = NULL; 
		CString strMsg; 
		AfxMessageBox("文件太大,不能打开"); 
		return; 
	} 
	::GlobalUnlock((HGLOBAL) m_hDIB); 
	//创建拷贝调色板 
	m_palDIB = new CPalette; 
	if (m_palDIB == NULL) 
	{ 
		// 释放内存 
		::GlobalFree((HGLOBAL) m_hDIB); 
		m_hDIB = NULL; 
		return; 
	} 
	if (::CreateDIBPalette(m_hDIB, m_palDIB) == NULL) 
	{ 
		delete m_palDIB; 
		m_palDIB = NULL; 
		return; 
	} 
} 
 
void CBackGround::ReplaceHDIB(HDIB hDIB) 
{ 
	if (m_hDIB != NULL) 
	{ 
		::GlobalFree((HGLOBAL) m_hDIB); 
	} 
	m_hDIB = hDIB; 
} 
 
void CBackGround::SetEndFrame(int nEndFrame) 
{ 
  m_nEndFrame=nEndFrame; 
}