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

📄 cdrawf.cpp

📁 face recognition test source code
💻 CPP
字号:
#include "stdafx.h"

#include "CDrawF.h"
#include "error.h"
#include <math.h>

BEGIN_MESSAGE_MAP(CDrawFace, CFrameWnd)
	//{{AFX_MSG_MAP(CDrawFace)
	ON_WM_PAINT()
	ON_WM_VSCROLL()
	ON_WM_CREATE()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CDrawFace::CDrawFace()
	{	
	pFaceDB = NULL;
	pFaceMat = NULL;
	pEigenVal = NULL;
	bMat = FALSE;
	}  
	
int CDrawFace::OnCreate(LPCREATESTRUCT lpCreateStruct)
	{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	/*Set the vertical scroll range*/
	GEOMPARAMS gp;
	RECT rect;
	
	GetGeomParams(&gp);
	nMaxVPos = gp.yNum + ((gp.lastNum > 0) ? 1:0);
	GetClientRect(&rect);
	if (nMaxVPos - (float)rect.bottom/(float)Getylen() + 2 > 1)
		SetScrollRange(SB_VERT, 1, nMaxVPos - (float)rect.bottom/(float)Getylen() + 2);
	else
		SetScrollRange(SB_VERT, 1, 1);
	nVPos = 1;
	
	/*Create the font*/
	LPSTR pszFace = "MS Sans Serif";
	HDC hdc = ::GetDC(GetSafeHwnd());
	
	MapModePrevious = SetMapMode(hdc, MM_TWIPS);
	hfont = CreateFont(-12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "MS Sans Serif");
	SetMapMode(hdc, MapModePrevious);
	
	::ReleaseDC(GetSafeHwnd(), hdc);

	return 0;
	}

void CDrawFace::OnSize(UINT nType, int cx, int cy)
	{
	CFrameWnd::OnSize(nType, cx, cy);
	
	/*Reset the vertical scroll range*/
	GEOMPARAMS gp;
	
	GetGeomParams(&gp);
	nMaxVPos = gp.yNum + ((gp.lastNum > 0) ? 1:0);
	if (nMaxVPos - (float)cy/(float)Getylen() + 2 > 1)
		SetScrollRange(SB_VERT, 1, nMaxVPos - (float)cy/(float)Getylen() + 2);
	else
		SetScrollRange(SB_VERT, 1, 1);
	
	int nLinePage;
	nLinePage = floor((float)cy / (float)Getylen());
   if (nVPos > nMaxVPos - nLinePage + 2)
   	nVPos = nMaxVPos - nLinePage + 2;
   if (nVPos < 1)
   	nVPos = 1;
   
	SetScrollPos(SB_VERT, nVPos);
	}

void CDrawFace::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
	{
	RECT rect;
	int nLinePage, nPrevVPos;
	
	GetClientRect(&rect);
	nLinePage = floor((float)(rect.bottom - rect.top) / (float)Getylen());
   
	nPrevVPos = nVPos;
	switch (nSBCode)
		{
		case SB_LINEDOWN:
			nVPos++;
			break;
		
		case SB_LINEUP:
			nVPos--;
			break;
		
		case SB_PAGEDOWN:
			nVPos += nLinePage;
			break;
		
		case SB_PAGEUP:
			nVPos -= nLinePage;
			break;
		
		case SB_THUMBPOSITION:
		case SB_THUMBTRACK:
			nVPos = nPos;
			break;
		}
	if (nVPos < 1)
		nVPos = 1;
   if (nVPos > nMaxVPos - nLinePage + 2)
   	nVPos = nMaxVPos - nLinePage + 2;
   
	SetScrollPos(SB_VERT, nVPos);
   ScrollWindow(0, -(nVPos - nPrevVPos)*Getylen());
   
	CFrameWnd::OnVScroll(nSBCode, nPos, pScrollBar);
	}

