CvTestbed.cpp
Go to the documentation of this file.
00001 #include "ar_track_alvar/CvTestbed.h"
00002 
00003 CvTestbed::CvTestbed() {
00004         cap=NULL;
00005         running=false;
00006         videocallback=NULL;
00007         keycallback=NULL;
00008         images.clear();
00009 }
00010 
00011 CvTestbed::~CvTestbed() {
00012         for (size_t i=0; i<images.size(); i++) {
00013                 if (images[i].release_at_exit) {
00014                         cvReleaseImage(&(images[i].ipl));
00015                 }
00016         }
00017         images.clear();
00018 }
00019 
00020 void CvTestbed::default_videocallback(IplImage *image) {
00021         // TODO: Skip frames if we are too slow? Impossible using OpenCV?
00022         /*
00023         static bool semaphore=false;
00024         if (semaphore) return;
00025         semaphore = true;
00026         */
00027 
00028         if (CvTestbed::Instance().videocallback) {
00029                 CvTestbed::Instance().videocallback(image);
00030         }
00031         CvTestbed::Instance().ShowVisibleImages();
00032 
00033         //semaphore = false;
00034 }
00035 
00036 void CvTestbed::WaitKeys() {
00037         running=true;
00038         static bool pause = false;
00039         while (running) {
00040                 if (cap) {
00041                         IplImage *frame = cap->captureImage();
00042                         if (frame) {
00043                                 default_videocallback(frame);
00044                                 if (wintitle.size() > 0) {
00045                                         cvShowImage(wintitle.c_str(), frame);
00046                                 }
00047                         }
00048                 }
00049                 int key;
00050 #ifdef WIN32
00051                 if( (key = cvWaitKey(1)) >= 0 ) {
00052 #else
00053                 if( (key = cvWaitKey(20)) >= 0 ) {
00054 #endif
00055                         if (keycallback) {
00056                                 key = keycallback(key);
00057                         }
00058                         // If 'keycallback' didn't handle key - Use default handling
00059                         // By default 'C' for calibration
00060                         if (key == 'C') {
00061                             if (cap) {
00062                     cap->showSettingsDialog();
00063                             }
00064                         }
00065                         // By default '0'-'9' toggles visible images
00066                         else if ((key >= '0') && (key <= '9')) {
00067                                 int index=key-'0';
00068                                 ToggleImageVisible(index);
00069                         }
00070                         else if(key == 'p') {
00071                                 pause = !pause;
00072                         }
00073                         else if (key > 0) {
00074                                 running=false;
00075                         }
00076                 }
00077         }
00078 }
00079 
00080 void CvTestbed::ShowVisibleImages() {
00081         for (size_t i=0; i<images.size(); i++) {
00082                 if (images[i].visible) {
00083                         cvShowImage(images[i].title.c_str(), images[i].ipl);
00084                 }
00085         }
00086 }
00087 
00088 CvTestbed& CvTestbed::Instance() {
00089         static CvTestbed obj;
00090         return obj;
00091 }
00092 
00093 void CvTestbed::SetVideoCallback(void (*_videocallback)(IplImage *image)) {
00094         videocallback=_videocallback;
00095 }
00096 
00097 void CvTestbed::SetKeyCallback(int (*_keycallback)(int key)) {
00098         keycallback=_keycallback;
00099 }
00100 
00101 bool CvTestbed::StartVideo(Capture *_cap, const char *_wintitle) {
00102         bool clean=false;
00103     cap = _cap;
00104     if (cap == NULL) {
00105                 CaptureFactory::CaptureDeviceVector vec = CaptureFactory::instance()->enumerateDevices();
00106                 if (vec.size() < 1) return false;
00107                 cap = CaptureFactory::instance()->createCapture(vec[0]);
00108                 if (!cap->start()) {
00109                         delete cap;
00110                         return false;
00111                 }
00112                 clean=true;
00113         }
00114     if (_wintitle) {
00115         wintitle = _wintitle;
00116         cvNamedWindow(_wintitle, 1);
00117     }
00118         WaitKeys(); // Call the main loop
00119         if (clean) {
00120                 cap->stop();
00121                 delete cap;
00122         }
00123         return true;
00124 }
00125 
00126 size_t CvTestbed::SetImage(const char *title, IplImage *ipl, bool release_at_exit /* =false */) {
00127         size_t index = GetImageIndex(title);
00128         if (index == -1) {
00129                 // If the title wasn't found create new
00130                 Image i(ipl, title, false, release_at_exit);
00131                 images.push_back(i);
00132                 return (images.size()-1);
00133         }
00134         // If the title was found replace the image
00135         if (images[index].release_at_exit) {
00136                 cvReleaseImage(&(images[index].ipl));
00137         }
00138         images[index].ipl = ipl;
00139         images[index].release_at_exit = release_at_exit;
00140         return index;
00141 }
00142 
00143 IplImage *CvTestbed::CreateImage(const char *title, CvSize size, int depth, int channels ) {
00144         IplImage *ipl=cvCreateImage(size, depth, channels);
00145         if (!ipl) return NULL;
00146         SetImage(title, ipl, true);
00147         return ipl;
00148 }
00149 
00150 IplImage *CvTestbed::CreateImageWithProto(const char *title, IplImage *proto, int depth /* =0 */, int channels /* =0 */) {
00151         if (depth == 0) depth = proto->depth;
00152         if (channels == 0) channels = proto->nChannels;
00153         IplImage *ipl= cvCreateImage(cvSize(proto->width, proto->height), depth, channels);
00154         if (!ipl) return NULL;
00155         ipl->origin = proto->origin;
00156         SetImage(title, ipl, true);
00157         return ipl;
00158 }
00159 
00160 IplImage *CvTestbed::GetImage(size_t index) {
00161         if (index < 0) return NULL;
00162         if (index >= images.size()) return NULL;
00163         return images[index].ipl;
00164 }
00165 
00166 size_t CvTestbed::GetImageIndex(const char *title) {
00167         std::string s(title);
00168         for (size_t i=0; i<images.size(); i++) {
00169                 if (s.compare(images[i].title) == 0) {
00170                         return i;
00171                 }
00172         }
00173         return (size_t)-1;
00174 }
00175 
00176 IplImage *CvTestbed::GetImage(const char *title) {
00177         return GetImage(GetImageIndex(title));
00178 }
00179 
00180 bool CvTestbed::ToggleImageVisible(size_t index, int flags) {
00181         if (index >= images.size()) return false;
00182         if (images[index].visible == false) {
00183                 images[index].visible=true;
00184                 cvNamedWindow(images[index].title.c_str(), flags);
00185                 return true;
00186         }
00187         else {
00188                 images[index].visible=false;
00189                 cvDestroyWindow(images[index].title.c_str());
00190                 return false;
00191         }
00192 }


ar_track_alvar
Author(s): Scott Niekum
autogenerated on Thu Jun 6 2019 21:12:54