=============2012/06/21===============
畫成電路洗成板子之後給同學使用,基本上 1/8 ~ 1/1000 秒都非常精準,至於 1/8 秒以下應該選用日製阻體較長的可變電阻就可以量測到了(給同學的只是便宜的台製B類1k可變電阻)。
#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()
};
#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`
#include <wx/wx.h>
#include <wx/spinctrl.h>
enum{
ID_ANGLE = 100,
ID_QUALITY
};
class App:public wxApp
{
public:
bool OnInit();
};
class Frame:public wxFrame
{
public:
Frame(const wxString&);
void OnOpen(wxCommandEvent&);
void OnSave(wxCommandEvent&);
void OnExit(wxCommandEvent&);
private:
wxArrayString filepaths;
wxArrayString filenames;
wxRadioBox *angle;
wxSlider *quality;
DECLARE_EVENT_TABLE()
};
#include "photorotate.h"
IMPLEMENT_APP(App)
DECLARE_APP(App)
bool App::OnInit()
{
wxFrame *frame = new Frame(wxT("PhotoRotate"));
frame->Show(true);
return true;
}
BEGIN_EVENT_TABLE(Frame,wxFrame)
EVT_BUTTON(wxID_OPEN,Frame::OnOpen)
EVT_BUTTON(wxID_SAVE,Frame::OnSave)
EVT_MENU(wxID_EXIT,Frame::OnExit)
END_EVENT_TABLE()
Frame::Frame(const wxString &title):wxFrame(NULL,wxID_ANY,title,wxDefaultPosition,wxDefaultSize,wxMINIMIZE_BOX | wxCLOSE_BOX | wxCAPTION | wxSYSTEM_MENU)
{
wxInitAllImageHandlers();
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);
wxBoxSizer *top = new wxBoxSizer(wxVERTICAL);
this->SetSizer(top);
wxBoxSizer *box1 = new wxBoxSizer(wxHORIZONTAL);
top->Add(box1,0,wxALIGN_CENTER_HORIZONTAL | wxALL,5);
wxArrayString item;
item.Add(wxT("+90"));
item.Add(wxT("-90"));
angle = new wxRadioBox(this,ID_ANGLE,wxT("Rotate Angle"),wxDefaultPosition,wxDefaultSize,item,wxRA_SPECIFY_COLS);
box1->Add(angle,0,wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL,5);
wxStaticText *quality_text = new wxStaticText(this,wxID_STATIC,wxT(" Quality:"),wxDefaultPosition,wxDefaultSize,0);
box1->Add(quality_text,0,wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL,5);
quality = new wxSlider(this,ID_QUALITY,100,0,100,wxDefaultPosition,wxSize(200,-1),wxSL_HORIZONTAL | wxSL_AUTOTICKS | wxSL_LABELS);
box1->Add(quality,0,wxALIGN_CENTER_HORIZONTAL | wxALL,5);
wxBoxSizer *box2 = new wxBoxSizer(wxHORIZONTAL);
top->Add(box2,0,wxALIGN_CENTER_HORIZONTAL | wxALL,5);
wxButton *open = new wxButton(this,wxID_OPEN,wxT("&Open"),wxDefaultPosition,wxDefaultSize);
box2->Add(open,0,wxALIGN_CENTER_VERTICAL | wxALL,5);
wxButton *save = new wxButton(this,wxID_SAVE,wxT("&Save"),wxDefaultPosition,wxDefaultSize);
box2->Add(save,0,wxALIGN_CENTER_VERTICAL | wxALL,5);
CreateStatusBar(2);
SetStatusText(wxT("PhotoRotate"));
top->Fit(this);
top->SetSizeHints(this);
}
void Frame::OnOpen(wxCommandEvent &event)
{
wxFileDialog dlg(this,wxT("選擇檔案"),wxT("."),wxT(""),wxT("JPG files (*.JPG)|*.JPG"),wxOPEN | wxMULTIPLE);
if(dlg.ShowModal() == wxID_OK){
dlg.GetPaths(filepaths);
dlg.GetFilenames(filenames);
}
}
void Frame::OnSave(wxCommandEvent &event)
{
wxDirDialog dlg(this,wxT("選擇目錄"),wxT("."),wxDD_NEW_DIR_BUTTON);
if(dlg.ShowModal() == wxID_OK){
const wxString target = dlg.GetPath();
const int _angle = angle->GetSelection();
const int _quality = quality->GetValue();
for(int i = 0;i < filenames.Count();i++){
wxImage image;
if(image.LoadFile(filepaths[i])){
image = image.Rotate90(_angle);
image.SetOption(wxIMAGE_OPTION_QUALITY,_quality);
image.SaveFile(target + wxT("/") + filenames[i]);
}
}
wxMessageBox(wxT("轉換完成!"),wxT("PhotoRotate"),wxOK,this);
}
}
void Frame::OnExit(wxCommandEvent &event)
{
Close();
}