/********************************************************** ** This is C-code which will read in a raw Odetics image, ** split it into range and reflectance images, and write ** them out in PGM format. **********************************************************/ #include main(argc,argv) int argc; char *argv[]; { char text[300]; unsigned char *combined,*range,*ref,*pgm; int r,c,i; FILE *fpt; if ((combined=(unsigned char *)calloc(1,128*128*2)) == NULL || (range=(unsigned char *)calloc(1,128*128)) == NULL || (pgm=(unsigned char *)calloc(1,128*128*3)) == NULL || (ref=(unsigned char *)calloc(1,128*128)) == NULL) { printf("Unable to acquire necessary memory\n"); exit(0); } if (argc < 2 || argc > 3 || (argc == 3 && strcmp(argv[2],"rotate") != 0)) { printf("Usage: odetics-to-pgm [filename] [rotate]\n"); exit(0); } if ((fpt=fopen(argv[1],"r")) == NULL) { printf("Unable to open %s\n",argv[1]); exit(0); } if (fread(combined,1,2*128*128,fpt) != 2*128*128) { printf("Problem reading odetics data\n"); exit(0); } fclose(fpt); /* splits the raw data into range and reflectance images */ for (r=0; r<128; r++) for (c=0; c<128; c++) { if (argc == 2) { /* no rotation */ range[r*128+c]=combined[(r*128+c)*2+1]; ref[r*128+c]=combined[(r*128+c)*2]; } else { /* rotation 90 degrees CW */ range[r*128+c]=combined[((127-c)*128+r)*2+1]; ref[r*128+c]=combined[((127-c)*128+r)*2]; } } for (i=0; i<2; i++) /* once for range, reflectance */ { if (i == 0) { for (r=0; r<128*128; r++) pgm[r]=range[r]; sprintf(text,"%s.range.pgm",argv[1]); } else { for (r=0; r<128*128; r++) pgm[r]=ref[r]; sprintf(text,"%s.refl.pgm",argv[1]); } if ((fpt=fopen(text,"w")) == NULL) { printf("Unable to open %s for writing\n",text); exit(0); } fprintf(fpt,"P5\n128 128 255\n"); if (fwrite(pgm,1,128*128,fpt) != 128*128) { printf("Problem writing pgm file\n"); exit(0); } fclose(fpt); } free(range); free(ref); free(combined); free(pgm); } /* ** This routine converts the data in an Odetics range image into 3D ** cartesian coordinate data. The range image is 8-bit, and comes ** already separated from the intensity image. The cartesian ** coordinates are returned in P, where P[0] is X, P[1] is Y and ** P[2] is Z. ImageTypeFlag, for all these images available, is 0. */ #include #include ConvertOdeticsRangeToCartesian(RangeImage,P,ImageTypeFlag) unsigned char *RangeImage; double *P[3]; int ImageTypeFlag; { int r,c; double cp[7]; double xangle,yangle,dist; double ScanDirectionFlag,SlantCorrection; cp[0]=1220.7; /* horizontal mirror angular velocity in rpm */ cp[1]=32.0; /* scan time per single pixel in microseconds */ cp[2]=(COLS/2)-0.5; /* middle value of columns */ cp[3]=1220.7/192.0; /* vertical mirror angular velocity in rpm */ cp[4]=6.14; /* scan time (with retrace) per line in milliseconds */ cp[5]=(ROWS/2)-0.5; /* middle value of rows */ cp[6]=10.0; /* standoff distance in range units (3.66cm per r.u.) */ cp[0]=cp[0]*3.1415927/30.0; /* convert rpm to rad/sec */ cp[3]=cp[3]*3.1415927/30.0; /* convert rpm to rad/sec */ cp[0]=2.0*cp[0]; /* beam ang. vel. is twice mirror ang. vel. */ cp[3]=2.0*cp[3]; /* beam ang. vel. is twice mirror ang. vel. */ cp[1]/=1000000.0; /* units are microseconds : 10^-6 */ cp[4]/=1000.0; /* units are milliseconds : 10^-3 */ switch(ImageTypeFlag) { case 1: /* Odetics image -- scan direction upward */ ScanDirectionFlag=-1; break; case 0: /* Odetics image -- scan direction downward */ ScanDirectionFlag=1; break; default: /* in case we want to do this on synthetic model */ ScanDirectionFlag=0; break; } /* start with semi-spherical coordinates from laser-range-finder: */ /* (r,c,RangeImage[r*COLS+c]) */ /* convert those to axis-independant spherical coordinates: */ /* (xangle,yangle,dist) */ /* then convert the spherical coordinates to cartesian: */ /* (P => X[] Y[] Z[]) */ for (r=0; r