Project 3: Image Enhancement - Spatial vs. Frequency Domain Filters
Project 3: Image Enhancement - Spatial vs. Frequency Domain Filters
Project 3: Image Enhancement - Spatial vs. Frequency Domain Filters
Frequency
Domain Filters
98+10
Abstract
The purpose of this project is to explore some simple image enhancement algorithms. This project
introduces spatial and frequency domain lters. Thus it involves creating masks, performing convolution, Fourier transforms and inverse Fourier transforms. An in-depth understanding of the
Fourier transform is critical to the understanding of this project.
Discussion
Task 1(10 points)
Below you can see the FFT transforms of a single pixel and of a large square on a 128x128 image.
use logtran
to show
mag image.
-1
As you can see, taking the FFT of a single pixel results in a constant magnitude with a phase
that alternates between two values in a checkerboard pattern.
Below are the 3x3, 5x5, and 7x7 gaussian kernels with sigma = 1.5
need to
show
kernel
values
-1
Figure 4: Guassian Kernel, Gaussian Filtered Image, Median Filtered Image (3x3, 5x5, 7x7)
Subjectively, the Median lter seems to outperform the Gaussian lter with all kernel sizes. The
Gaussian lter seems to make the picture fuzzy, and the Median lter seems to make the picture
seem unnatural or cartoonish. Subjectively, both methods appear to remove the most artifacts with
the smallest degradation with the 5x5 kernel. The Gaussian lter is linear, and thus it becomes
fuzzier as the kernel size increases. The Median lter is nonlinear, and thus it does not become
fuzzier as the kernel size increases. However, it does become more cartoonish looking when the
kernel size increases.
Decreasing the cuto frequency, D_0, in the frequency lter is similar to increasing the size of
the mask with the spatial lter. Below are some spatial and frequency domain comparisons.
Figure 5: Spatial Guassian Filtered Image, Frequency Gaussian Filtered Image, Frequency Butterworth Filter (order =2)(3x3, D_0 = 64; 5x5, D_0 = 32; 7x7, D_0 = 16)
D_0
64
32
16
Gaussian
99.0953
97.6749
94.9893
Butterworth
99.4303
98.1878
95.5876
Table 1: LP Power Ratios
Based on Tasks 2.1 and 2.2, I believe the same results can be acheived from spatial and frequency
lters. However, linear and nonlinear lters cannot be interchanged to acheive the same results.
Task 3 (30 points)
convolution operation while the Sobel edge detector takes two convolution operations.
Below is an unsharp mask with 3x3 and 9x9 kernels respectively.
As you can see, the larger the kernel the wider this edge becomes. While this make it easier for
the human eye to view, it results in a less precise edge.
Below are the Butterworth and Gaussian High Pass Filter results. Butterworth is in the left
column and the cuto frequency, D_0, increases as you go down the column.
Figure 9: Two Sets w/ Three Kernel Sizes: Butterworth(D_0=(10,20,40), order =2) and Gaussian
Edge Detection Results(D_0 = 10,20,40)
As you can see these both produce similar results. The Butterworth seems to have some additional artifacts. The power ratios for these high pass lters are shown below. They are small
because the high-frequency content, the edges, are a small portion of the image.
D_0
Butterworth
Gaussian
40
0.536922
0.44061
20
2.38941
1.92622
10
7.11757
5.96034
Table 2: HP Power Ratios
Below are the results from the spatial domain and the frequency domian along with their difference image.
Spatial
0.08
Freq
1.22
Table 3: Computation Times
Below are the autocorrelation images computed both spatially and in the frequency domain.
10
Spatial
114.7
Freq
0.79
Table 4: Computation Times
For this task, the following image was used to demonstrate Homomorphic ltering.
+10
Discussion
This project reinforced the topics discussed in class. It broadened the students knowledge of the
image enhancement techniques beyond what can be gained just by discussion or reading. It is
especially important to understand the Fourier transform and its eects upon computation time
and how to design lters to accomplish a task.
12
10/03/11
20:27:49
task1.cpp
/********************************************************************
* task1.cpp - Implementation file for task1
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "square.h"
#include "line.h"
#include "Image.h"
#include "Dip.h"
#include <iostream>
#include <cstdlib>
#include <cmath>
// new: for log()
using namespace std;
#define Usage "./task1 ROWS COLS SQUARE_SIZE LINE_LOC LINE_WIDTH\n"
int main(int argc, char **argv)
{
Image inimg, outimg, mag, phase, maglog;
int nr, nc, size_sq, line_loc, line_wid;
int i, j;
// output image
cout << "Write magnitude image ..." << endl;
writeImage(mag, "../output/squaretestmag.pgm", 1);
cout << "Write magnitude image AFTER log transformation ..." << endl;
writeImage(maglog, "../output/squaretestmaglog.pgm", 1);
cout << "Write phase image ..." << endl;
writeImage(phase, "../output/squaretestphase.pgm", 1);
cout << "Write image after inverse Fourier transform ..." << endl;
writeImage(outimg, "../output/squaretestifft.pgm");
// read in image
inimg = line(nr, nc, line_loc, line_wid);
nr = inimg.getRow();
nc = inimg.getCol();
// Fourier transform
fft(inimg, mag, phase);
// magnitude after log transformation
// maglog = logtran(mag);
maglog = inimg;
// new: allocate memory
for (i=0; i<nr; i++)
// new: perform log transformation to compress the dyna
mic range
for (j=0; j<nc; j++)
// new: you should be able to call the logtran() you de
signed in proj2
maglog(i,j) = log(1+fabs(mag(i,j)));
// inverse Fourier transform
ifft(outimg, mag, phase);
if (argc < 6) {
cout << Usage;
exit(3);
}
// output image
cout << "Write magnitude image ..." << endl;
writeImage(mag, "../output/linetestmag.pgm", 1);
cout << "Write magnitude image AFTER log transformation ..." << endl;
writeImage(maglog, "../output/linetestmaglog.pgm", 1);
cout << "Write phase image ..." << endl;
writeImage(phase, "../output/linetestphase.pgm", 1);
cout << "Write image after inverse Fourier transform ..." << endl;
writeImage(outimg, "../output/linetestifft.pgm");
return 0;
// read in image
inimg = square(nr, nc, size_sq);
nr = inimg.getRow();
nc = inimg.getCol();
// allocate memory
mag.createImage(nr, nc);
phase.createImage(nr, nc);
outimg.createImage(nr, nc);
// Fourier transform
fft(inimg, mag, phase);
// magnitude after log transformation
// maglog = logtran(mag);
maglog = inimg;
// new: allocate memory
for (i=0; i<nr; i++)
// new: perform log transformation to compress the dyna
mic range
for (j=0; j<nc; j++)
// new: you should be able to call the logtran() you de
signed in proj2
maglog(i,j) = log(1+fabs(mag(i,j)));
// inverse Fourier transform
ifft(outimg, mag, phase);
10/03/11
20:22:24
/********************************************************************
* task2.cpp - Implementation file for task2_1
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "spatialFilter.h"
#include "Image.h"
#include "Dip.h"
#include <iostream>
#include <cstdlib>
#include <cmath>
// new: for log()
using namespace std;
#define Usage "./task2 INPUT_IMAGE N OUTPUT_IMAGE N_median OUTPUT_median\n"
int main(int argc, char **argv)
{
Image inimg, outimg;
int n, n_m;
if (argc < 6) {
cout << Usage;
exit(3);
}
// Convert Arugments to Integers
n = atoi(argv[2]);
n_m = atoi(argv[4]);
// read in image
inimg = readImage(argv[1]);
// filter image
outimg = gaussianFilter(inimg, n);
// output image
writeImage(outimg, argv[3], 1);
// median filter
outimg = medianFilter(inimg, n_m);
// output median image
writeImage(outimg, argv[5], 1);
return 0;
}
task2.cpp
10/03/11
20:26:39
task2_2.cpp
/********************************************************************
* task2_2.cpp - Implementation file for task2_2
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "freqFilter.h"
#include "Image.h"
#include "Dip.h"
//#include <iostream>
#include <cstdlib>
#include <math.h>
// new: for log()
//using namespace std;
#define Usage "./task2_2 INPUT_IMAGE CUTOFF ORDER OUTPUT_butterworth OUTPUT_gaussia
n\n"
int main(int argc, char **argv)
{
Image inimg, outimg;
int cutoff, order;
if (argc < 6) {
cout << Usage;
exit(3);
}
// Convert Arugments to Integers
cutoff = atoi(argv[2]);
order = atoi(argv[3]);
// read in image
inimg = readImage(argv[1]);
// filter image
outimg = butterworthFilter(inimg, cutoff, order);
// output image
writeImage(outimg, argv[4], 1);
// gaussian filter
outimg = gaussianFilterFreq(inimg, cutoff);
// output median image
writeImage(outimg, argv[5], 1);
return 0;
}
10/03/11
20:26:23
task3_1.cpp
/********************************************************************
* task3_1.cpp - Implementation file for task3_1
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "spatialFilter.h"
#include "Image.h"
#include "Dip.h"
//#include <iostream>
#include <cstdlib>
#include <math.h>
// new: for log()
//using namespace std;
#define Usage "./task3_1 input_image BLUR_AMOUNT output_unsharp output_sobel output
_laplace\n"
int main(int argc, char **argv)
{
Image inimg, outimg;
int mask_size, i, j, nr, nc;
if (argc < 6) {
cout << Usage;
exit(3);
}
// Convert Arugments to Integers
mask_size = atoi(argv[2]);
// read in image
inimg = readImage(argv[1]);
nr = inimg.getRow();
nc = inimg.getCol();
// filter image
outimg = unsharp(inimg, mask_size);
// write image
writeImage(outimg, argv[3], 0);
// sobel filter
outimg = sobelFilt(inimg);
// output sobel
writeImage(outimg, argv[4], 0);
// laplacian filter
outimg = laplacianFilter(inimg);
// output laplace
writeImage(outimg, argv[5], 0);
return 0;
}
10/03/11
20:25:33
task3_2.cpp
/********************************************************************
* task3_2.cpp - Implementation file for task3_2
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "freqFilter.h"
#include "Image.h"
#include "Dip.h"
//#include <iostream>
#include <cstdlib>
#include <math.h>
// new: for log()
//using namespace std;
#define Usage "./task3_2 INPUT_IMAGE CUTOFF ORDER OUTPUT_butterworth OUTPUT_gaussia
n\n"
int main(int argc, char **argv)
{
Image inimg, inimg_raw, outimg, outimg_raw;
int cutoff, order, nr, nc, i, j, sq;
if (argc < 6) {
cout << Usage;
exit(3);
}
// Convert Arugments to Integers
cutoff = atoi(argv[2]);
order = atoi(argv[3]);
// read in image
inimg_raw = readImage(argv[1]);
nr = inimg_raw.getRow();
nc = inimg_raw.getCol();
// pad image for fft
sq = 256;
inimg.createImage(sq,sq);
for(i=0;i<sq;i++){
for(j=0;j<sq;j++){
if(i<nr && j<nc){
inimg(i,j,0)=inimg_raw(i,j,0);
}else{
inimg(i,j,0)=0;
}
}
}
// filter image
outimg = butterworthFilterHP(inimg, cutoff, order);
outimg_raw.createImage(nr,nc);
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
outimg_raw(i,j,0)=outimg(i,j,0);
}
}
// output image
writeImage(outimg_raw, argv[4], 1);
// gaussian filter
outimg = gaussianFilterFreqHP(inimg, cutoff);
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
outimg_raw(i,j,0)=outimg(i,j,0);
}
}
// output median image
writeImage(outimg_raw, argv[5], 1);
return 0;
}
10/03/11
20:25:11
task4.cpp
/********************************************************************
* task4.cpp - Implementation file for task4
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "freqFilter.h"
#include "spatialFilter.h"
#include "Image.h"
#include "Dip.h"
#include "conv.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <math.h>
// new: for log()
using namespace std;
start = clock();
nr = inimg.getRow();
nc = inimg.getCol();
img_flip.createImage(nr,nc);
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
img_flip(i,j,0)=inimg(nr-1-i, nc-1-j,0);
}
}
outimg = conv(inimg, img_flip);
end = clock();
cout << "Spatial Filter(s): " << (end-start)/(double)CLOCKS_PER_SEC << endl;
// output image
writeImage(outimg, argv[4], 1);
// autocorellation freq
start = clock();
outimg = auto_freq(inimg);
end = clock();
cout << "Frequency Filter(s): " << (end-start)/(double)CLOCKS_PER_SEC << endl;
// write image
writeImage(outimg, argv[5], 1);
return 0;
10/03/11
20:28:58
extraCredit.cpp
/********************************************************************
* extraCredit.cpp - Implementation file for extraCredit
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "freqFilter.h"
#include "Image.h"
#include "Dip.h"
//#include <iostream>
#include <cstdlib>
#include <math.h>
//using namespace std;
10/03/11
20:32:42
conv.cpp
/********************************************************************
* conv.cpp - Implementation file for convolution function
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "conv.h"
Image conv(Image input, Image mask){
Image output;
int szr, szc, mask_nr, mask_nc, mrad_r, mrad_c;
int i, j, ii, jj;
szr = input.getRow();
szc = input.getCol();
mask_nr = mask.getRow();
mask_nc = mask.getCol();
mrad_r = mask_nr/2;
mrad_c = mask_nc/2;
output.createImage(szr, szc);
for(i=0;i<szr;i++){
for(j=0;j<szc;j++){
output(i,j,0)=0;
for(ii=0;ii<mask_nr;ii++){
for(jj=0;jj<mask_nc;jj++){
if((i-mrad_r +ii >= 0) && (i-mrad_r +ii < szc) && (j-mrad_c +jj >= 0) &&
(j-mrad_c +jj < szr)){
output(i,j,0) += input(i-mrad_r + ii, j-mrad_c +jj,0) * mask(mask_nr-1ii, mask_nc-1-jj, 0);
}
}
}
}
}
return output;
}
10/03/11
20:32:50
/********************************************************************
* conv.h - Header file for convolution function
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#ifndef LINE_H
#define LINE_H
#include "Image.h"
Image conv(Image, Image);
#endif
conv.h
10/03/11
20:19:28
/********************************************************************
* square.cpp - Implementation file for square
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "square.h"
square.cpp
10/03/11
20:15:24
/********************************************************************
* square.h - Header file for square
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#ifndef SQUARE_H
#define SQUARE_H
#include "Image.h"
Image square(int, int, int);
#endif
square.h
10/03/11
20:18:11
/********************************************************************
* line.cpp - Implementation file for line
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "line.h"
line.cpp
10/03/11
20:13:55
/********************************************************************
* line.h - Header file for line
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#ifndef LINE_H
#define LINE_H
#include "Image.h"
Image line(int, int, int, int);
#endif
line.h
10/03/11
20:29:47
spatialFilter.cpp
/********************************************************************
* spatialFilter.cpp - Implementation file for spatial computations
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
}
return output;
}
Image unsharp(Image inimg, int blur_size){
Image blur, sub_blur;
//blur image
blur = averageFilt(inimg, blur_size);
// Subtract blur
sub_blur = inimg - blur;
#include "spatialFilter.h"
Image gaussianFilter(Image inimg, int n){
Image mask, output;
int i, j, center;
float den, sigma;
// add back
inimg = inimg + (sub_blur*10);
return sub_blur;
}
Image averageFilt(Image inimg, int size){
// allocate memory
mask.createImage(n, n);
sigma = 1.5;
den = 1/(2*PI*sigma*sigma);
center = n/2;
mask.createImage(size,size);
for(i=0;i<size;i++){
for(j=0;j<size;j++){
mask(i,j,0)= 1.0/(size*size);
}
}
// create mask
for(i=0;i<n;i++){
for(j=0;j<n;j++){
mask(i,j,0) = exp(-(abs(center-i)+abs(center-j))/(2*sigma*sigma)) / den;
}
}
return output;
}
mask.createImage(3,3);
Image medianFilter(Image inimg, int n){
Image mask, output;
int nr, nc, i, j, ii, jj, middle;
nr = inimg.getRow();
nc = inimg.getCol();
output.createImage(nr,nc);
// create mask
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
list<int> p_values;
for(ii=max(0,i-n/2);ii<min(nr,i+n/2+1);ii++){
for(jj=max(0,j-n/2);jj<min(nc,j+n/2+1);jj++){
p_values.push_back(inimg(ii,jj,0));
}
}
p_values.sort();
middle = p_values.size()/2;
list<int>::iterator it = p_values.begin();
advance(it,middle);
output(i,j,0) = *it;
}
1;
2;
1;
for(i=0;i<output2.getRow();i++){
for(j=0;j<output2.getCol();j++){
output2(i,j,0) = abs(output2(i,j,0));
}
}
10/03/11
20:29:47
return output + output2;
}
Image laplacianFilter(Image inimg){
Image mask, output;
mask.createImage(3,3);
mask(0,0)= 0; mask(0,1)=-1; mask(0,2) = 0;
mask(1,0)=-1; mask(1,1)= 4; mask(1,2) = -1;
mask(2,0)= 0; mask(2,1)=-1; mask(2,2) = 0;
output = conv(inimg, mask);
return output;
}
spatialFilter.cpp
10/03/11
20:14:20
/********************************************************************
* spatialFilter.h - Header file for spatial computations
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#ifndef SPATIALFILTER_H
#define SPATIALFILTER_H
#include "Image.h"
#include <math.h>
#include "Dip.h"
#include "conv.h"
#include <list>
Image gaussianFilter(Image, int);
Image medianFilter(Image, int);
Image unsharp(Image, int);
Image averageFilt(Image, int);
Image sobelFilt(Image);
Image laplacianFilter(Image);
#endif
spatialFilter.h
10/03/11
20:32:27
freqFilter.cpp
/********************************************************************
* freqFilter.cpp - Implementation file for frequency computations
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#include "freqFilter.h"
cout << "HP Butterworthn PR: " << 100*power/total_power << endl;
// get ifft
ifft(outimg, mag, phase);
// filter
nr = mag.getRow();
nc = mag.getCol();
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
mag(i,j,0) = mag(i,j,0) /(1+pow(cutoff/d2c(nr,nc,i,j),2*order));
}
}
float power = calculatePower(mag);
return outimg;
}
nr = inimg.getRow();
nc = inimg.getCol();
Image gaussianFilterFreq(Image inimg, int cutoff){
// allocate memory
mag.createImage(nr, nc);
phase.createImage(nr, nc);
outimg.createImage(nr, nc);
// get fft
fft(inimg, mag, phase);
float total_power = calculatePower(mag);
// allocate memory
mag.createImage(nr, nc);
phase.createImage(nr, nc);
outimg.createImage(nr, nc);
// filter
nr = mag.getRow();
nc = mag.getCol();
// get fft
fft(inimg, mag, phase);
float total_power = calculatePower(mag);
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
mag(i,j,0) = mag(i,j,0) /(1+pow(d2c(nr,nc,i,j)/cutoff,2*order));
}
}
float power = calculatePower(mag);
// filter
nr = mag.getRow();
nc = mag.getCol();
cout << "LP Butterworthn PR: " << 100*power/total_power << endl;
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
float dist = d2c(nr,nc,i,j);
mag(i,j,0) = mag(i,j,0) * exp(-dist*dist/(2*cutoff*cutoff));
}
}
// get ifft
ifft(outimg, mag, phase);
return outimg;
}
// get ifft
ifft(outimg, mag, phase);
nr = inimg.getRow();
nc = inimg.getCol();
return outimg;
}
// allocate memory
mag.createImage(nr, nc);
phase.createImage(nr, nc);
outimg.createImage(nr, nc);
// get fft
fft(inimg, mag, phase);
10/03/11
20:32:27
freqFilter.cpp
nc = inimg.getCol();
// filter
nr = mag.getRow();
nc = mag.getCol();
// allocate memory
mag.createImage(nr, nc);
phase.createImage(nr, nc);
outimg.createImage(nr, nc);
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
mag(i,j,0) = mag(i,j,0) * mask_mag(i,j,0);
phase(i,j,0) = phase(i,j,0) - mask_phase(i,j,0);
}
}
// get fft
fft(inimg, mag, phase);
float total_power = calculatePower(mag);
// filter
nr = mag.getRow();
nc = mag.getCol();
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
float dist = d2c(nr,nc,i,j);
mag(i,j,0) = mag(i,j,0) *(1 }
}
// get ifft
ifft(outimg, mag, phase);
outimg = subImage(outimg,0,0,nr/2-1, nc/2-1);
return outimg;
}
exp(-dist*dist/(2*cutoff*cutoff)));
nr = inimg.getRow();
nc = inimg.getCol();
in_pad.createImage(2*nr, 2*nc);
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
in_pad(i,j,0)=inimg(i,j,0);
}
}
nr = in_pad.getRow();
nc = in_pad.getCol();
nr = inimg.getRow();
nc = inimg.getCol();
// allocate memory
mag.createImage(nr, nc);
phase.createImage(nr, nc);
outimg.createImage(nr, nc);
magf.createImage(nr, nc);
phasef.createImage(nr, nc);
// get fft
fft(in_pad, mag, phase);
// filter
nr = mag.getRow();
nc = mag.getCol();
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
mag(i,j,0) = mag(i,j,0) * mag(i,j,0);
phase(i,j,0) = 0;
}
}
// get ifft
ifft(outimg, mag, phase);
outimg2.createImage(nr/2, nc/2);
// get fft
fft(img_pad, mag, phase);
fft(mask, mask_mag, mask_phase);
// rearrange image
for(i=0;i<nr/2;i++){
10/03/11
20:32:27
freqFilter.cpp
for(j=0;j<nc/2;j++){
int x = 3*nr/4+i;
int y = 3*nc/4+j;
if(x > nr-1){
x = x - nr;
}
if(y > nc-1){
y = y - nc;
}
outimg2(i,j,0) = outimg(x,y,0);
}
// Calculate Power
float p_t = 0;
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
p_t += mag(i,j,0) * mag(i,j,0);
}
}
return p_t;
}
}
return outimg2;
}
float d2c(int nr, int nc, int x, int y){
float nrf = (float) nr;
float ncf = (float) nc;
float xf = (float) x;
float yf = (float) y;
return sqrt( ((nrf/2)-xf)*((nrf/2)-xf) + ((ncf/2)-yf)*((ncf/2)-yf));
}
Image homomorphic(Image inimg, float c, float gamma_l, float gamma_h, int cutoff){
Image mag, phase, outimg;
int nr, nc, i , j;
nr = inimg.getRow();
nc = inimg.getCol();
// allocate memory
mag.createImage(nr, nc);
phase.createImage(nr, nc);
outimg.createImage(nr, nc);
// get fft
fft(inimg, mag, phase);
// filter
nr = mag.getRow();
nc = mag.getCol();
for(i=0;i<nr;i++){
for(j=0;j<nc;j++){
float dist = d2c(nr,nc,i,j);
mag(i,j,0) = mag(i,j,0) *((gamma_h-gamma_l)*(1 toff)))+gamma_l);
}
}
// get ifft
ifft(outimg, mag, phase);
return outimg;
}
float calculatePower(Image mag){
int i, j, nr, nc;
nr = mag.getRow();
nc = mag.getCol();
exp(-c*dist*dist/(cutoff*cu
10/03/11
20:13:33
/********************************************************************
* freqFilter.h - Header file for frequency computations
*
* Author: Steven Young (syoung22@utk.edu), EECS
*
University of Tennessee
*
* Class: ECE 572 Fall 2011
*
* Created: 10/01/2011
*
* Note:
*
********************************************************************/
#ifndef FREQFILTER_H
#define FREQFILTER_H
#include "Image.h"
#include <math.h>
#include "Dip.h"
#include "conv.h"
#include <list>
Image butterworthFilter(Image, int, int);
Image butterworthFilterHP(Image, int, int);
Image gaussianFilterFreq(Image, int);
Image gaussianFilterFreqHP(Image, int);
Image averageFilterFreq(Image);
Image auto_freq(Image);
float d2c(int, int, int, int);
Image homomorphic(Image, float, float, float, int);
float calculatePower(Image);
#endif
freqFilter.h