本节为opencv数字图像处理(7):频率域滤波的第四小节,频率域滤波的基础公式、步骤与C++实现,频率域滤波的前三小节(频率域滤波的基础概念、取样和取样函数的傅立叶变换以及二维取样定理与二维傅里叶变换),更偏向于数学概念,围绕傅立叶变换对展开,包括一维、二维、连续、离散傅立叶变换对机器性质以及此基础上得到的采样定理。从本节开始,会更偏向于如何使用频率域滤波来处理图像,本小节的主要内容包括:频率域滤波的基础公式与步骤,以及用C++代码实现的完整过程。

1. 频率域滤波基础

  频域率滤波由修改一幅图像的傅里叶变换然后计算其反变换得到处理后的结果组成,给定一幅大小为M×NM\times NM×N的数字图像f(x,y)f(x,y)f(x,y),则基本滤波公式如下:
g(x,y)=ζ−1[H(u,v)F(u,v)]g(x,y)=\zeta^{-1}[H(u,v)F(u,v)] g(x,y)=ζ−1[H(u,v)F(u,v)]

  其中,ζ−1\zeta^{-1}ζ−1时IDFT,F(u,v)F(u,v)F(u,v)是输入图像f(x,y)f(x,y)f(x,y)的DFT,H(u,v)H(u,v)H(u,v)是滤波函数(滤波器/滤波传递函数),g(x,y)g(x,y)g(x,y)是滤波后输出的图像,并且函数F、H、gF、H、gF、H、g都是大小与输入图像相同的M×NM\times NM×N阵列【使用中心堆成的函数可以显著简化H(u,v)H(u,v)H(u,v)的技术条件,这要求F(u,v)F(u,v)F(u,v)也被中心化,可以在变换前使用(−1)x+y(-1)^{x+y}(−1)x+y乘以输入图像来实现】。通常情况下,HHH是实对称函数而fff是是函数,则上式中的IDFT理论上生成实数量,但实际中该反变换通常包含由舍入误差和其他计算错误引起的寄生复数像,因此,通常取IDFT的实部来形成函数ggg。
  考虑一个最简单的滤波器,它在变换的中心处是0,其他处为1。当建立乘积H(u,v)F(u,v)H(u,v)F(u,v)H(u,v)F(u,v)时,滤波器将抑制F(u,v)F(u,v)F(u,v)的直流项而通过所有其他项。因为直流项决定图像的平均灰度,所以,将其置为0会把图像的平均灰度减小为0,图像变得更暗,因为均值为0灰度那么必存在负灰度,通常为显示目的将负灰度修剪为0。

  图像经傅里叶变换至频率域,其中的低频与图像中缓慢变换的灰度分量有关,而高频由灰度的尖锐过渡造成。基于此,我们认为衰减高频而通过低频的低通滤波器H(u,v)H(u,v)H(u,v)将模糊一幅图像,具有相反特性的高通滤波器将增强尖锐的细节同时造成图像对比度的降低。如下图所示,第一行是从左到右为低通滤波器,高通滤波器和调整后的高通滤波器(对滤波器加上一个小常数,不影响尖锐性的同时,防止直流项的消除以保留色调),第二行是效果图。

2. 频率域滤波步骤

  频率域滤波分为以下七步:

  • 给定一幅大小为M×NM\times NM×N的输入图像f(x,y)f(x,y)f(x,y),设置填充参数P=2M,Q=2NP=2M,Q=2NP=2M,Q=2N;
  • 对f(x,y)f(x,y)f(x,y)添加必要数量的0,形成大小为P×QP\times QP×Q的填充后的图像fp(x,y)f_p(x,y)fp​(x,y);
  • 用(−1)x+y(-1)^{x+y}(−1)x+y乘以fp(x,y)f_p(x,y)fp​(x,y)移到其变换的中心;
  • 计算上一步骤得到的图像的DFT,得到F(u,v)F(u,v)F(u,v);
  • 生成一个实对称的滤波函数H(u,v)H(u,v)H(u,v),其大小为P×QP\times QP×Q,中心在(P/2,Q/2)(P/2,Q/2)(P/2,Q/2)处,用阵列相乘形成乘积G(u,v)=H(u,v)F(u,v)G(u,v)=H(u,v)F(u,v)G(u,v)=H(u,v)F(u,v),即G(i,k)=H(i,k)F(i,k)G(i,k)=H(i,k)F(i,k)G(i,k)=H(i,k)F(i,k);
  • 得到处理后的图像:gp(x,y)={real[ζ−1[G(u,v)]]}(−1)x+yg_p(x,y)=\{real[\zeta^{-1}[G(u,v)]]\}(-1)^{x+y}gp​(x,y)={real[ζ−1[G(u,v)]]}(−1)x+y,其中,忽略计算不准确导致的寄生复分量,选择实部,下标p指出处理的是填充的阵列
  • 通过从g(x,y)g(x,y)g(x,y)的左上象限提取M×NM\times NM×N区域,得到最终处理结果g(x,y)g(x,y)g(x,y)

  示意图和代码如下所示:

  C++实现:

