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


ar_track_alvar
Author(s): Scott Niekum
autogenerated on Sun Oct 5 2014 22:16:26