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

📄 mainfrm.cpp

📁 VC各工程的源码集合
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "VideoCapture.h"

#include "MainFrm.h"
#include "Math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_COMMAND(ID_FORMAT, OnFormat)
	ON_COMMAND(ID_PREVIEW, OnPreview)
	ON_COMMAND(ID_SOURCE, OnSource)
	ON_COMMAND(ID_CAPTURE, OnCapture)
	ON_COMMAND(ID_FACE, OnFace)
	ON_COMMAND(ID_FACELOCATION, OnFacelocation)
	ON_COMMAND(ID_Videofacelac, OnVideofacelac)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

//-------------------------------------------------------------
unsigned char bgr_max(unsigned char b,unsigned char g,unsigned char r)
{
	unsigned char max;
	max=(b>g?b:g);
	max=(max>r?max:r);
	return(max);
}
unsigned char bgr_min(unsigned char b,unsigned char g,unsigned char r)
{
	unsigned char min;
	min=(b<g?b:g);
	min=(min<r?min:r);
	return(min);
}
//-------------------------------------------------------------
//三个回调函数的定义
//-------------------------------------------------------------
LRESULT CALLBACK EXPORT ErrorCallbackProc(HWND hWnd,int nErrID,LPSTR lpErrorText)
//错误回调函数
//hWnd:        Applocation main window handle
//nErrID:      Error code for the encountered error
//lpErrorText: Error text string for the encountered error

{
	if(nErrID==0)
		return TRUE;    //Clear out old errors...
	AfxMessageBox(lpErrorText,MB_OK,NULL);
  
		return TRUE;
}
//--------------------------------------------------------------
LRESULT FAR PASCAL StatusCallbackProc(HWND hWnd,int nID,LPSTR lpStatusText)
//状态回调函数
//hWnd:         Application main window handle
//Nid:          Status code for the current status
//lpStatusText: Status text string for the crurrent status
{
	static int CurrentID;
  
  //the CAP_END message sometimes overwrites a useful
  //statistics message;
  
	if(nID==IDS_CAP_END)
		{
		if((CurrentID==IDS_CAP_STAT_VIDEOAUDIO)||
			 (CurrentID==IDS_CAP_STAT_VIDEOONLY))
			return(TRUE);
		}
	CurrentID=nID;
	return(LRESULT)TRUE;
}
//--------------------------------------------------------------
BOOL videoflag;

