00001 #include "CvTestbed.h"
00002 #include "MarkerDetector.h"
00003 #include "MultiMarker.h"
00004 #include "Pose.h"
00005 #include "Shared.h"
00006 using namespace alvar;
00007 using namespace std;
00008
00009 int visualize=0;
00010 bool detect_additional = false;
00011 const int nof_markers = 5;
00012 const double marker_size = 4;
00013 MarkerDetector<MarkerData> marker_detector;
00014
00015 MultiMarker *multi_marker;
00016 std::stringstream calibrationFilename;
00017
00018 void videocallback(IplImage *image)
00019 {
00020 static Camera cam;
00021 Pose pose;
00022 bool flip_image = (image->origin?true:false);
00023 if (flip_image) {
00024 cvFlip(image);
00025 image->origin = !image->origin;
00026 }
00027
00028 static bool init = true;
00029 if (init)
00030 {
00031
00032 init = false;
00033
00034
00035 cout<<"Loading calibration: "<<calibrationFilename.str();
00036
00037 if (cam.SetCalib(calibrationFilename.str().c_str(), image->width, image->height))
00038 {
00039 cout<<" [Ok]"<<endl;
00040 }
00041 else
00042 {
00043 cam.SetRes(image->width, image->height);
00044 cout<<" [Fail]"<<endl;
00045 }
00046
00047 vector<int> id_vector;
00048 for(int i = 0; i < nof_markers; ++i)
00049 id_vector.push_back(i);
00050
00051
00052 marker_detector.SetMarkerSize(marker_size);
00053 marker_detector.SetMarkerSizeForId(0, marker_size*2);
00054 multi_marker = new MultiMarker(id_vector);
00055 pose.Reset();
00056 multi_marker->PointCloudAdd(0, marker_size*2, pose);
00057 pose.SetTranslation(-marker_size*2.5, +marker_size*1.5, 0);
00058 multi_marker->PointCloudAdd(1, marker_size, pose);
00059 pose.SetTranslation(+marker_size*2.5, +marker_size*1.5, 0);
00060 multi_marker->PointCloudAdd(2, marker_size, pose);
00061 pose.SetTranslation(-marker_size*2.5, -marker_size*1.5, 0);
00062 multi_marker->PointCloudAdd(3, marker_size, pose);
00063 pose.SetTranslation(+marker_size*2.5, -marker_size*1.5, 0);
00064 multi_marker->PointCloudAdd(4, marker_size, pose);
00065 }
00066
00067 double error=-1;
00068 if (marker_detector.Detect(image, &cam, true, (visualize == 1), 0.0)) {
00069 if (detect_additional) {
00070 error = multi_marker->Update(marker_detector.markers, &cam, pose);
00071 multi_marker->SetTrackMarkers(marker_detector, &cam, pose, visualize ? image : NULL);
00072 marker_detector.DetectAdditional(image, &cam, (visualize == 1));
00073 }
00074 if (visualize == 2)
00075 error = multi_marker->Update(marker_detector.markers, &cam, pose, image);
00076 else
00077 error = multi_marker->Update(marker_detector.markers, &cam, pose);
00078 }
00079
00080 static Marker foo;
00081 foo.SetMarkerSize(marker_size*4);
00082 if ((error >= 0) && (error < 5))
00083 {
00084 foo.pose = pose;
00085 }
00086 foo.Visualize(image, &cam);
00087
00088 if (flip_image) {
00089 cvFlip(image);
00090 image->origin = !image->origin;
00091 }
00092 }
00093
00094 int keycallback(int key)
00095 {
00096 if(key == 'v')
00097 {
00098 visualize = (visualize+1)%3;
00099 }
00100 else if(key == 'l')
00101 {
00102 if(multi_marker->Load("mmarker.xml", alvar::FILE_FORMAT_XML))
00103 {
00104 cout<<"Multi marker loaded"<<endl;
00105 }
00106 else
00107 cout<<"Cannot load multi marker"<<endl;
00108 }
00109 else if(key == 'd')
00110 {
00111 detect_additional = !detect_additional;
00112 if(detect_additional)
00113 cout<<"Unreadable marker detection enabled."<<endl;
00114 else
00115 cout<<"Unreadable marker detection disabled."<<endl;
00116 }
00117 else return key;
00118
00119 return 0;
00120 }
00121
00122 int main(int argc, char *argv[])
00123 {
00124 try {
00125
00126 std::string filename(argv[0]);
00127 filename = filename.substr(filename.find_last_of('\\') + 1);
00128 std::cout << "SampleMultiMarker" << std::endl;
00129 std::cout << "=================" << std::endl;
00130 std::cout << std::endl;
00131 std::cout << "Description:" << std::endl;
00132 std::cout << " This is an example of how to use the 'MultiMarker' class to detect" << std::endl;
00133 std::cout << " preconfigured multi-marker setup (see ALVAR.pdf). A large cube is drawn" << std::endl;
00134 std::cout << " over the detected multi-marker even when only some of the markers are" << std::endl;
00135 std::cout << " visible." << std::endl;
00136 std::cout << std::endl;
00137 std::cout << "Usage:" << std::endl;
00138 std::cout << " " << filename << " [device]" << std::endl;
00139 std::cout << std::endl;
00140 std::cout << " device integer selecting device from enumeration list (default 0)" << std::endl;
00141 std::cout << " highgui capture devices are prefered" << std::endl;
00142 std::cout << std::endl;
00143 std::cout << "Keyboard Shortcuts:" << std::endl;
00144 std::cout << " v: switch between three debug visualizations" << std::endl;
00145 std::cout << " l: load marker configuration from mmarker.txt" << std::endl;
00146 std::cout << " d: toggle the detection of non-readable markers" << std::endl;
00147 std::cout << " q: quit" << std::endl;
00148 std::cout << std::endl;
00149
00150
00151 CvTestbed::Instance().SetVideoCallback(videocallback);
00152 CvTestbed::Instance().SetKeyCallback(keycallback);
00153
00154
00155 CaptureFactory::CapturePluginVector plugins = CaptureFactory::instance()->enumeratePlugins();
00156 if (plugins.size() < 1) {
00157 std::cout << "Could not find any capture plugins." << std::endl;
00158 return 0;
00159 }
00160
00161
00162 std::cout << "Available Plugins: ";
00163 outputEnumeratedPlugins(plugins);
00164 std::cout << std::endl;
00165
00166
00167 CaptureFactory::CaptureDeviceVector devices = CaptureFactory::instance()->enumerateDevices();
00168 if (devices.size() < 1) {
00169 std::cout << "Could not find any capture devices." << std::endl;
00170 return 0;
00171 }
00172
00173
00174 int selectedDevice = defaultDevice(devices);
00175 if (argc > 1) {
00176 selectedDevice = atoi(argv[1]);
00177 }
00178 if (selectedDevice >= (int)devices.size()) {
00179 selectedDevice = defaultDevice(devices);
00180 }
00181
00182
00183 std::cout << "Enumerated Capture Devices:" << std::endl;
00184 outputEnumeratedDevices(devices, selectedDevice);
00185 std::cout << std::endl;
00186
00187
00188 Capture *cap = CaptureFactory::instance()->createCapture(devices[selectedDevice]);
00189 std::string uniqueName = devices[selectedDevice].uniqueName();
00190
00191
00192
00193 if (cap) {
00194 std::stringstream settingsFilename;
00195 settingsFilename << "camera_settings_" << uniqueName << ".xml";
00196 calibrationFilename << "camera_calibration_" << uniqueName << ".xml";
00197
00198 cap->start();
00199 cap->setResolution(640, 480);
00200
00201 if (cap->loadSettings(settingsFilename.str())) {
00202 std::cout << "Loading settings: " << settingsFilename.str() << std::endl;
00203 }
00204
00205 std::stringstream title;
00206 title << "SampleMultiMarker (" << cap->captureDevice().captureType() << ")";
00207
00208 CvTestbed::Instance().StartVideo(cap, title.str().c_str());
00209
00210 if (cap->saveSettings(settingsFilename.str())) {
00211 std::cout << "Saving settings: " << settingsFilename.str() << std::endl;
00212 }
00213
00214 cap->stop();
00215 delete cap;
00216 }
00217 else if (CvTestbed::Instance().StartVideo(0, argv[0])) {
00218 }
00219 else {
00220 std::cout << "Could not initialize the selected capture backend." << std::endl;
00221 }
00222
00223 return 0;
00224 }
00225 catch (const std::exception &e) {
00226 std::cout << "Exception: " << e.what() << endl;
00227 }
00228 catch (...) {
00229 std::cout << "Exception: unknown" << std::endl;
00230 }
00231 }