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
00013
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
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
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
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;
00090
00091 for (x = 0; x < kernal_size[i]; x++) {
00092
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
00110 if (kernel11 == NULL)
00111 create_filter_kernels();
00112
00113 conv = (double *)calloc(width*height, sizeof(double));
00114
00115
00116 for (x = 0; x < width; x++) {
00117 for (y = 0; y < height; y++) {
00118 output[y*width + x] = 0;
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
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
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
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
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
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
00224 if ((the_error = rgb2hsv_ppm(im_rgb, &im_hsv)) != PPM_OK) {
00225 ppm_handle_error(the_error);
00226 exit(1);
00227 }
00228
00229
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
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
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 }