/*************************************************************************************************
* Draws the area that must be redrawn. This fct is called by windows
*************************************************************************************************/
void CDrawFace::OnPaint()
	{
	CPaintDC dc(this); 										// device context for painting
	typeface *pData = NULL; 
	long x, y, xlen, ylen, nFace, nNumFace;
	COLORREF color;
	CORNER c;
	RECT DrawRect, FaceRect, TextRect;
	RECT area;
	char name[64];
	unsigned int val;
	float shift = 0.0;
	float scale = 1.0;
	CFace *pFace = NULL;
	
	GetUpdateRect(&area, TRUE);							/*Put in area the rectangle that must be redrawn*/
	if (IsRectEmpty(&area))
		GetClientRect(&area);

	GetGeomParams(&gp);
	
	if (bMat == TRUE)
		{
		nNumFace = pFaceMat->GetCol();
		}
	else
		{
		nNumFace = pFaceDB->GetNumFace();
		}
		
	/*Select the font*/
	hfontOld = (HFONT)::SelectObject(dc.m_hDC, (HGDIOBJ)hfont);

	for (nFace = (nVPos-1)*gp.xNum+1; nFace <= nNumFace; nFace++)
		{
		if (bMat == TRUE)
			{
			pFaceMat->Expand(nFace, &scale, &shift, 0, 255);
			pFaceMat->Lock();
			
			pEigenVal->Lock();
			sprintf(name, "%.3f", pEigenVal->GetAt(nFace));
			pEigenVal->Unlock();
			
			xlen = (long)sqrt((double)pFaceMat->GetLi());
			ylen = xlen;
			}
		else
			{	
			pFaceDB->Expand(nFace, &scale, &shift, 0, 255);
			pFace = pFaceDB->GetFace(nFace);
			strcpy(name, pFace->GetName());
			xlen = pFace->Getxlen();
			ylen = pFace->Getylen();
			pFace->Lock();
			}
		
		GetCornerFace(&c, nFace);
		c.y -= (nVPos-1)*Getylen();
		
		SetRect(&FaceRect, c.x, c.y, c.x + xlen, c.y + ylen);
		if (IntersectRect(&DrawRect, &area, &FaceRect))
								/*Assigns to DrawRect the rectangle that must be drawn*/ 
			{					/*The face has to be drawn because it is inside the drawing area*/
			for (y = DrawRect.top - FaceRect.top + 1L; y <= DrawRect.bottom - FaceRect.top; y++)
				{
				for (x = DrawRect.left - FaceRect.left + 1L; x <= DrawRect.right - FaceRect.left; x++)
					{
					if (bMat == TRUE)
						{
						val = (unsigned int)(shift + scale*pFaceMat->GetAt(xlen*y+x+1L, nFace));
						}
					else
						{
						val = (unsigned int)(shift + scale*pFace->GetAt(x, y));
						}
					/*the value of a single pixel is set in this loop, the grey level range is from 0 to 255*/
					color = RGB((unsigned int)val, (unsigned int)val, (unsigned int)val);
					dc.SetPixel(x + c.x, y + c.y, color);
																	/*Set the pixel's value*/
					}
				}
			
			/* Draw the face's name at the bottom of it */
			GetCornerName(&c, nFace);
			c.y -= (nVPos-1)*Getylen();
			SetRect(&TextRect, c.x, c.y, xlen, YTEXT);
			dc.DrawText(name, strlen(name), &TextRect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE);
			}
		if (bMat == TRUE)
			{
			pFaceMat->Unlock();
			}
		else
			{
			pFace->Unlock();
			}
		}

	SelectObject(dc.m_hDC, hfontOld);					/*deselect the font*/
	}
	
/*************************************************************************************************
* Puts in the CORNER struct c (basically a point) the point where the face whose number is nFace
* must be drawn in the face database drawing area.
*************************************************************************************************/
void CDrawFace::GetCornerFace(CORNER *c, long nFace)
	{
	int nx, ny;
	
	nFace--;
		
	nx =  fmod(nFace, gp.xNum);
	ny = floor(nFace / gp.xNum);
	c->x = nx*Getxlen();
	c->y = ny*Getylen();
	}
	
/*************************************************************************************************
* Puts in the CORNER struct c (basically a point) the point where the face's name whose number is 
* nFace must be drawn in the face database drawing area.
*************************************************************************************************/
void CDrawFace::GetCornerName(CORNER *c, long nFace)
	{
	long lval;
	
	GetCornerFace(c, nFace);
	
	if (bMat == TRUE)
		{
		lval = (long)sqrt((double)pFaceMat->GetLi());
		}
	else
		lval = pFaceDB->Getylen();
	c->y += lval + YFACETEXT;
	}
	
/*************************************************************************************************
* Returns the width of a face as it is displayed in the face database drawing area (including the 
* space around it).
*************************************************************************************************/
int CDrawFace::Getxlen()
	{
	long lval;
	
	if (bMat == TRUE)
		{
		lval = (long)sqrt((double)pFaceMat->GetLi());
		}
	else
		lval = pFaceDB->Getxlen();
	return XSPACE + lval;
	}
	
/*************************************************************************************************
* Returns the length of a face as it is displayed in the face database drawing area (including the 
* space around it, the space for the face's name and for the little area between the face and its 
* name).
*************************************************************************************************/
int CDrawFace::Getylen()
	{
	long lval;
	if (bMat == TRUE)
		{
		lval = (long)sqrt((double)pFaceMat->GetLi());
		}
	else
		lval = pFaceDB->Getylen();
	return YSPACE + lval + YFACETEXT + YTEXT;
	}
	
/*************************************************************************************************
* Puts in a struct GEOMPARAMS the number of faces displayed in the two directions and the number 
* of faces which are displayed on the last line.
*************************************************************************************************/
void CDrawFace::GetGeomParams(GEOMPARAMS *gp)
	{
	long lval;
	RECT rect;
	
	if (bMat == TRUE)
		{
		lval = pFaceMat->GetCol();
		}
	else
		lval = pFaceDB->GetNumFace();

   GetClientRect(&rect);
   
	gp->xNum = floor((float)rect.right/(float)Getxlen());
	gp->yNum = floor((float)lval/(float)gp->xNum);
	
	gp->lastNum = lval - gp->xNum*gp->yNum;
	}
	
/*****************************************************************************
* SetFaceDB initialise the face database data (pFaceDB).
******************************************************************************/
void CDrawFace::SetFaceDB(CFaceDB *pFaceDBt)
	{
	pFaceDB = pFaceDBt;
	bMat = FALSE;
	}
		
/*****************************************************************************
* SetFaceDB initialise the face matrix (pFaceMat).
******************************************************************************/
void CDrawFace::SetFaceDB(CMatrix *pFaceMatt, CDiag *pEigenValt)
	{
	pFaceMat = pFaceMatt;
	pEigenVal = pEigenValt;
	bMat = TRUE;
	}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -