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

1.基础

见《数字图像处理第四版》P137-P209

1.1傅里叶变换Fourier Transform

Fourier Transform由法国的一位数学家和物理学家Jean-Baptiste Joseph Fourier (1768-1830)提出,主要包括适用于周期函数的傅里叶级数(Fourier Serier)和应用于非周期函数(曲线下面积有限)的傅里叶变换。

  • 傅里叶级数
    傅里叶级数意味着周期为T的连续变量t的周期信号f%28t%29可以表示为正弦函数和余弦函数之和乘以适当的系数。
    借助欧拉公式和欧拉恒等变换,

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

傅里叶级数可以用复指数的形式表示,形式为,

(十一)OpenCV实现图像频率域滤波
其中,系数c_n可表示为:c_n%20%3D%20%5Cfrac%7B1%7D%7BT%7D%5Cint_%7B-T/2%7D%5E%7BT/2%7D%20f%28t%29e%5E%7B-%5Cfrac%7B2%5Cpi%20nt%7D%7BT%7D%7Ddt%2C%20n%3D0%2C%5Cpm%201%2C%5Cpm%202%2C...j%3D%5Csqrt-1
从傅里叶级数的的公式可以看出,周期函数被分解成了使用不同频率,幅度,相角的正弦和/或余弦函数表示的形式。能够将信号从时域在频域上展开来进行分析。这正是傅里叶变换的意义,关于其形象化的描述可参考

  • 连续函数的傅里叶变换
    非周期函数可以看成是一个周期无限大的函数。参照傅里叶级数中的c_n,其频率与系数大小的关系,即傅里叶变换,可表示为:
    F%28%5Cmu%29%20%3D%20%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7Df%28t%29e%5E%7B-j2%5Cpi%5Cmu%20t%7Ddt

1.2卷积定理

连续变量t的两个连续函数f%28t%29h%28t%29的卷积的定义为:

%28f%5Cstar%20h%29%28t%29%20%3D%20%5Cint%20_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7Df%28%5Ctau%29h%28t-%5Ctau%29d%5Ctau

其中,-%5Ctau表示对卷积核函数旋转180度,t是一个函数滑过另一个函数的位移,%5Ctau是积分虚拟变量。上式的傅里叶变换表示为:

(十一)OpenCV实现图像频率域滤波
式中方括号内是h%28t-%5Ctau%29的傅里叶变换,F%28h%28t-%5Ctau%29%29%3DH%28%5Cmu%29e%5E%7B-j2%5Cpi%5Cmu%5Ctau%7D,H%28%5Cmu%29h%28t%29的傅里叶变换,式(5)可表示为:
(十一)OpenCV实现图像频率域滤波 其中%5Cbullet表示乘法,%5Czeta表示傅里叶变换。

从上式可以看出,两个函数在空间域的卷积的傅里叶变换等于两个函数在频域的傅里叶变换的乘积。反之,如果频域有两次傅里叶变换的乘积,则可以通过计算傅里叶逆变换得到空间域的卷积。综上所述,卷积定理可以表示为:

%28f%5Cstar%20h%29%28t%29%20%5CLeftrightarrow%20%28F%5Cbullet%20H%29%28%5Cmu%29

%28f%5Cbullet%20h%29%28t%29%20%5CLeftrightarrow%20%28F%5Cstar%20H%29%28%5Cmu%29

1.3冲激函数及其取样性质

连续变量tt%3D0处的单位冲量表示为%5Cdelta%7Bt%7D,表示为:

(十一)OpenCV实现图像频率域滤波
脉冲函数满足以下性质:

  • 满足身份:%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7D%5Cdelta%28t%29dt%20%3D%201
  • 采样属性:%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7Df%28t%29%5Cdelta%28t-t_0%29dt%20%3D%20f%28t_0%29,采样属性刚好在脉冲位置t_0处得到f%28t%29的值。

实际采样f%28t%29时,需要使用一系列脉冲信号,以%5CDelta%20T为间隔进行采样,这样可以定义脉冲串:

