gabor981029.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <malloc.h>
00004 #include <math.h>
00005 #include <string.h>
00006 #include <unistd.h>
00007 #include <fft.h>
00008 #include <ppm.h>
00009 
00010 #include "gabor.h"
00011 
00012 /* note that all this is taken from the paper JaH98 in ~/tex/bib/squizz.bib */
00013 /* (with my corrections!) */
00014 
00015 static double ***kernel11 = NULL;
00016 static double ***kernel12 = NULL;
00017 static double ***kernel21 = NULL;
00018 static double ***kernel22 = NULL;
00019 static int kernal_size[num_gabor_scales] = {gabor_kernel_size_0, gabor_kernel_size_1, gabor_kernel_size_2};
00020 
00021 void save_norm_double_pgm(double *double_im, int w, int h, char *fname) {
00022 
00023   PPM *im;
00024   float *norm_im;
00025   int i;
00026   FILE *outfile;
00027   int the_error;
00028 
00029   /* copy the image, and then normalise the contrast */
00030   norm_im = (float *)malloc(w*h*sizeof(float));
00031   for (i = 0; i < w*h; i++)
00032     norm_im[i] = (float)double_im[i];
00033   normaliseContrast(norm_im, w*h);
00034 
00035   im = new_ppm();
00036   im->type = PGM_RAW;
00037   im->width = w;
00038   im->height = h;
00039   im->max_col_comp = 255;
00040   im->bytes_per_pixel = 1;
00041   im->pixel = (byte *)malloc(w*h*sizeof(byte));
00042   for (i = 0; i < w*h; i++)
00043     im->pixel[i] = (byte)norm_im[i];
00044   outfile = fopen(fname, "wb");
00045   if ((the_error = write_ppm(outfile, im, PGM_RAW)) != PPM_OK) {
00046     ppm_handle_error(the_error);
00047     exit(1);
00048   }
00049   fclose(outfile);
00050   destroy_ppm(&im);
00051   free(norm_im);
00052 }
00053 
00054 void create_filter_kernels() {
00055 
00056   int i, j, n;
00057   int x, x_c;
00058   double u0, u, v, sigma, theta;
00059   char fname[256];
00060 
00061   /* allocate space for all the filter kernels */
00062   kernel11 = (double ***)malloc(num_gabor_scales*sizeof(double **));
00063   kernel12 = (double ***)malloc(num_gabor_scales*sizeof(double **));
00064   kernel21 = (double ***)malloc(num_gabor_scales*sizeof(double **));
00065   kernel22 = (double ***)malloc(num_gabor_scales*sizeof(double **));
00066   for (i = 0; i < num_gabor_scales; i++) {
00067     kernel11[i] = (double **)malloc(num_gabors_per_scale*sizeof(double *));
00068     for (j = 0; j < num_gabors_per_scale; j++)
00069       kernel11[i][j] = (double *)malloc(kernal_size[i]*sizeof(double));
00070     kernel12[i] = (double **)malloc(num_gabors_per_scale*sizeof(double *));
00071     for (j = 0; j < num_gabors_per_scale; j++)
00072       kernel12[i][j] = (double *)malloc(kernal_size[i]*sizeof(double));
00073     kernel21[i] = (double **)malloc(num_gabors_per_scale*sizeof(double *));
00074     for (j = 0; j < num_gabors_per_scale; j++)
00075       kernel21[i][j] = (double *)malloc(kernal_size[i]*sizeof(double));
00076     kernel22[i] = (double **)malloc(num_gabors_per_scale*sizeof(double *));
00077     for (j = 0; j < num_gabors_per_scale; j++)
00078       kernel22[i][j] = (double *)malloc(kernal_size[i]*sizeof(double));
00079   }
00080 
00081   /* now set the values of the kernels */
00082   u0 = u00;
00083   for (i = 0; i < num_gabor_scales; i++) {
00084     sigma = sigma_m(u0);
00085     for (j = 0; j < num_gabors_per_scale; j++) {
00086       theta = j*theta_step;
00087       u = u0*cos(theta);
00088       v = u0*sin(theta);
00089       x_c = kernal_size[i]/2; /* since sizes are odd, this gives the
00090                          centre value */
00091       for (x = 0; x < kernal_size[i]; x++) {
00092         /* note that x is "y" for kernels 12 and 22 */
00093         kernel11[i][j][x] = (1/(sqrt(2*M_PI)*sigma)*exp(-sq((x - x_c))/(2*sq(sigma)))*cos(2*M_PI*u*(x - x_c)));
00094         kernel12[i][j][x] = (1/(sqrt(2*M_PI)*sigma)*exp(-sq((x - x_c))/(2*sq(sigma)))*cos(2*M_PI*v*(x - x_c)));
00095         kernel21[i][j][x] = (1/(sqrt(2*M_PI)*sigma)*exp(-sq((x - x_c))/(2*sq(sigma)))*sin(2*M_PI*u*(x - x_c)));
00096         kernel22[i][j][x] = (1/(sqrt(2*M_PI)*sigma)*exp(-sq((x - x_c))/(2*sq(sigma)))*sin(2*M_PI*v*(x - x_c)));
00097       }
00098     }
00099     u0 = u0/2;
00100   }
00101 }
00102 
00103 void gabor_filter(double *image, int width, int height, int filter_scale, int n_theta, double *output) {
00104 
00105   double *conv;
00106   int x, y, t_x, t_y;
00107   int i;
00108 
00109   /* create the filter kernels, if it has not already been done */
00110   if (kernel11 == NULL)
00111     create_filter_kernels();
00112 
00113   conv = (double *)calloc(width*height, sizeof(double));
00114 
00115   /* first convolution */
00116   for (x = 0; x < width; x++) {
00117   for (y = 0; y < height; y++) {
00118     output[y*width + x] = 0; /* might as well be here */
00119     for (t_x = -kernal_size[filter_scale]/2; t_x <= kernal_size[filter_scale]/2; t_x++) {
00120       if (((x - t_x) >= 0) && ((x - t_x) < width)) {
00121         conv[y*width + x] +=
00122           kernel11[filter_scale][n_theta][t_x + kernal_size[filter_scale]/2]*image[y*width+ (x - t_x)];
00123       }
00124     }
00125   }
00126   }
00127 
00128   /* second convolution */
00129   for (x = 0; x < width; x++) {
00130   for (y = 0; y < height; y++) {
00131     for (t_y = -kernal_size[filter_scale]/2; t_y <= kernal_size[filter_scale]/2; t_y++) {
00132       if (((y - t_y) >= 0) && ((y - t_y) < height))
00133         output[y*width + x] +=
00134           kernel12[filter_scale][n_theta][t_y + kernal_size[filter_scale]/2]*conv[(y - t_y)*width + x];
00135     }
00136   }
00137   }
00138 
00139   for (i = 0; i < width*height; i++)
00140     conv[i] = 0;
00141 
00142   /* third convolution */
00143   for (x = 0; x < width; x++) {
00144   for (y = 0; y < height; y++) {
00145     for (t_x = -kernal_size[filter_scale]/2; t_x <= kernal_size[filter_scale]/2; t_x++) {
00146       if (((x - t_x) >= 0) && ((x - t_x) < width)) {
00147         conv[y*width + x] +=
00148         kernel21[filter_scale][n_theta][t_x + kernal_size[filter_scale]/2]*image[y*width + (x - t_x)];
00149       }
00150     }
00151   }
00152   }
00153 
00154   /* fourth convolution */
00155   for (x = 0; x < width; x++) {
00156   for (y = 0; y < height; y++) {
00157     for (t_y = -kernal_size[filter_scale]/2; t_y <= kernal_size[filter_scale]/2; t_y++) {
00158       if (((y - t_y) >= 0) && ((y - t_y) < height))
00159         output[y*width + x] -=
00160         kernel22[filter_scale][n_theta][t_y + kernal_size[filter_scale]/2]*conv[(y - t_y)*width + x];
00161     }
00162   }
00163   }
00164 
00165   free(conv);
00166 }
00167 
00168 int main(int argc, char *argv[]) {
00169   
00170   char *in_fname, *out_fname, *out_fname_prefix, buffer[80];
00171   char *point_pos;
00172   FILE *ppm_file, *outfile;
00173   PPM *im_rgb, *im_hsv, *im_filtered;
00174   int *colmap, colmap_size;
00175   enum file_types ppm_type;
00176   enum ppm_error the_error;
00177   double *db_val_image, *filtered_image;  
00178   double max_energy;
00179   double min_energy;
00180   int scale, orientation;
00181   int i;
00182 
00183     switch(argc) {
00184     case 4:
00185         in_fname = argv[1];
00186     scale = atoi(argv[2]);
00187     orientation = atoi(argv[3]);
00188         break;
00189     default:
00190         fprintf(stderr, "Usage: %s ppm_file scale orientation\n\n", argv[0]);
00191         exit(1);
00192         break;
00193     }
00194  
00195     if ((ppm_file = fopen (in_fname, "r")) == NULL) {
00196         fprintf(stderr, "Can't open file: %s", in_fname);
00197         exit(1);
00198     }
00199  
00200     /* now get the filename prefix */
00201     out_fname_prefix = (char *)malloc((strlen(in_fname) + 40)*sizeof(char));
00202     out_fname = (char *)malloc((strlen(in_fname) + 40)*sizeof(char));
00203     if ((point_pos = strchr(in_fname, '.')) == NULL) {
00204         fprintf(stderr, "File %s has no ""."" - can't generate filtered image filenames\n\n", in_fname);
00205         exit(1);
00206     }
00207   strncpy(out_fname_prefix, in_fname, (int)(point_pos - in_fname));
00208 
00209   /* read the rgb image which we are going to filter */
00210   switch(ppm_type = read_magic_no(ppm_file)) {
00211   case PGM_ASC: case PPM_ASC: case PGM_RAW: case PPM_RAW:
00212     if ((the_error = read_ppm(ppm_file, &im_rgb, ppm_type)) != PPM_OK) {
00213       ppm_handle_error(the_error);
00214       exit(1);
00215     }
00216         break;
00217     default:
00218         fprintf(stderr, "Unrecognized file type.\n");
00219         exit(1);
00220         break;
00221     }
00222 
00223     /* convert it to hsv */
00224     if ((the_error = rgb2hsv_ppm(im_rgb, &im_hsv)) != PPM_OK) {
00225         ppm_handle_error(the_error);
00226         exit(1);
00227     }
00228 
00229   /* make space for the output filtered image */
00230     im_filtered = new_ppm();
00231     add_comment(im_filtered, "# Value image block quantized image.\n");
00232     im_filtered->type = PGM_RAW;
00233     im_filtered->width = im_hsv->width;
00234     im_filtered->height = im_hsv->height;
00235     im_filtered->max_col_comp = 255;
00236     im_filtered->bytes_per_pixel = 1;
00237     im_filtered->pixel = (byte *)malloc(im_hsv->width*im_hsv->height*sizeof(byte));
00238 
00239   /* extract the value plane */
00240   db_val_image = (double *)malloc(im_hsv->width*im_hsv->height*sizeof(double));
00241   filtered_image = (double *)malloc(im_hsv->width*im_hsv->height*sizeof(double));
00242   for (i = 0; i < im_hsv->width*im_hsv->height; i++)
00243     db_val_image[i] = (double)(im_hsv->pixel[3*i + VALUE]);
00244     
00245   /* now apply the filter */
00246   gabor_filter(db_val_image, im_hsv->width, im_hsv->height, scale, orientation, filtered_image);
00247   max_energy = 0;
00248   min_energy = 255*255;
00249   for (i = 0; i < im_hsv->width*im_hsv->height; i++) {
00250 #ifdef GABOR_WRITE_FILTERED
00251     im_filtered->pixel[i] = (byte)sqrt(sq(filtered_image[i]));
00252 #endif
00253     printf("%f\n", sq(filtered_image[i]));
00254     if (sq(filtered_image[i]) > max_energy)
00255       max_energy = sq(filtered_image[i]);
00256     if (sq(filtered_image[i]) < min_energy)
00257       min_energy = sq(filtered_image[i]);
00258   }
00259 #ifdef GABOR_WRITE_FILTERED
00260   sprintf(out_fname, "%s_gabor_%d_%d.pgm", out_fname_prefix, scale, orientation);
00261   outfile = fopen(out_fname, "wb");
00262   if ((the_error = write_ppm(outfile, im_filtered, PGM_RAW)) != PPM_OK) {
00263     ppm_handle_error(the_error);
00264     exit(1);
00265   }
00266   fclose(outfile);
00267 #endif
00268 }

Generated on Wed Jan 7 00:30:35 2009 for Gift by  doxygen 1.5.6