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

📄 videowin.cpp

📁 这是一个朋友做的人脸检测软件
💻 CPP
字号:
// VideoWin.cpp : implementation file
//

#include "stdafx.h"
#include "VideoShow.h"
#include "VideoWin.h"
#include "cv.h"
#include "highgui.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CVideoWin

IplImage *image = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0;
CvHistogram *hist = 0;
int backproject_mode = 0;
int select_object = 0;
int track_object = 0;
int show_hist = 1;
CvPoint origin;
CvRect selection;
CvRect track_window;
CvBox2D track_box;
CvConnectedComp track_comp;
int hdims = 16;
float hranges_arr[] = {0,180};
float* hranges = hranges_arr;
int vmin = 10, vmax = 256, smin = 30;


CVideoWin::CVideoWin()
{
     //标志位初始化
	 m_State=STATE_NOVIEW;
     g_capture=0;
}

CVideoWin::~CVideoWin()
{
StopVideoPreview();
}


BEGIN_MESSAGE_MAP(CVideoWin, CStatic)
	//{{AFX_MSG_MAP(CVideoWin)
	ON_WM_TIMER()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CVideoWin message handlers
//开始视频预览
void CVideoWin::StartVideoPreview()
{
     
	if(!g_capture)
	{
	//获取摄像头
    g_capture = cvCaptureFromCAM(-1);
	
	//错误警告
    if( !g_capture )
    {
		::AfxMessageBox("没有找到摄像头,请检查驱动是否安装正确");
        return;
    }
	 //设置标志位
     m_State=STATE_PREVIEW;

   

    //设置预览开始
	SetTimer(1,10,NULL);	
    }
	
    else
	{
     m_State=STATE_PREVIEW;
	}

}

void CVideoWin::OnTimer(UINT nIDEvent) 
{
   //摄像头没有打开	
	if(!g_capture||m_State==STATE_STOP)
	return;
	/*
	switch(m_STATE)
	
	
	
	// TODO: Add your message handler code here and/or call default
     //没有开始预览退出
	 if(!flag_Preview||flag_Stop)
     return;
    */
	CDC *pDC=GetDC();
	//获取一桢图像
    g_src = cvQueryFrame( g_capture );

   
	if(g_src)
	{
	 switch(m_State)
	 {
	 case STATE_PREVIEW:
	 break;

	 case STATE_PAUSE:
     return;

	 case STATE_FACEDETECT:
		 {
         detect_and_draw(g_src);
		 break;
		 }
      case STATE_CAMSHIFT:
		  {
		    CamShif();
			break;
		  }
	  default: break;
	 }	 
	 CvvImage PreviewImage;
	//获取对话框的大小
    RECT previewWnd;
	GetClientRect(&previewWnd);
	PreviewImage.CopyOf(g_src,-1);
	PreviewImage.DrawToHDC(pDC->m_hDC,&previewWnd);
	}
   
    
	CStatic::OnTimer(nIDEvent);
}


void CVideoWin::PauseVideoPreview()
{
//停止预览
m_State=STATE_PAUSE; 
}

void CVideoWin::StopVideoPreview()
{
//结束预览
if(m_State==STATE_STOP)
return;
m_State=STATE_STOP;
if(g_capture)
{
cvReleaseCapture(&g_capture);
} 
//画背景
DrawNoviewBackGround();
}


bool CVideoWin::FaceDectectInit()
{
 //加载人脸特征库
 const char* cascade_name =
	 "haarcascade_frontalface_alt.xml";
    // "haarcascade_profileface.xml";
 cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
 if( !cascade )
 {
		 
     return false;
 }
   storage = cvCreateMemStorage(0);
   return true;
}



void CVideoWin::detect_and_draw( IplImage* img )
{
int scale = 1;
    IplImage* temp = cvCreateImage( cvSize(img->width/scale,img->height/scale), 8, 3 );
    CvPoint pt1, pt2;
    int i;

    //cvPyrDown( img, temp, CV_GAUSSIAN_5x5 );
    cvClearMemStorage( storage );

    if( cascade )
    {
        CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
                                            1.1, 2, CV_HAAR_DO_CANNY_PRUNING,
                                            cvSize(40, 40) );
        for( i = 0; i < (faces ? faces->total : 0); i++ )
        {
            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
            pt1.x = r->x*scale;
            pt2.x = (r->x+r->width)*scale;
            pt1.y = r->y*scale;
            pt2.y = (r->y+r->height)*scale;
            cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
        }
    }
    cvReleaseImage( &temp );
}

void CVideoWin::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
        if(m_State!=STATE_CAMSHIFT)
		return;

        if( !image )
        return;
        int x=point.x;
	    int y=point.y;
        if( image->origin )
        y = image->height - y;

	    origin = cvPoint(x,y);
        selection = cvRect(x,y,0,0);
        select_object = 1;
	    CStatic::OnLButtonDown(nFlags, point);
}

void CVideoWin::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
    if(m_State!=STATE_CAMSHIFT)
	return;
	 select_object = 0;
     if( selection.width > 0 && selection.height > 0 )
     track_object = -1;

	CStatic::OnLButtonUp(nFlags, point);
}