(十一)OpenCV实现图像频率域滤波
在上面,t被解释为一个连续的时间变量。对于离散变量,冲激函数定义为:

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

满足的性质等价于:

  • 身份:(十一)OpenCV实现图像频率域滤波– 采样属性:(十一)OpenCV实现图像频率域滤波

1.4冲激和冲激串的傅里叶变换

根据连续单变量函数傅里叶变换的定义,函数%5Cdelta%28t%29的傅里叶变换可表示为:

%5Czeta%20%5C%7B%5Cdelta%28t%29%5C%7D%3DF%28%5Cmu%29%3D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7D%5Cdelta%28t%29e%5E%7B-j2%5Cpi%20%5Cmu%20t%7Ddt%3D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7De%5E%7B-j2%5Cpi%20%5Cmu%20t%7D%5Cdelta%28t%29dt%3De%5E%7B-j2%5Cpi%20%5Cmu%200%7D%3D1

t%3Dt_0处,脉冲的傅里叶变换为:

%5Czeta%20%5C%7B%5Cdelta%28t-t_0%29%5C%7D%3DF%28%5Cmu%29%3D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7D%5Cdelta%28t-t_0%29e%5E%7B-j2%5Cpi%20%5Cmu%20t%7Ddt%3D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7De%5E%7B-j2%5Cpi%20%5Cmu%20t%7D%5Cdelta%28t-t_0%29dt%3De%5E%7B-j2%5Cpi%20%5Cmu%20t_0%7D

为了获得离散信号,通常需要使用周期性脉冲序列进行采样。因此,在推导离散信号的傅里叶变换时,需要先得到周期脉冲序列的傅里叶变换。

首先,由上面的定义的傅立叶变换和反变换可知,若函数f%28t%29有傅立叶变换F%28%5Cmu%29,则函数F%28t%29的傅里叶变换为f%28-%5Cmu%29,由此性质,冲激%5Cdelta%28t-t_0%29的傅立叶变换为e%5E%7B-j2%5Cpi%20%5Cmu%20t_0%7D,则e%5E%7B-j2%5Cpi%20%5Cmu%20t_0%7D的傅里叶变换为%5Cdelta%28-%5Cmu-t_0%29。记a%3D-t_0,则e%5E%7Bj2%5Cpi%20%5Cmu%20a%7D的傅立叶变换为%5Cdelta%28-%5Cmu%20%2B%20a%29,对于冲激函数,除%5Cmu%20%3D%20a外,%5Cdelta都为0,因此%5Cdelta%28-%5Cmu%20%2B%20a%29%3D%5Cdelta%28%5Cmu%20-%20a%29,也即%5Czeta%5Be%5E%7Bj2%5Cpi%20%5Cmu%20a%7D%5D%3D%5Cdelta%28%5Cmu%20-%20a%29

由1.3知S_%7B%5CDelta%20T%7D%28t%29是周期为%5CDelta%20T的周期函数,其傅立叶级数表示为:

(十一)OpenCV实现图像频率域滤波
(十一)OpenCV实现图像频率域滤波
周期对%5B-%5CDelta%20T/2%EF%BC%8C%20%5CDelta%20T/2%5D的积分只包括原点的冲量,所以%5B-%5CDelta%20T/2%EF%BC%8C%20%5CDelta%20T/2%5D可以表示为:

c_n%3D%5Cfrac%7B1%7D%7B%5CDelta%20T%7D%5Cint_%7B-%5CDelta%20T/2%7D%5E%7B%5CDelta%20T/2%7D%5Cdelta%28t%29e%5E%7B-j%5Cfrac%7B2%5Cpi%20n%7D%7B%5CDelta%20T%7D%7Ddt%3D%5Cfrac%7B1%7D%7B%5CDelta%20T%7De%5E0%3D%5Cfrac%7B1%7D%7B%5CDelta%20T%7D