#if 1
#include "opencv2/opencv.hpp"int main()
{cv::Mat input = cv::imread("1.JPG", cv::IMREAD_GRAYSCALE);cv::imshow("step0_ori", input);int w = cv::getOptimalDFTSize(input.cols);int h = cv::getOptimalDFTSize(input.rows);cv::Mat padded;cv::copyMakeBorder(input, padded, 0, h - input.rows, 0, w - input.cols,cv::BORDER_CONSTANT, cv::Scalar::all(0));padded.convertTo(padded, CV_32FC1);cv::imshow("step1_padded", padded);for (int i = 0; i < padded.rows; i++){float* ptr = padded.ptr<float>(i);for (int j = 0; j < padded.cols; j++)ptr[j] *= pow(-1, i + j);}cv::imshow("step2_center", padded);cv::Mat plane[] = { padded,cv::Mat::zeros(padded.size(),CV_32F) };cv::Mat complexImg;cv::merge(plane, 2, complexImg);cv::dft(complexImg, complexImg);cv::split(complexImg, plane);cv::magnitude(plane[0], plane[1], plane[0]);plane[0] += cv::Scalar::all(1);cv::log(plane[0], plane[0]);cv::normalize(plane[0], plane[0], 1, 0, cv::NORM_MINMAX);cv::imshow("dft", plane[0]);cv::Mat gaussianBlur(padded.size(), CV_32FC2);float D0 = 2 * 10 * 10;for (int i = 0; i < padded.rows; i++){float* p = gaussianBlur.ptr<float>(i);for (int j = 0; j < padded.cols; j++){float d = pow(i - padded.rows / 2, 2) + pow(j - padded.cols / 2, 2);p[2 * j] = expf(-d / D0);p[2 * j + 1] = expf(-d / D0);}}cv::split(gaussianBlur, plane);cv::magnitude(plane[0], plane[1], plane[0]);plane[0] += cv::Scalar::all(1);cv::log(plane[0], plane[0]);cv::normalize(plane[0], plane[0], 1, 0, cv::NORM_MINMAX);cv::imshow("gaussianBlurKernel", plane[0]);multiply(complexImg, gaussianBlur, gaussianBlur);cv::split(gaussianBlur, plane);cv::magnitude(plane[0], plane[1], plane[0]);plane[0] += cv::Scalar::all(1);cv::log(plane[0], plane[0]);cv::normalize(plane[0], plane[0], 1, 0, cv::NORM_MINMAX);cv::imshow("gaussianBlurOnDFT", plane[0]);cv::idft(gaussianBlur, gaussianBlur);cv::split(gaussianBlur, plane);cv::magnitude(plane[0], plane[1], plane[0]);cv::normalize(plane[0], plane[0], 1, 0, cv::NORM_MINMAX);cv::imshow("idft-gaussianBlur", plane[0]);cv::waitKey();return 0;
}
#endif

欢迎扫描二维码关注微信公众号 深度学习与数学   [每天获取免费的大数据、AI等相关的学习资源、经典和最新的深度学习相关的论文研读,算法和其他互联网技能的学习,概率论、线性代数等高等数学知识的回顾]