void CVideoWin::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	 if(m_State!=STATE_CAMSHIFT)
	 return;
	 if( !image )
     return;
    
     int x=point.x;
	 int y=point.y;

   
     if( image->origin )
     y = image->height - y;
  
    if( select_object )
    {
        selection.x = MIN(x,origin.x);
        selection.y = MIN(y,origin.y);
        selection.width = selection.x + CV_IABS(x - origin.x);
        selection.height = selection.y + CV_IABS(y - origin.y);
        
        selection.x = MAX( selection.x, 0 );
        selection.y = MAX( selection.y, 0 );
        selection.width = MIN( selection.width, image->width );
        selection.height = MIN( selection.height, image->height );
        selection.width -= selection.x;
        selection.height -= selection.y;
    }
	CStatic::OnMouseMove(nFlags, point);
}

CvScalar CVideoWin::hsv2rgb( float hue )
{
    int rgb[3], p, sector;
    static const int sector_data[][3]=
        {{0,2,1}, {1,2,0}, {1,0,2}, {2,0,1}, {2,1,0}, {0,1,2}};
    hue *= 0.033333333333333333333333333333333f;
    sector = cvFloor(hue);
    p = cvRound(255*(hue - sector));
    p ^= sector & 1 ? 255 : 0;

    rgb[sector_data[sector][0]] = 255;
    rgb[sector_data[sector][1]] = 0;
    rgb[sector_data[sector][2]] = p;

    return cvScalar(rgb[2], rgb[1], rgb[0],0);
}

void CVideoWin::CamShif()
{    
     IplImage* frame = 0;
     
	 frame=g_src;

     //int i, bin_w, c;
     int i, bin_w;
     if( !image )
        {
            /* allocate all the buffers */
            image = cvCreateImage( cvGetSize(frame), 8, 3 );
            image->origin = frame->origin;
            hsv = cvCreateImage( cvGetSize(frame), 8, 3 );
            hue = cvCreateImage( cvGetSize(frame), 8, 1 );
            mask = cvCreateImage( cvGetSize(frame), 8, 1 );
            backproject = cvCreateImage( cvGetSize(frame), 8, 1 );
            hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 );
            histimg = cvCreateImage( cvSize(320,200), 8, 3 );
            cvZero( histimg );
        }

        cvCopy( frame, image, 0 );
        cvCvtColor( image, hsv, CV_BGR2HSV );

        if( track_object )
        {
            int _vmin = vmin, _vmax = vmax;

            cvInRangeS( hsv, cvScalar(0,smin,MIN(_vmin,_vmax),0),
                        cvScalar(180,256,MAX(_vmin,_vmax),0), mask );
            cvSplit( hsv, hue, 0, 0, 0 );

            if( track_object < 0 )
            {
                float max_val = 0.f;
                cvSetImageROI( hue, selection );
                cvSetImageROI( mask, selection );
                cvCalcHist( &hue, hist, 0, mask );
                cvGetMinMaxHistValue( hist, 0, &max_val, 0, 0 );
                cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 );
                cvResetImageROI( hue );
                cvResetImageROI( mask );
                track_window = selection;
                track_object = 1;

                cvZero( histimg );
                bin_w = histimg->width / hdims;
                for( i = 0; i < hdims; i++ )
                {
                    int val = cvRound( cvGetReal1D(hist->bins,i)*histimg->height/255 );
                    CvScalar color = hsv2rgb(i*180.f/hdims);
                    cvRectangle( histimg, cvPoint(i*bin_w,histimg->height),
                                 cvPoint((i+1)*bin_w,histimg->height - val),
                                 color, -1, 8, 0 );
                }
            }

            cvCalcBackProject( &hue, backproject, hist );
            cvAnd( backproject, mask, backproject, 0 );
            cvCamShift( backproject, track_window,
                        cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),
                        &track_comp, &track_box );
            track_window = track_comp.rect;
            
            if( backproject_mode )
                cvCvtColor( backproject, image, CV_GRAY2BGR );
            if( image->origin )
                track_box.angle = -track_box.angle;
            cvEllipseBox( image, track_box, CV_RGB(255,0,0), 3, CV_AA, 0 );
        }
        
        if( select_object && selection.width > 0 && selection.height > 0 )
        {
            cvSetImageROI( image, selection );
            cvXorS( image, cvScalarAll(255), image, 0 );
            cvResetImageROI( image );
        }
        
		g_src=image;
       


}
void CVideoWin::DrawNoviewBackGround()
{

    CDC *dc;
	dc=GetDC();
	
	CDC dcMem; 
	dcMem.CreateCompatibleDC(dc); 
	CBitmap bmpBackground;
	bmpBackground.LoadBitmap(IDB_VIEWBACK);
	BITMAP bitMap;
	bmpBackground.GetBitmap(&bitMap);
	CBitmap *pbmpOld=dcMem.SelectObject(&bmpBackground);
	dc->StretchBlt(0,0,bitMap.bmWidth,bitMap.bmHeight,&dcMem,0,0,bitMap.bmWidth,bitMap.bmHeight,SRCCOPY);//???
	ReleaseDC(dc);
	dcMem.SelectObject(pbmpOld);
	ReleaseDC(&dcMem);
	  

}

void CVideoWin::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	if((m_State==STATE_NOVIEW)||(m_State==STATE_STOP))
	DrawNoviewBackGround();
	else
    {
    CvvImage PreviewImage;
	RECT previewWnd;
	GetClientRect(&previewWnd);
	PreviewImage.CopyOf(g_src,-1);
	PreviewImage.DrawToHDC(dc.m_hDC,&previewWnd);
	}
	// TODO: Add your message handler code here
	
	// Do not call CStatic::OnPaint() for painting messages
}

⌨️ 快捷键说明

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