那么,傅里叶级数可以表示为:
(十一)OpenCV实现图像频率域滤波结合以上%5Czeta%5Be%5E%7Bj2%5Cpi%20%5Cmu%20a%7D%5D%3D%5Cdelta%28%5Cmu%20-%20a%29,则

%5Czeta%5Be%5E%7Bj%5Cfrac%7B2%5Cpi%20n%7D%7B%5CDelta%20T%7Dt%7D%5D%3D%5Cdelta%28%5Cmu%20-%20%5Cfrac%7Bn%7D%7B%5CDelta%20T%7D%29
组合和的傅里叶变换等于各分量的傅里叶变换之和,则周期脉冲串的傅里叶变换为

(十一)OpenCV实现图像频率域滤波 由上式可知,周期为%5CDelta%20T的脉冲串的傅里叶变换仍是脉冲串,其周期为%5Cfrac%7B1%7D%7B%5CDelta%20T%7D,其周期成反比。

1.5取样后函数的傅里叶变换和取样定理

(十一)OpenCV实现图像频率域滤波
使用脉冲序列采样的过程如上图所示,其数学表达式为:

%5Ctilde%20f%28t%29%3Df%28t%29S_%7B%5CDelta%20T%7D%28t%29%3D%5Csum_%7Bn%3D-%5Cinfty%7D%5E%7B%5Cinfty%7Df%28t%29%5Cdelta%20%28t-n%5CDelta%20T%29
%5Ctilde%20f%28t%29表示采样后的函数。采样后,采样序列中任意一个样本的值f_k由下式给出:

f_k%3D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7Df%28t%29%5Cdelta%28t-k%5CDelta%20T%29dt%3Df%28k%5CDelta%20T%29

采样函数的傅里叶变换表示:
F%28%5Cmu%29表示连续函数f%28t%29函数的傅里叶变换,采样函数%5Ctilde%20f%28t%29f%28t%29与脉冲串的乘积。根据卷积定理,空间域中两个函数的乘积的傅里叶变换是频域中两个变换的卷积。因此,%5Ctilde%20f%28t%29的傅里叶变换可以表示为:

%5Ctilde%20F%28%5Cmu%29%20%3D%20%5Czeta%5C%7B%5Ctilde%20f%28t%29%5C%7D%3D%5Czeta%5C%7Bf%28t%29S_%7B%5CDelta%20T%7D%28t%29%5C%7D%3D%28F%5Cstar%20S%29%28%5Cmu%29
由以上推导可知,脉冲序列的傅里叶变换为:
(十一)OpenCV实现图像频率域滤波
根据一维卷积的定义,F%28%5Cmu%29S%28%5Cmu%29的卷积可以表示为:

(十一)OpenCV实现图像频率域滤波
由以上推导可知,采样函数%5Ctilde%20f%28t%29的傅里叶变换%5Ctilde%20F%28%5Cmu%29是原函数傅里叶变换的无限循环复制序列。考虑带限函数的傅里叶变换示意图:

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

上图中,图a是函数f%28t%29的傅里叶变换F%28%5Cmu%29,图b是函数%5Ctilde%20f%28t%29的傅里叶变换%5Ctilde%20F%28%5Cmu%291/%5CDelta%20T是取样函数的取样率,从上图可以看到取样率要高到足以在各个周期之间提供有效的间隔,以保持F%28%5Cmu%29的完整性。图c和图d分别对应的是临界取样和欠取样。

对于以原点为中心的有限区间%5B-%5Cmu_%7Bmax%7D%2C%5Cmu_%7Bmax%7D%5D以外的频率值,傅里叶变换为零的函数f%28t%29称为带限函数。从上图可以看出,当%5CDelta%20T很大时,%5Ctilde%20F%28%5Cmu%29会重叠,完整的F%28%5Cmu%29不能与%5Ctilde%20F%28%5Cmu%29分开,即无法通过傅里叶逆变换恢复原始信号。因此,为了恢复原始信号,必须提高采样频率,如下图所示:
(十一)OpenCV实现图像频率域滤波
1/2%5CDelta%20T%5Cgt%5Cmu_%7Bmax%7D时可以保证足够的间隔:%5Cfrac%7B1%7D%7B%5CDelta%20T%7D%5Cgt2%5Cmu_%7Bmax%7D,该式表明,如果以超过函数最高频率2倍的取样率来得到样本,那么连续带限函数就能由其样本集合复原,该结论即取样定理。

