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

📄 facedemodlg.cpp

📁 海康威视人脸检测系统!需要海康威视的硬件支持!其中底层用到海康的sdk
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// FaceDemoDlg.cpp : implementation file
//

#include "stdafx.h"
#include "FaceDemo.h"
#include "FaceDemoDlg.h"
#include <afxpriv2.h>
#include <malloc.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WM_CAPFACEMESSAGE  WM_USER+2101
HWND	g_cfHwnd;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
CString g_csPath;
typedef struct _YUV_FRAME_
{
	unsigned char *y;
	unsigned char *u;
	unsigned char *v;
}YUV_FRAME;

YUV_FRAME yuvTemp;

typedef struct
{
	YUV_FRAME	pBmpBuff;//用于截取yuv数据的内存
	CTime		time;//抓取时间
	IPicture	*iPic;//用于显示的bmp数据
	int			nChannel;
	CRect		sRect;//显示范围
	int			w;
	int			h;
}BMP,*PBMP;

BMP bpInfo[12];

typedef struct
{
	BOOL		bDetectNow;//是否已经在检测
	int			nPicType;//0-YUV,1-jpeg图像
	int			nFrameInterval;//检测帧间隔
	int			nJpegQuality;//jpeg图像质量
	BOOL		bSaveFile;//是否存盘
}FACEDETECTPARAM;

FACEDETECTPARAM fdParam[4];

static int nFaceW = 0;


