Search

2012年4月14日 星期六

wxWidgets with OpenCV(1)

    最近閒閒去MakerBot看到一個外國人的3D Scanner專案,感覺很有趣研究一下他的source code發現是用wxWidgets加OpenCV寫的,害我突然對OpenCV很有興趣跑去研究一下,基本上要把IplImage結構轉換成wxImage只是BGR轉RGB而已,可以自己寫個函數去轉不然就是用cvConvertImage,然後例如要把Webcam的畫面畫到Panel上就可以用個Timer或是Thread去控制,先貼上Timer的,Thread其實也差不多。



wxCV.h


#include <wx/wx.h>
#include <cv.h>
#include <highgui.h>

enum{
   ID_SCREEN1 = 100,
   ID_SCREEN2,
   ID_START,
   ID_STOP,
   ID_TIMER
};

class App:public wxApp
{
   public:
      bool OnInit();
};

class Frame:public wxFrame
{
   public:
      Frame(const wxString&);
      ~Frame();

   private:
      wxPanel *screen1;
      wxPanel *screen2;
      wxButton *start;
      wxButton *stop;
      wxTimer timer;

      CvCapture *camera;
      IplImage *frame;
      IplImage *temp;
      CvVideoWriter *video_writer;

      void CreateUI();
      void OnPaint(wxPaintEvent&);
      void OnTimer(wxTimerEvent&);
      void OnStart(wxCommandEvent&);
      void OnStop(wxCommandEvent&);
      void OnCapture(wxCommandEvent&);
      void OnExit(wxCommandEvent&);

      DECLARE_EVENT_TABLE()
};


wxCV.cpp


#include "wxCV.h"
/*
 * BGR to RGB
void copy_and_swap_rb(char *s,char *d,int size) {
    const int step = 3;
    char *end = s + size;
    while (s < end) {
        d[0] = s[2];
        d[1] = s[1];
        d[2] = s[0];
        d += step;s += step;   
    }
}

void wx2cv(wxImage &wx,IplImage *ipl) {
    copy_and_swap_rb((char*)wx.GetData(),ipl->imageData,ipl->imageSize);
}

void cv2wx(IplImage *ipl,wxImage &wx ) {
    copy_and_swap_rb(ipl->imageData,(char*)wx.GetData(),wx.GetWidth() * wx.GetHeight() * 3);
}
*/

IMPLEMENT_APP(App)
DECLARE_APP(App)

BEGIN_EVENT_TABLE(Frame,wxFrame)
   EVT_MENU(wxID_EXIT,Frame::OnExit)
   EVT_PAINT(Frame::OnPaint)
   EVT_TIMER(ID_TIMER,Frame::OnTimer)
   EVT_BUTTON(ID_START,Frame::OnStart)
   EVT_BUTTON(ID_STOP,Frame::OnStop)
END_EVENT_TABLE()

bool App::OnInit()
{
   wxFrame *frame = new Frame(wxT("wxCV"));

   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),timer(this,ID_TIMER)
{
   timer.Stop();

   wxInitAllImageHandlers();

   CreateUI();

   camera = NULL;
   frame = NULL;
   temp = NULL;
   video_writer = cvCreateVideoWriter("video.avi",CV_FOURCC('P','I','M','1'),25,cvSize(640,480),1);
}

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);

   screen1 = new wxPanel(this,ID_SCREEN1,wxDefaultPosition,wxSize(400,500));
   screen_box->Add(screen1,0,wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL,5);

   screen2 = new wxPanel(this,ID_SCREEN2,wxDefaultPosition,wxSize(400,500));
   screen_box->Add(screen2,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);
}

void Frame::OnPaint(wxPaintEvent &event)
{
   screen1->Refresh();
   screen1->Update();

   screen2->Refresh();
   screen2->Update();
}

void Frame::OnExit(wxCommandEvent &event)
{
   timer.Stop();
   if(frame){
      cvReleaseImage(&frame);
   }
   if(temp){
      cvReleaseImage(&temp);
   }
   if(camera){
      cvReleaseCapture(&camera);
   }
   if(video_writer){
      cvReleaseVideoWriter(&video_writer);
   }

   Close();
}

void Frame::OnStart(wxCommandEvent &event)
{
   camera = cvCaptureFromCAM(-1);

   if(!camera){
      wxMessageBox(wxT("Camera Error!"),wxT("Error"),wxOK,this);
   }
   else{
      timer.Start(40);
   }
}

void Frame::OnStop(wxCommandEvent &event)
{
   timer.Stop();

   if(camera){
      cvReleaseCapture(&camera);
   }
}

void Frame::OnTimer(wxTimerEvent &event)
{
   wxClientDC dc1(screen1);
   wxClientDC dc2(screen2);

   frame = cvQueryFrame(camera);
   temp = cvCreateImage(cvSize(frame->width,frame->height),8,3);
   cvZero(temp);

   cvWriteFrame(video_writer,frame);

   cvConvertImage(frame,temp,CV_CVTIMG_SWAP_RB);

   unsigned char *data;

   cvGetRawData(temp,&data);

   wxImage *image = new wxImage(temp->width,temp->height,data,true);

/*
   wxImage *image = new wxImage(frame->width,frame->height);
   cv2wx(frame,*image);
*/

   wxBitmap *bitmap1 = new wxBitmap(*image);
   wxBitmap *bitmap2 = new wxBitmap(image->ConvertToGreyscale());

   int x,y,width,height;

   dc1.GetClippingBox(&x,&y,&width,&height);
   dc1.DrawBitmap(*bitmap1,x,y);

   dc2.GetClippingBox(&x,&y,&width,&height);
   dc2.DrawBitmap(*bitmap2,x,y);

   delete image;
   delete bitmap1;
   delete bitmap2;
}

g++ -o2 -o wxCV wxCV.cpp `wx-config --cxxflags --libs --unicode` `pkg-config opencv --cflags --libs`


沒有留言:

張貼留言