-
Notifications
You must be signed in to change notification settings - Fork 2
/
frequencyfilters.cpp
132 lines (112 loc) · 4.05 KB
/
frequencyfilters.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "frequencyfilters.h"
using namespace std;
using namespace cv;
/*
* function to add gaussian noise to an image
* params : CV::Mat object type image, double mean, double variance
* first we clone the image then we create a gaussian noise and finally we add this noise to the image
*/
// create output image of optimal size - prepare the image for dft
Mat adjustSize(Mat& img)
{
Mat padded;
int rows = getOptimalDFTSize(img.rows);
int cols = getOptimalDFTSize(img.cols);
copyMakeBorder(img, padded, 0, rows - img.rows, 0, cols - img.cols, BORDER_CONSTANT, Scalar::all(0));
return padded;
}
/*
* function to add gaussian noise to an image
* params : CV::Mat object type image, double mean, double variance
* first we clone the image then we create a gaussian noise and finally we add this noise to the image
*/
void fourierShift(Mat& Img)
{
Img = Img(Rect(0, 0, Img.cols & -2, Img.rows & -2));
int cx = Img.cols / 2;
int cy = Img.rows / 2;
// Split image into quadrants
Mat q0(Img, Rect(0, 0, cx, cy));
Mat q1(Img, Rect(cx, 0, cx, cy));
Mat q2(Img, Rect(0, cy, cx, cy));
Mat q3(Img, Rect(cx, cy, cx, cy));
// Swap quadrants
Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
// Swap other quadrants
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
}
/*
* function to add gaussian noise to an image
* params : CV::Mat object type image, double mean, double variance
* first we clone the image then we create a gaussian noise and finally we add this noise to the image
*/
// Convert the image to complex numbers by applying dft
Mat calcDFT(Mat& img) {
// Mat padded = adjustSize(img);
// copy the source image, on the border add zero values
Mat planes[] = { Mat_<float>(img), Mat::zeros(img.size(), CV_32F) };
Mat complex_img;
merge(planes, 2, complex_img);
// create a complex matrix (Fourier transform)
dft(complex_img, complex_img);
fourierShift(complex_img);
return complex_img;
}
/*
* function to add gaussian noise to an image
* params : CV::Mat object type image, double mean, double variance
* first we clone the image then we create a gaussian noise and finally we add this noise to the image
*/
Mat createFilter(Mat& complex_img, float distance, string filterType)
{
Mat filter(complex_img.size(), CV_32F, Scalar(1));
Point center = Point(complex_img.rows / 2, complex_img.cols / 2);
float radius;
for (int i = 0; i < complex_img.rows; i++)
for (int j = 0; j < complex_img.cols; j++)
{
radius = sqrt(pow((i - center.x), 2.0) + pow((j - center.y), 2.0));
if (filterType == "lowpass"){
if (radius > distance)
filter.at<float>(i, j) = 0;
}
else if (filterType == "highpass") {
if (radius < distance)
filter.at<float>(i, j) = 0;
}
}
return filter;
}
/*
* function to add gaussian noise to an image
* params : CV::Mat object type image, double mean, double variance
* first we clone the image then we create a gaussian noise and finally we add this noise to the image
*/
void ifft(Mat& complex_img)
{
fourierShift(complex_img);
dft(complex_img, complex_img, DFT_INVERSE | DFT_REAL_OUTPUT);
normalize(complex_img, complex_img, 0, 1, NORM_MINMAX);
}
/*
* function to add gaussian noise to an image
* params : CV::Mat object type image, double mean, double variance
* first we clone the image then we create a gaussian noise and finally we add this noise to the image
*/
Mat applyFilter(Mat& complex_img, Mat& filter)
{
Mat output_img;
Mat planes_filter[] = { Mat_<float>(filter.clone()), Mat_<float>(filter.clone()) };
Mat planes_dft[] = { Mat_<float>(complex_img), Mat::zeros(complex_img.size(), CV_32F) };
split(complex_img, planes_dft);
Mat planes_out[] = { Mat::zeros(complex_img.size(), CV_32F), Mat::zeros(complex_img.size(), CV_32F) };
planes_out[0] = planes_filter[0].mul(planes_dft[0]);
planes_out[1] = planes_filter[1].mul(planes_dft[1]);
merge(planes_out, 2, output_img);
return output_img;
}