基于opencv的理想低通滤波器和巴特沃斯低通滤波器

来源:互联网 发布:淘宝客里的dw教程 编辑:程序博客网 时间:2024/04/28 10:09

首先看个图了解下什么是理想低通滤波器公式和图是转自Rolin的专栏

低通滤波器


        1.理想的低通滤波器


       其中,D0表示通带的半径。D(u,v)的计算方式也就是两点间的距离,很简单就能得到。

       使用低通滤波器所得到的结果如下所示。低通滤波器滤除了高频成分,所以使得图像模糊。由于理想低通滤波器的过度特性过于急峻,所以会产生了振铃现象。


        2.巴特沃斯低通滤波器

       同样的,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_<float>(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<double>(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 IDFTinvDFT.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_<float>(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<double>(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 IDFTinvDFT.convertTo(invDFTcvt, CV_8U);imshow("巴特沃斯低通滤波器", invDFTcvt);}


                                             
0 0
原创粉丝点击