1.6由取样后的数据复原函数

定义函数H%28%5Cmu%29为:
(十一)OpenCV实现图像频率域滤波F%28%5Cmu%29为:F%28%5Cmu%29%3DH%28%5Cmu%29%5Ctilde%20F%28%5Cmu%29,得到F%28%5Cmu%29后,可通过傅里叶逆变换f%28t%29恢复:
f%28t%29%3D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7DF%28%5Cmu%29e%5E%7Bj2%5Cpi%5Cmu%20t%7D

F%28%5Cmu%29%3DH%28%5Cmu%29%5Ctilde%20F%28%5Cmu%29我们可以得到:
f%28t%29%3D%5Czeta%5E%7B-1%7D%5C%7BF%28%5Cmu%29%5C%7D%3D%5Czeta%5E%7B-1%7D%5C%7BH%28%5Cmu%29%5Ctilde%20F%28%5Cmu%29%5C%7D%3Dh%28t%29%5Cstar%5Ctilde%20f%28t%29
即频域中函数的处理相当于空间域中的卷积。

2.离散傅里叶变换(Discrete Fourier Transform)

2.1一维离散傅里叶变换

前面讨论采样定理时,发现了采样函数%5Ctilde%20f%28t%29的傅里叶变换%5Ctilde%20F%28%5Cmu%29与原函数f%28t%29的傅里叶变换F%28%5Cmu%29之间的关系,但没有给出%5Ctilde%20F%28%5Cmu%29的表达式。定义要求:
(十一)OpenCV实现图像频率域滤波
%5Ctilde%20F%28%5Cmu%EF%BC%89F%28%5Cmu%EF%BC%89的关系,可知,%5Ctilde%20F%28%5Cmu%EF%BC%89是周期为1/%5CDelta%20T的无限周期连续函数,因此表征%5Ctilde%20F%28%5Cmu%EF%BC%89只需要一个周期。假设从%5Cmu%3D0%5Cmu%3D1/%5CDelta%20T的一个周期内等间隔的取%5Ctilde%20F%28%5Cmu%EF%BC%89的M个样本,在如下频率处取样可实现:%5Cmu%3D%5Cfrac%7Bm%7D%7BM%5CDelta%20T%7D%2C%20m%3D0%2C1%2C2%2C...%2CM-1%5Cmu代入上面的公式中可得%5Ctilde%20F%28%5Cmu%29的表达式为:

(十一)OpenCV实现图像频率域滤波
已知一个由f(t)的M个样本组成的集合%5C%7Bf_m%5C%7D时,上式给出了一个与输入样本集合的离散傅里叶变换相对应的M个复值集合%5C%7BF_m%5C%7D。反之,求得%5C%7BF_m%5C%7D时也可由傅里叶反变换求得%5C%7Bf_m%5C%7D

(十一)OpenCV实现图像频率域滤波在图像中,xy通常用于表示图像坐标,%5Cmuv用于表示频率变量。这些变量被理解为整数,上面的傅里叶变换对可以表示为:

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

2.2二维函数的傅里叶变换:

将前面的概念扩展到两个维度。

二维脉冲函数:%5Cdelta%28t%2Cz%29%5Cbegin%7Bcases%7D%20%3D1%2Ct%3Dz%3D0%5C%5C%200%2Cothers%20%5Cend%7Bcases%7D%2C%20%E4%B8%94%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7D%5Cdelta%28t%2Cz%29dtdz%20%3D%201

