Bundle2PMVS2.cpp
Go to the documentation of this file.
00001 /* Bundle2PMVS.cpp */
00002 
00003 #include <assert.h>
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <vector>
00007 #include <string>
00008 #include <string.h>
00009 
00010 /* For mkdir */
00011 #include <sys/stat.h>
00012 #include <sys/types.h>
00013 
00014 #include "image.h"
00015 #include "matrix.h"
00016 #include "sfm.h"
00017 #include "LoadJPEG.h"
00018 
00019 typedef struct 
00020 {
00021     double pos[3];
00022     double color[3];
00023     
00024 } point_t;
00025 
00026 void ReadListFile(char *list_file, std::vector<std::string> &files)
00027 {
00028     FILE *f = fopen(list_file, "r");
00029     
00030     char buf[256];
00031     while (fgets(buf, 256, f)) {
00032         if (buf[strlen(buf)-1] == '\n')
00033             buf[strlen(buf)-1] = 0;
00034 
00035         char *space = strchr(buf, ' ');
00036         if (space) *space = 0;
00037 
00038         files.push_back(std::string(buf));
00039     }
00040 
00041     fclose(f);
00042 }
00043 
00044 void ReadBundleFile(char *bundle_file, 
00045                     std::vector<camera_params_t> &cameras,
00046                     std::vector<point_t> &points, double &bundle_version)
00047 {
00048     FILE *f = fopen(bundle_file, "r");
00049     if (f == NULL) {
00050         printf("Error opening file %s for reading\n", bundle_file);
00051         return;
00052     }
00053 
00054     int num_images, num_points;
00055 
00056     char first_line[256];
00057     fgets(first_line, 256, f);
00058     if (first_line[0] == '#') {
00059         double version;
00060         sscanf(first_line, "# Bundle file v%lf", &version);
00061 
00062         bundle_version = version;
00063         printf("[ReadBundleFile] Bundle version: %0.3f\n", version);
00064 
00065         fscanf(f, "%d %d\n", &num_images, &num_points);
00066     } else if (first_line[0] == 'v') {
00067         double version;
00068         sscanf(first_line, "v%lf", &version);
00069         bundle_version = version;
00070         printf("[ReadBundleFile] Bundle version: %0.3f\n", version);
00071 
00072         fscanf(f, "%d %d\n", &num_images, &num_points);
00073     } else {
00074         bundle_version = 0.1;
00075         sscanf(first_line, "%d %d\n", &num_images, &num_points);
00076     }
00077 
00078     printf("[ReadBundleFile] Reading %d images and %d points...\n",
00079            num_images, num_points);
00080 
00081     /* Read cameras */
00082     for (int i = 0; i < num_images; i++) {
00083         double focal_length, k0, k1;
00084         double R[9];
00085         double t[3];
00086         
00087         if (bundle_version < 0.2) {
00088             /* Focal length */
00089             fscanf(f, "%lf\n", &focal_length);
00090         } else {
00091             fscanf(f, "%lf %lf %lf\n", &focal_length, &k0, &k1);
00092         }
00093 
00094         /* Rotation */
00095         fscanf(f, "%lf %lf %lf\n%lf %lf %lf\n%lf %lf %lf\n", 
00096                R+0, R+1, R+2, R+3, R+4, R+5, R+6, R+7, R+8);
00097         /* Translation */
00098         fscanf(f, "%lf %lf %lf\n", t+0, t+1, t+2);
00099 
00100         // if (focal_length == 0.0)
00101         //     continue;
00102 
00103         camera_params_t cam;
00104 
00105         cam.f = focal_length;
00106         memcpy(cam.R, R, sizeof(double) * 9);
00107         memcpy(cam.t, t, sizeof(double) * 3);
00108 
00109         cameras.push_back(cam);
00110     }
00111     
00112     /* Read points */
00113     for (int i = 0; i < num_points; i++) {
00114         point_t pt;
00115 
00116         /* Position */
00117         fscanf(f, "%lf %lf %lf\n", 
00118                pt.pos + 0, pt.pos + 1, pt.pos + 2);
00119 
00120         /* Color */
00121         fscanf(f, "%lf %lf %lf\n", 
00122                pt.color + 0, pt.color + 1, pt.color + 2);
00123 
00124         int num_visible;
00125         fscanf(f, "%d", &num_visible);
00126 
00127         for (int j = 0; j < num_visible; j++) {
00128             int view, key;
00129             fscanf(f, "%d %d", &view, &key);
00130 
00131             double x, y;
00132             if (bundle_version >= 0.3)
00133                 fscanf(f, "%lf %lf", &x, &y);
00134         }
00135 
00136         if (num_visible > 0) {
00137             points.push_back(pt);
00138         }
00139     }
00140 
00141     fclose(f);
00142 }
00143 
00144 void WritePMVS(const char *output_path, char *list_file, char *bundle_file,
00145                std::vector<std::string> images, 
00146                std::vector<camera_params_t> &cameras)
00147 {
00148     int num_cameras = (int) cameras.size();
00149 
00150     /* Make sure output_path exists */
00151     mkdir(output_path, 0770);
00152 
00153     char buf[2048];
00154     sprintf(buf, "%s/prep_pmvs.sh", output_path);
00155 
00156     FILE *f_scr = fopen(buf, "w");
00157 
00158     fprintf(f_scr, "#!/bin/bash\n\n");
00159     fprintf(f_scr, "# Script for preparing images and calibration data \n"
00160             "#   for Yasutaka Furukawa's PMVS system\n");
00161     fprintf(f_scr, "# Modified by Dorian Galvez for RoboEarth WP1\n\n");
00162     
00163     fprintf(f_scr, "BUNDLER_BIN_PATH=\"$1\" # Edit this line before running\n");
00164     fprintf(f_scr, "USE_IMAGES_WITH_BG=$2\n\n");
00165     /*
00166     fprintf(f_scr, "if [ \"$BUNDLER_BIN_PATH\" == \"\" ]; then\n"
00167             "  echo \"Please edit prep_pmvs.sh to specify the path to the "
00168             " bundler binaries.\"\n  exit\nfi\n");
00169     */
00170 
00171     std::string list_file_with_bg;
00172     std::string s_list_file = list_file;
00173 
00174     std::string::size_type n = s_list_file.find_last_of('.');
00175 
00176     if(n == std::string::npos)
00177       list_file_with_bg = s_list_file + "_with_bg";
00178     else
00179     {
00180       list_file_with_bg = s_list_file.substr(0, n) + "_with_bg.txt";
00181     }
00182 
00183     fprintf(f_scr, "if [ $USE_IMAGES_WITH_BG -eq 0 ]; then\n");
00184     fprintf(f_scr, "  LIST_FILE=%s\n", list_file);
00185     fprintf(f_scr, "else\n");
00186     fprintf(f_scr, "  LIST_FILE=%s\n", list_file_with_bg.c_str());
00187     fprintf(f_scr, "fi\n\n");
00188 
00189     fprintf(f_scr, "# Apply radial undistortion to the images\n");
00190     fprintf(f_scr, "$BUNDLER_BIN_PATH/RadialUndistort %s %s %s\n", 
00191             "$LIST_FILE", bundle_file, output_path);
00192     fprintf(f_scr, "\n# Create directory structure\n");
00193     // fprintf(f_scr, "mkdir -p %s/\n", output_path);
00194     fprintf(f_scr, "mkdir -p %s/txt/\n", output_path);
00195     fprintf(f_scr, "mkdir -p %s/visualize/\n", output_path);
00196     fprintf(f_scr, "mkdir -p %s/models/\n", output_path);
00197     fprintf(f_scr, "\n# Copy and rename files\n");
00198 
00199     int count = 0;
00200     for (int i = 0; i < num_cameras; i++) {
00201         if (cameras[i].f == 0.0)
00202             continue;
00203 
00204         char buf[256];
00205         sprintf(buf, "%s/%08d.txt", output_path, count);
00206         FILE *f = fopen(buf, "w");
00207         assert(f);
00208 
00209         /* Compute the projection matrix */
00210         double focal = cameras[i].f;
00211         double *R = cameras[i].R;
00212         double *t = cameras[i].t;
00213 
00214         int w, h;
00215         GetJPEGDimensions(images[i].c_str(), w, h);
00216 
00217         double K[9] = 
00218             { -focal, 0.0, 0.5 * w - 0.5,
00219               0.0, focal, 0.5 * h - 0.5,
00220               0.0, 0.0, 1.0 };
00221 
00222         double Ptmp[12] = 
00223             { R[0], R[1], R[2], t[0],
00224               R[3], R[4], R[5], t[1],
00225               R[6], R[7], R[8], t[2] };
00226         
00227         double P[12];
00228         matrix_product(3, 3, 3, 4, K, Ptmp, P);
00229         matrix_scale(3, 4, P, -1.0, P);
00230 
00231         fprintf(f, "CONTOUR\n");
00232         fprintf(f, "%0.6f %0.6f %0.6f %0.6f\n", P[0], P[1], P[2],  P[3]);
00233         fprintf(f, "%0.6f %0.6f %0.6f %0.6f\n", P[4], P[5], P[6],  P[7]);
00234         fprintf(f, "%0.6f %0.6f %0.6f %0.6f\n", P[8], P[9], P[10], P[11]);
00235 
00236         fclose(f);
00237 
00238         int last_dot = images[i].rfind('.', images[i].length()-1);
00239         int first_pos = images[i].rfind('/');
00240         if(first_pos == std::string::npos) first_pos = 0;
00241         else first_pos++;
00242                 
00243         std::string basename = images[i].substr(first_pos, last_dot-first_pos);
00244 
00245         fprintf(f_scr, "mv %s/%s.rd.jpg %s/visualize/%08d.jpg\n", 
00246                 output_path, basename.c_str(), output_path, count);
00247         fprintf(f_scr, "mv %s %s/txt/\n", buf, output_path);
00248 
00249         count++;
00250     }
00251 
00252     /* Write the options file */
00253     sprintf(buf, "%s/pmvs_options.txt", output_path);
00254     FILE *f_opt = fopen(buf, "w");
00255 
00256     fprintf(f_opt, "level 1\n");
00257     fprintf(f_opt, "csize 2\n");
00258     fprintf(f_opt, "threshold 0.7\n");
00259     fprintf(f_opt, "wsize 7\n");
00260     fprintf(f_opt, "minImageNum 3\n");
00261     fprintf(f_opt, "CPU 8\n");
00262     fprintf(f_opt, "setEdge 0\n");
00263     fprintf(f_opt, "useBound 0\n");
00264     fprintf(f_opt, "useVisData 1\n");
00265     fprintf(f_opt, "sequence -1\n");
00266     fprintf(f_opt, "timages -1 0 %d\n", count);
00267     fprintf(f_opt, "oimages -3\n");
00268 
00269     fclose(f_opt);
00270 
00271     fprintf(f_scr, "\necho \"Running Bundle2Vis to generate vis.dat\"\n");
00272     fprintf(f_scr, "$BUNDLER_BIN_PATH/Bundle2Vis %s/bundle.rd.out %s/vis.dat\n", 
00273             output_path, output_path);
00274 
00275     fprintf(f_scr, "\n\n\necho @@ Sample command for running pmvs:\n");
00276     fprintf(f_scr, "echo \"   pmvs2 %s/ pmvs_options.txt\"\n", output_path);
00277     fprintf(f_scr, "echo \"    - or - \"\n");
00278     fprintf(f_scr, "echo \"   use Dr. Yasutaka Furukawa's view clustering algorithm to generate a set of options files.\"\n");
00279     fprintf(f_scr, "echo \"       The clustering software is available at http://grail.cs.washington.edu/software/cmvs\"\n");
00280 
00281     fclose(f_scr);
00282 }
00283 
00284 int main(int argc, char **argv) 
00285 {
00286     if (argc != 3 && argc != 4) {
00287         printf("Usage: %s <list.txt> <bundle.out> [pmvs_output_path (default: pmvs)]\n", 
00288                argv[0]);
00289         return 1;
00290     }
00291     
00292     char *list_file = argv[1];
00293     char *bundle_file = argv[2];
00294     char *output_path = "pmvs";
00295 
00296     if (argc == 4)
00297         output_path = argv[3];
00298 
00299     /* Read the list file */
00300     FILE *f = fopen(list_file, "r");
00301     if (f == NULL) {
00302         printf("Error opening file %s for reading\n", list_file);
00303         return 1;
00304     }
00305 
00306     std::vector<std::string> images;
00307     ReadListFile(list_file, images);
00308 
00309     /* Read the bundle file */
00310     std::vector<camera_params_t> cameras;
00311     std::vector<point_t> points;
00312     double bundle_version;
00313     ReadBundleFile(bundle_file, cameras, points, bundle_version);
00314 
00315     /* Write camera geometry in the PMVS file format */
00316     WritePMVS(output_path, list_file, bundle_file, images, cameras);
00317 
00318     printf("\n\n");
00319     printf("@@ Conversion complete, execute \"sh %s/prep_pmvs.sh\" to finalize\n", output_path);
00320     printf("@@ (you will first need to edit prep_pmvs.sh to specify your bundler path, \n");
00321     printf("@@  so that the script knows where to find your\n"
00322            "@@  RadialUndistort and Bundle2Vis binaries)\n");
00323 
00324     return 0;
00325 }


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:30:48