OpenCV 笔记(37):频域高通滤波——高斯高通滤波器、巴特沃斯高通滤波器

1. 高斯高通滤波器

与高斯低通滤波器(用于平滑图像、模糊图像)相反,高斯高通滤波器(GHPF)通过抑制低频成分来实现图像锐化。高斯高通滤波器的作用是增强图像中的高频成分,从而突出图像的边缘和细节。

高斯高通滤波器的传递函数可以由一个低通滤波器的传递函数转换得到。通常,我们可以用以下公式来表示高斯高通滤波器的传递函数:

H(u,v)= 1 - e^{-D^2(u,v)/2D_0^2}

其中,D_0是截止频率,控制着滤波器的截止范围。

D_0值越大,滤波器对低频的抑制变得较弱,更多的频率成分可以通过,滤波器有较弱的高通滤波效果。
D_0值越小,低频成分会被大幅抑制,高频分量更容易通过,滤波器有较强的高通滤波效果。

高斯高通滤波器具有以下特性:

  • 增强高频成分: 高斯高通滤波器通过抑制低频成分,突出图像中的边缘和细节,从而达到锐化图像的效果。
  • 平滑过渡: 相比于其他高通滤波器,高斯高通滤波器的频率响应曲线更加平滑,在抑制低频成分的同时,不会引入过多的噪声。
  • 基于高斯函数: 高斯高通滤波器的设计基于高斯函数,具有良好的对称性和旋转不变性。

2. 巴特沃斯高通滤波器

巴特沃斯高通滤波器(BHPF)最显著的特点是通带内的频率响应曲线最大限度平坦,即在通带范围内,信号的幅度几乎不受影响。其设计目标是在频率域中尽量保持传递函数的平滑性,没有急剧的增益变化。

巴特沃斯高通滤波器的主要特性:

  • 通带平坦: 在通带范围内,频率响应曲线近似水平,没有纹波,保证了信号的幅度失真最小。
  • 阻带衰减: 在阻带范围内,频率响应曲线逐渐下降,高频信号被有效衰减。
  • 过渡带平滑: 从通带过渡到阻带的过程中,幅度响应变化平滑,没有尖锐的峰值或谷值,这有助于减少信号的失真。
  • 相位线性: 巴特沃斯滤波器的相位响应接近线性,这意味着不同频率的信号通过滤波器后,相位延迟的差异较小,从而减少了信号的失真。

对于一个 n 阶的巴特沃斯高通滤波器,其频域传递函数:

H(u,v)=\frac{1}{1+[\frac{D_0}{D(u,v)}]^{2n}}

  • 在截止频率D_0以下的频率分量,传递函数的值趋近于 0 ,即低频信号被衰减;

  • 在截止频率D_0以上的频率分量,传递函数的值趋近于 1,高频信号能够无衰减地通过。

下面的例子,展示了分别展示了高斯高通滤波器和巴特沃斯高通滤波器的实现代码

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <random>

using namespace std;
using namespace cv;

// 巴特沃斯高通滤波核函数
cv::Mat butterworth_high_kernel(cv::Mat &scr, float sigma, int n)
{
    cv::Mat butterworth_high_pass(scr.size(), CV_32FC1);
    float D0 = sigma;
    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));
            butterworth_high_pass.at<float>(i, j) =1.0f-1.0f / (1.0f + pow(d / D0, 2 * n));
        }
    }
    return butterworth_high_pass;
}

// 高斯高通滤波核函数
cv::Mat gaussian_high_pass_kernel(cv::Mat scr, float sigma)
{
    cv::Mat gaussianBlur(scr.size(), CV_32FC1);
    float d0 = sigma;
    for (int i = 0; i < scr.rows; i++) {
        for (int j = 0; j < scr.cols; j++) {
            float d = pow(float(i - scr.rows / 2), 2) + pow(float(j - scr.cols / 2), 2);
            gaussianBlur.at<float>(i, j) = 1 - expf(-d / (2 * d0*d0));
        }
    }
    return gaussianBlur;
}

// fft 变换后进行频谱中心化
void fftshift(cv::Mat &plane0, cv::Mat &plane1)
{
    int cx = plane0.cols / 2;
    int cy = plane0.rows / 2;
    cv::Mat q0_r(plane0, cv::Rect(0, 0, cx, cy));  // 元素坐标表示为(cx, cy)
    cv::Mat q1_r(plane0, cv::Rect(cx, 0, cx, cy));
    cv::Mat q2_r(plane0, cv::Rect(0, cy, cx, cy));
    cv::Mat q3_r(plane0, cv::Rect(cx, cy, cx, cy));

    cv::Mat temp;
    q0_r.copyTo(temp);  //左上与右下交换位置(实部)
    q3_r.copyTo(q0_r);
    temp.copyTo(q3_r);

    q1_r.copyTo(temp);  //右上与左下交换位置(实部)
    q2_r.copyTo(q1_r);
    temp.copyTo(q2_r);

    cv::Mat q0_i(plane1, cv::Rect(0, 0, cx, cy));  //元素坐标(cx,cy)
    cv::Mat q1_i(plane1, cv::Rect(cx, 0, cx, cy));
    cv::Mat q2_i(plane1, cv::Rect(0, cy, cx, cy));
    cv::Mat q3_i(plane1, cv::Rect(cx, cy, cx, cy));

    q0_i.copyTo(temp);  //左上与右下交换位置(虚部)
    q3_i.copyTo(q0_i);
    temp.copyTo(q3_i);

    q1_i.copyTo(temp);  //右上与左下交换位置(虚部)
    q2_i.copyTo(q1_i);
    temp.copyTo(q2_i);
}