二维脉冲函数的采样性质:

%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7Df%28t%2Cz%29%5Cdelta%28t-t_0%2Cz-z_0%29dtdz%20%3D%20f%28t_0%2Cz_0%29

二维连续函数的傅里叶变换对:

F%28%5Cmu%2Cv%29%20%3D%20%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7Df%28t%2Cz%29e%5E%7B-j2%5Cpi%28%5Cmu%20t%2Bvz%29%7Ddtdzf%28t%2Cz%29%20%3D%20%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7D%5Cint_%7B-%5Cinfty%7D%5E%7B%5Cinfty%7DF%28%5Cmu%2Cv%29e%5E%7Bj2%5Cpi%28%5Cmu%20t%2Bvz%29%7Dd%5Cmu%20d%20v

二维脉冲序列(二维采样函数):
(十一)OpenCV实现图像频率域滤波
二维采样定理:

%5Cbegin%7Bcases%7D%20%5CDelta%20T%20%5Clt%20%5Cfrac%7B1%7D%7B2%5Cmu_%7Bmax%7D%7D%20%5C%5C%20%5CDelta%20Z%20%5Clt%20%5Cfrac%7B1%7D%7B2%20v_%7Bmax%7D%7D%20%5Cend%7Bcases%7D

2D 信号的混叠:

(十一)OpenCV实现图像频率域滤波 二维离散傅里叶变换对:

(十一)OpenCV实现图像频率域滤波
二维离散傅里叶变换的平移旋转和周期性:

从定义可以得到:

  • 潘:f%28x%2Cy%29e%5E%7Bj2%5Cpi%28%5Cmu_0x/M%2Bv_0%20y/M%29%7D%5CLeftrightarrow%20F%28%5Cmu%20-%5Cmu_0%2C%20v-%20v_0%29
    f%28x-x_0%2Cy-y_0%29%5CLeftrightarrow%20F%28%5Cmu%20-%5Cmu_0%2C%20v-%20v_0%29e%5E%7B-j2%5Cpi%28x_0%5Cmu/M%2By_0%20v/M%29%7D
    用所示的指数项乘以f%28x%2Cy%29将使DFT的原点移动到%28%5Cmu_0%2Cv_0%29处,用负指数乘以F%28%5Cmu%2C%20v%29将使f%28x%2Cy%29的原点移动到点f%28x_0%2Cy_0%29处。平移不影响F%28%5Cmu%2Cv%29的幅度
  • 回转:
    使用极坐标:x%3Drcos%5Ctheta%2Cy%3Drsin%20%5Ctheta%2C%20%5Cmu%3D%5Comega%20cos%20%5Cvarphi%2C%20v%20%3D%20sin%20%5Cvarphi,则有如下变换对:$f(r,\theta+\theta_0)\Leftrightarrow F(\omega, \varphi + \theta_0)%E5%8D%B3%EF%BC%8C%E8%8B%A5f%28x%2Cy%29%E6%97%8B%E8%BD%AC\theta_0%E8%A7%92%E5%BA%A6%EF%BC%8C%E5%88%99F(\mu,v)%E4%B9%9F%E5%B0%86%E6%97%8B%E8%BD%AC%E7%9B%B8%E5%90%8C%E7%9A%84%E8%A7%92%E5%BA%A6%E3%80%82%E5%8F%8D%E4%B9%8B%EF%BC%8C%E8%8B%A5F(\mu,v)%E6%97%8B%E8%BD%AC%E6%9F%90%E4%B8%AA%E8%A7%92%E5%BA%A6%EF%BC%8Cf(x,y)$也旋转相同的角度。
  • 定期:
    在同一维下,二维离散傅里叶变换及其逆变换在%5Cmuv方向上是无限周期性的,即:
    F%28%5Cmu%2Cv%29%3DF%28u%2Bk_1M%2Cv%29%3DF%28%5Cmu%2Cv%2Bk_2N%29%3DF%28u%2Bk_1M%2Cv%2Bk_2N%29

    f%28x%2Cy%29%3Df%28x%2Bk_1M%2Cy%29%3Df%28x%2Cy%2Bk_2N%29%3Df%28x%2Bk_1M%2Cy%2Bk_2N%29
    从第一部分的分析,可发现,区间0到M-1上的变换数据由在点M/2处相遇的两个半周期组成,可以发现该周期内较第部分的F%28%5Cmu%29出现在较高的频率处,不便于分析和滤波。根据上述的平移性质,
    f%28x%29e%5E%7Bj2%5Cpi%20%28%5Cmu_0x/M%29%7D%5CLeftrightarrow%20F%28%5Cmu%20-%5Cmu_0%29
    该式将把数据的原点F%280%29平移到%5Cmu_0,若另%5Cmu_0%3DM/2,则指数项变为e%5E%7Bj%5Cpi%20x%7D,因为x是整数,故根据欧拉公式,其可表示为%28-1%29%5Ex,代入上式可得:
    f%28x%29%28-1%29%5Ex%5CLeftrightarrow%20F%28%5Cmu%20-%20M/2%29
    如下所示。
    (十一)OpenCV实现图像频率域滤波 对于二维情况,可以表示为:
    f%28x%2Cy%29%28-1%29%5E%7Bx%2By%7D%5CLeftrightarrow%20F%28%5Cmu%20-%20M/2%2C%20v-N/2%29

