精华内容
下载资源
问答
  • 巴特沃斯高通滤波器

    2014-06-04 21:38:43
    图像增强方面的巴特沃斯高通滤波器的C语言代码,有助于图像增强方面的研究,但是需要opencv的支持
  • 频域滤波巴特沃斯高通滤波器
  • 2、巴特沃斯高通滤波器 传递函数: 巴特沃斯低通滤波器 传递函数: 描述:在公式中,D(u,v)代表频域当中,点(u,v)到中心点的距离。而D0就是截止距离了,就相当于在频域当中画一个圈,对圈内或者圈外...

    一、目标:

    1. 对lena图像采用高频强调滤波增强方法,并分析方法的效果。(理想、巴特沃斯、高斯)。其结果好不好?能否有改善的方法?

     

    二、函数分析:

    1、高斯高通滤波器

    传递函数:

     

    高斯低通滤波器

    传递函数:

    D0指截止频率。

     

    2、巴特沃斯高通滤波器

        传递函数:

     

    巴特沃斯低通滤波器

    传递函数:

    描述:在公式中,D(u,v)代表频域当中,点(u,v)到中心点的距离。而D0就是截止距离了,就相当于在频域当中画一个圈,对圈内或者圈外保留就可以达到所谓的低通和高通了,这个D0就相当于一维当中的截止频率

     

    3、高频强调滤波方法

        传递函数:

       Hhfe(u,v) = a + bHhp(u,v)

    描述:加入一个偏移量同时乘以一个大于1的常数,使用原图像中的一部分低频分量进入高频区域,而在高频滤波后被保留下来,从而不仅保持一些光滑区域灰度,又使边缘得到增强,而且整幅图像的层次也较丰富,不那么昏暗了。

    总的来说高频强调滤波方法是保留了高频分量的同时,加入了背景的低频分量。

     

    三、代码展示:

    % 1、对lena图像采用高频强调滤波增强方法,
    %    并分析方法的效果。(理想、巴特沃斯、高斯)
    %    其结果好不好?能否有改善的方法?
    %
    % @author: jackma
    % @time:   2020-10-19 10:15
    % @URL:    www.jackrma.com
    % @Copyright:博客所有权归本人和CSDN所有,如有转载请在显著位置给出博文
    %            链接和作者姓名,否则本人将付诸法律。
    % @edit:   
    
    % 1. Lena图像采用高频强调滤波增强方法
    clc
    clear
    imgrgb = imread('x.jpg'); %读取彩色图像
    f = rgb2gray(imgrgb); %将rgb图像转换成灰度图像
    subplot(2, 2, 1);
    imshow(f)
    title('原始图像')
    
    %高斯高通滤波
    I = double(f);
    g = fft2(I);%二维傅立叶变换
    g = fftshift(g);%频移
    [M, N] = size(g);
    D0 = 5;%截止频率为5
    m = fix(M / 2); n = fix(N / 2);
    
    for i = 1:M
    
        for j = 1:N
            D = sqrt((i - m)^2 + (j - n)^2);
            H = exp(-(D.^2) ./ (2 * (D0^2)));
            result(i, j) = (1 - H) * g(i, j);
        end
    
    end
    
    result = ifftshift(result);
    J1 = ifft2(result);
    J2 = uint8(real(J1));
    subplot(2, 2, 2);
    imshow(J2)
    title('高斯高通滤波后的图像')
    
    %高频强调滤波
    F = 0.5 + 0.75 * (1 - H);
    G = F * g;
    result2 = ifftshift(G);
    J3 = ifft2(result2);
    J4 = uint8(real(J3));
    subplot(2, 2, 3)
    imshow(J4)
    title('高频强调滤波后的图像')
    
    %对高频强调滤波后图像进行直方图均衡化
    J5 = histeq(J4, 256);
    J5 = uint8(J5);
    subplot(2, 2, 4);
    imshow(J5)
    title('直方图均衡化后的图像')
    
    %%%%%巴特沃斯高通滤波
    figure('Name', '图像加入巴特沃斯高通滤波'); %标题
    [M, N] = size(f);
    a = fft2(f);
    a = fftshift(a);
    m1 = fix(M / 2); n1 = fix(N / 2);
    
    for u = 1:M
    
        for v = 1:N
            D1 = sqrt((u - m1)^2 + (v - n1)^2);
    
            if D1 == 0
                H1(u, v) = 0;
            else
                %    H(u,v)=1/(1+0.414*(500/D1)^4);%截至频率为500
                H1(u, v) = 1 / (1 + (500 / D1)^4); %2阶巴特沃斯高通滤波器,截至频率为500
            end
    
        end
    
    end
    
    F1 = H1 .* a;
    F1 = ifftshift(F1);
    I2 = abs(ifft2(F1));
    subplot(2, 2, 1);
    imshow(f)
    title('原始图像')
    subplot(2, 2, 2);
    imshow(I2)
    title('巴特沃斯高通滤波后的图像')
    
    %高频强调滤波
    FF = 0.5 + 0.75 * (1 - H1);
    G1 = FF .* a;
    result3 = ifftshift(G1);
    J8 = ifft2(result3);
    J9 = uint8(real(J8));
    subplot(2, 2, 3)
    imshow(J9)
    title('高频强调滤波后的图像')
    
    %对高频强调滤波后图像进行直方图均衡化
    J10 = histeq(J9, 256);
    J10 = uint8(J10);
    subplot(2, 2, 4);
    imshow(J10)
    title('直方图均衡化后的图像')
    

    四、结果展示及分析:

    图1 原始灰度图像和高斯高通滤波的图像,使用高频强调滤波增强图像

    图2 原始灰度图像和巴特沃斯高通滤波的图像,使用高频强调滤波增强图像

    显然通过图像对比可得,高频强调滤波增强和直方图均衡化效果远比高斯高通滤波和巴特沃斯高通滤波效果好,背景更加清晰。

    展开全文
  • 巴特沃斯高通滤波器对一幅图像进行锐化处理,该过程用自然语言描述为下: (1)将该图像进行适当的扩充。 (2)对扩充后的图像进行二维傅立叶变换。 (3)将傅立叶变换后的频率域下的值乘以巴特沃斯高通滤波器...

    用巴特沃斯高通滤波器对一幅图像进行锐化处理,该过程用自然语言描述为下:

    (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);  
    }

    原始图像如下:

    锐化处理后的图像:


    阈值处理后的图像:


    展开全文
  • 长江大学 毕业设计开题报告 题 目 名 称 基于Matlab的数字高通滤波器设计 院 系 电子信息学院 专 业 班 级 电子信息工程 学 生 姓 名 指 导 教 师 辅 导 教 师 开题报告日期 2014年3月15日 一题目来源 随着信息时代...
  • matlab巴特沃斯高通滤波器

    万次阅读 2018-05-28 20:38:55
    I1=imread('原图.jpg'); figure(1);imshow(I1); title('原图'); m=double(I1); f=fft2(m); f=fftshift(f); [N1,N2]=size(f);...title('巴特沃斯高通滤波d0=10');...imwrite(B,'巴特沃斯高通滤波d0=10.jpg')
    I1=imread('原图.jpg');
    figure(1);imshow(I1);
    title('原图');
    m=double(I1);
    f=fft2(m);
    f=fftshift(f);
    [N1,N2]=size(f);
    n1=round(N1/2);
    n2=round(N2/2);
    n=2;d0=10;
    for i=1:N1
        for j=1:N2
            d=sqrt((i-n1)^2+(j-n2)^2);
            h=(1/(1+(d0/d)^(2*n)))+0.5;
            y(i,j)=h*f(i,j);
        end
    end
    y=ifftshift(y);
    A=ifft2(y);
    B=uint8(real(A));
    figure(2);imshow(B);
    title('巴特沃斯高通滤波d0=10');
    imwrite(B,'巴特沃斯高通滤波d0=10.jpg')

    展开全文
  • 想对读入的数组数据进行过高通滤波,想找一段四阶的高通巴特沃斯基于MFC的源码,请大家帮帮忙啦~
  • 武汉理工大学MATLAB 武汉理工大学MATLAB原理与应用课程设计说明书 ...2 数字信号处理与图像处理基础知识 3 双线性变换法的原理和算法 4 巴特沃斯高通滤波器的性能指标 要求完成的主要任务:包括课程设计工作量及技术要求
  • 此报告重点介绍了用双线性不变法设计IIR数字滤波器的基本流程,比较了各种设计方法...最后以双线性不变法设计了一个高通巴特沃斯IIR数字滤波器,介绍了设计步骤,然后在Matlab环境下进行了仿真与调试,实现了设计目标。
  • 利用MATLAB仿真软件系统结合双线性变换法设计一个数字巴特沃斯高通IIR滤波器
  • Matlab 课程设计任务书 学生姓名 管行 专业班级 通信0606 指导教师王晟 工作单位 信息工程学院 题 目: 利用MATLAB 仿真软件系统结合双线性变换法设计一个数字巴特沃斯 高通IIR 滤波器 基础强化训练目的 1理论目的 ...
  • PAGE PAGE 1 Matlab课程设计任务书 学生姓名 管行 专业班级 通信0606 指导教师王晟 工作单位 信息工程学院 题 目: 利用MATLAB仿真软件系统结合双线性变换法设计一个数字巴特沃斯高通IIR滤波器 基础强化训练目的 1...
  • 此报告重点介绍了用双线性不变法设计IIR数字滤波器的基本流程,比较了各种设计方法...最后以双线性不变法设计了一个高通巴特沃斯IIR数字滤波器,介绍了设计步骤,然后在Matlab环境下进行了仿真与调试,实现了设计目标。
  • 武汉理工大学数字信号处理报告 2 先进行双线性变换将模拟低通原型滤波器变换成数字低通滤波器然 后在 Z 域内经数字频率变换为所需类型的数字滤波器 综上所述频率变换法是基于双线性变换法或冲激响应不变法用于频带...
  • 分享了巴特沃斯高通&低通滤波器的C++&OpenCV实现

    场景需求

    做图像处理,滤波是家常便饭,今天给大家分享巴特沃斯滤波器实现。

    众所周知,在频谱中,低频主要对应图像在平滑区域的总体灰度级分布,高频对应图像细节部分,如边缘和噪声。巴特沃斯滤波器被称作最大平坦滤波器。其特点是通频带内的频率响应曲线最大限度平坦,没有纹波,而在阻频带则逐渐下降为零,公式和具体原理就不再罗列了,百度一下全都有,接下来是硬货——C++&OpenCV代码实现。

     

    相关功能函数的C++实现代码

    // 巴特沃斯低通滤波核函数
    cv::Mat butterworth_low_kernel(cv::Mat &scr, float sigma, int n)
    {
    	cv::Mat butterworth_low_pass(scr.size(), CV_32FC1); //,CV_32FC1
    	float D0 = sigma;//半径D0越小,模糊越大;半径D0越大,模糊越小
    	for (int i = 0; i < scr.rows; i++) {
    		for (int j = 0; j < scr.cols; j++) {
    			float d = sqrt(pow(float(i - scr.rows / 2), 2) + pow(float(j - scr.cols / 2), 2));//分子,计算pow必须为float型
    			butterworth_low_pass.at<float>(i, j) = 1.0f / (1.0f + pow(d / D0, 2 * n));
    		}
    	}
    	return butterworth_low_pass;
    }
    
    // 巴特沃斯低通滤波
    cv::Mat butterworth_low_pass_filter(cv::Mat &src, float d0, int n)
    {
    	// H = 1 / (1+(D/D0)^2n)   n表示巴特沃斯滤波器的次数
    	// 阶数n=1 无振铃和负值    阶数n=2 轻微振铃和负值  阶数n=5 明显振铃和负值   阶数n=20 与ILPF相似
    	cv::Mat padded = image_make_border(src);
    	cv::Mat butterworth_kernel = butterworth_low_kernel(padded, d0, n);
    	cv::Mat result = frequency_filter(padded, butterworth_kernel);
    	return result;
    }
    
    // 巴特沃斯高通滤波核函数
    cv::Mat butterworth_high_kernel(cv::Mat &scr, float sigma, int n)
    {
    	cv::Mat butterworth_high_pass(scr.size(), CV_32FC1); //,CV_32FC1
    	float D0 = (float)sigma;  // 半径D0越小,模糊越大;半径D0越大,模糊越小
    	for (int i = 0; i < scr.rows; i++) {
    		for (int j = 0; j < scr.cols; j++) {
    			float d = sqrt(pow(float(i - scr.rows / 2), 2) + pow(float(j - scr.cols / 2), 2));//分子,计算pow必须为float型
    			butterworth_high_pass.at<float>(i, j) =1.0f-1.0f / (1.0f + pow(d / D0, 2 * n));
    		}
    	}
    	return butterworth_high_pass;
    }
    
    // 巴特沃斯高通滤波
    cv::Mat butterworth_high_pass_filter(cv::Mat &src, float d0, int n)
    {
    	cv::Mat padded = image_make_border(src);
    	cv::Mat butterworth_kernel = butterworth_high_kernel(padded, d0, n);
    	cv::Mat result = frequency_filter(padded, butterworth_kernel);
    	return result;
    }
    
    // 频率域滤波
    cv::Mat frequency_filter(cv::Mat &scr, cv::Mat &blur)
    {
    	cv::Mat mask = scr == scr;
    	scr.setTo(0.0f, ~mask);
    
    	//创建通道,存储dft后的实部与虚部(CV_32F,必须为单通道数)
    	cv::Mat plane[] = { scr.clone(), cv::Mat::zeros(scr.size() , CV_32FC1) };
    
    	cv::Mat complexIm;
    	cv::merge(plane, 2, complexIm); // 合并通道 (把两个矩阵合并为一个2通道的Mat类容器)
    	cv::dft(complexIm, complexIm); // 进行傅立叶变换,结果保存在自身
    
    	// 分离通道(数组分离)
    	cv::split(complexIm, plane);
    
    	// 以下的操作是频域迁移
    	fftshift(plane[0], plane[1]);
    
    	// *****************滤波器函数与DFT结果的乘积****************
    	cv::Mat blur_r, blur_i, BLUR;
    	cv::multiply(plane[0], blur, blur_r);  // 滤波(实部与滤波器模板对应元素相乘)
    	cv::multiply(plane[1], blur, blur_i);  // 滤波(虚部与滤波器模板对应元素相乘)
    	cv::Mat plane1[] = { blur_r, blur_i };
    
    	// 再次搬移回来进行逆变换
    	fftshift(plane1[0], plane1[1]);
    	cv::merge(plane1, 2, BLUR); // 实部与虚部合并
    
    	cv::idft(BLUR, BLUR);       // idft结果也为复数
    	BLUR = BLUR / BLUR.rows / BLUR.cols;
    
    	cv::split(BLUR, plane);//分离通道,主要获取通道
    
    	return plane[0];
    }
    
    // 图像边界处理
    cv::Mat image_make_border(cv::Mat &src)
    {
    	int w = cv::getOptimalDFTSize(src.cols); // 获取DFT变换的最佳宽度
    	int h = cv::getOptimalDFTSize(src.rows); // 获取DFT变换的最佳高度
    
    	cv::Mat padded;
    	// 常量法扩充图像边界,常量 = 0
    	cv::copyMakeBorder(src, padded, 0, h - src.rows, 0, w - src.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));
    	padded.convertTo(padded, CV_32FC1);
    
    	return padded;
    }
    
    // 实现频域滤波器的网格函数
    void getcart(int rows, int cols, cv::Mat &x, cv::Mat &y) {
    	x.create(rows, cols, CV_32FC1);
    	y.create(rows, cols, CV_32FC1);
    	//设置边界
    
    	//计算其他位置的值
    	for (int i = 0; i < rows; ++i) {
    		if (i <= rows / 2) {
    			x.row(i) = i;
    		}
    		else {
    			x.row(i) = i - rows;
    		}
    	}
    	for (int i = 0; i < cols; ++i) {
    		if (i <= cols / 2) {
    			y.col(i) = i;
    		}
    		else {
    			y.col(i) = i - cols;
    		}
    	}
    }
    
    // fft变换后进行频谱搬移
    void fftshift(cv::Mat &plane0, cv::Mat &plane1)
    {
    	// 以下的操作是移动图像  (零频移到中心)
    	int cx = plane0.cols / 2;
    	int cy = plane0.rows / 2;
    	cv::Mat part1_r(plane0, cv::Rect(0, 0, cx, cy));  // 元素坐标表示为(cx, cy)
    	cv::Mat part2_r(plane0, cv::Rect(cx, 0, cx, cy));
    	cv::Mat part3_r(plane0, cv::Rect(0, cy, cx, cy));
    	cv::Mat part4_r(plane0, cv::Rect(cx, cy, cx, cy));
    
    	cv::Mat temp;
    	part1_r.copyTo(temp);  //左上与右下交换位置(实部)
    	part4_r.copyTo(part1_r);
    	temp.copyTo(part4_r);
    
    	part2_r.copyTo(temp);  //右上与左下交换位置(实部)
    	part3_r.copyTo(part2_r);
    	temp.copyTo(part3_r);
    
    	cv::Mat part1_i(plane1, cv::Rect(0, 0, cx, cy));  //元素坐标(cx,cy)
    	cv::Mat part2_i(plane1, cv::Rect(cx, 0, cx, cy));
    	cv::Mat part3_i(plane1, cv::Rect(0, cy, cx, cy));
    	cv::Mat part4_i(plane1, cv::Rect(cx, cy, cx, cy));
    
    	part1_i.copyTo(temp);  //左上与右下交换位置(虚部)
    	part4_i.copyTo(part1_i);
    	temp.copyTo(part4_i);
    
    	part2_i.copyTo(temp);  //右上与左下交换位置(虚部)
    	part3_i.copyTo(part2_i);
    	temp.copyTo(part3_i);
    }

     

    测试代码

    #include<iostream>
    #include<opencv2/opencv.hpp>
    #include<ctime>
    using namespace std;
    using namespace cv;
    
    cv::Mat butterworth_low_kernel(cv::Mat &scr, float sigma, int n);
    cv::Mat butterworth_low_pass_filter(cv::Mat &src, float d0, int n);
    cv::Mat butterworth_high_kernel(cv::Mat &scr, float sigma, int n);
    cv::Mat butterworth_high_pass_filter(cv::Mat &src, float d0, int n);
    cv::Mat frequency_filter(cv::Mat &scr, cv::Mat &blur);
    cv::Mat image_make_border(cv::Mat &src);
    void fftshift(cv::Mat &plane0, cv::Mat &plane1);
    void getcart(int rows, int cols, cv::Mat &x, cv::Mat &y);
    Mat powZ(cv::InputArray src, double power);
    Mat sqrtZ(cv::InputArray src);
    
    int main(void)
    {
    	Mat test = imread("tangsan.jpg", 0);
    	float D0 = 50.0f;
    	float D1 = 5.0f;
    	Mat lowpass = butterworth_low_pass_filter(test, D0,2);
    	Mat highpass = butterworth_high_pass_filter(test, D1, 2);
    
    	imshow("original", test);
    	imshow("low pass", lowpass / 255);     // lowpass的数据都比较大,0-255,imshow对于float型Mat显示需要除以255
    	imshow("high pass", highpass / 255);   // highpass的数据都比较大,0-255,imshow对于float型Mat显示需要除以255
    	waitKey(0);
    
    	system("pause");
    	return 0;
    }
    
    // 巴特沃斯低通滤波核函数
    cv::Mat butterworth_low_kernel(cv::Mat &scr, float sigma, int n)
    {
    	cv::Mat butterworth_low_pass(scr.size(), CV_32FC1); //,CV_32FC1
    	float D0 = sigma;//半径D0越小,模糊越大;半径D0越大,模糊越小
    	for (int i = 0; i < scr.rows; i++) {
    		for (int j = 0; j < scr.cols; j++) {
    			float d = sqrt(pow(float(i - scr.rows / 2), 2) + pow(float(j - scr.cols / 2), 2));//分子,计算pow必须为float型
    			butterworth_low_pass.at<float>(i, j) = 1.0f / (1.0f + pow(d / D0, 2 * n));
    		}
    	}
    	return butterworth_low_pass;
    }
    
    // 巴特沃斯低通滤波
    cv::Mat butterworth_low_pass_filter(cv::Mat &src, float d0, int n)
    {
    	// H = 1 / (1+(D/D0)^2n)   n表示巴特沃斯滤波器的次数
    	// 阶数n=1 无振铃和负值    阶数n=2 轻微振铃和负值  阶数n=5 明显振铃和负值   阶数n=20 与ILPF相似
    	cv::Mat padded = image_make_border(src);
    	cv::Mat butterworth_kernel = butterworth_low_kernel(padded, d0, n);
    	cv::Mat result = frequency_filter(padded, butterworth_kernel);
    	return result;
    }
    
    // 巴特沃斯高通滤波核函数
    cv::Mat butterworth_high_kernel(cv::Mat &scr, float sigma, int n)
    {
    	cv::Mat butterworth_high_pass(scr.size(), CV_32FC1); //,CV_32FC1
    	float D0 = (float)sigma;  // 半径D0越小,模糊越大;半径D0越大,模糊越小
    	for (int i = 0; i < scr.rows; i++) {
    		for (int j = 0; j < scr.cols; j++) {
    			float d = sqrt(pow(float(i - scr.rows / 2), 2) + pow(float(j - scr.cols / 2), 2));//分子,计算pow必须为float型
    			butterworth_high_pass.at<float>(i, j) =1.0f-1.0f / (1.0f + pow(d / D0, 2 * n));
    		}
    	}
    	return butterworth_high_pass;
    }
    
    // 巴特沃斯高通滤波
    cv::Mat butterworth_high_pass_filter(cv::Mat &src, float d0, int n)
    {
    	cv::Mat padded = image_make_border(src);
    	cv::Mat butterworth_kernel = butterworth_high_kernel(padded, d0, n);
    	cv::Mat result = frequency_filter(padded, butterworth_kernel);
    	return result;
    }
    
    // 频率域滤波
    cv::Mat frequency_filter(cv::Mat &scr, cv::Mat &blur)
    {
    	cv::Mat mask = scr == scr;
    	scr.setTo(0.0f, ~mask);
    
    	//创建通道,存储dft后的实部与虚部(CV_32F,必须为单通道数)
    	cv::Mat plane[] = { scr.clone(), cv::Mat::zeros(scr.size() , CV_32FC1) };
    
    	cv::Mat complexIm;
    	cv::merge(plane, 2, complexIm); // 合并通道 (把两个矩阵合并为一个2通道的Mat类容器)
    	cv::dft(complexIm, complexIm); // 进行傅立叶变换,结果保存在自身
    
    	// 分离通道(数组分离)
    	cv::split(complexIm, plane);
    
    	// 以下的操作是频域迁移
    	fftshift(plane[0], plane[1]);
    
    	// *****************滤波器函数与DFT结果的乘积****************
    	cv::Mat blur_r, blur_i, BLUR;
    	cv::multiply(plane[0], blur, blur_r);  // 滤波(实部与滤波器模板对应元素相乘)
    	cv::multiply(plane[1], blur, blur_i);  // 滤波(虚部与滤波器模板对应元素相乘)
    	cv::Mat plane1[] = { blur_r, blur_i };
    
    	// 再次搬移回来进行逆变换
    	fftshift(plane1[0], plane1[1]);
    	cv::merge(plane1, 2, BLUR); // 实部与虚部合并
    
    	cv::idft(BLUR, BLUR);       // idft结果也为复数
    	BLUR = BLUR / BLUR.rows / BLUR.cols;
    
    	cv::split(BLUR, plane);//分离通道,主要获取通道
    
    	return plane[0];
    }
    
    // 图像边界处理
    cv::Mat image_make_border(cv::Mat &src)
    {
    	int w = cv::getOptimalDFTSize(src.cols); // 获取DFT变换的最佳宽度
    	int h = cv::getOptimalDFTSize(src.rows); // 获取DFT变换的最佳高度
    
    	cv::Mat padded;
    	// 常量法扩充图像边界,常量 = 0
    	cv::copyMakeBorder(src, padded, 0, h - src.rows, 0, w - src.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));
    	padded.convertTo(padded, CV_32FC1);
    
    	return padded;
    }
    
    // 实现频域滤波器的网格函数
    void getcart(int rows, int cols, cv::Mat &x, cv::Mat &y) {
    	x.create(rows, cols, CV_32FC1);
    	y.create(rows, cols, CV_32FC1);
    	//设置边界
    
    	//计算其他位置的值
    	for (int i = 0; i < rows; ++i) {
    		if (i <= rows / 2) {
    			x.row(i) = i;
    		}
    		else {
    			x.row(i) = i - rows;
    		}
    	}
    	for (int i = 0; i < cols; ++i) {
    		if (i <= cols / 2) {
    			y.col(i) = i;
    		}
    		else {
    			y.col(i) = i - cols;
    		}
    	}
    }
    
    // fft变换后进行频谱搬移
    void fftshift(cv::Mat &plane0, cv::Mat &plane1)
    {
    	// 以下的操作是移动图像  (零频移到中心)
    	int cx = plane0.cols / 2;
    	int cy = plane0.rows / 2;
    	cv::Mat part1_r(plane0, cv::Rect(0, 0, cx, cy));  // 元素坐标表示为(cx, cy)
    	cv::Mat part2_r(plane0, cv::Rect(cx, 0, cx, cy));
    	cv::Mat part3_r(plane0, cv::Rect(0, cy, cx, cy));
    	cv::Mat part4_r(plane0, cv::Rect(cx, cy, cx, cy));
    
    	cv::Mat temp;
    	part1_r.copyTo(temp);  //左上与右下交换位置(实部)
    	part4_r.copyTo(part1_r);
    	temp.copyTo(part4_r);
    
    	part2_r.copyTo(temp);  //右上与左下交换位置(实部)
    	part3_r.copyTo(part2_r);
    	temp.copyTo(part3_r);
    
    	cv::Mat part1_i(plane1, cv::Rect(0, 0, cx, cy));  //元素坐标(cx,cy)
    	cv::Mat part2_i(plane1, cv::Rect(cx, 0, cx, cy));
    	cv::Mat part3_i(plane1, cv::Rect(0, cy, cx, cy));
    	cv::Mat part4_i(plane1, cv::Rect(cx, cy, cx, cy));
    
    	part1_i.copyTo(temp);  //左上与右下交换位置(虚部)
    	part4_i.copyTo(part1_i);
    	temp.copyTo(part4_i);
    
    	part2_i.copyTo(temp);  //右上与左下交换位置(虚部)
    	part3_i.copyTo(part2_i);
    	temp.copyTo(part3_i);
    }
    
    Mat powZ(cv::InputArray src, double power) {
    	cv::Mat dst;
    	cv::pow(src, power, dst);
    	return dst;
    }
    
    Mat sqrtZ(cv::InputArray src) {
    	cv::Mat dst;
    	cv::sqrt(src, dst);
    	return dst;
    }
    
    

     

    测试效果

    图1 效果图

    不同的滤波参数导致的滤波器尺寸大小不一,得到的结果也就不一样~

    另外,如果我的代码有什么问题,欢迎大家提出异议批评指正,一同进步~

    展开全文
  • 计划用主频为40Hz的雷克子波,傅里叶变换后,利用巴特沃斯高通滤波器滤除5,7,15Hz及以下的频率,以下为我写的程序及滤波后所得结果,有两个问题需要请教:1.滤波后所得频谱图(图二)的横坐标没有从零开始,2.感觉效果...
  • 目录使用高通滤波器锐化图像由低通滤波器得到理想、高斯和巴特沃斯高通滤波器指纹增强频域中的拉普拉斯钝化掩蔽、高提升滤波和高频强调滤波同态滤波 使用高通滤波器锐化图像 由低通滤波器得到理想、高斯和巴特沃斯...
  • 滤波器有四个基本原型,低通、带通、带阻、高通。实现滤波器就是实现相应的谐振系统。纪总参数就是电感、电容,分布参数就是各种射频/微波传输线形成的谐振器。理论上,滤波器是无耗元件。滤波器的指标工作频率。...
  • 高通滤波器与低通几乎完全一样,只要注意 [B,A] = butter(N, wc, ‘ftype’, ‘s’)中的 ftype=high 例: 设计通带截止频率4kHz,通带衰减0.1dB,阻带截止频率1kHz,阻带衰减40dB的巴特沃斯高通滤波器 代码如下: ...
  • Butterworth高通滤波器

    2018-05-31 15:44:16
    巴特沃斯滤波器是电子滤波器的一种。巴特沃斯滤波器的特点是通频带的频率响应曲线最平滑。
  • 以下示例为10Hz~500Hz的带通滤波器(由一个五阶巴特沃斯低通滤波器和一个五阶巴特沃斯高通滤波器构成)。 五阶巴特沃斯低通滤波器 二阶低通滤波器结构 1-2.三阶低通滤波器结构 5阶=3阶+2阶 ...
  • 例如:按频率选择的特性可以分为:低通、高通、带通、带阻滤波器等;按实现方式可以分为:LC滤波器、声表面波/体声波滤波器、螺旋滤波器、介质滤波器、腔体滤波器、高温超导滤波器、平面结构滤波器。按不同的频率...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 183
精华内容 73
关键字:

巴特沃斯高通滤波器