RTFD.h
#include <wx/wx.h>
#include <wx/thread.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
class Thread;
enum{
ID_SCREEN = 100,
ID_START,
ID_STOP,
ID_THREAD_CLOSE
};
class App:public wxApp
{
public:
bool OnInit();
};
class Frame:public wxFrame
{
public:
Frame(const wxString&);
~Frame();
void Capture();
void FindFace();
private:
wxPanel *screen;
wxButton *start;
wxButton *stop;
CvCapture *camera;
IplImage *frame;
CvVideoWriter *video_writer;
CvHaarClassifierCascade *classifier;
CvMemStorage *face_storage;
CvSeq *faces;
int min_face_width;
int min_face_height;
wxString cascade_name;
void CreateUI();
void OnStart(wxCommandEvent&);
void OnStop(wxCommandEvent&);
void OnCapture(wxCommandEvent&);
void OnExit(wxCommandEvent&);
void OnClose(wxCloseEvent&);
Thread *thread;
DECLARE_EVENT_TABLE()
};
class Thread:public wxThread
{
public:
Thread(Frame *parent):wxThread(wxTHREAD_DETACHED){frame = parent;}
~Thread();
void* Entry();
private:
Frame *frame;
};
RTFD.cpp
#include "RTFD.h"
IMPLEMENT_APP(App)
DECLARE_APP(App)
BEGIN_EVENT_TABLE(Frame,wxFrame)
EVT_MENU(wxID_EXIT,Frame::OnExit)
EVT_CLOSE(Frame::OnClose)
EVT_BUTTON(ID_START,Frame::OnStart)
EVT_BUTTON(ID_STOP,Frame::OnStop)
END_EVENT_TABLE()
bool App::OnInit()
{
wxFrame *frame = new Frame(wxT("Real Time Face Detection"));
frame->Show(true);
return true;
}
Frame::Frame(const wxString &title):wxFrame(NULL,wxID_ANY,title,wxDefaultPosition,wxSize(800,600),wxMINIMIZE_BOX | wxCLOSE_BOX | wxCAPTION | wxSYSTEM_MENU)
{
wxInitAllImageHandlers();
CreateUI();
thread = NULL;
camera = NULL;
frame = NULL;
video_writer = cvCreateVideoWriter("video.avi",CV_FOURCC('P','I','M','1'),20,cvSize(640,480),1);
min_face_width = 110;
min_face_height = 110;
cascade_name = wxT("./haarcascades/haarcascade_frontalface_alt.xml");
classifier = (CvHaarClassifierCascade*)cvLoad(cascade_name.mb_str(),0,0,0);
if(!classifier){
wxMessageBox(wxT("Classifier Error!"));
Close();
}
face_storage = cvCreateMemStorage(0);
cvClearMemStorage(face_storage);
}
Frame::~Frame()
{
}
void Frame::CreateUI()
{
wxMenu *file = new wxMenu;
file->Append(wxID_EXIT,wxT("E&xit\tAlt-e"),wxT("Exit"));
wxMenuBar *bar = new wxMenuBar;
bar->Append(file,wxT("File"));
SetMenuBar(bar);
CreateStatusBar(2);
SetStatusText(wxT("wxCV"));
wxBoxSizer *top = new wxBoxSizer(wxVERTICAL);
this->SetSizer(top);
wxBoxSizer *screen_box = new wxBoxSizer(wxHORIZONTAL);
top->Add(screen_box,0,wxALIGN_CENTER_HORIZONTAL | wxALL,5);
screen = new wxPanel(this,ID_SCREEN,wxDefaultPosition,wxSize(600,470));
screen_box->Add(screen,0,wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL,5);
wxBoxSizer *button_box = new wxBoxSizer(wxHORIZONTAL);
top->Add(button_box,0,wxALIGN_CENTER_HORIZONTAL | wxALL,5);
start = new wxButton(this,ID_START,wxT("&Start"),wxDefaultPosition,wxDefaultSize);
button_box->Add(start,0,wxALIGN_CENTER_VERTICAL | wxALL,5);
stop = new wxButton(this,ID_STOP,wxT("&Stop"),wxDefaultPosition,wxDefaultSize);
button_box->Add(stop,0,wxALIGN_CENTER_VERTICAL | wxALL,5);
stop->Enable(false);
}
void Frame::OnExit(wxCommandEvent &event)
{
Close();
}
void Frame::OnClose(wxCloseEvent &event)
{
if(thread){
thread->Delete();
thread = NULL;
}
if(frame){
cvReleaseImage(&frame);
}
if(camera){
cvReleaseCapture(&camera);
}
if(video_writer){
cvReleaseVideoWriter(&video_writer);
}
if(classifier){
cvReleaseHaarClassifierCascade(&classifier);
}
if(face_storage){
cvReleaseMemStorage(&face_storage);
}
Destroy();
}
void Frame::OnStart(wxCommandEvent &event)
{
start->Enable(false);
stop->Enable(true);
if(camera){
cvReleaseCapture(&camera);
}
camera = cvCaptureFromCAM(-1);
if(!camera){
wxMessageBox(wxT("Camera Error¡I"),wxT("Error"),wxOK,this);
start->Enable(true);
stop->Enable(false);
}
else{
thread = new Thread(this);
if(thread->Create() != wxTHREAD_NO_ERROR){
wxLogError(wxT("Thread Create Error!"));
thread->Delete();
thread = NULL;
}
else{
if(thread){
if(thread->Run() != wxTHREAD_NO_ERROR){
wxLogError(wxT("Thread Run Error!"));
thread->Delete();
thread = NULL;
}
}
}
}
}
void Frame::OnStop(wxCommandEvent &event)
{
start->Enable(true);
stop->Enable(false);
if(thread){
thread->Delete();
thread = NULL;
}
screen->Refresh();
screen->Update();
}
void Frame::Capture()
{
wxClientDC dc(screen);
frame = cvQueryFrame(camera);
FindFace();
cvWriteFrame(video_writer,frame);
cvConvertImage(frame,frame,CV_CVTIMG_SWAP_RB);
unsigned char *data;
cvGetRawData(frame,&data);
wxImage *image = new wxImage(frame->width,frame->height,data,true);
wxBitmap *bitmap = new wxBitmap(*image);
int x,y,width,height;
dc.GetClippingBox(&x,&y,&width,&height);
dc.DrawBitmap(*bitmap,x,y);
delete image;
delete bitmap;
}
void Frame::FindFace()
{
faces = cvHaarDetectObjects(frame,classifier,face_storage,
1.1,3,
CV_HAAR_DO_CANNY_PRUNING,
cvSize(min_face_width,min_face_height));
if(faces){
for(int i = 0;i < faces->total;++i){
CvPoint p1,p2;
CvRect *rect = (CvRect*)cvGetSeqElem(faces,i);
p1.x = rect->x;
p1.y = rect->y;
p2.x = rect->x + rect->width;
p2.y = rect->y + rect->height;
cvRectangle(frame,p1,p2,CV_RGB(255,0,0),3,8,0);
}
}
}
Thread::~Thread()
{
}
void* Thread::Entry()
{
while(!TestDestroy()){
wxMutexGuiEnter();
frame->Capture();
wxMutexGuiLeave();
Sleep(10);
}
return NULL;
}
沒有留言:
張貼留言