频谱、相位频谱和功率频谱:

从前面的分析可知,二维DFT通常是复函数,用极坐标形式表示为:

F%28%5Cmu%2Cv%29%3DR%28%5Cmu%2Cv%29%2BjI%28%5Cmu%2Cv%29%3D%7CF%28%5Cmu%2Cv%29%7Ce%5E%7Bj%5Cphi%28%5Cmu%2Cv%29%7D

傅里叶光谱:
%7CF%28%5Cmu%2Cv%29%7C%3D%5BR%5E2%28%5Cmu%2Cv%29%2BI%5E2%28%5Cmu%2Cv%29%5D%5E%7B1/2%7D

相谱:%5Cphi%28%5Cmu%2Cv%29%3Darctan%5B%5Cfrac%7BI%28%5Cmu%2Cv%29%7D%7BR%28%5Cmu%2Cv%29%7D%5D

功率谱:P%28%5Cmu%2Cv%29%3D%7CF%28%5Cmu%2Cv%29%7C%5E2%20%3D%20R%5E2%28%5Cmu%2Cv%29%20%2B%20I%5E2%28%5Cmu%2Cv%29

一张图像的光谱示意图如下:
(十一)OpenCV实现图像频率域滤波

图A是原图像,图B是直接对原图像进行傅里叶变换得到的频谱,可以看到四个角较亮,但因为其值分散在四个角落,因此很难观察,使用前述的变换,对原函数f%28x%2Cy%29乘以%28-1%29%5E%7Bx%2By%7D将其变换的中心移动到图像的中心可得图C,更便于观察分析。图D是对频谱值取对数后的结果。

2.2二维离散卷积定理

将一维离散卷积定理扩展到两个变量,我们得到:

(十一)OpenCV实现图像频率域滤波二维卷积定理可以表示为:

%28f%20%5Cstar%20h%29%28x%2Cy%29%20%5CLeftrightarrow%20%28F%5Cbullet%20H%29%28%5Cmu%2Cv%29
使用卷积定理时的问题:

如果使用DFT和卷积定理来求得如下图左列相同的卷积结果时,需考虑DFT表达式中固有的周期性。
(十一)OpenCV实现图像频率域滤波
上图中左列,是根据定义使用尺寸为400的卷积核对尺寸为400的原信号进行卷积,先对卷积核函数旋转180度,再依次滑过原信号,得到图左列最后所示的卷积结果。

