OpenCV 笔记(34):频域低通滤波——理想低通滤波器

1.  频域低通滤波

1.1 频域滤波

频域滤波器是一种通过对图像进行傅里叶变换,然后在频域上选择性地滤除或增强某些频率成分来实现图像滤波的方法。

频域滤波空域滤波都有各自的优缺点和使用场景:

特性频域滤波空域滤波
原理基于频谱进行操作基于像素进行操作
实现计算量较大计算量较小
滤波效果灵活可控较简单
应用去周期性噪声、增强细节、图像配准去随机噪声、平滑图像、锐化图像

频域滤波器的基本步骤如下:

  1. 对图像进行傅里叶变换:将图像从空域转换为频域 F(u, v)。

  2. 设计频域滤波器:选择一个合适的频域滤波器函数 H(u, v) 来滤除或增强特定的频率成分。

  3. 将频域滤波器应用于图像:对 F(u, v) 进行乘法运算:G(u, v) = H(u, v) * F(u, v)。

  4. 对滤波后的频谱进行傅里叶逆变换:将滤波后的频谱 G(u, v) 转换回空域,得到滤波后的图像 g(x, y)。

常见的频域滤波器函数包括:

  • 低通滤波器:滤除高频成分,保留低频成分。

  • 高通滤波器:滤除低频成分,保留高频成分。

  • 带通滤波器:保留特定频率范围内的成分,滤除其他频率成分。

  • 带阻滤波器:滤除特定频率范围内的成分,保留其他频率成分。

1.2 频域低通滤波

频域低通滤波是一种在图像处理中用于去除图像高频成分,保留低频成分的滤波方法。

低频成分通常代表了信号的主要信息趋势,而高频成分则往往是噪声或细节。因此,频域低通滤波常用于图像降噪边缘检测信号平滑等场合。因此,频域低通滤波常用于图像降噪边缘检测信号平滑等场合。

下面汇总了频域低通滤波的优缺点

优点缺点
能够有效去除信号中的高频噪声,提高信号的质量。可能会导致信号失真,例如出现振铃现象。
可以用于图像降噪,平滑图像,去除图像中的细节。可能会造成图像模糊,降低图像清晰度。
可以用于边缘检测,提取图像中的边缘信息。滤波器的截止频率需要根据具体应用进行选择,否则可能无法达到预期的效果。
计算量相对较小,实现简单。在某些情况下,可能无法完全去除高频噪声。

1.3 频域低通滤波分类

常用的频域低通滤波器包括:

  • 理想低通滤波器(ILPF):理想低通滤波器在截止频率以下的频率分量保持不变,而高于截止频率的频率分量完全衰减为零。然而,理想低通滤波器在现实中是不可实现的,因为其频谱特性呈矩形,导致其在时域中会出现振铃现象。

  • 高斯低通滤波器(GLPF):高斯低通滤波器的频率响应曲线呈高斯形状,具有良好的平滑性和抗噪性。因此其滚降速率较慢。

  • 巴特沃斯低通滤波器(BLPF):巴特沃斯低通滤波器是一种常用的近似理想低通滤波器的滤波器,其频谱特性平滑,在截止频率附近具有较快的衰减速度。

2.  理想低通滤波器

理想低通滤波器是一种具有理想频域特性的滤波器,它在截止频率以下保持幅度不变,完全衰减高于截止频率的频域成分。

,,

其中,是一个正常数,D(u,v) 表示中心点到频域中心的距离,即

理想低通滤波器的主要特性如下:

  • 完全抑制高频成分:在截止频率以上,信号的幅度完全衰减为零,因此高频成分被完全去除。

  • 保留低频成分:在截止频率以下,信号的幅度保持不变,因此低频成分得以保留。

  • 频域特性呈矩形函数:理想低通滤波器的频域特性为矩形函数,具有非常尖锐的截止特性。

理想低通滤波器虽然具有良好的频域特性和去噪性能,但在现实中无法实现,因为其频域特性呈矩形函数,导致其时域特性会出现振铃现象,因此在实际应用中存在一定的局限性。为了克服这些局限性,通常会使用近似理想低通滤波器来代替理想低通滤波器。常用的近似理想低通滤波器包括巴特沃斯低通滤波器和高斯低通滤波器。

下面的例子,展示了理想低通滤波器的实现代码

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

using namespace std;
using namespace cv;

