频域滤波

内容

  • 利用理想高通和低通滤波器对灰度图像进行频域滤波

  • 利用布特沃斯高通和低通滤波器对灰度图像进行频域滤波

频谱图展示

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
void showFrequencySpectrum(const Mat& srcImg, string name) {
Mat srcImage = srcImg.clone();
// 虚部初始化为0
Mat dft_planes[] = { Mat_<float>(srcImage), Mat::zeros(srcImage.size(), CV_32F) };

// dft转换
Mat dft_input;
merge(dft_planes, 2, dft_input);

Mat dft_output;
dft(dft_input, dft_output);

// 分离实部和虚部
split(dft_output, dft_planes);

// 计算幅度谱
Mat frequency_spectrum;
magnitude(dft_planes[0], dft_planes[1], frequency_spectrum);

// 对数变换以增强可视性
frequency_spectrum += Scalar::all(1);
log(frequency_spectrum, frequency_spectrum);
normalize(frequency_spectrum, frequency_spectrum, 0, 1, NORM_MINMAX);

// 中心化
centerMat(frequency_spectrum);

// 显示幅度谱
imshow(name+" Frequency Spectrum", frequency_spectrum);
frequency_spectrum.convertTo(frequency_spectrum, CV_8UC1, 255.0);
imwrite(name + "_frequency_spectrum.jpg", frequency_spectrum);
}

中心化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void centerMat(Mat& scrMat) {
int rows = scrMat.rows;
int cols = scrMat.cols;
int centerRow = rows / 2;
int centerCol = cols / 2;

Mat q0(scrMat, Rect(0, 0, centerRow, centerCol)); // 左上区域
Mat q1(scrMat, Rect(centerRow, 0, centerRow, centerCol)); // 右上区域
Mat q2(scrMat, Rect(0, centerCol, centerRow, centerCol)); // 左下区域
Mat q3(scrMat, Rect(centerRow, centerCol, centerRow, centerCol)); // 右下区域
Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
}

理想低通滤波

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
void idealLowpassFilter(const Mat& srcImage, Mat& dstImage, const double cutoffFrequency) {
int channels = srcImage.channels();
vector<Mat> srcImage_planes(channels);
vector<Mat> dstImage_planes(channels);
split(srcImage, srcImage_planes);
for (int c = 0; c < srcImage.channels(); c++) {
int rows = srcImage_planes[c].rows;
int cols = srcImage_planes[c].cols;
int centerRow = rows / 2;
int centerCol = cols / 2;

// 虚部初始化为0
Mat dft_planes[] = { Mat_<float>(srcImage_planes[c]), Mat::zeros(srcImage_planes[c].size(), CV_32F) };

// dft转换
Mat dft_input;
merge(dft_planes, 2, dft_input);

Mat dft_output;
dft(dft_input, dft_output);

// 分离实部和虚部
split(dft_output, dft_planes);

// 计算幅度谱
Mat frequency_spectrum;
magnitude(dft_planes[0], dft_planes[1], frequency_spectrum);

// 对数变换以增强可视性
//frequency_spectrum += Scalar::all(1);
//log(frequency_spectrum, frequency_spectrum);
//normalize(frequency_spectrum, frequency_spectrum, 0, 1, NORM_MINMAX);

// 中心化
centerMat(frequency_spectrum);
centerMat(dft_planes[0]); // real
centerMat(dft_planes[1]); // imaginary

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// 计算到中心的距离
double distance = std::sqrt(std::pow(i - centerRow, 2) + std::pow(j - centerCol, 2));

// 如果距离大于截止频率,传递函数为0
if (distance > cutoffFrequency) {
dft_planes[0].at<float>(i, j) = 0; // real
dft_planes[1].at<float>(i, j) = 0; // imaginary
}
}
}

// idft转换
Mat idft_input;
merge(dft_planes, 2, idft_input);

Mat idft_output;
idft(idft_input, idft_output);

// 分离实部和虚部
Mat idft_planes[] = { Mat::zeros(dft_output.size(), CV_32F), Mat::zeros(dft_output.size(), CV_32F) };
split(idft_output, idft_planes);

magnitude(idft_planes[0], idft_planes[1], dstImage_planes[c]);
normalize(dstImage_planes[c], dstImage_planes[c], 0, 1, NORM_MINMAX);
}
merge(dstImage_planes, dstImage);
}