若使用卷积定理,则f,h都具有周期性,若根据卷积定理,先计算f和h的DFT,然后让这个变换相乘,再计算傅里叶反变换,将得到如上图右侧所示的结果,显然如此计算的卷积结果是不对的。

交叠错误很容易解决。考虑f(x)和h(x),他们分别由A个样本和B个样本组成,可证明,若在这两个函数中填充零,使他们长度P相同,则选择

P%5Cge%20A%2BB-1

可以避免重叠错误。

f%28x%2Cy%29h%28x%2Cy%29分别表示大小为AXB像素和CXD像素的图像阵列.它们循环卷积中的交叠错误可通过对这两个函数填充零来避免,
f_p%28x%2Cy%29%20%3D%20%5Cbegin%7Bcases%7D%20f%28x%2Cy%29%2C0%5Cle%20x%20%5Cle%20A-1%20%E5%92%8C%200%20%5Cle%20y%20%5Cle%20B-1%5C%5C%200%2CA%20%5Cle%20x%20%5Cle%20P%E6%88%96B%20%5Cle%20y%20%5Cle%20Q%20%5Cend%7Bcases%7D

h_p%28x%2Cy%29%3D%5Cbegin%7Bcases%7D%20h%28x%2Cy%29%2C%200%20%5Cle%20C-1%E5%92%8C%200%20%5Cle%20y%20%5Cle%20D-1%5C%5C%200%2C%20C%20%5Cle%20x%20%5Cle%20P%20%E6%88%96%20D%20%5Cle%20y%20%5Cle%20Q%20%5Cend%7Bcases%7D
其中,P%20%5Cge%20A%2BC-1Q%20%5Cge%20B%2BD-1

填充零后图像大小为PXQ,若两个阵列大小相同,都为MXN,则要求P%5Cge2M-1Q%5Cge2N-1.DFT算法执行偶数大小的阵列时速度较快,因此通常选择满足上述公式的最小偶整数作为P和Q的值,若两个阵列相同,则P%3D2MQ%3D2N

3.频率域滤波步骤

  • 1)一幅大小为MXN的输入图像f%28x%2Cy%29,由前述公式得到填充零后的尺寸P=2M和Q=2N
  • 2)使用零填充,镜像填充或者复制填充,形成大小为PXQ的填充后的图像f_P%28x%2Cy%29
  • 3)根据前述二维傅里叶变换的平移性质,将f_P%28x%2Cy%29乘以%28-1%29%5E%7Bx%2By%7D,使傅里叶变换位于PXQ大小的频率矩形的中心
  • 4)计算步骤3得到的图像的DFT,即F%28%5Cmu%2Cv%29
  • 5)建一个实对称滤波器传递函数H%28%5Cmu%2C%20v%29,其大小为PXQ,中心在%28P/2%2CQ/2%29
  • 6)采用对应像素相乘得到G%28%5Cmu%2Cv%29%3DH%28%5Cmu%2Cv%29F%28%5Cmu%2Cv%29,即G%28i%2Ck%29%3DH%28i%2Ck%29F%28i.k%29%2Ci%3D0%2C1%2C2%2C...%2CM-1k%3D0%2C1%2C2%2C...%2CN-1
  • 7)计算G%28%5Cmu%2C%20v%29的IDFT得到滤波后的图像(大小为PXQ):g_p%28x%2Cy%29%3D%5C%7Breal%5B%5Czeta%5E%7B-1%7D%5BG%28%5Cmu%2Cv%29%5D%5D%5C%7D%28-1%29%5E%7Bx%2By%7D
  • 8)最后,从g_P%28x%2Cy%29的左上象限提取一个大小为MXN的区域,得到与输入图像大小相同的滤波结果g%28x%2Cy%29

