python实现图像的频域滤波_一起学习python-opencv二十七(图像频域操作下)

频域滤波演示

频域滤波其实就是根据卷积定理把原来在空间域的操作转移到频域,这样会提高速度,然后再傅里叶反变换回去得到结果,需要注意的是根据卷积的定义,空域滤波的时候需要翻转模板,不过一般的模板都是对称的,可以不用翻转。

这是前面提到过的卷积定理。首先要避免缠绕的条件是

然后频域滤波的步骤就是:

其中乘以(-1)^(x+y)和fftshift是等价的,这个我暂时也没想明白为什么,不过我试验过

用fftshift的结果ifft回来,看到的就像是原来的乘一个(-1)^(x+y)一样。

我们用python来演示几个滤波函数,参考了https://www.cnblogs.com/tlnshuju/p/7308590.html

上面的文章还叙述了一个比较有意思的现象。

代码在文中有,我们来看结果

虽然相位并不是方向的含义,学过三角函数的都知道,相位决定了什么位置三角函数有最大值

,有最小值,幅值只是决定这个值有多大,那么用在图像里面,幅值只是决定亮度信息,也就是决定山有多高,而相位决定的是哪里应该高,哪里应该低。相位决定的是一个地方的地形特征,比如这里是盆地,这里是高原,而幅值决定的是盆地有多低,高原有多高,可以说相位信息包含了大部分的边缘信息,而幅值是对边缘细节的补充,比如边缘应该有多陡。

但是最后的频域滤波的结果不太对,

我有点迷茫,同样的操作在MATLAB我做过,空域频域结果是一样的啊。

这个傅里叶变换出来的结果感觉好大,但是反变换又没有问题。

用MATALB算出来的也是这么大。MATLAB算出来的结果没有问题啊。

为什么结果都差不是很多,显示出来的就是不一样??

好吧,最后找到了原因:

ifft后面少加了一个2。这个少一个2影响会很大。

fft会默认对每一列进行一维傅里叶变换,而不是对二维数组进行二维傅里叶变换,这个区别会很大。

看来还是得细心啊。说明了频域滤波和空域滤波结果的一致性。再试一个拉普拉斯边缘算子。

下面在介绍几种滤波器:

但是一般我们不同理想的,而是用:

还有我们熟悉的高斯,不过这个是直接在频域里面。

和低通相反的就是高通:

还有带通和带阻滤波器:

其它变换方法

频域的变换方法还有余弦变换,小波变换等。

这个特点其实和傅里叶变换差不多。

这个在opencv也有函数:

这个变换的思路请看https://blog.csdn.net/dugudaibo/article/details/78410570

而二维余弦变换就满足这个可分性和对称性。当然DFT其实也是满足可分性的。

我们或许可以理解,为什么是(ux+vy)了,可分性对于计算量来说会简化很多。

但二维余弦变换的计算量比傅里叶变换要少:https://www.jianshu.com/p/b923cd47ac4a

也就是说只需要一半的数据,余弦变换就能还原傅里叶变换的结果。

余弦变换其实很像三角形式展开的傅里叶级数:

我们完全可以对括号里的余弦和正弦用一下辅助角公式,都化成余弦,当然上面是一维的形式,后来为什么要用欧拉公式改成e指数形式呢,我感觉是因为比较好计算吧。

不过我们上课也就只学习了傅里叶变换,余弦变换原理很简单,其实就相当于傅里叶变换的精简版,小波变换后续会跟上的,暂时没有时间研究。

同态滤波

每种物体都可以不同程度的吸收光。

这样会压缩低频段,更好的展示高频细节。

然后我们来看一个例子:

opencv中的同态滤波:

参考代码:https://blog.csdn.net/qq_34725005/article/details/82691487

不过这段代码是有问题的。

首先滤波的时候没有考虑缠绕问题。首先我介绍一个函数:

可选参数有很多啊。参考了https://blog.csdn.net/solomon1558/article/details/44689611

1范数,2范数,无穷范数都可以计算,当然我们一般用的是最小最大,它是归一化范围的。

这个关键字还是得打上。

以前我用的是convertscaleAbs。这个函数其实用起来是会有问题的,它是先取绝对值然后再采取饱和操作,只能用uint8存储,取完绝对值大于255的都会饱和限制在255。

我下面来试验一下缠绕带来的后果,为了让缠绕的效果明显,原图像的大小最好小一点,因为这样p>=A+C-1,缠绕的相对占比才会大一些,效果明显,如果我们选择了A=100,C=3,这样子P>=102,如果最后填充尺寸都是100,那么其实缠绕效果很不明显的。

有缠绕:

无缠绕

看起来区别还是挺大的。就像我上面说的,原图像尺寸一大,那么效果很不明显:

无缠绕:

有缠绕:

虽然差不多,但是我们还是尽量避免缠绕。还有一个问题,有点不严谨的地方,就是

这个距离应该是对fftshift过的图像操作的,因为那样子低频才在中间,如果没有经过fftshift,低频是在四周的边缘。还有就是你回到上面仔细看看其实滤波函数也不太一样。我改进一下,调整参数之后:

我们放大看这个结果:

还是相当不错的,不过这个还是比较难调整的,而且运行时间比较长。

这次是真的老师下达了任务,先停更至少一周吧。

你可能感兴趣的:(python实现图像的频域滤波)