void addSaltNoise(Mat &src, int num, Mat &dst)
{
    dst = src.clone();

    // 随机数产生器
    std::random_device rd; //种子
    std::mt19937 gen(rd()); // 随机数引擎

    auto rows = src.rows; // 行数
    auto cols = src.cols * src.channels();

    for (int i = 0; i < num; i++)
    {
        auto row = static_cast<int>(gen() % rows);
        auto col = static_cast<int>(gen() % cols);

        auto p = dst.ptr<uchar>(row);
        p[col++] = 255;
        p[col++] = 255;
        p[col] = 255;
    }
}

// 理想低通滤波核函数
cv::Mat ideal_low_kernel(cv::Mat &src, float sigma)
{
    cv::Mat ideal_low_pass(src.size(), CV_32FC1);
    float d0 = sigma;//半径D0越小,模糊越大;半径D0越大,模糊越小
    for (int i = 0; i < src.rows; i++) {
        for (int j = 0; j < src.cols; j++) {
            float d = sqrt(pow(float(i - src.rows / 2), 2) + pow(float(j - src.cols / 2), 2));
            if (d <= d0) {
                ideal_low_pass.at<float>(i, j) = 1;
            }
            else {
                ideal_low_pass.at<float>(i, j) = 0;
            }
        }
    }
    return ideal_low_pass;
}

// 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);

    addSaltNoise(gray,100000,gray);
    imshow("add salt", gray);

    // 扩充边界
    int w = getOptimalDFTSize(gray.cols);
    int h = getOptimalDFTSize(gray.rows);

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

    Mat kernel = ideal_low_kernel(padded, 80.0f); // 理想低通滤波核函数
    Mat dst = frequency_filter(padded, kernel);

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

    waitKey(0);
    return 0;
}
406749ed0ddbd85d35413cee9b1023c9.jpeg
灰度图像vs椒盐噪声vs理想低通滤波的效果.png

3.  总结

本文介绍了频域滤波、频域低通滤波、理想低通滤波器。

频域滤波和空域滤波都有各自的优缺点和使用场景。频域低通滤波是一种重要的信号处理技术,具有广泛的应用前景。理想低通滤波器是一种理论上的滤波器,具有完全抑制高频成分、保留低频成分的特性。常用的近似理想低通滤波器在频域上的特性与理想低通滤波器相似,但在时域上能够抑制振铃现象。

Java与Android技术栈】公众号

关注 Java/Kotlin 服务端、桌面端 、Android 、机器学习、端侧智能

更多精彩内容请关注:

  • 11
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV中提供了多种高滤波滤波的函数,下面分别介绍其中的几种。 1. 高斯滤波滤波) 高斯滤波是一种常用的滤波器,可以过对信号进行平滑处理来去除高噪声,保留信号中的信息。在OpenCV中,可以使用`cv2.GaussianBlur`函数实现高斯滤波。 ```python blurred = cv2.GaussianBlur(image, (ksize, ksize), sigmaX) ``` 其中,`image`为输入图像,`ksize`为滤波器的大小,`sigmaX`为高斯核的标准差。 2. 拉普拉斯滤波(高滤波) 拉普拉斯滤波是一种常用的高滤波器,可以过增强信号的高成分来增强图像的边缘信息。在OpenCV中,可以使用`cv2.Laplacian`函数实现拉普拉斯滤波。 ```python laplacian = cv2.Laplacian(image, cv2.CV_32F, ksize) ``` 其中,`image`为输入图像,`cv2.CV_32F`表示输出图像的数据类型为32位浮点数,`ksize`为滤波器的大小。 3. Sobel滤波(高滤波) Sobel滤波也是一种常用的高滤波器,它可以过检测图像中的边缘来增强图像的高成分。在OpenCV中,可以使用`cv2.Sobel`函数实现Sobel滤波。 ```python sobelx = cv2.Sobel(image, cv2.CV_32F, 1, 0, ksize) sobely = cv2.Sobel(image, cv2.CV_32F, 0, 1, ksize) ``` 其中,`image`为输入图像,`cv2.CV_32F`表示输出图像的数据类型为32位浮点数,`1`和`0`表示对x和y方向进行滤波,`ksize`为滤波器的大小。 总的来说,OpenCV提供了多种高滤波滤波的函数,具体使用哪种滤波器取决于信号的特性和需要的处理效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值