opencv图像分析与处理(7)- 频率域滤波的基础公式、步骤与C++实现相关推荐

  1. OpenCV —— 频率域滤波(傅里叶变换,低通和高通滤波,带通和带阻滤波,同态滤波)

    频率域滤波 基本概念 傅里叶变换 二维离散的傅里叶变换 快速傅里叶变换 傅里叶幅度谱与相位谱 谱残差显著性检测 卷积与傅里叶变换的 频率域滤波 低通滤波和高通滤波 带通和带阻滤波 同态滤波 基本概念 ...

  2. 【OpenCV 例程200篇】86. 频率域滤波应用:指纹图像处理

    [OpenCV 例程200篇]86. 频率域滤波应用:指纹图像处理 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 4 ...

  3. (十一)OpenCV实现图像频率域滤波

    1.基础 见<数字图像处理第四版>P137-P209 1.1傅里叶变换Fourier Transform Fourier Transform由法国的一位数学家和物理学家Jean-Bapti ...

  4. OpenCV实现频率域滤波——以高斯低通滤波去噪为例

    最近由于作业原因,试着用OpenCV实现频率域滤波,但是OpenCV中并没有像MATLAB中fftshift这样的中心化操作,所以我写了一个频率域滤波的函数,以后用频率域滤波的时候在主函数中调用即可. ...

  5. 数字图像处理第四章频率域滤波(低通滤波器、高通滤波器、拉普拉斯滤波、同态滤波器)

    本章节的主要内容具体包括:傅里叶变换的概念及处理的相关知识.频率域卷积概念.三种低通滤波器的原理及代码实现.三种高通滤波器的原理及代码实现.频率域拉普拉斯算法原理及实现.同态滤波器原理及代码实现. 4 ...

  6. 空间滤波 频率域滤波

    图像滤波包括:空间阈滤波 和 频率域滤波 . 空间域滤波 空间滤波和空间滤波器的定义 使用空间模板进行的图像处理,被称为空间滤波.模板本身被称为空间滤波器. 执行空间滤波时的相关和卷积概念 一维滤波器 ...

  7. 数字图像处理——第四章 频率域滤波

    数字图像处理--第4章 频率域滤波 文章目录 数字图像处理--第4章 频率域滤波 频率域 1.傅里叶级数原理 1.1.一维傅里叶变换 1.2.二维傅里叶变换 2.python×傅里叶级数 2.1.傅里 ...

  8. 频率域滤波matlab函数,频率域滤波(2) - osc_t0xmr011的个人空间 - OSCHINA - 中文开源技术交流社区...

    一.频率域滤波的基本步骤: 1)使用函数tofloat把输入图像转换为浮点图像(im2double函数也可以) [f,revertclass] = tofloat(f) 2)使用函数paddedsiz ...

  9. python数字图像处理(四) 频率域滤波

    import matplotlib.pyplot as plt import numpy as np import cv2 %matplotlib inline 首先读入这次需要使用的图像 img = ...

  10. 图像处理中的傅里叶变换和频率域滤波概念

    写在前面的话 作者是一名在读的硕士研究僧,方向是机器视觉.由于视觉是一门相对复杂的学科,作者在课堂上学到的东西只是非常浅显的内容,我们老师说是,领我们进了个门.现在打算利用图书馆和网络上的资源进行自学 ...

最新文章

  1. 谷歌搜索喜迎20年,为手机主页添加信息流!
  2. python中typing.NamedTuple示例
  3. IT人为了自己父母和家庭,更得注意自己的身体和心理健康
  4. 被IP代理网站屏蔽了,真是跪了
  5. virtualBox中的ubuntu共享文件夹
  6. 慕课网Spark SQL日志分析 - 4.从Hive平滑过渡到Spark SQL
  7. [Hadoop in China 2011] 华为 - NoSQL/NewSQL在传统IT产业的机遇和挑战
  8. ubuntu xfce下面两个终端合并为一个终端
  9. Spring与网关的集成
  10. Python机器学习:逻辑回归001什么是逻辑回归
  11. SAP License:SAP ECC6安装系列一:安装前硬件和软件准备
  12. mysql 查询语法基础_入门MySQL——查询语法练习
  13. 高二计算机考试题库和答案,2017计算机基础考试题库及答案
  14. matlab2015使用dsolve错误,matlab - 当变量乘以常数时,dsolve中的错误(R2011a) - 堆栈内存溢出...
  15. JAVA编程语言基础第六章
  16. bttray.exe
  17. 【NOIP 2002】字串变换
  18. 基于单片机的十字路口交通灯设计(带左转、紧急、夜间模式且每个绿灯后都有黄灯二)
  19. 达梦数据库表导出的两种方法
  20. 网易邮箱中非常实用的工具,手机、IP等归属地

热门文章

  1. 文件权限管理命令chmod,chown与文本搜索命令grep
  2. 【BZOJ 3652】大新闻 数位dp+期望概率dp
  3. 转载~final, static和 nested class 总结 原文~http://yulin10.bokee.com/2544792.html
  4. 1.2顺序线性表的归并
  5. 匿名对象与非匿名对象的区别
  6. C++ 非类型的模板参数
  7. 13. Use Objects to manage resources.
  8. 微服务学习之Ribbon【Hoxton.SR1版】
  9. 每天一道剑指offer-合并两个排序的链表
  10. python 窗口键 键位码_Python制作AI贪吃蛇,很多很多细节、思路都写下来了