//读取图像文件用于显示
void LoadPictureFromFile(CString strBmpFileName,int index)
{
	if(strBmpFileName)
	{
		CFile file;
		if (!file.Open(strBmpFileName, CFile::modeRead|CFile::shareDenyWrite))
		{
			return;
		}
		
		CArchive ar(&file, CArchive::load | CArchive::bNoFlushOnDelete);
		
		CArchiveStream arcstream(&ar);	
		
		if (bpInfo[index].iPic) 
		{
			bpInfo[index].iPic->Release();
		}
		HRESULT hr = OleLoadPicture((IStream*)&arcstream, 0, FALSE, IID_IPicture, (void**)&bpInfo[index].iPic);
		
//		ASSERT(SUCCEEDED(hr) && bpInfo[index].iPic);
		if(!SUCCEEDED(hr))
		{
			TRACE("LOAD PICTURE ERR\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
			bpInfo[index].iPic=NULL;
		}
		
		file.Close();
	}else
	{
		if (bpInfo[index].iPic) 
		{
			bpInfo[index].iPic->Release();
			bpInfo[index].iPic = NULL;
		}
	}
	
			
}
/*	从yuv数据中读取人脸信息
	nChannel:通道号
	pImage为原始图像地址
	FACE_INFO 为图像中的人脸位置信息(矩形)
	w:原始图像宽度
	h:原始图像高度
*/
void FGetYUVFace(int nChannel,char * pImage,FACE_INFO * pFaceInfo,UINT w,UINT h)
{
	CFaceDemoDlg*dlgmain=(CFaceDemoDlg*)AfxGetMainWnd();
	WaitForSingleObject(dlgmain->m_muShowPic,INFINITE);
	
	int dw,dh;
	int x,y,fw,fh;
	char *Y,*U,*V,*yd,*ud,*vd;

	/*
		!!注意:由于当前版本的人脸检测基于CIF图像,而返回的图像是2CIF,因此水平方向的x和width应该放大一倍。
		这部分以后会完善!
		未压缩格式时,先将人脸存储为BMP格式的临时文件,然后从文件中加载图像显示。
	*/
	x = pFaceInfo->x * 2;
	y = pFaceInfo->y;
	fw = pFaceInfo->width * 2;
	fh = pFaceInfo->height;

	Y = pImage;
	U = pImage + w * h;
	V = pImage + w * h * 5 / 4;

	yd = (char *)bpInfo[nFaceW].pBmpBuff.y;
	ud = (char *)(bpInfo[nFaceW].pBmpBuff.y + (fw * fh));
	vd = (char *)(bpInfo[nFaceW].pBmpBuff.y + (fw * fh * 5 / 4));

	for(int i=y;i< (y + fh);i++)
	{
		//从原始图像中取出局部的人脸图像
		memcpy(yd,Y + i * w + x,fw);
		yd += fw;
		//原始图像是420格式,UV数据每隔一行取一行
		if(!(i & 1))
		{
			memcpy(ud,U + i * w / 4 + x / 2,fw / 2);
			memcpy(vd,V + i * w / 4 + x / 2,fw / 2);
			ud += fw / 2;
			vd += fw / 2;
		}
	}
	bpInfo[nFaceW].time = CTime::GetCurrentTime();

	dw = pFaceInfo->width * 2;
	dh = pFaceInfo->height;



	char csFileName[200];
	if(dlgmain->m_bSaveFile)
	{
		sprintf(csFileName,"%s\\%02d%02d%d.bmp",dlgmain->m_csPath,bpInfo[nFaceW].time.GetMonth(),bpInfo[nFaceW].time.GetDay(),GetTickCount());
	}else
	{
		sprintf(csFileName,"%stempbmp.bmp",g_csPath);
	}
	//设置要显示的图像区域,此时存储的是人脸局部图像,因此要显示全部图像内容。
	bpInfo[nFaceW].sRect.left = 0;
	bpInfo[nFaceW].sRect.top = 0;
	bpInfo[nFaceW].sRect.right = dw;
	bpInfo[nFaceW].sRect.bottom = dh;
	bpInfo[nFaceW].w = dw;
	bpInfo[nFaceW].h = dh;

	//将人脸的局部图像(YUV格式)转换到BMP格式并写入文件
	HW_ConvertToBmpFile(bpInfo[nFaceW].pBmpBuff.y,dw * dh * 3 / 2,dw,dh,csFileName,0);
	//加载BMP文件
	LoadPictureFromFile(csFileName,nFaceW);
	ReleaseMutex(dlgmain->m_muShowPic);
	bpInfo[nFaceW].nChannel = nChannel;
	//显示图像
	SendMessage(g_cfHwnd,WM_CAPFACEMESSAGE, 0, nFaceW);
	nFaceW ++;
	if(nFaceW >= 12)
		nFaceW = 0;
	
}
/* 从jpeg文件中读取人脸信息
	nChannel:通道号
	csFileName:jpeg文件名
	FACE_INFO:为图像中的人脸位置信息(矩形)
	w:原始图像宽度
	h:原始图像高度
*/
void FGetJpegFace(int nChannel,char * csFileName,FACE_INFO *pFaceInfo,UINT w,UINT h)
{
	CFaceDemoDlg*dlgmain=(CFaceDemoDlg*)AfxGetMainWnd();
	WaitForSingleObject(dlgmain->m_muShowPic,INFINITE);
	
	//设置要显示的图像区域,此时文件中存储的是包含全部人脸的大图像,要显示的人脸只是其中的一部分。
	bpInfo[nFaceW].time = CTime::GetCurrentTime();
	bpInfo[nFaceW].sRect.left = pFaceInfo->x * 2;	//人脸的x和width要乘2
	bpInfo[nFaceW].sRect.top = pFaceInfo->y ;
	bpInfo[nFaceW].sRect.right =  pFaceInfo->width * 2 + pFaceInfo->x * 2;
	bpInfo[nFaceW].sRect.bottom = pFaceInfo->height + pFaceInfo->y;
	bpInfo[nFaceW].h = h;
	bpInfo[nFaceW].w = w;
	TRACE("x=%d,y=%d,w=%d,h=%d\n",pFaceInfo->x * 2,pFaceInfo->y , pFaceInfo->width * 2 ,pFaceInfo->height);
	
	//加载图像
	LoadPictureFromFile(csFileName,nFaceW);
	

	bpInfo[nFaceW].nChannel = nChannel;
	ReleaseMutex(dlgmain->m_muShowPic);
	SendMessage(g_cfHwnd,WM_CAPFACEMESSAGE, 0, nFaceW);
	nFaceW ++;
	if(nFaceW >= 12)
		nFaceW = 0;
	
}

//回调函数
void FaceDetectionCallback(UINT nChannel,UINT nFaceCount,FACE_INFO *pFaceInfo,char *pImage,UINT len,UINT w,UINT h)
{

	CFaceDemoDlg*dlgmain=(CFaceDemoDlg*)AfxGetMainWnd();
	UINT i;
	

	if(fdParam[nChannel].nPicType == 0)
	{
		//未压缩格式,原始图像,直接处理
		for(i=0;i<nFaceCount;i++)
		{
			FGetYUVFace(nChannel,pImage,pFaceInfo,w,h);
			pFaceInfo++;
		}
	}
	else
	{
		//图像已经压缩为JPEG格式,先存储到文件
		char csFileName[200];
		FILE * f;
		if(fdParam[nChannel].bSaveFile)
		{
			sprintf(csFileName,"%s\\ch%02d_%02d%02d%d.jpg",dlgmain->m_csPath,nChannel,bpInfo[nFaceW].time.GetMonth(),bpInfo[nFaceW].time.GetDay(),GetTickCount());
		}else
		{
			sprintf(csFileName,"%stempjpg.jpg",g_csPath);
		}
		f=fopen(csFileName,"wb");
		fwrite(pImage,1,len,f);
		fclose(f);
		for(i=0;i<nFaceCount;i++)
		{
			FGetJpegFace(nChannel,csFileName,pFaceInfo,w,h);
			pFaceInfo++;
		}
	}

}
class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFaceDemoDlg dialog

CFaceDemoDlg::CFaceDemoDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CFaceDemoDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFaceDemoDlg)
	m_csTime1 = _T("");
	m_csTime10 = _T("");
	m_csTime11 = _T("");
	m_csTime2 = _T("");
	m_csTime4 = _T("");
	m_csTime3 = _T("");
	m_csTime6 = _T("");
	m_csTime7 = _T("");
	m_csTime8 = _T("");
	m_csTime9 = _T("");
	m_csTime0 = _T("");
	m_bSaveFile = FALSE;
	m_nJpegQuality = 50;
	m_nFrameInterval = 10;
	m_csChan1 = _T("");
	m_csChan10 = _T("");
	m_csChan11 = _T("");
	m_csChan12 = _T("");
	m_csChan2 = _T("");
	m_csChan3 = _T("");
	m_csChan4 = _T("");
	m_csChan5 = _T("");
	m_csChan6 = _T("");
	m_csChan7 = _T("");
	m_csChan8 = _T("");
	m_csChan9 = _T("");
	m_nChannel=0;
	m_bInited=FALSE;
	m_bStartCap=FALSE;
	m_bColorFace=TRUE;
	m_nType = 0;
	m_csTime5 = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CFaceDemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFaceDemoDlg)
	DDX_Control(pDX, IDC_PIC_TIME9, m_edTime9);
	DDX_Control(pDX, IDC_PIC_TIME8, m_edTime8);
	DDX_Control(pDX, IDC_PIC_TIME7, m_edTime7);
	DDX_Control(pDX, IDC_PIC_TIME6, m_edTime6);
	DDX_Control(pDX, IDC_PIC_TIME5, m_edTime5);
	DDX_Control(pDX, IDC_PIC_TIME4, m_edTime4);
	DDX_Control(pDX, IDC_PIC_TIME3, m_edTime3);
	DDX_Control(pDX, IDC_PIC_TIME2, m_edTime2);
	DDX_Control(pDX, IDC_PIC_TIME11, m_edTime11);
	DDX_Control(pDX, IDC_PIC_TIME10, m_edTime10);
	DDX_Control(pDX, IDC_PIC_TIME1, m_edTime1);
	DDX_Control(pDX, IDC_PIC_TIME0, m_edTime0);
	DDX_Control(pDX, IDC_PIC_CHAN9, m_edChan9);
	DDX_Control(pDX, IDC_PIC_CHAN8, m_edChan8);
	DDX_Control(pDX, IDC_PIC_CHAN7, m_edChan7);
	DDX_Control(pDX, IDC_PIC_CHAN6, m_edChan6);
	DDX_Control(pDX, IDC_PIC_CHAN5, m_edChan5);
	DDX_Control(pDX, IDC_PIC_CHAN4, m_edChan4);
	DDX_Control(pDX, IDC_PIC_CHAN3, m_edChan3);
	DDX_Control(pDX, IDC_PIC_CHAN2, m_edChan2);
	DDX_Control(pDX, IDC_PIC_CHAN12, m_edChan12);
	DDX_Control(pDX, IDC_PIC_CHAN11, m_edChan11);
	DDX_Control(pDX, IDC_PIC_CHAN10, m_edChan10);
	DDX_Control(pDX, IDC_PIC_CHAN1, m_edChan1);
	DDX_Control(pDX, IDC_COMBO_MODE, m_cmbType);
	DDX_Text(pDX, IDC_PIC_TIME1, m_csTime1);
	DDX_Text(pDX, IDC_PIC_TIME10, m_csTime10);
	DDX_Text(pDX, IDC_PIC_TIME11, m_csTime11);
	DDX_Text(pDX, IDC_PIC_TIME2, m_csTime2);
	DDX_Text(pDX, IDC_PIC_TIME4, m_csTime4);
	DDX_Text(pDX, IDC_PIC_TIME3, m_csTime3);
	DDX_Text(pDX, IDC_PIC_TIME6, m_csTime6);
	DDX_Text(pDX, IDC_PIC_TIME7, m_csTime7);
	DDX_Text(pDX, IDC_PIC_TIME8, m_csTime8);
	DDX_Text(pDX, IDC_PIC_TIME9, m_csTime9);
	DDX_Text(pDX, IDC_PIC_TIME0, m_csTime0);
	DDX_Check(pDX, IDC_CHECK_FILE, m_bSaveFile);
	DDX_Text(pDX, IDC_JPEG_QUALITY, m_nJpegQuality);
	DDX_Text(pDX, IDC_FRAME_INTERVAL, m_nFrameInterval);
	DDX_Text(pDX, IDC_PIC_CHAN1, m_csChan1);
	DDX_Text(pDX, IDC_PIC_CHAN10, m_csChan10);
	DDX_Text(pDX, IDC_PIC_CHAN11, m_csChan11);
	DDX_Text(pDX, IDC_PIC_CHAN12, m_csChan12);
	DDX_Text(pDX, IDC_PIC_CHAN2, m_csChan2);
	DDX_Text(pDX, IDC_PIC_CHAN3, m_csChan3);
	DDX_Text(pDX, IDC_PIC_CHAN4, m_csChan4);
	DDX_Text(pDX, IDC_PIC_CHAN5, m_csChan5);
	DDX_Text(pDX, IDC_PIC_CHAN6, m_csChan6);
	DDX_Text(pDX, IDC_PIC_CHAN7, m_csChan7);
	DDX_Text(pDX, IDC_PIC_CHAN8, m_csChan8);
	DDX_Text(pDX, IDC_PIC_CHAN9, m_csChan9);
	DDX_Text(pDX, IDC_PIC_TIME5, m_csTime5);
	//}}AFX_DATA_MAP
	
//	DDX_Text(pDX, IDC_FACE_TYPE1, m_bColorFace);
}

BEGIN_MESSAGE_MAP(CFaceDemoDlg, CDialog)
ON_CONTROL_RANGE(BN_CLICKED,IDC_FACE_TYPE1,IDC_FACE_TYPE3,OnChangeFaceType)
	//{{AFX_MSG_MAP(CFaceDemoDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_MOVE()
	ON_BN_CLICKED(IDC_START_CAP, OnStartCap)
	ON_BN_CLICKED(IDC_STOP_CAP, OnStopCap)
	ON_BN_CLICKED(IDC_EXIT, OnExit)
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_CHECK_FILE, OnCheckFile)
	ON_BN_CLICKED(IDC_STOPALL, OnStopall)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_CAPFACEMESSAGE,OnClientMessage)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFaceDemoDlg message handlers

BOOL CFaceDemoDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
    
	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	////////////////////以下是为初始化抓face准备
	m_pPic = NULL;
	
	g_cfHwnd=this->m_hWnd;
	char *p;

⌨️ 快捷键说明

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