Changes between Version 7 and Version 8 of RemapFilter


Ignore:
Timestamp:
Jun 17, 2016, 3:09:09 PM (3 years ago)
Author:
fsluiter
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • RemapFilter

    v7 v8  
    2525* Samsung gear camera: input files for resolution 2560x1280
    2626
    27 Note: if you have a different camera or need other resolutions, let me know ( fsluiter_at_gmail.com). I can generate the input files if you sent me a sample frame.
    28 
     27Note: for questions about these examples, let me know ( fsluiter_at_gmail.com).
     28
     29How to generate PGM files:
     30
     31{{{
     32#!div style="font-size: 80%"
     33{{{#!c
     34
     35#include <stdio.h>
     36#include <stdlib.h>
     37#include <libgen.h>
     38#include <string.h>
     39#include <getopt.h>
     40#include <math.h>
     41
     42
     43
     44/* Compile with: gcc projection.c -Wall -o project -lm
     45 * math.h does not like to be linked directly...
     46 */
     47
     48/* Flag set by ‘--verbose’. */
     49static int verbose_flag;
     50
     51typedef struct double2{
     52    double x;
     53    double y;
     54}double2;
     55typedef struct double3{
     56    double x;
     57    double y;
     58    double z;
     59}double3;
     60
     61
     62enum CameraMode {
     63    FRONT,
     64    FRONT235,
     65    BACK,
     66    UP,
     67    DOWN,
     68    SAMSUNG_GEAR_360,
     69    THETAS
     70};
     71
     72typedef struct configuration {
     73    char* xmap_filename;
     74    char* ymap_filename;
     75    int xmap_set;
     76    int ymap_set;
     77    int rows; // target
     78    int cols; // target
     79    int height; //source
     80    int width;//source
     81    int rows_set;
     82    int cols_set;
     83    int height_set;
     84    int width_set;
     85    int crop;
     86    enum CameraMode mode;
     87} configuration;
     88
     89configuration parse_options(int argc, char **argv){
     90  int c;
     91  configuration po; //to hold parsed options
     92  po.xmap_filename=NULL;
     93  po.ymap_filename=NULL;
     94  po.xmap_set=0;
     95  po.ymap_set=0;
     96  po.rows=0;
     97  po.cols=0;
     98  po.rows_set=0;
     99  po.cols_set=0;
     100  po.height_set=0;
     101  po.width_set=0;
     102  po.mode=FRONT; //default
     103
     104  while (1)
     105    {
     106      static struct option long_options[] =
     107        {
     108          /* These options set a flag. */
     109          {"verbose", no_argument,       &verbose_flag, 1},
     110          {"brief",   no_argument,       &verbose_flag, 0},
     111
     112          /* These options don’t set a flag.
     113             We distinguish them by their indices. */
     114          {"help",  no_argument,       0, 'q'},
     115
     116          /* options with arg*/
     117          {"xmap",    required_argument, 0, 'x'},
     118          {"ymap",    required_argument, 0, 'y'},
     119          {"rows",    required_argument, 0, 'r'},//target
     120          {"cols",    required_argument, 0, 'c'},//target
     121          {"height",  required_argument, 0, 'h'},//source
     122          {"width",   required_argument, 0, 'w'},//source
     123          {"mode",    required_argument, 0, 'm'},
     124          {"crop",    required_argument, 0, 'b'},
     125
     126          {0, 0, 0, 0}
     127        };
     128      /* getopt_long stores the option index here. */
     129      int option_index = 0;
     130
     131      c = getopt_long (argc, argv, "qx:y:r:c:h:w:m:b:",
     132                       long_options, &option_index);
     133
     134      /* Detect the end of the options. */
     135      if (c == -1)
     136        break;
     137
     138      switch (c)
     139        {
     140        case 0:
     141          /* If this option set a flag, do nothing else now. */
     142          if (long_options[option_index].flag != 0)
     143            break;
     144          printf ("option %s", long_options[option_index].name);
     145          if (optarg)
     146            printf (" with arg %s", optarg);
     147          printf ("\n");
     148          break;
     149
     150        case 'x':
     151          po.xmap_filename = optarg;
     152          po.xmap_set++;
     153          break;
     154
     155        case 'y':
     156          po.ymap_filename = optarg;
     157          po.ymap_set++;
     158          break;
     159        case 'h':
     160          po.height = atoi(optarg);
     161          po.height_set++;
     162          break;
     163        case 'w':
     164          po.width = atoi(optarg);
     165          po.width_set++;
     166          break;
     167        case 'c':
     168          po.cols = atoi(optarg);
     169          po.cols_set++;
     170          break;
     171        case 'r':
     172          po.rows = atoi(optarg);
     173          po.rows_set++;
     174          break;
     175        case 'b':
     176          po.crop = atoi(optarg);
     177          break;
     178        case 'm':
     179          if (strcmp(optarg, "front") == 0)
     180          {
     181            po.mode = FRONT;
     182          }
     183          else if (strcmp(optarg, "front235") == 0)
     184          {
     185            po.mode = FRONT235;
     186          }
     187          else if (strcmp(optarg, "down") == 0)
     188          {
     189            po.mode = DOWN;
     190          }
     191          else if (strcmp(optarg, "samsung_gear_360") == 0)
     192          {
     193            po.mode = SAMSUNG_GEAR_360;
     194          }
     195          else if (strcmp(optarg, "thetas") == 0)
     196          {
     197            po.mode = THETAS;
     198          }
     199          /* more else if clauses */
     200          else /* default: */
     201          {
     202             printf("Camera mode %s not implemented \n",optarg); exit(1);
     203          }
     204          break;
     205
     206        case '?':
     207          /* getopt_long already printed an error message. */
     208        case 'q':
     209          printf ("Usage: %s -x|--xmap FILE_x.pgm -y|--ymap FILE_y.pgm -h|--height 300 -w|--width 400 -r|--rows 600 -c|--cols 800 \n", argv[0]);
     210          printf ("h,w is source size, r,c is targetsize \n");
     211          exit(1);
     212          break;
     213
     214        default:
     215          abort ();
     216        }
     217    }
     218
     219  /* Instead of reporting ‘--verbose’
     220     and ‘--brief’ as they are encountered,
     221     we report the final status resulting from them. */
     222  if(verbose_flag){
     223    switch(po.mode){
     224      case FRONT:   printf("Camera: Front proj\n"); break;
     225      case FRONT235:   printf("Camera: Front 235 proj\n"); break;
     226      case DOWN:   printf("Camera: Down proj\n"); break;
     227      case SAMSUNG_GEAR_360: printf("Camera: samsung_gear_360\n"); break;
     228      case THETAS: printf("Camera: Theta S\n"); break;
     229      default: printf("Camera mode not in verbose, exiting\n"); exit(1);
     230    }
     231  }
     232    /* Print any remaining command line arguments (not options). */
     233    if (optind < argc)
     234    {
     235      printf ("ERROR: non-option ARGV-elements: ");
     236      while (optind < argc)
     237        printf ("%s ", argv[optind++]);
     238      putchar ('\n');
     239      exit(1);
     240    }
     241 
     242    if(po.xmap_set!=1||po.ymap_set!=1){ printf("ERROR: Xmap and ymap are mandatory arguments and have to appear only once!\ntry --help for help\n\n ");exit(-1);}
     243    if(po.rows_set!=1||po.cols_set!=1){ printf("ERROR: Target Rows and Cols are mandatory arguments and have to appear only once!\ntry --help for help\n\n ");exit(-1);}
     244    if(po.height_set!=1||po.width_set!=1){ printf("ERROR: Source Height and Width are mandatory arguments and have to appear only once!\ntry --help for help\n\n ");exit(-1);}
     245    return po;
     246
     247
     248#define MAXROWS 4500
     249#define MAXCOLS 4500
     250
     251int pgmWrite_ASCII(char* filename, int rows,int cols,
     252             int **image,char* comment_string) {
     253      FILE* file;        /* pointer to the file buffer */
     254//      int maxval;        /* maximum value in the image array */
     255      long nwritten = 0; /* counter for the number of pixels written */
     256      long x,y;          /* for loop counters */
     257
     258      /* return 0 if the dimensions are larger than the image array. */
     259      if (rows > MAXROWS || cols > MAXCOLS) {
     260           printf ("ERROR: row/col specifications larger than image array:\n");
     261           return (0);
     262      }
     263
     264      /* open the file; write header and comments specified by the user. */
     265      if ((file = fopen(filename, "w")) == NULL)        {
     266           printf("ERROR: file open failed\n");
     267           return(0);
     268      }
     269      fprintf(file,"P2\n");
     270
     271      if (comment_string != NULL) fprintf(file,"# %s \n", comment_string);
     272   
     273      /* write the dimensions of the image */   
     274      fprintf(file,"%i %i \n", cols, rows);
     275
     276      /* NOTE: MAXIMUM VALUE IS WHITE; COLOURS ARE SCALED FROM 0 - */
     277      /* MAXVALUE IN A .PGM FILE. */
     278     
     279      /* WRITE MAXIMUM VALUE TO FILE */
     280      fprintf(file, "%d\n", (int)65535);
     281
     282      /* Write data */
     283
     284  for (y = 0; y<rows;y++){
     285    for (x = 0; x < cols; x++){
     286      fprintf(file,"%i ",image[y][x]);
     287      nwritten++;
     288    }
     289  fprintf(file,"\n");
     290  }
     291  fprintf(file,"\n");
     292
     293     
     294      printf ("\nNumber of pixels total(from rows*cols): %i\n",rows*cols);
     295      printf ("Number of pixels written in file %s: %ld\n\n",filename,nwritten);
     296
     297      fclose(file);
     298      return(1);
     299}
     300
     301
     302
     303
     304/* So, to get the x’,y’ position for the circular image we will have to first pass the
     305 * coordinates x,y from the rectangular output image to spherical coordinates using the
     306 * first coordinate system, then those to the second shown spherical coordinate system,
     307 * then those to the polar projection and then pass the polar system to cardinal x’,y’.
     308 */
     309double2 evaluatePixel_Front(double2 outCoord, double2 srcSize)
     310{
     311        double2 o;
     312        double theta,phi;
     313        double3 sphericCoords;
     314        double phi2_over_pi;
     315        double theta2;
     316        double2 inCentered;
     317
     318//convert outcoords to radians (180 = pi, so half a sphere)
     319        o.x = outCoord.x / srcSize.x;
     320        o.y = outCoord.y / srcSize.y;
     321        theta = (1.0-o.x) * M_PI;
     322        phi = o.y * M_PI;
     323
     324//Convert outcoords to spherical (x,y,z on unisphere)
     325        sphericCoords.x = cos(theta)*sin(phi);
     326        sphericCoords.y = sin(theta)*sin(phi);
     327        sphericCoords.z = cos(phi);
     328       
     329//Convert spherical to input coordinates...
     330        theta2 = atan2(-sphericCoords.z,sphericCoords.x);
     331        phi2_over_pi = acos(sphericCoords.y)/(M_PI);
     332       
     333        inCentered.x = ((phi2_over_pi*cos(theta2))+0.5)*srcSize.x;
     334        inCentered.y = ((phi2_over_pi*sin(theta2))+0.5)*srcSize.y;
     335       
     336        return inCentered;
     337}
     338
     339
     340void gen_front_maps(configuration cfg,int** image_x,int** image_y ){
     341    int x,y;
     342
     343  printf("Front proj\n");
     344  for (y = 0; y<cfg.rows;y++){
     345    for (x = 0; x < cfg.cols; x++){
     346      double2 o = evaluatePixel_Front((double2){((double)x/((double)cfg.cols)) * ((cfg.width)-(2*cfg.crop)),
     347                                                ((double)y/(double)cfg.rows)   * ((cfg.height)  -(2*cfg.crop))},
     348                                      (double2){(cfg.width)-(2*cfg.crop), cfg.height-(2*cfg.crop)});
     349      image_x[y][x] = (int)round(o.x)+cfg.crop;
     350      image_y[y][x] = (int)round(o.y)+cfg.crop;
     351    }
     352  }
     353}
     354
     355
     356int
     357main (int argc, char **argv)
     358{
     359    int y;
     360    int** image_x;
     361    int** image_y;
     362    configuration cfg = parse_options(argc,argv);
     363
     364
     365    if(cfg.xmap_filename)  printf("xmapfile: %s\n",cfg.xmap_filename);
     366    if(cfg.ymap_filename)  printf("ymapfile: %s\n",cfg.ymap_filename);
     367
     368      image_x = malloc((cfg.rows)*sizeof(*image_x));
     369      for(y=0;y<(cfg.rows);y++) image_x[y]= malloc((cfg.cols)*sizeof(*(image_x[y])));
     370      image_y = malloc((cfg.rows)*sizeof(*image_y));
     371      for(y=0;y<(cfg.rows);y++) image_y[y]= malloc((cfg.cols)*sizeof(*(image_y[y])));
     372
     373
     374    switch(cfg.mode){
     375      case FRONT:    gen_front_maps(cfg,image_x,image_y); break;
     376/*      case FRONT235:    gen_front235_maps(cfg,image_x,image_y); break;
     377      case DOWN:    gen_down_maps(cfg,image_x,image_y); break;
     378      case SAMSUNG_GEAR_360: gen_samsung_gear_360_maps(cfg,image_x,image_y); break;
     379      case THETAS: gen_thetas_maps(cfg,image_x,image_y); break;
     380*/
     381      default: printf("Camera mode not implemented\n"); exit(1);
     382
     383    }
     384
     385
     386
     387
     388  printf("Writing files\n");
     389  pgmWrite_ASCII(cfg.ymap_filename, cfg.rows,cfg.cols,image_y,cfg.ymap_filename);
     390  pgmWrite_ASCII(cfg.xmap_filename, cfg.rows,cfg.cols,image_x,cfg.xmap_filename);
     391
     392    if(image_y){
     393         for (y = 0; y<cfg.rows;y++) free(image_y[y]);
     394       free(image_y);
     395    }
     396    if(image_x){
     397         for (y = 0; y<cfg.rows;y++) free(image_x[y]);
     398       free(image_x);
     399    }
     400
     401
     402    exit (0);
     403}
     404
     405}}}
     406}}}