// 频率域滤波
cv::Mat frequency_filter(cv::Mat &src, cv::Mat &blur)
{
    Mat mask = src == src;
    src.setTo(0.0f, ~mask);

    // 创建一个双通道矩阵 planes,用来储存复数的实部与虚部
    Mat planes[] = {src.clone(), cv::Mat::zeros(src.size() , CV_32FC1) };

    Mat complexI;
    merge(planes, 2, complexI); // 合并通道 (把两个矩阵合并为一个2通道的Mat类容器)
    dft(complexI, complexI); // 进行傅立叶变换,结果保存在自身

    // 分离通道(数组分离)
    cv::split(complexI, planes);

    // 频谱中心化
    fftshift(planes[0], planes[1]);

    //  H(u, v) * F(u, v)
    Mat blur_r, blur_i, dst;
    multiply(planes[0], blur, blur_r);  // 滤波(实部与滤波器模板对应元素相乘)
    multiply(planes[1], blur, blur_i);  // 滤波(虚部与滤波器模板对应元素相乘)
    Mat planes1[] = {blur_r, blur_i };

    // 频谱中心化
    fftshift(planes1[0], planes1[1]);
    merge(planes1, 2, dst); // 实部与虚部合并

    // 傅里叶逆变换
    idft(dst, dst);       // idft 结果也为复数
    dst = dst / dst.rows / dst.cols;

    split(dst, planes1);//分离通道,主要获取通道

    return planes1[0];
}

int main()
{
    Mat src = imread(".../girl.jpg");
    imshow("src", src);

    Mat gray;
    cvtColor(src, gray, COLOR_BGR2GRAY);
    imshow("gray", gray);

    // 扩充边界
    int w = cv::getOptimalDFTSize(src.cols); // 获取DFT变换的最佳宽度
    int h = cv::getOptimalDFTSize(src.rows); // 获取DFT变换的最佳高度

    cv::Mat padded;
    // 常量法扩充图像边界,常量 = 0
    cv::copyMakeBorder(gray, padded, 0, h - src.rows, 0, w - src.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));
    padded.convertTo(padded, CV_32FC1);

    float d0 = 5.0f;
    int n = 2;

    cv::Mat gaussian_kernel = gaussian_high_pass_kernel(padded, d0);
    cv::Mat dst = frequency_filter(padded, gaussian_kernel);

    convertScaleAbs(dst, dst);
    imshow("gaussian_high_pass", dst);

    cv::Mat butterworth_kernel = butterworth_high_kernel(padded, d0, n);
    cv::Mat dst2 = frequency_filter(padded, butterworth_kernel);

    convertScaleAbs(dst2, dst2);
    imshow("butterworth_high_pass", dst2);

    waitKey(0);
    return 0;
}
灰度图像vs高斯高通滤波的效果vs巴特沃斯高通滤波的效果.png

小结一下理想高通滤波器、高斯高通滤波器、巴特沃斯高通滤波器三者的区别:

滤波器 特点 优点 缺点 主要应用场景
理想高通滤波器 频域响应突变 概念简单 振铃现象严重 理论分析、概念性应用
巴特沃斯高通滤波器 频域响应平滑 通带平坦 阻带衰减较慢 图像锐化、噪声滤波、特征提取
高斯高通滤波器 频域响应呈高斯分布 抑制噪声能力强 阻带衰减较慢 图像去噪、纹理分析、边缘检测

高斯高通滤波器相比于巴特沃斯高通滤波器,其响应更平滑,衰减曲线符合高斯分布。但是在需要精确滤波的场景下,表现不如巴特沃斯高通滤波器。

3. 总结

高斯高通滤波器(GHPF)、巴特沃斯高通滤波器(BHPF)在图像处理中都有广泛应用。

但由于各自的特性在不同场景下表现出不同的优势。例如,如果需要在噪声中提取边缘信息,同时保留图像的细节,可以选择巴特沃斯高通滤波器。如果需要对图像进行去噪,同时平滑图像,可以选择高斯高通滤波器。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,815评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,251评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 171,999评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,996评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,993评论 6 400
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,477评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,848评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,823评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,361评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,401评论 3 346
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,518评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,119评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,850评论 3 338
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,292评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,424评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,072评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,588评论 2 365

推荐阅读更多精彩内容