00001 #include <math.h>
00002 #include <ppm.h>
00003 #include <fft.h>
00004
00005 #include "gabor.h"
00006
00007
00008
00009
00010 static double ***kernel11 = NULL;
00011 static double ***kernel12 = NULL;
00012 static double ***kernel21 = NULL;
00013 static double ***kernel22 = NULL;
00014 static int kernal_size[num_gabor_scales] = {gabor_kernel_size_0, gabor_kernel_size_1, gabor_kernel_size_2};
00015
00016 void save_norm_double_pgm(double *double_im, int w, int h, char *fname) {
00017
00018 PPM *im;
00019 float *norm_im;
00020 int i;
00021 FILE *outfile;
00022 int the_error;
00023
00024
00025 norm_im = (float *)malloc(w*h*sizeof(float));
00026 for (i = 0; i < w*h; i++)
00027 norm_im[i] = (float)double_im[i];
00028 normaliseContrast(norm_im, w*h);
00029
00030 im = new_ppm();
00031 im->type = PGM_RAW;
00032 im->width = w;
00033 im->height = h;
00034 im->max_col_comp = 255;
00035 im->bytes_per_pixel = 1;
00036 im->pixel = (byte *)malloc(w*h*sizeof(byte));
00037 for (i = 0; i < w*h; i++)
00038 im->pixel[i] = (byte)norm_im[i];
00039 outfile = fopen(fname, "wb");
00040 if ((the_error = write_ppm(outfile, im, PGM_RAW)) != PPM_OK) {
00041 ppm_handle_error(the_error);
00042 exit(1);
00043 }
00044 fclose(outfile);
00045 destroy_ppm(&im);
00046 free(norm_im);
00047 }
00048
00049 void create_filter_kernels() {
00050
00051 int i, j, n;
00052 int x, x_c;
00053 double u0, u, v, sigma, theta;
00054
00055
00056 kernel11 = (double ***)malloc(num_gabor_scales*sizeof(double **));
00057 kernel12 = (double ***)malloc(num_gabor_scales*sizeof(double **));
00058 kernel21 = (double ***)malloc(num_gabor_scales*sizeof(double **));
00059 kernel22 = (double ***)malloc(num_gabor_scales*sizeof(double **));
00060 for (i = 0; i < num_gabor_scales; i++) {
00061 kernel11[i] = (double **)malloc(num_gabors_per_scale*sizeof(double *));
00062 for (j = 0; j < num_gabors_per_scale; j++)
00063 kernel11[i][j] = (double *)malloc(kernal_size[i]*sizeof(double));
00064 kernel12[i] = (double **)malloc(num_gabors_per_scale*sizeof(double *));
00065 for (j = 0; j < num_gabors_per_scale; j++)
00066 kernel12[i][j] = (double *)malloc(kernal_size[i]*sizeof(double));
00067 kernel21[i] = (double **)malloc(num_gabors_per_scale*sizeof(double *));
00068 for (j = 0; j < num_gabors_per_scale; j++)
00069 kernel21[i][j] = (double *)malloc(kernal_size[i]*sizeof(double));
00070 kernel22[i] = (double **)malloc(num_gabors_per_scale*sizeof(double *));
00071 for (j = 0; j < num_gabors_per_scale; j++)
00072 kernel22[i][j] = (double *)malloc(kernal_size[i]*sizeof(double));
00073 }
00074
00075
00076 u0 = u00;
00077 for (i = 0; i < num_gabor_scales; i++) {
00078 sigma = sigma_m(u0);
00079 x_c = kernal_size[i]/2;
00080
00081 for (j = 0; j < num_gabors_per_scale; j++) {
00082 theta = j*theta_step;
00083 u = u0*cos(theta);
00084 v = u0*sin(theta);
00085 for (x = 0; x < kernal_size[i]; x++) {
00086
00087 kernel11[i][j][x] = gabor_f11(sigma, x - x_c, u);
00088 #ifdef DEBUG
00089 fprintf(stderr, "kernel11[%d][%d][%d] = %f\n", i, j, x, kernel11[i][j][x]);
00090 #endif
00091 kernel11[i][j][x] = gabor_f11(sigma, x - x_c, u);
00092 kernel12[i][j][x] = gabor_f12(sigma, x - x_c, v);
00093 kernel21[i][j][x] = gabor_f21(sigma, x - x_c, u);
00094 kernel22[i][j][x] = gabor_f22(sigma, x - x_c, v);
00095 }
00096 }
00097 u0 = u0/2;
00098 }
00099 }
00100
00101 void gabor_filter(double *I, int block_size, int filter_scale, int n_theta, double *output) {
00102
00103 double *conv;
00104 int x, y, t_x, t_y;
00105 int i;
00106
00107
00108 if (kernel11 == NULL)
00109 create_filter_kernels();
00110
00111 conv = (double *)calloc(sq(block_size), sizeof(double));
00112
00113
00114 for (x = 0; x < block_size; x++) {
00115 for (y = 0; y < block_size; y++) {
00116 output[y*block_size + x] = 0;
00117 for (t_x = x - kernal_size[filter_scale]/2; t_x <= kernal_size[filter_scale]/2; t_x++) {
00118 if (((x - t_x) >= 0) && ((x - t_x) < block_size))
00119 conv[y*block_size + x] +=
00120 kernel11[filter_scale][n_theta][t_x + kernal_size[filter_scale]/2]*I[y*block_size + (x - t_x)];
00121 }
00122 }
00123 }
00124 save_norm_double_pgm(conv, block_size, block_size, "Conv1.pgm");
00125
00126
00127
00128 for (x = 0; x < block_size; x++) {
00129 for (y = 0; y < block_size; y++) {
00130 for (t_y = y - kernal_size[filter_scale]/2; t_y <= kernal_size[filter_scale]/2; t_y++) {
00131 if (((y - t_y) >= 0) && ((y - t_y) < block_size))
00132 output[y*block_size + x] +=
00133 kernel12[filter_scale][n_theta][t_y + kernal_size[filter_scale]/2]*conv[(y - t_y)*block_size + x];
00134 }
00135 }
00136 }
00137 save_norm_double_pgm(output, block_size, block_size, "Conv2.pgm");
00138
00139 for (i = 0; i < sq(block_size); i++)
00140 conv[i] = 0;
00141
00142
00143 for (x = 0; x < block_size; x++) {
00144 for (y = 0; y < block_size; y++) {
00145 for (t_x = x - kernal_size[filter_scale]/2; t_x <= kernal_size[filter_scale]/2; t_x++) {
00146 if (((x - t_x) >= 0) && ((x - t_x) < block_size)) {
00147 conv[y*block_size + x] +=
00148 kernel21[filter_scale][n_theta][t_x + kernal_size[filter_scale]/2]*I[y*block_size + (x - t_x)];
00149 }
00150 }
00151 }
00152 }
00153 save_norm_double_pgm(conv, block_size, block_size, "Conv3.pgm");
00154
00155
00156 for (x = 0; x < block_size; x++) {
00157 for (y = 0; y < block_size; y++) {
00158 for (t_y = y - kernal_size[filter_scale]/2; t_y <= kernal_size[filter_scale]/2; t_y++) {
00159 if (((y - t_y) >= 0) && ((y - t_y) < block_size))
00160 output[y*block_size + x] -=
00161 kernel22[filter_scale][n_theta][t_y + kernal_size[filter_scale]/2]*conv[(y - t_y)*block_size + x];
00162 }
00163 }
00164 }
00165 save_norm_double_pgm(output, block_size, block_size, "Conv4.pgm");
00166
00167 free(conv);
00168 }
00169
00170 int main(int argc, char *argv[]) {
00171
00172 double *impulse = NULL;
00173 double *impulse_response = NULL;
00174 int im_size;
00175 char out_fname[256];
00176 int i, j, x, y;
00177 int scale = 0;
00178 double u0, u, v, sigma, theta;
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 for (i = 0; i < num_gabor_scales; i++) {
00230 if (impulse != NULL)
00231 free(impulse);
00232 if (impulse_response != NULL)
00233 free(impulse_response);
00234 im_size = kernal_size[i];
00235 impulse = (double *)calloc(sq(im_size), sizeof(double));
00236 impulse_response = (double *)calloc(sq(im_size), sizeof(double));
00237 impulse[((im_size/2)*im_size) + im_size/2] = 1;
00238 gabor_filter(impulse, im_size, i ,0, impulse_response);
00239
00240 sprintf(out_fname, "impulse_%d.pgm", i);
00241 save_norm_double_pgm(impulse, im_size, im_size, out_fname);
00242 sprintf(out_fname, "impulse_response_%d.pgm", i);
00243 save_norm_double_pgm(impulse_response, im_size, im_size, out_fname);
00244 }
00245 }