SampleMarkerCreator.cpp
Go to the documentation of this file.
00001 #include "ar_track_alvar/MultiMarker.h"
00002 #include "highgui.h"
00003 using namespace std;
00004 using namespace alvar;
00005 
00006 struct State {
00007     IplImage *img;
00008     stringstream filename;
00009     double minx, miny, maxx, maxy; // top-left and bottom-right in pixel units
00010     MultiMarker multi_marker;
00011 
00012     // General options
00013     bool   prompt;
00014     double units;           // how many pixels per one unit
00015     double marker_side_len; // marker side len in current units
00016     int    marker_type;     // 0:MarkerData, 1:ArToolkit
00017     double posx, posy;      // The position of marker center in the given units
00018     int    content_res;
00019     double margin_res;
00020     bool   array;
00021 
00022     // MarkerData specific options
00023     MarkerData::MarkerContentType marker_data_content_type;
00024     bool                          marker_data_force_strong_hamming;
00025 
00026     State() 
00027         : img(0),
00028           prompt(false),
00029           units(96.0/2.54),      // cm assuming 96 dpi
00030           marker_side_len(9.0),  // 9 cm
00031           marker_type(0),
00032           posx(0), posy(0),
00033           content_res(0),        // 0 uses default
00034           margin_res(0.0),       // 0.0 uses default (can be n*0.5)
00035           marker_data_content_type(MarkerData::MARKER_CONTENT_TYPE_NUMBER),
00036           marker_data_force_strong_hamming(false)
00037     {}
00038     ~State() {
00039         if (img) cvReleaseImage(&img);
00040     }
00041     void AddMarker(const char *id) {
00042         std::cout<<"ADDING MARKER "<<id<<std::endl;
00043         if (marker_type == 0) {
00044             MarkerData md(marker_side_len, content_res, margin_res);
00045             int side_len = int(marker_side_len*units+0.5);
00046             if (img == 0) {
00047                 img = cvCreateImage(cvSize(side_len, side_len), IPL_DEPTH_8U, 1);
00048                 filename.str("");
00049                 filename<<"MarkerData";
00050                 minx = (posx*units) - (marker_side_len*units/2.0);
00051                 miny = (posy*units) - (marker_side_len*units/2.0);
00052                 maxx = (posx*units) + (marker_side_len*units/2.0);
00053                 maxy = (posy*units) + (marker_side_len*units/2.0);
00054             } else {
00055                 double new_minx = (posx*units) - (marker_side_len*units/2.0);
00056                 double new_miny = (posy*units) - (marker_side_len*units/2.0);
00057                 double new_maxx = (posx*units) + (marker_side_len*units/2.0);
00058                 double new_maxy = (posy*units) + (marker_side_len*units/2.0);
00059                 if (minx < new_minx) new_minx = minx;
00060                 if (miny < new_miny) new_miny = miny;
00061                 if (maxx > new_maxx) new_maxx = maxx;
00062                 if (maxy > new_maxy) new_maxy = maxy;
00063                 IplImage *new_img = cvCreateImage(cvSize(int(new_maxx-new_minx+0.5), int(new_maxy-new_miny+0.5)), IPL_DEPTH_8U, 1);
00064                 cvSet(new_img, cvScalar(255));
00065                 CvRect roi = cvRect(int(minx-new_minx+0.5), int(miny-new_miny+0.5), img->width, img->height);
00066                 cvSetImageROI(new_img, roi);
00067                 cvCopy(img, new_img);
00068                 cvReleaseImage(&img);
00069                 img = new_img;
00070                 roi.x = int((posx*units) - (marker_side_len*units/2.0) - new_minx + 0.5); 
00071                 roi.y = int((posy*units) - (marker_side_len*units/2.0) - new_miny + 0.5); 
00072                 roi.width = int(marker_side_len*units+0.5); roi.height = int(marker_side_len*units+0.5);
00073                 cvSetImageROI(img, roi);
00074                 minx = new_minx; miny = new_miny;
00075                 maxx = new_maxx; maxy = new_maxy;
00076             }
00077             if (marker_data_content_type == MarkerData::MARKER_CONTENT_TYPE_NUMBER) {
00078                 int idi = atoi(id);
00079                 md.SetContent(marker_data_content_type, idi, 0);
00080                 if (filename.str().length()<64) filename<<"_"<<idi;
00081 
00082                 Pose pose;
00083                 pose.Reset();
00084                 pose.SetTranslation(posx, -posy, 0);
00085                 multi_marker.PointCloudAdd(idi, marker_side_len, pose);
00086             } else {
00087                 md.SetContent(marker_data_content_type, 0, id);
00088                 const char *p = id;
00089                 int counter=0;
00090                 filename<<"_";
00091                 while(*p) {
00092                     if (!isalnum(*p)) filename<<"_";
00093                     else filename<<(char)tolower(*p);
00094                     p++; counter++;
00095                     if (counter > 8) break;
00096                 }
00097             }
00098             md.ScaleMarkerToImage(img);
00099             cvResetImageROI(img);
00100         }
00101         else if (marker_type == 1) {
00102             // Create and save MarkerArtoolkit marker (Note, that this doesn't support multi markers)
00103             MarkerArtoolkit md(marker_side_len, content_res, margin_res);
00104             int side_len = int(marker_side_len*units+0.5);
00105             if (img != 0) cvReleaseImage(&img);
00106             img = cvCreateImage(cvSize(side_len, side_len), IPL_DEPTH_8U, 1);
00107             filename.str("");
00108             filename<<"MarkerArtoolkit";
00109             md.SetContent(atoi(id));
00110             filename<<"_"<<atoi(id);
00111             md.ScaleMarkerToImage(img);
00112         }
00113     }
00114     void Save() {
00115         if (img) {
00116             std::stringstream filenamexml;
00117             filenamexml<<filename.str()<<".xml";
00118             filename<<".png";
00119             std::cout<<"Saving: "<<filename.str()<<std::endl;
00120             cvSaveImage(filename.str().c_str(), img);
00121             if (multi_marker.Size() > 1) {
00122                 std::cout<<"Saving: "<<filenamexml.str()<<std::endl;
00123                 multi_marker.Save(filenamexml.str().c_str(), alvar::FILE_FORMAT_XML);
00124             }
00125         }
00126     }
00127 } st;
00128 
00129 int main(int argc, char *argv[])
00130 {
00131     try {
00132         if (argc < 2) st.prompt = true;
00133         for (int i=1; i<argc; i++) {
00134             if (strcmp(argv[i],"-f") == 0) 
00135                 st.marker_data_force_strong_hamming=true;
00136             else if (strcmp(argv[i],"-1") == 0) 
00137                 st.marker_data_content_type = MarkerData::MARKER_CONTENT_TYPE_STRING;
00138             else if (strcmp(argv[i],"-2") == 0) 
00139                 st.marker_data_content_type = MarkerData::MARKER_CONTENT_TYPE_FILE;
00140             else if (strcmp(argv[i],"-3") == 0) 
00141                 st.marker_data_content_type = MarkerData::MARKER_CONTENT_TYPE_HTTP;
00142             else if (strcmp(argv[i],"-u") == 0)
00143                 st.units = atof(argv[++i]);
00144             else if (strcmp(argv[i],"-uin") == 0)
00145                 st.units = (96.0);
00146             else if (strcmp(argv[i],"-ucm") == 0)
00147                 st.units = (96.0/2.54);
00148             else if (strcmp(argv[i],"-s") == 0)
00149                 st.marker_side_len = atof(argv[++i]);
00150             else if (strcmp(argv[i],"-r") == 0)
00151                 st.content_res = atoi(argv[++i]);
00152             else if (strcmp(argv[i],"-m") == 0)
00153                 st.margin_res = atof(argv[++i]);
00154             else if (strcmp(argv[i],"-a") == 0)
00155                 st.marker_type = 1;
00156             else if (strcmp(argv[i],"-p") == 0)
00157                 st.prompt = true;
00158             else if (strcmp(argv[i],"-xy") == 0) {
00159                 st.posx = atof(argv[++i]);
00160                 st.posy = atof(argv[++i]);
00161             }
00162             else if (strcmp(argv[i],"-ar") == 0) {
00163                 st.array = true;
00164             }
00165             else st.AddMarker(argv[i]);
00166         }
00167 
00168         // Output usage message
00169         if (st.prompt) {
00170             std::string filename(argv[0]);
00171             filename = filename.substr(filename.find_last_of('\\') + 1);
00172             std::cout << "SampleMarkerCreator" << std::endl;
00173             std::cout << "===================" << std::endl;
00174             std::cout << std::endl;
00175             std::cout << "Description:" << std::endl;
00176             std::cout << "  This is an example of how to use the 'MarkerData' and 'MarkerArtoolkit'" << std::endl;
00177             std::cout << "  classes to generate marker images. This application can be used to" << std::endl;
00178             std::cout << "  generate markers and multimarker setups that can be used with" << std::endl;
00179             std::cout << "  SampleMarkerDetector and SampleMultiMarker." << std::endl;
00180             std::cout << std::endl;
00181             std::cout << "Usage:" << std::endl;
00182             std::cout << "  " << filename << " [options] argument" << std::endl;
00183             std::cout << std::endl;
00184             std::cout << "    65535             marker with number 65535" << std::endl;
00185             std::cout << "    -f 65535          force hamming(8,4) encoding" << std::endl;
00186             std::cout << "    -1 \"hello world\"  marker with string" << std::endl;
00187             std::cout << "    -2 catalog.xml    marker with file reference" << std::endl;
00188             std::cout << "    -3 www.vtt.fi     marker with URL" << std::endl;
00189             std::cout << "    -u 96             use units corresponding to 1.0 unit per 96 pixels" << std::endl;
00190             std::cout << "    -uin              use inches as units (assuming 96 dpi)" << std::endl;
00191             std::cout << "    -ucm              use cm's as units (assuming 96 dpi) <default>" << std::endl;
00192             std::cout << "    -s 5.0            use marker size 5.0x5.0 units (default 9.0x9.0)" << std::endl;
00193             std::cout << "    -r 5              marker content resolution -- 0 uses default" << std::endl;
00194             std::cout << "    -m 2.0            marker margin resolution -- 0 uses default" << std::endl;
00195             std::cout << "    -a                use ArToolkit style matrix markers" << std::endl;
00196             std::cout << "    -p                prompt marker placements interactively from the user" << std::endl;
00197             std::cout << std::endl;
00198 
00199             // Interactive stuff here
00200             if (st.prompt) {
00201                 st.marker_type = 0;
00202                 st.marker_data_content_type = MarkerData::MARKER_CONTENT_TYPE_NUMBER;
00203                 std::cout<<"\nPrompt marker placements interactively"<<std::endl;
00204                 std::cout<<"  units: "<<st.units/96.0*2.54<<" cm "<<st.units/96.0<<" inches"<<std::endl;
00205                 std::cout<<"  marker side: "<<st.marker_side_len<<" units"<<std::endl;
00206                 bool loop=true;
00207                 std::string s;
00208                 int marker_id=0;
00209                 double posx=0.0, posy=0.0;
00210                 bool vert=false;
00211                 while(loop) {
00212                     std::cout<<"  marker id (use -1 to end) ["<<marker_id<<"]: "; std::flush(std::cout);
00213                     std::getline(std::cin, s); if (s.length() > 0) marker_id=atoi(s.c_str());
00214                     if (marker_id < 0) break;
00215                     std::cout<<"  x position (in current units) ["<<posx<<"]: "; std::flush(std::cout);
00216                     std::getline(std::cin, s); if (s.length() > 0) posx=atof(s.c_str());
00217                     std::cout<<"  y position (in current units) ["<<posy<<"]: "; std::flush(std::cout);
00218                     std::getline(std::cin, s); if (s.length() > 0) posy=atof(s.c_str());
00219                     st.posx=posx; st.posy=posy;
00220                     std::stringstream ss;
00221                     ss<<marker_id;
00222                     st.AddMarker(ss.str().c_str());
00223 
00224                     // Guess suitable marker_id and placement for the next marker
00225                     marker_id++;
00226                     if (posx <= 0) {
00227                         posx = int(sqrt(double(marker_id)))*st.marker_side_len*2;
00228                         posy = 0;
00229                         vert = true;
00230                     } else if (vert) {
00231                         posy += (st.marker_side_len*2);
00232                         if (posy >= posx) vert = false;
00233                     } else {
00234                         posx -= (st.marker_side_len*2);
00235                     }
00236                 }
00237             }
00238         }
00239         else if(st.array) {
00240             st.marker_type = 0;
00241             st.marker_data_content_type = MarkerData::MARKER_CONTENT_TYPE_NUMBER;
00242             int rows = 0;
00243             int cols = 0;
00244             double rows_distance = 0;
00245             double cols_distance = 0;
00246             bool column_major = 1;
00247             int first_id = 0;
00248             int marker_id = 0;
00249             std::string s;
00250             std::cout<<"\nPrompt marker placements interactively"<<std::endl;
00251             std::cout<<"  units: "<<st.units/96.0*2.54<<" cm "<<st.units/96.0<<" inches"<<std::endl;
00252             std::cout<<"  marker side: "<<st.marker_side_len<<" units"<<std::endl;
00253             std::cout<<"Array rows : "; std::flush(std::cout);
00254             std::getline(std::cin, s); if (s.length() > 0) rows=atoi(s.c_str());
00255             std::cout<<"Array cols : "; std::flush(std::cout);
00256             std::getline(std::cin, s); if (s.length() > 0) cols=atoi(s.c_str());
00257             std::cout<<"Rows distance : "; std::flush(std::cout);
00258             std::getline(std::cin, s); if (s.length() > 0) rows_distance=atof(s.c_str());
00259             std::cout<<"Cols distance : "; std::flush(std::cout);
00260             std::getline(std::cin, s); if (s.length() > 0) cols_distance=atof(s.c_str());
00261             std::cout<<"Column major (1 or 0) : "; std::flush(std::cout);
00262             std::getline(std::cin, s); if (s.length() > 0) column_major=atoi(s.c_str());
00263             std::cout<<"First marker ID : "; std::flush(std::cout);
00264             std::getline(std::cin, s); if (s.length() > 0) first_id=atoi(s.c_str());
00265             if(!column_major) {
00266                 for(int row = 0; row<rows; row++)
00267                     for(int col = 0; col<cols; col++)
00268                     {
00269                         st.posy=row*rows_distance; st.posx=col*cols_distance;
00270                         marker_id = first_id + row*cols + col;
00271                         std::stringstream ss;
00272                         ss<<marker_id;
00273                         st.AddMarker(ss.str().c_str());
00274                     }
00275             }
00276             else {
00277                 for(int col = 0; col<cols; col++)
00278                     for(int row = 0; row<rows; row++)
00279                     {
00280                         st.posy=row*rows_distance; st.posx=col*cols_distance;
00281                         marker_id = first_id + col*rows + row;
00282                         std::stringstream ss;
00283                         ss<<marker_id;
00284                         st.AddMarker(ss.str().c_str());
00285                     }
00286             }
00287 
00288         }
00289         st.Save();
00290         return 0;
00291     }
00292     catch (const std::exception &e) {
00293         std::cout << "Exception: " << e.what() << endl;
00294     }
00295     catch (...) {
00296         std::cout << "Exception: unknown" << std::endl;
00297     }
00298 }


ar_track_alvar
Author(s): Scott Niekum
autogenerated on Thu Feb 16 2017 03:23:02