4.OpenCV API

  • int cv::getOptimalDFTSize ( int vecsize )
    在进行傅里叶变换时,需要对原始图像进行扩展以提高处理速度。这种方法正是为了获得满足最优处理速度的最小扩展。
  • void cv::copyMakeBorder ( InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, const Scalar & value = Scalar() )对图像进行扩充,可设置上下左右的扩充大小和类型
  • void cv::merge ( const Mat * mv, size_t count, OutputArray dst )将Mat数组mv合并成count channel的dst,与split刚好相反
  • void cv::dft ( InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0 )执行1d或2d离散傅里叶变换
  • void cv::magnitude ( InputArray x, InputArray y, OutputArray magnitude )计算xy的模,dst%28I%29%3D%5Csqrt%7Bx%28I%29%5E2%2By%28I%29%5E2%29%7D

例子:

// https://docs.opencv.org/4.x/d8/d01/tutorial_discrete_fourier_transform.html
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"

#include <iostream>

using namespace cv;
using namespace std;

static void help(char ** argv)
{
    cout << endl
        <<  "This program demonstrated the use of the discrete Fourier transform (DFT). " << endl
        <<  "The dft of an image is taken and it's power spectrum is displayed."  << endl << endl
        <<  "Usage:"                                                                      << endl
        << argv[0] << " [image_name -- default lena.jpg]" << endl << endl;
}

int main(int argc, char ** argv)
{
    help(argv);

    const char* filename = argc >=2 ? argv[1] : "lena.jpg";

    Mat I = imread( samples::findFile( filename ), IMREAD_GRAYSCALE);
    if( I.empty()){
        cout << "Error opening image" << endl;
        return EXIT_FAILURE;
    }

    //! [expand]
    Mat padded;                            //expand input image to optimal size
    int m = getOptimalDFTSize( I.rows );
    int n = getOptimalDFTSize( I.cols ); // on the border add zero values
    copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));
    //! [expand]

    //! [complex_and_real]
    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    Mat complexI;
    merge(planes, 2, complexI);         // Add to the expanded another plane with zeros
    //! [complex_and_real]

    //! [dft]
    dft(complexI, complexI);            // this way the result may fit in the source matrix
    //! [dft]

    // compute the magnitude and switch to logarithmic scale
    // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
    //! [magnitude]
    split(complexI, planes);                   // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
    magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
    Mat magI = planes[0];
    //! [magnitude]

    //! [log]
    magI += Scalar::all(1);                    // switch to logarithmic scale
    log(magI, magI);
    //! [log]

    //! [crop_rearrange]
    // crop the spectrum, if it has an odd number of rows or columns
    magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));

    // rearrange the quadrants of Fourier image  so that the origin is at the image center
    int cx = magI.cols/2;
    int cy = magI.rows/2;

    Mat q0(magI, Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant
    Mat q1(magI, Rect(cx, 0, cx, cy));  // Top-Right
    Mat q2(magI, Rect(0, cy, cx, cy));  // Bottom-Left
    Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right

    Mat tmp;                           // swap quadrants (Top-Left with Bottom-Right)
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);

    q1.copyTo(tmp);                    // swap quadrant (Top-Right with Bottom-Left)
    q2.copyTo(q1);
    tmp.copyTo(q2);
    //! [crop_rearrange]

    //! [normalize]
    normalize(magI, magI, 0, 1, NORM_MINMAX); // Transform the matrix with float values into a
                                            // viewable image form (float between values 0 and 1).
    //! [normalize]
    imshow("Input Image"       , I   );    // Show the result
    imshow("spectrum magnitude", magI);
    waitKey();

    return EXIT_SUCCESS;
}

结果:
(十一)OpenCV实现图像频率域滤波
REF:

1.https://zhuanlan.zhihu.com/p/351173878
2.https://zhuanlan.zhihu.com/p/19763358
3.https://zhuanlan.zhihu.com/p/31371519
4.https://docs.opencv.org/4.x/d8/d01/tutorial_discrete_fourier_transform.html
5.https://www.cnblogs.com/HL-space/p/10546602.html

版权声明:本文为博主恒友成原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/lx_ros/article/details/123173528

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2022年3月2日 下午4:43
下一篇 2022年3月2日 下午5:16

相关推荐