用巴特沃斯高通滤波器对一幅图像进行锐化处理,该过程用自然语言描述为下:
(1)将该图像进行适当的扩充。
(2)对扩充后的图像进行二维傅立叶变换。
(3)将傅立叶变换后的频率域下的值乘以巴特沃斯高通滤波器的滤波函数
(4)将两个相乘的值进行傅立叶反变换,即得到锐化的图像。
ButterWorth高通滤波器的系统函数为
实现的代码如下:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void DFT(Mat &src, Mat &dst)
{
Mat padded;
int m = getOptimalDFTSize(src.rows); //获取最佳DFT变换尺寸
int n = getOptimalDFTSize(src.cols);
copyMakeBorder(src, padded, 0, m - src.rows, 0, n - src.cols, BORDER_CONSTANT, Scalar::all(0));
//填充输入图像src,输出矩阵为padded
Mat planes[] = { Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F) };
Mat complexI;
merge(planes, 2, complexI); //将planes融合合并成一个多通道数组complexI
dft(complexI, complexI); //进行傅立叶变换
dst = complexI;
dst = dst(Rect(0, 0, complexI.cols & -2, complexI .rows & -2));//把行和列变为偶数便于下面获取中心坐标
}
int main()
{
Mat test1,test1_gray;
int n =4;//巴特沃斯滤波器的阶数
test1 = imread("D:\\VCprogress\\Imagework4\\test1.bmp");
Mat img = test1.clone();
cvtColor(img, test1_gray, CV_BGR2GRAY); //傅立叶处理的是灰度图像
//test1_gray.convertTo(test1_gray, CV_64FC1);
Mat mag;
DFT(test1_gray, mag);
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 = 50.0; //巴特沃斯高通滤波器的截至频率
double h;
cout << mag.at<Vec2f>(0,0) << endl;
cout << mag.ptr<float>(0)[1] << endl;
for (int y = 0; y < mag.rows; y++)
{
float* data = mag.ptr<float>(y); //获得mag二维数组的第Y行的第一个元素的地址
//double* res = result[0].ptr<double>(y);
int j = 0;
for (int x = 0; x < mag.cols; x++)
{
double d = sqrt(pow((y - cy), 2) + pow((x - cx), 2)); //求当前像素点离中心点的距离
if (d == 0) h = 0.0;
else h = 1.0 / (1.0 + pow((D0 / d), 2 * n)); //计算巴特沃斯高通滤波器的系统函数
data[x + j] = data[x] * h;
data[x + j + 1] = data[x + j + 1] * h; //将图像的傅立叶函数值与滤波器函数相乘
j += 1;
}
}
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); // 傅立叶反变换
Mat direct_rui;
invDFT.convertTo(direct_rui, CV_8U);
Mat show(direct_rui, Rect(0, 0, test1_gray.cols, test1_gray.rows));
namedWindow("原始图像");
imshow("原始图像", test1_gray);
namedWindow("锐化后的图像");
imshow("锐化处理图像", show);
imwrite("锐化处理后的图像.jpg", show);
Mat dst;
threshold(invDFT, dst, 0,255, 0);
dst.convertTo(invDFTcvt, CV_8U);
;
Mat ruihua(invDFTcvt,Rect(0, 0, test1_gray.cols, test1_gray.rows));
imshow("阈值处理后的图像", ruihua);
imwrite("阈值处理后的图像.jpg", ruihua);
waitKey(0);
}
原始图像如下:
锐化处理后的图像:
阈值处理后的图像: