www.pudn.com > 人体步态跟踪识别bate版.rar > TrackMotion.cpp
// TrackMotion.cpp: implementation of the CTrackMotion class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "humantrack.h"
#include "TrackMotion.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTrackMotion::CTrackMotion()
{
m_hDIB = NULL;
m_palDIB = NULL;
for(int i=0;i<7;i++)
if (m_JointP[i].GetSize()!=0)
{
m_JointP[i].RemoveAll();
}
}
CTrackMotion::~CTrackMotion()
{
}
/*************************************************************************
* \函数名称: GetFileName()
* \输入参数:
* CString strFilePathName - 图象的文件名
* int nCurFrameNum - 当前帧的图象文件名
* \返回值:
* CString - 返回给定帧数的图象文件名
*
* \说明:
* 该函数根据指定文件路径名和当前图象序列的帧数获取图象文件名
* 该函数中需要注意的是,只能读取0-999帧图象,图象为bmp格式,且按照
* 帧数数字进行存储,例如第一帧图象文件名为×××001.bmp,第33帧图象
* 的文件名为×××033.bmp。如果不是bmp文件,则返回"NULL"。
*
*************************************************************************
*/
CString CTrackMotion::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("_0%d",nCurFrameNum);
}
else {
if(nCurFrameNum<100 &&nCurFrameNum>=10){
strTempNum.Format("_%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 CTrackMotion::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;
}
//得到文件的路径名
void CTrackMotion::SetFileName(CString StrFilePathName)
{
m_FileName=StrFilePathName;
}
//得到当前帧
void CTrackMotion::SetCurrentFrame(int nCurrentFrame)
{
m_nCurrentFrame=nCurrentFrame;
m_nBeginFrame=nCurrentFrame;
}
void CTrackMotion::InitDIBData()
{
if (m_palDIB != NULL)
{
delete m_palDIB;
m_palDIB = NULL;
}
if (m_hDIB == NULL)
{
return;
}
//创建文档尺寸
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
if (::DIBWidth(lpDIB) > 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 CTrackMotion::ReplaceHDIB(HDIB hDIB)
{
if (m_hDIB != NULL)
{
::GlobalFree((HGLOBAL) m_hDIB);
}
m_hDIB = hDIB;
}
void CTrackMotion::SetEndFrame(int nEndFrame)
{
m_nEndFrame=nEndFrame;
}
void CTrackMotion::MotionTrack(int CurrentFrame)
{
int nImageWidth=m_ImageWidth;
int nImageHeight=m_ImageHeight;
unsigned char* pdata=new unsigned char[nImageWidth*nImageHeight];
m_nCurrentFrame=CurrentFrame;
if(!LoadDibSeq()){return ;}
LPSTR lpDIBHdr; // 指向BITMAPINFOHEADER的指针
LPSTR lpDIBBits; // 指向一个DIB位
//检查DIB句柄是否有效
if (m_hDIB == NULL)return ;
//锁住DIB,取得一个起始指针
lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
lpDIBBits = ::FindDIBBits(lpDIBHdr);
// 然后将数据取出,存放在pUnchTemp1中
memcpy(pdata,lpDIBBits,nImageWidth*nImageHeight*sizeof(unsigned char));
::GlobalUnlock((HGLOBAL) m_hDIB);
//寻找头的坐标点
int SearchLineBegin=sh.m_head.Point.y;
int SearchLineEnd=sh.m_neck.Point.y;
int SearchcolBegin=0;
int SearchcolEnd=0;
unsigned char tmp;
for(int i=SearchLineBegin;iSelectObject(&pen);
for(int i=0;i<57;i++)
{
Pos=m_JointP[0].GetAt(i);
Pos.Offset(-4,-82);
pDC->MoveTo(Pos);
Pos=m_JointP[0].GetAt(i);
Pos.Offset(-4,-61);
pDC->LineTo(Pos);
Pos=m_JointP[0].GetAt(i);
Pos.Offset(0,-55);
pDC->LineTo(Pos);
pDC->LineTo(m_JointP[0].GetAt(i));
pDC->LineTo(m_JointP[1].GetAt(i));
pDC->LineTo(m_JointP[2].GetAt(i));
pDC->LineTo(m_JointP[3].GetAt(i));
pDC->MoveTo(m_JointP[0].GetAt(i));
pDC->LineTo(m_JointP[4].GetAt(i));
pDC->LineTo(m_JointP[5].GetAt(i));
pDC->LineTo(m_JointP[6].GetAt(i));
CPen pen1(PS_SOLID,4,RGB(0,255,0));
pDC->SelectObject(&pen1);
}
}
/*************************************************************************
*
* 函数名称:
* HprojectDIB()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
*
* 返回值:
* BOOL - 运算成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用于对两幅图像进行水平投影运算。
*
* 要求目标图像为只有0和255两个灰度值的灰度图像。
************************************************************************/
BOOL CTrackMotion::HprojectDIB(LPSTR lpDIBBits,LONG lWidth, LONG lHeight)
{
// 指向源图像的指针
LPSTR lpSrc;
// 指向缓存图像的指针
LPSTR lpDst;
// 指向缓存DIB图像的指针
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
//循环变量
long i;
long j;
//图像中每行内的黑点个数
long lBlackNumber;
//像素值
unsigned char pixel;
// 图像每行的字节数
LONG lLineBytes;
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化新分配的内存,设定初始值为255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, lWidth * lHeight);
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
for (j = 0;j < lHeight ;j++)
{
lBlackNumber = 0;
for(i = 0;i < lWidth ;i++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;
if (pixel != 255 && pixel != 0)
{
return false;
}
if(pixel == 0)
{
lBlackNumber++;
}
}
for(i = 0;i < lBlackNumber ;i++)
{
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;
*lpDst = (unsigned char)0;
}
}
// 复制投影图像
memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* VprojectDIB()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
*
* 返回值:
* BOOL - 运算成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用于对两幅图像进行垂直投影运算。
*
* 要求目标图像为只有0和255两个灰度值的灰度图像。
************************************************************************/
BOOL CTrackMotion::VprojectDIB(LPSTR lpDIBBits,LONG lWidth, LONG lHeight)
{
// 指向源图像的指针
LPSTR lpSrc;
// 指向缓存图像的指针
LPSTR lpDst;
// 指向缓存DIB图像的指针
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
//循环变量
long i;
long j;
//图像中每行内的黑点个数
long lBlackNumber;
//像素值
unsigned char pixel;
// 图像每行的字节数
LONG lLineBytes;
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化新分配的内存,设定初始值为255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, lWidth * lHeight);
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
for (i = 0;i < lWidth ;i++)
{
lBlackNumber = 0;
for(j = 0;j < lHeight ;j++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;
if (pixel != 255 && pixel != 0)
{
return false;
}
if(pixel == 0)
{
lBlackNumber++;
}
}
for(j = 0;j < lBlackNumber ;j++)
{
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;
*lpDst = (unsigned char)0;
}
}
// 复制投影图像
memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}