LRESULT FAR PASCAL VideoCallbackProc(HWND hWnd,LPVIDEOHDR lpVHdr)
//视频流回调函数
{
//	AfxMessageBox("开始执行视频流回调函数",MB_OK,NULL);

	CWnd * p=AfxGetMainWnd();
	if (!p) return (LRESULT)TRUE;
	((CMainFrame*)p)->m_dibinfo.bitmapinfoheader.biSizeImage=lpVHdr->dwBytesUsed;

//	AfxMessageBox("得到视频流图像大小",MB_OK,NULL);

	memcpy(((CMainFrame*)AfxGetMainWnd())->m_dibinfo.buffer
	+((CMainFrame*)AfxGetMainWnd())->m_dibinfo.VideoFormatSize,
	lpVHdr->lpData,lpVHdr->dwBytesUsed);

	
//	AfxMessageBox("视频流拷贝到内存",MB_OK,NULL);
	CWnd * p_CWnd=AfxGetMainWnd();
	CMainFrame * p_CMainFrame=(CMainFrame*)p_CWnd;
	p_CMainFrame->m_iscapture=TRUE;
//--------------------------------------------------------------
	if(videoflag)
	{
	int FaceNum=0;

//	if(p_CMainFrame->m_enable_skindect)
//	{
//		p_CMainFrame->m_iscapture=FALSE;
//		p_CMainFrame->m_after_skindect=TRUE;

		p_CMainFrame->RGBToYCrCb();
		p_CMainFrame->Skin_detection();

    
	    FaceNum=p_CMainFrame->ErasionFalseArea();

//	}
		if(FaceNum!=0)
		{
			int i,j;
//	int BlackPixelNum=0;
//	int flagy=0;
	//标记是否出现下边界,0表示没有出现下边界,1表示出现了下边界;
//	int flagx=0; 
	//标记是否出现左边界,0表示没有出现左边界,1表示出现了左边界;
			long Offset;
			unsigned char * lpb;
			lpb=p_CMainFrame->m_ycc_buffer;
//	lpb=m_rgb_buffer;

			LPBITMAPINFOHEADER lpbi;
			lpbi=&(p_CMainFrame->m_bitmapheader); 
			//lpbi_ycc是指向"存放'以YCrCb色彩空间表达的数据信息'的信息头信息"的指针;
//	lpbi=&m_rgb_bitmapheader;
	
			DWORD wBytesPerLine=p_CMainFrame->BytePerLine(lpbi);
			//得到每行像素所占用的字节数;

//	int	m_y1=p_CMainFrame->m_y1;
//	int	m_y2=p_CMainFrame->m_y2;
//	int	m_x1=p_CMainFrame->m_x1;
//	int	m_x2=p_CMainFrame->m_x2;
			const int AREAPIXEL=1200;//表示人脸的像素个数必须大于AREAPIXEL;
			int square=0;	
	
			while(square<AREAPIXEL)
			{
				p_CMainFrame->m_x1=-1;
				p_CMainFrame->m_x2=-1;
				p_CMainFrame->m_y1=-1;
				p_CMainFrame->m_y2=-1;

				p_CMainFrame->scan();
				square=(p_CMainFrame->m_x2-p_CMainFrame->m_x1)*(p_CMainFrame->m_y2-p_CMainFrame->m_y1);
			
				if(square<AREAPIXEL)
				{
					for(i=p_CMainFrame->m_y1;i<=(p_CMainFrame->m_y2);i++)
						for(j=p_CMainFrame->m_x1;j<=(p_CMainFrame->m_x2);j++)
						{
							Offset=p_CMainFrame->PixelOffset(i,j,wBytesPerLine);
							*(lpb+Offset)=0;
							*(lpb+Offset+1)=0;
							*(lpb+Offset+2)=0;
						}
				}
			
			
			}
		
			lpb=((CMainFrame*)AfxGetMainWnd())->m_dibinfo.buffer
			+((CMainFrame*)AfxGetMainWnd())->m_dibinfo.VideoFormatSize;
			//用矩形定位人脸,矩形边线呈绿色
			//画人脸的下边界
			i=p_CMainFrame->m_y1;
			for(j=p_CMainFrame->m_x1;j<=p_CMainFrame->m_x2;j++)
			{
				Offset=p_CMainFrame->PixelOffset(i,j,wBytesPerLine); 
				//得到像素点数据在整个数据区中的偏移;
				*(lpb+Offset)=0;
				*(lpb+Offset+1)=255;
				*(lpb+Offset+2)=0;
			}
			//画人脸的上边界;
			i=p_CMainFrame->m_y2;
			for(j=p_CMainFrame->m_x1;j<=p_CMainFrame->m_x2;j++)
			{
				Offset=p_CMainFrame->PixelOffset(i,j,wBytesPerLine); 
				//得到像素点数据在整个数据区中的偏移;
				*(lpb+Offset)=0;
				*(lpb+Offset+1)=255;
				*(lpb+Offset+2)=0;
			}
			//画人脸的左边界;
			j=p_CMainFrame->m_x1;
			for(i=p_CMainFrame->m_y1;i<=p_CMainFrame->m_y2;i++)
			{
				Offset=p_CMainFrame->PixelOffset(i,j,wBytesPerLine); 
				//得到像素点数据在整个数据区中的偏移;
				*(lpb+Offset)=0;
				*(lpb+Offset+1)=255;
				*(lpb+Offset+2)=0;
			}
			//画人脸的右边界;
			j=p_CMainFrame->m_x2;
			for(i=p_CMainFrame->m_y1;i<=p_CMainFrame->m_y2;i++)
			{
				Offset=p_CMainFrame->PixelOffset(i,j,wBytesPerLine); 
				//得到像素点数据在整个数据区中的偏移;
				*(lpb+Offset)=0;
				*(lpb+Offset+1)=255;
				*(lpb+Offset+2)=0;
			}
	
//		m_iscapture=TRUE;
//		m_after_skindect=FALSE;
//		(((CMainFrame*)AfxGetMainWnd())->GetActiveView())->
//		InvalidateRect(NULL,FALSE);
		}
	}
//--------------------------------------------------------------
	
	
	(((CMainFrame*)AfxGetMainWnd())->GetActiveView())->
	InvalidateRect(NULL,FALSE);

//	AfxMessageBox("回调结束,返回",MB_OK,NULL);
	
	
	return(LRESULT)TRUE;
}

//----------------------------------------------------------------
/*
LRESULT PASCAL FrameCallbackProc(HWND hWnd,LPVIDEOHDR lpVHdr)
//单帧回调函数
{

	CWnd * p=AfxGetMainWnd();
	if (!p) return (LRESULT)TRUE;
	((CMainFrame*)p)->m_dibinfo.bitmapinfoheader.biSizeImage=lpVHdr->dwBytesUsed;

	memcpy(((CMainFrame*)AfxGetMainWnd())->m_dibinfo.buffer
	+((CMainFrame*)AfxGetMainWnd())->m_dibinfo.VideoFormatSize,
	lpVHdr->lpData,lpVHdr->dwBytesUsed);

	CWnd * p_CWnd=AfxGetMainWnd();
	CMainFrame * p_CMainFrame=(CMainFrame*)p_CWnd;
	p_CMainFrame->m_iscapture=TRUE;
	
	(((CMainFrame*)AfxGetMainWnd())->GetActiveView())->
	InvalidateRect(NULL,FALSE);

	return(LRESULT)TRUE;		
}
//-----------------------------------------------------------
*/
//ChangeSize的定义
//-----------------------------------------------------------------
void CMainFrame::ChangeSize()
{
  static UINT uiVideoX=0;
  static UINT uiVideoY=0;
  CAPSTATUS cs;
  RECT rc;
  
  m_wndSource.GetWindowRect(&rc);
  capGetStatus(m_hWndCap,&cs,sizeof(cs));

  if(uiVideoX!=cs.uiImageWidth||uiVideoY!=cs.uiImageHeight)
    {
      m_wndSource.MoveWindow(rc.left,rc.top,
      cs.uiImageWidth+4,cs.uiImageHeight+28);
     
      uiVideoX=cs.uiImageWidth;
      uiVideoY=cs.uiImageWidth;
    }
    
    //Get Video format
	m_dibinfo.VideoFormatSize=capGetVideoFormatSize(m_hWndCap);
    capGetVideoFormat(m_hWndCap,&m_dibinfo.bitmapinfoheader,
    m_dibinfo.VideoFormatSize);//得到视频流的图像信息头
}
//----------------------------------------------------------------

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	// TODO: add member initialization code here
	
}