理想低通滤波效果

滤波前(r=100) 滤波后(r=100)
grayImg gray_ilpf
频谱图 频谱图
gray_frequency_spectrum gray_ilpf_frequency_spectrum
彩色 彩色(存在振铃效应)
colorImg color_ilpf

理想高通滤波

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
void idealHighpassFilter(const Mat& srcImage, Mat& dstImage, const double cutoffFrequency) {
int channels = srcImage.channels();
vector<Mat> srcImage_planes(channels);
vector<Mat> dstImage_planes(channels);
split(srcImage, srcImage_planes);
for (int c = 0; c < srcImage.channels(); c++) {
int rows = srcImage_planes[c].rows;
int cols = srcImage_planes[c].cols;
int centerRow = rows / 2;
int centerCol = cols / 2;

// 虚部初始化为0
Mat dft_planes[] = { Mat_<float>(srcImage_planes[c]), Mat::zeros(srcImage_planes[c].size(), CV_32F) };

// dft转换
Mat dft_input;
merge(dft_planes, 2, dft_input);

Mat dft_output;
dft(dft_input, dft_output);

// 分离实部和虚部
split(dft_output, dft_planes);

// 计算幅度谱
Mat frequency_spectrum;
magnitude(dft_planes[0], dft_planes[1], frequency_spectrum);

// 对数变换以增强可视性
frequency_spectrum += Scalar::all(1);
log(frequency_spectrum, frequency_spectrum);
normalize(frequency_spectrum, frequency_spectrum, 0, 1, NORM_MINMAX);

// 中心化
centerMat(frequency_spectrum);
centerMat(dft_planes[0]); // real
centerMat(dft_planes[1]); // imaginary

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// 计算到中心的距离
double distance = std::sqrt(std::pow(i - centerRow, 2) + std::pow(j - centerCol, 2));

// 如果距离小于截止频率,传递函数为0
if (distance < cutoffFrequency) {
dft_planes[0].at<float>(i, j) = 0; // real
dft_planes[1].at<float>(i, j) = 0; // imaginary
}
}
}

// idft转换
Mat idft_input;
merge(dft_planes, 2, idft_input);

Mat idft_output;
idft(idft_input, idft_output);

// 分离实部和虚部
Mat idft_planes[] = { Mat::zeros(dft_output.size(), CV_32F), Mat::zeros(dft_output.size(), CV_32F) };
split(idft_output, idft_planes);

magnitude(idft_planes[0], idft_planes[1], dstImage_planes[c]);
normalize(dstImage_planes[c], dstImage_planes[c], 0, 1, NORM_MINMAX);
}
merge(dstImage_planes, dstImage);
}

理想高通滤波效果

滤波前(r=20) 滤波后(r=20)
grayImg gray_ihpf
频谱图 频谱图
gray_frequency_spectrum gray_ihpf_frequency_spectrum
彩色 彩色
colorImg color_ihpf

巴特沃斯低通滤波

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
void butterworthLowpassFilter(const Mat& srcImage, Mat& dstImage, const double cutoffFrequency, const int order) {
int channels = srcImage.channels();
vector<Mat> srcImage_planes(channels);
vector<Mat> dstImage_planes(channels);
split(srcImage, srcImage_planes);
for (int c = 0; c < srcImage.channels(); c++) {
int rows = srcImage_planes[c].rows;
int cols = srcImage_planes[c].cols;
int centerRow = rows / 2;
int centerCol = cols / 2;

// 虚部初始化为0
Mat dft_planes[] = { Mat_<float>(srcImage_planes[c]), Mat::zeros(srcImage_planes[c].size(), CV_32F) };

// dft转换
Mat dft_input;
merge(dft_planes, 2, dft_input);

Mat dft_output;
dft(dft_input, dft_output);

// 分离实部和虚部
split(dft_output, dft_planes);

// 计算幅度谱
Mat frequency_spectrum;
magnitude(dft_planes[0], dft_planes[1], frequency_spectrum);

// 对数变换以增强可视性
frequency_spectrum += Scalar::all(1);
log(frequency_spectrum, frequency_spectrum);
normalize(frequency_spectrum, frequency_spectrum, 0, 1, NORM_MINMAX);

// 中心化
centerMat(frequency_spectrum);
centerMat(dft_planes[0]); // real
centerMat(dft_planes[1]); // imaginary

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// 计算到中心的距离
double distance = std::sqrt(std::pow(i - centerRow, 2) + std::pow(j - centerCol, 2));

// 计算传递函数
double transferFunction = 1 / (1 + std::pow(distance / cutoffFrequency, 2 * order));

// 乘以传递函数
dft_planes[0].at<float>(i, j) *= transferFunction; // real
dft_planes[1].at<float>(i, j) *= transferFunction; // imaginary
}
}

