首先看个图了解下什么是理想低通滤波器公式和图是转自Rolin的专栏
其中,D0表示通带的半径。D(u,v)的计算方式也就是两点间的距离,很简单就能得到。
使用低通滤波器所得到的结果如下所示。低通滤波器滤除了高频成分,所以使得图像模糊。由于理想低通滤波器的过度特性过于急峻,所以会产生了振铃现象。
同样的,D0表示通带的半径,n表示的是巴特沃斯滤波器的次数。随着次数的增加,振铃现象会越来越明显。
void ideal_Low_Pass_Filter(Mat src){
Mat img;
cvtColor(src, img, CV_BGR2GRAY);
imshow("img",img);
//调整图像加速傅里叶变换
int M = getOptimalDFTSize(img.rows);
int N = getOptimalDFTSize(img.cols);
Mat padded;
copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));
//记录傅里叶变换的实部和虚部
Mat planes[] = { Mat_(padded), Mat::zeros(padded.size(), CV_32F) };
Mat complexImg;
merge(planes, 2, complexImg);
//进行傅里叶变换
dft(complexImg, complexImg);
//获取图像
Mat mag = complexImg;
mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));//这里为什么&上-2具体查看opencv文档
//其实是为了把行和列变成偶数 -2的二进制是11111111.......10 最后一位是0
//获取中心点坐标
int cx = mag.cols / 2;
int cy = mag.rows / 2;
//调整频域
Mat tmp;
Mat q0(mag, Rect(0, 0, cx, cy));
Mat q1(mag, Rect(cx, 0, cx, cy));
Mat q2(mag, Rect(0, cy, cx, cy));
Mat q3(mag, Rect(cx, cy, cx, cy));
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
//Do为自己设定的阀值具体看公式
double D0 = 60;
//处理按公式保留中心部分
for (int y = 0; y < mag.rows; y++){
double* data = mag.ptr(y);
for (int x = 0; x < mag.cols; x++){
double d = sqrt(pow((y - cy),2) + pow((x - cx),2));
if (d <= D0){
}
else{
data[x] = 0;
}
}
}
//再调整频域
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
//逆变换
Mat invDFT, invDFTcvt;
idft(mag, invDFT, DFT_SCALE | DFT_REAL_OUTPUT); // Applying IDFT
invDFT.convertTo(invDFTcvt, CV_8U);
imshow("理想低通滤波器", invDFTcvt);
}
void Butterworth_Low_Paass_Filter(Mat src){
int n = 1;//表示巴特沃斯滤波器的次数
//H = 1 / (1+(D/D0)^2n)
Mat img;
cvtColor(src, img, CV_BGR2GRAY);
imshow("img", img);
//调整图像加速傅里叶变换
int M = getOptimalDFTSize(img.rows);
int N = getOptimalDFTSize(img.cols);
Mat padded;
copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));
Mat planes[] = { Mat_(padded), Mat::zeros(padded.size(), CV_32F) };
Mat complexImg;
merge(planes, 2, complexImg);
dft(complexImg, complexImg);
Mat mag = complexImg;
mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));
int cx = mag.cols / 2;
int cy = mag.rows / 2;
Mat tmp;
Mat q0(mag, Rect(0, 0, cx, cy));
Mat q1(mag, Rect(cx, 0, cx, cy));
Mat q2(mag, Rect(0, cy, cx, cy));
Mat q3(mag, Rect(cx, cy, cx, cy));
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
double D0 = 100;
for (int y = 0; y < mag.rows; y++){
double* data = mag.ptr(y);
for (int x = 0; x < mag.cols; x++){
//cout << data[x] << endl;
double d = sqrt(pow((y - cy), 2) + pow((x - cx), 2));
//cout << d << endl;
double h = 1.0 / (1 + pow(d / D0, 2 * n));
if (h <= 0.5){
data[x] = 0;
}
else{
//data[x] = data[x]*0.5;
//cout << h << endl;
}
//cout << data[x] << endl;
}
}
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
//逆变换
Mat invDFT, invDFTcvt;
idft(complexImg, invDFT, DFT_SCALE | DFT_REAL_OUTPUT); // Applying IDFT
invDFT.convertTo(invDFTcvt, CV_8U);
imshow("巴特沃斯低通滤波器", invDFTcvt);
}