CMainFrame::~CMainFrame()
{
	this->m_wndSource.CloseWindow();
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("Failed to create toolbar\n");
		return -1;      // fail to create
	}

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		  sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}

	// TODO: Delete these three lines if you don't want the toolbar to
	//  be dockable
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

//---------------------------------------------------------------

	m_iscapture=FALSE;
	m_after_skindect=FALSE;
	m_enable_skindect=FALSE;
	m_enable_facelac=FALSE;
	videoflag=FALSE;

	m_x1=-1;
	m_x2=-1;
	m_y1=-1;
	m_y2=-1;

	if(!m_wndSource.CreateEx(WS_EX_TOPMOST,NULL,"Source",
		WS_CAPTION,CRect(100,100,150,180),NULL,0))
		return -1;
	m_wndSource.ShowWindow(SW_HIDE);

//	AfxMessageBox("创建采集窗口",MB_OK,NULL);

	m_hWndCap=capCreateCaptureWindow((LPSTR)"Video Capture Windows",
			WS_CHILD|WS_VISIBLE,0,0,320,240,m_wndSource.m_hWnd,0);

	capSetCallbackOnError(m_hWndCap,(FARPROC)ErrorCallbackProc);
	capSetCallbackOnStatus(m_hWndCap,(FARPROC)StatusCallbackProc);
	capSetCallbackOnVideoStream(m_hWndCap,(FARPROC)VideoCallbackProc);

//	capSetCallbackOnFrame(m_hWndCap,(FARPROC)FrameCallbackProc);
	
	capDriverConnect(m_hWndCap,0);//connect to the first VIDEOdriver;
	capDriverGetCaps(m_hWndCap,&m_caps,sizeof(CAPDRIVERCAPS));

	ChangeSize();	 
//---------------------------------------------------------------

	return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers

//------------------------------------------------------------------
//TODO:Add your message handler code here and/or call default
  void CMainFrame::OnAppExit()
  {
    capSetCallbackOnVideoStream(m_hWndCap,NULL);
    capCaptureAbort(m_hWndCap);//stop to capture
    capDriverDisconnect(m_hWndCap);
  }
//----------------------------------------------------------------

//利用ClassWizard处理WM_CLOSE消息,结束相应的视频处理.
//----------------------------------------------------------------
void CMainFrame::OnClose()
{
    OnAppExit();
    CFrameWnd::OnClose();
  
}
//----------------------------------------------------------

//-----------------------------------------------------------------

void CMainFrame::OnFormat() 
{
	// TODO: Add your command handler code here
	if(m_caps.fHasDlgVideoFormat )
	{
		capDlgVideoFormat(m_hWndCap);
		ChangeSize();
	}
	
}

void CMainFrame::OnPreview() 
{
	// TODO: Add your command handler code here
	static BOOL bPreview = FALSE;
	bPreview = !bPreview;
	capPreviewRate(m_hWndCap,10);
	capPreview(m_hWndCap,bPreview);
}

void CMainFrame::OnSource() 
{
	// TODO: Add your command handler code here
	static BOOL bShow=FALSE;
	bShow=!bShow;
	m_wndSource.ShowWindow (bShow?SW_SHOW:SW_HIDE);
	
}

void CMainFrame::OnCapture() 
{
	// TODO: Add your command handler code here
	static BOOL bCapture=FALSE;
	CAPTUREPARMS CapParms;
	bCapture=!bCapture;

	m_x1=-1;
	m_x2=-1;
	m_y1=-1;
	m_y2=-1;
	m_iscapture=FALSE;
	m_after_skindect=FALSE;
	m_enable_skindect=FALSE;
	m_enable_facelac=FALSE;

	if(bCapture)
	{
//      AfxMessageBox("设置采集参数",MB_OK,NULL);
	  //Get the default setup for video capture from the AVICap Window
		capCaptureGetSetup(m_hWndCap,&CapParms,sizeof(CAPTUREPARMS));
      //set the defaults we won't bother the user with
		CapParms.dwIndexSize=324000;//3(hour)*30(fps)*60*60

⌨️ 快捷键说明

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