// idft转换
Mat idft_input;
merge(dft_planes, 2, idft_input);

Mat idft_output;
idft(idft_input, idft_output);

// 分离实部和虚部
Mat idft_planes[] = { Mat::zeros(dft_output.size(), CV_32F), Mat::zeros(dft_output.size(), CV_32F) };
split(idft_output, idft_planes);

magnitude(idft_planes[0], idft_planes[1], dstImage_planes[c]);
normalize(dstImage_planes[c], dstImage_planes[c], 0, 1, NORM_MINMAX);
}
merge(dstImage_planes, dstImage);

}

巴特沃斯低通滤波效果

滤波前(r=100,n=2) 滤波后(r=100,n=2)
grayImg gray_blpf
频谱图 频谱图
gray_frequency_spectrum gray_blpf_frequency_spectrum
彩色 彩色
colorImg color_blpf

巴特沃斯高通滤波

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
void butterworthHighpassFilter(const Mat& srcImage, Mat& dstImage, const double cutoffFrequency, const int order) {
int channels = srcImage.channels();
vector<Mat> srcImage_planes(channels);
vector<Mat> dstImage_planes(channels);
split(srcImage, srcImage_planes);
for (int c = 0; c < srcImage.channels(); c++) {
int rows = srcImage_planes[c].rows;
int cols = srcImage_planes[c].cols;
int centerRow = rows / 2;
int centerCol = cols / 2;

// 虚部初始化为0
Mat dft_planes[] = { Mat_<float>(srcImage_planes[c]), Mat::zeros(srcImage_planes[c].size(), CV_32F) };

// dft转换
Mat dft_input;
merge(dft_planes, 2, dft_input);

Mat dft_output;
dft(dft_input, dft_output);

// 分离实部和虚部
split(dft_output, dft_planes);

// 计算幅度谱
Mat frequency_spectrum;
magnitude(dft_planes[0], dft_planes[1], frequency_spectrum);

// 对数变换以增强可视性
frequency_spectrum += Scalar::all(1);
log(frequency_spectrum, frequency_spectrum);
normalize(frequency_spectrum, frequency_spectrum, 0, 1, NORM_MINMAX);

// 中心化
centerMat(frequency_spectrum);
centerMat(dft_planes[0]); // real
centerMat(dft_planes[1]); // imaginary

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// 计算到中心的距离
double distance = std::sqrt(std::pow(i - centerRow, 2) + std::pow(j - centerCol, 2));

// 计算传递函数
double transferFunction = 1 / (1 + std::pow(cutoffFrequency / distance, 2 * order));

// 乘以传递函数
dft_planes[0].at<float>(i, j) *= transferFunction; // real
dft_planes[1].at<float>(i, j) *= transferFunction; // imaginary
}
}

// idft转换
Mat idft_input;
merge(dft_planes, 2, idft_input);

Mat idft_output;
idft(idft_input, idft_output);

// 分离实部和虚部
Mat idft_planes[] = { Mat::zeros(dft_output.size(), CV_32F), Mat::zeros(dft_output.size(), CV_32F) };
split(idft_output, idft_planes);

magnitude(idft_planes[0], idft_planes[1], dstImage_planes[c]);
normalize(dstImage_planes[c], dstImage_planes[c], 0, 1, NORM_MINMAX);
}
merge(dstImage_planes, dstImage);

}

巴特沃斯高通滤波效果

滤波前(r=20,n=2) 滤波后(r=20,n=2)
grayImg gray_bhpf
频谱图 频谱图
gray_frequency_spectrum gray_bhpf_frequency_spectrum
彩色 彩色
colorImg color_bhpf