?? videowin.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 + -