#define USE_FFTW_DLL #include #include "common.h" #include "fftw.h" // Function to display the Fourier Transform Image_data * FourierTransform(Image_data *piData) { int i; Image_data *pproData; fftwnd_plan plan; int width, height; double magme; float *magnitude; FFTW_COMPLEX *in; FFTW_COMPLEX *out; width = piData->n_cols; height = piData->n_rows; in = calloc(width*height,sizeof(FFTW_COMPLEX)); out = calloc(width*height,sizeof(FFTW_COMPLEX)); magnitude = calloc(width*height,sizeof(float)); // ----------- Memory allocation stuff --------------// pproData = malloc(sizeof(Image_data)); pproData->image_G_ptr = malloc(piData->n_rows * piData->n_cols); pproData->n_cols = piData->n_cols; pproData->n_rows = piData->n_rows; lstrcpy(pproData->filename, "Fourier Transform"); // -------------------------------------------------// plan = fftw2d_create_plan(height, width, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_USE_WISDOM); if (plan==NULL) { MessageBox(0, "Error Creating Plan", "", MB_OK); return NULL; } // Fill in the 'in' array with intensity values for (i=0; i < width*height; i++) { c_re(in[i]) = (int)piData->image_G_ptr[i]; c_im(in[i])=0; } fftwnd(plan,1,in,1,0,out,1,0); // Scale the transform so that it becomes visible for (i=0; i < width*height; i++) { magme = sqrt(c_re(out[i])*c_re(out[i]) + c_im(out[i])*c_im(out[i])); magme = magme / 100.0; if (magme > 255.0) magme = 255.0; pproData->image_G_ptr[i]=(unsigned char)(magme); } // Free up allocated memory fftwnd_destroy_plan(plan); fftw_free(in); fftw_free(out); free(magnitude); return pproData; } // The Low Pass Filter implementation Image_data * LowPass(Image_data *piData, int x, int y) { int i; Image_data *pproData; fftwnd_plan plan; int width, height; double magme, scale=0; double threshold, d1, d2, d3, d4; FFTW_COMPLEX *in; FFTW_COMPLEX *out; width = piData->n_cols; height = piData->n_rows; in = calloc(width*height,sizeof(FFTW_COMPLEX)); out = calloc(width*height,sizeof(FFTW_COMPLEX)); // ----------- Memory allocation stuff --------------// pproData = malloc(sizeof(Image_data)); pproData->image_G_ptr = malloc(piData->n_rows * piData->n_cols); pproData->n_cols = piData->n_cols; pproData->n_rows = piData->n_rows; lstrcpy(pproData->filename, "Low Passed Image"); // -------------------------------------------------// plan = fftw2d_create_plan(height, width, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_USE_WISDOM); if (plan==NULL) { MessageBox(0, "Error Creating Plan", "", MB_OK); return NULL; } // Fill 'in' array with intensity values of the pixels for (i=0; i < width*height; i++) { c_re(in[i]) = (int)piData->image_G_ptr[i]; c_im(in[i])=0; } fftwnd(plan,1,in,1,0,out,1,0); // Compute transform fftwnd_destroy_plan(plan); // Compute the threshold which the the shortest distance // to any of the 4 corners if ((xheight/2)) // bottom left quadrant threshold = sqrt(x*x + (height-y)*(height-y)); else if ((x>width/2) && (y threshold) && (d2 > threshold) && (d3 > threshold) && (d4 > threshold)) { c_re(out[y*width+x]) = 0.0; c_im(out[y*width+x]) = 0.0; } } plan = fftw2d_create_plan(height, width, FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_USE_WISDOM); if (plan == NULL) { MessageBox(0, "Error Creating Plan", "", MB_OK); return NULL; } fftwnd(plan,1,out,1,0,in,1,0); // Inverse Transform scale = c_re(in[0]); // Compute appropriate scale for (i=0; i < width*height; i++) { if (scale < c_re(in[i])) scale = c_re(in[i]); } // Retrieve pixel values from inverse transform for (i=0; i < width*height; i++) { magme = sqrt(c_re(in[i])*c_re(in[i]) + c_im(in[i])*c_im(in[i])); pproData->image_G_ptr[i]=(unsigned char)((magme/scale)*255.0); } // Free up allocated memory fftwnd_destroy_plan(plan); fftw_free(in); fftw_free(out); return pproData; } // The High Pass Filter implementation Image_data * HighPass(Image_data *piData, int x, int y) { int i, j; Image_data *pproData; fftwnd_plan plan; int width, height; double magme, scale=0; double threshold, d1, d2, d3, d4; FFTW_COMPLEX *in; FFTW_COMPLEX *out; width = piData->n_cols; height = piData->n_rows; in = calloc(width*height,sizeof(FFTW_COMPLEX)); out = calloc(width*height,sizeof(FFTW_COMPLEX)); // ----------- Memory allocation stuff --------------// pproData = malloc(sizeof(Image_data)); pproData->image_G_ptr = malloc(piData->n_rows * piData->n_cols); pproData->n_cols = piData->n_cols; pproData->n_rows = piData->n_rows; lstrcpy(pproData->filename, "High Passed Image"); // -------------------------------------------------// plan = fftw2d_create_plan(height, width, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_USE_WISDOM); if (plan == NULL) { MessageBox(0, "Error Creating Plan", "", MB_OK); return NULL; } // Fill 'in' array with pixel intensiy values for (i=0; i < width*height; i++) { c_re(in[i]) = (int)piData->image_G_ptr[i]; c_im(in[i])=0; } fftwnd(plan,1,in,1,0,out,1,0); // Compute transform fftwnd_destroy_plan(plan); // Compute the threshold which the the shortest distance // to any of the 4 corners if ((xheight/2)) // bottom left quadrant threshold = sqrt(x*x + (height-y)*(height-y)); else if ((x>width/2) && (yimage_G_ptr[i]=(unsigned char)((magme/scale)*255.0); } // Free up allocated memory fftwnd_destroy_plan(plan); fftw_free(in); fftw_free(out); return pproData; } // Function to execute High Pass on certain area of image Image_data * LocalHighPass(Image_data *piData, int startx, int starty, int endx, int endy, int x, int y) { Image_data *ptempData, *psubimage, *pproData; int i, j, k, width, height; width = piData->n_cols; height = piData->n_rows; if (startx > endx) // If endx < startx, swap them, otherwise for loop will fail { i = startx; startx = endx; endx = i; } if (starty > endy) // If endy < starty, swap them, otherwise for loop will fail { i = starty; starty = endy; endy = i; } // ----------- Memory allocation stuff --------------// pproData = malloc(sizeof(Image_data)); pproData->image_G_ptr = malloc(width * height); memcpy(pproData->image_G_ptr, piData->image_G_ptr, width*height); pproData->n_cols = piData->n_cols; pproData->n_rows = piData->n_rows; lstrcpy(pproData->filename, "High Passed (Local)"); psubimage = malloc(sizeof(Image_data)); psubimage->image_G_ptr = malloc((endx-startx) * (endy-starty)); psubimage->n_cols = endx-startx; psubimage->n_rows = endy-starty; lstrcpy(psubimage->filename, "Subimage"); //---------------------------------------------------// // Create a subimage to pass to the HighPass() function k = 0; for (j = starty; j < endy; j++) for (i = startx; i < endx; i++) { psubimage->image_G_ptr[k] = piData->image_G_ptr[j*width + i]; ++k; } ptempData = HighPass(psubimage, x, y); // Superimpose processed subimage on the original image k = 0; for (j = starty; j < endy; j++) for (i = startx; i < endx; i++) { pproData->image_G_ptr[j*width + i] = ptempData->image_G_ptr[k]; ++k; } // Free up allocated memory free(psubimage->image_G_ptr); free(psubimage); free(ptempData->image_G_ptr); free(ptempData); return pproData; } // Function to execute Low Pass on certain area of image Image_data * LocalLowPass(Image_data *piData, int startx, int starty, int endx, int endy, int x, int y) { Image_data *ptempData, *psubimage, *pproData; int i, j, k, width, height; width = piData->n_cols; height = piData->n_rows; if (startx > endx) // If endx < startx, swap them, otherwise for loop will fail { i = startx; startx = endx; endx = i; } if (starty > endy) // If endy < starty, swap them, otherwise for loop will fail { i = starty; starty = endy; endy = i; } // ----------- Memory allocation stuff --------------// pproData = malloc(sizeof(Image_data)); pproData->image_G_ptr = malloc(width * height); memcpy(pproData->image_G_ptr, piData->image_G_ptr, width*height); pproData->n_cols = piData->n_cols; pproData->n_rows = piData->n_rows; lstrcpy(pproData->filename, "High Passed (Local)"); psubimage = malloc(sizeof(Image_data)); psubimage->image_G_ptr = malloc((endx-startx) * (endy-starty)); psubimage->n_cols = endx-startx; psubimage->n_rows = endy-starty; lstrcpy(psubimage->filename, "Subimage"); //----------------------------------------------------// // Create a subimage to pass to the LowPass() function k = 0; for (j = starty; j < endy; j++) for (i = startx; i < endx; i++) { psubimage->image_G_ptr[k] = piData->image_G_ptr[j*width + i]; ++k; } ptempData = LowPass(psubimage, x, y); // Superimpose processed subimage on the original image k = 0; for (j = starty; j < endy; j++) for (i = startx; i < endx; i++) { pproData->image_G_ptr[j*width + i] = ptempData->image_G_ptr[k]; ++k; } // Free up allocated memory free(psubimage->image_G_ptr); free(psubimage); free(ptempData->image_G_ptr); free(ptempData); return pproData; }