gabor.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 /* for memset(), others */
00006 #include <string.h>
00007 #include <unistd.h>
00008 #include <ppm.h>
00009 
00010 #include "gabor.h"
00011 
00012 /* for uint32_t */
00013 #include <stdint.h>
00014 
00015 /* note that all this is taken from the paper JaH98 in ~/tex/bib/squizz.bib */
00016 /* (with my corrections!) */
00017 
00018 static int kernal_size[num_gabor_scales] = {gabor_kernel_size_0, gabor_kernel_size_1, gabor_kernel_size_2};
00019 
00020 #define MAX_KERNAL_SIZE gabor_kernel_size_2
00021 
00022 void save_norm_double_pgm(double *double_im, int w, int h, char *fname) {
00023 
00024   PPM *im;
00025   float *norm_im;
00026   int i;
00027   FILE *outfile;
00028   int the_error;
00029 
00030   /* copy the image, and then normalise the contrast */
00031   norm_im = (float *)malloc(w*h*sizeof(float));
00032   for (i = 0; i < w*h; i++)
00033     norm_im[i] = (float)double_im[i];
00034   normaliseContrast(norm_im, w*h);
00035 
00036   im = new_ppm();
00037   im->type = PGM_RAW;
00038   im->width = w;
00039   im->height = h;
00040   im->max_col_comp = 255;
00041   im->bytes_per_pixel = 1;
00042   im->pixel = (byte *)malloc(w*h*sizeof(byte));
00043   for (i = 0; i < w*h; i++)
00044     im->pixel[i] = (byte)norm_im[i];
00045   outfile = fopen(fname, "wb");
00046   if ((the_error = write_ppm(outfile, im, PGM_RAW)) != PPM_OK) {
00047     ppm_handle_error(the_error);
00048     exit(1);
00049   }
00050   fclose(outfile);
00051   destroy_ppm(&im);
00052   free(norm_im);
00053 }
00054 
00055 void create_filter_kernels(double ** kernelsxy) {
00056 
00057   uint32_t i, j;
00058   int32_t x, x_c; /* ints to force type promotion later */
00059   double u0, u, v, sigma, theta;
00060 
00061   /* set the values of the kernels */
00062   u0 = u00;
00063   for (i = 0; i < num_gabor_scales; i++) {
00064     sigma = sigma_m(u0);
00065     for (j = 0; j < num_gabors_per_scale; j++) {
00066       theta = j*theta_step;
00067       u = u0*cos(theta);
00068       v = u0*sin(theta);
00069       x_c = kernal_size[i]/2; /* since sizes are odd, this gives the
00070                          centre value */
00071 
00072       kernelsxy[(i*num_gabors_per_scale+j)] = (double *)malloc(kernal_size[i]*sizeof(double)*4);
00073       for (x = 0; x < kernal_size[i]; x++) {
00074         /* note that x is "y" for kernels 12 and 22 */
00075         kernelsxy[(i*num_gabors_per_scale+j)][x] = (1/(sqrt(2*M_PI)*sigma)*exp(-sq((x - x_c))/(2*sq(sigma)))*cos(2*M_PI*u*(x - x_c)));
00076         kernelsxy[(i*num_gabors_per_scale+j)][x+kernal_size[i]] = (1/(sqrt(2*M_PI)*sigma)*exp(-sq((x - x_c))/(2*sq(sigma)))*cos(2*M_PI*v*(x - x_c)));                    
00077         kernelsxy[(i*num_gabors_per_scale+j)][x+kernal_size[i]*2] = (1/(sqrt(2*M_PI)*sigma)*exp(-sq((x - x_c))/(2*sq(sigma)))*sin(2*M_PI*u*(x - x_c)));
00078         kernelsxy[(i*num_gabors_per_scale+j)][x+kernal_size[i]*3] = (1/(sqrt(2*M_PI)*sigma)*exp(-sq((x - x_c))/(2*sq(sigma)))*sin(2*M_PI*v*(x - x_c)));
00079       }
00080     }
00081     u0 = u0/2;
00082   }
00083 }
00084 
00085 /* conv, conv2, and output need to be cleared before feeding them to this function. */
00086 /* conv and conv2 are just temporary space, for juggling image data between filters */
00087 void gabor_filter(double *image, int width, int height, int filter_scale, int orientation, double **kernelsxy, double *conv, double *conv2, double *output) {
00088 
00089   uint32_t x, y;
00090   uint32_t k;
00091   double * target_kernal;
00092   double * target_conv;
00093   double * target_image;
00094   double temparray[MAX_KERNAL_SIZE];
00095 
00096   /* first convolution */
00097   target_kernal=kernelsxy[filter_scale*num_gabors_per_scale+orientation];
00098   for (x = 0; x < width; x++) {
00099   for (y = 0; y < height; y++) {
00100     target_image=&image[(width*height-1)-(y*width+x+kernal_size[filter_scale]/2)];
00101     if ((x>=kernal_size[filter_scale]/2) && ((x+kernal_size[filter_scale]/2)<width))
00102       {
00103         for (k = 0; k < kernal_size[filter_scale]; k++)
00104           temparray[k]= target_kernal[k]*target_image[k];
00105         for (k = 0; k < kernal_size[filter_scale]; k++)
00106           conv[((width*height)-1)-(x*height+y)] += temparray[k];
00107       }
00108     else
00109       {
00110     for (k=0; k < kernal_size[filter_scale]; k++) {
00111       if ((x+kernal_size[filter_scale]/2 >= k) && (x+kernal_size[filter_scale]/2 < width+k)) {
00112         conv[((width*height)-1)-(x*height+y)] +=
00113           target_kernal[k]*target_image[k];
00114       }
00115     }
00116       }
00117   }
00118   }
00119 
00120   /* second convolution */
00121   target_kernal=&target_kernal[kernal_size[filter_scale]];
00122   for (x = 0; x < width; x++) {
00123   for (y = 0; y < height; y++) {
00124     target_conv=&conv[((width*height)-1)-(x*height+y+(kernal_size[filter_scale]/2))];
00125     if (((y>=kernal_size[filter_scale]/2)) && ((y+kernal_size[filter_scale]/2)<height))
00126       {
00127         /* first do the matrix multiply, then do the summation, so the matrix multiply can be vectored. */
00128         for (k = 0; k < kernal_size[filter_scale]; k++)
00129           temparray[k] = target_kernal[k]*target_conv[k];
00130         for (k = 0; k < kernal_size[filter_scale]; k++)
00131           output[y*width+x] += temparray[k];
00132       }
00133     else
00134       {
00135     for (k = 0; k < kernal_size[filter_scale]; k++) {
00136       if (((y+(kernal_size[filter_scale]/2))>=k) && (y+(kernal_size[filter_scale]/2)<height+k))
00137         output[y*width + x] +=
00138           target_kernal[k]*target_conv[k];
00139     }
00140       }
00141   }
00142   }
00143 
00144   /* third convolution */
00145   target_kernal=&target_kernal[kernal_size[filter_scale]];
00146   for (x = 0; x < width; x++) {
00147   for (y = 0; y < height; y++) {
00148     target_image=&image[(width*height-1)-(y*width+x+kernal_size[filter_scale]/2)];
00149     if ((x>=kernal_size[filter_scale]/2) && ((x+kernal_size[filter_scale]/2)<width))
00150       {
00151         for (k = 0; k < kernal_size[filter_scale]; k++)
00152           temparray[k]= target_kernal[k]*target_image[k];
00153         for (k = 0; k < kernal_size[filter_scale]; k++)
00154           conv2[((width*height)-1)-(x*height+y)] += temparray[k];
00155       }
00156     else
00157       {
00158     for (k=0; k < kernal_size[filter_scale]; k++) {
00159       if ((x+kernal_size[filter_scale]/2 >= k) && (x+kernal_size[filter_scale]/2 < width+k)) {
00160         conv2[((width*height)-1)-(x*height+y)] +=
00161           target_kernal[k]*target_image[k];
00162       }
00163     }
00164       }
00165   }
00166   }
00167 
00168   /* fourth convolution */
00169   target_kernal=&target_kernal[kernal_size[filter_scale]];
00170   for (x = 0; x < width; x++) {
00171   for (y = 0; y < height; y++) {
00172     target_conv=&conv2[((width*height)-1)-(x*height+y+(kernal_size[filter_scale]/2))];
00173     if (((y>=kernal_size[filter_scale]/2)) && ((y+kernal_size[filter_scale]/2)<height))
00174       {
00175         /* first do the matrix multiply, then do the summation, so the matrix multiply can be vectored. */
00176         for (k = 0; k < kernal_size[filter_scale]; k++)
00177           temparray[k] = target_kernal[k]*target_conv[k];
00178         for (k = 0; k < kernal_size[filter_scale]; k++)
00179           output[y*width+x] -= temparray[k];
00180       }
00181     else
00182       {
00183     for (k = 0; k < kernal_size[filter_scale]; k++) {
00184       if (((y+(kernal_size[filter_scale]/2))>=k) && (y+(kernal_size[filter_scale]/2)<height+k))
00185         output[y*width + x] -=
00186           target_kernal[k]*target_conv[k];
00187     }
00188     }
00189   }
00190   }
00191 
00192 }

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