import matplotlib.pyplot as plt
import numpy as np
import cv2
%matplotlib inline

首先读入这次需要使用的图像

img = cv2.imread('apple.jpg',0) #直接读为灰度图像
plt.imshow(img,cmap="gray")
plt.axis("off")
plt.show()

使用numpy带的fft库完成从频率域到空间域的转换。

f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)

低通滤波器

低通滤波器的公式如下

\[H(u,v)=
\begin{cases}
1, & \text{if $D(u,v)$ } \leq D_{0}\\
0, & \text{if $D(u,v)$} \geq D_{0}
\end{cases}
\]

其中\(D(u,v)\)为频率域上\((u,v)\)点到中心的距离,\(D_0\)由自己设置



白点就是所允许通过的频率范围

3d图像如下

我们先把苹果转化成频率域看下效果

#取绝对值:将复数变化成实数
#取对数的目的为了将数据变化到0-255
s1 = np.log(np.abs(fshift))
plt.subplot(121),plt.imshow(s1,'gray')
plt.title('Frequency Domain')
plt.show()

matplotlib对于不是uint8的图像会自动把图像的数值缩放到0-255上,更多可以查看对该问题的讨论

我们在频率域上试着取不同的\(d_0\)再将其反变换到空间域看下效果

def make_transform_matrix(d,image):
transfor_matrix = np.zeros(image.shape)
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
for i in range(transfor_matrix.shape[0]):
for j in range(transfor_matrix.shape[1]):
def cal_distance(pa,pb):
from math import sqrt
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
return dis
dis = cal_distance(center_point,(i,j))
if dis <= d:
transfor_matrix[i,j]=1
else:
transfor_matrix[i,j]=0
return transfor_matrix d_1 = make_transform_matrix(10,fshift)
d_2 = make_transform_matrix(30,fshift)
d_3 = make_transform_matrix(50,fshift)

设定距离分别为10,30,50其通过的频率的范围如图

plt.subplot(131)
plt.axis("off")
plt.imshow(d_1,cmap="gray")
plt.title('D_1 10')
plt.subplot(132)
plt.axis("off")
plt.title('D_2 30')
plt.imshow(d_2,cmap="gray")
plt.subplot(133)
plt.axis("off")
plt.title("D_3 50")
plt.imshow(d_3,cmap="gray")
plt.show()

img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_1)))
img_d2 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_2)))
img_d3 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_3)))
plt.subplot(131)
plt.axis("off")
plt.imshow(img_d1,cmap="gray")
plt.title('D_1 10')
plt.subplot(132)
plt.axis("off")
plt.title('D_2 30')
plt.imshow(img_d2,cmap="gray")
plt.subplot(133)
plt.axis("off")
plt.title("D_3 50")
plt.imshow(img_d3,cmap="gray")
plt.show()

讲上面过程整理得到频率域低通滤波器的代码如下

def lowPassFilter(image,d):
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f) def make_transform_matrix(d):
transfor_matrix = np.zeros(image.shape)
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
for i in range(transfor_matrix.shape[0]):
for j in range(transfor_matrix.shape[1]):
def cal_distance(pa,pb):
from math import sqrt
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
return dis
dis = cal_distance(center_point,(i,j))
if dis <= d:
transfor_matrix[i,j]=1
else:
transfor_matrix[i,j]=0
return transfor_matrix
d_matrix = make_transform_matrix(d)
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
return new_img
plt.imshow(lowPassFilter(img,60),cmap="gray")

高通滤波器

高通滤波器同低通滤波器非常类似,只不过二者通过的波正好是相反的

\[H(u,v)=
\begin{cases}
0, & \text{if $D(u,v)$ } \leq D_{0}\\
1, & \text{if $D(u,v)$} \geq D_{0}
\end{cases}
\]

def highPassFilter(image,d):
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f)
def make_transform_matrix(d):
transfor_matrix = np.zeros(image.shape)
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
for i in range(transfor_matrix.shape[0]):
for j in range(transfor_matrix.shape[1]):
def cal_distance(pa,pb):
from math import sqrt
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
return dis
dis = cal_distance(center_point,(i,j))
if dis <= d:
transfor_matrix[i,j]=0
else:
transfor_matrix[i,j]=1
return transfor_matrix
d_matrix = make_transform_matrix(d)
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
return new_img
img_d1 = highPassFilter(img,10)
img_d2 = highPassFilter(img,30)
img_d3 = highPassFilter(img,50)
plt.subplot(131)
plt.axis("off")
plt.imshow(img_d1,cmap="gray")
plt.title('D_1 10')
plt.subplot(132)
plt.axis("off")
plt.title('D_2 30')
plt.imshow(img_d2,cmap="gray")
plt.subplot(133)
plt.axis("off")
plt.title("D_3 50")
plt.imshow(img_d3,cmap="gray")
plt.show()

显然当\(D_0=10\)时,苹果的边缘最清楚

不同滤波的比较

import imagefilter
thread_img = imagefilter.RobertsAlogrithm(img)
laplace_img = imagefilter.LaplaceAlogrithm(img,"fourfields")
mean_img = cv2.blur(img,(3,3))
plt.subplot(131)
plt.imshow(thread_img,cmap="gray")
plt.title("ThreadImage")
plt.axis("off")
plt.subplot(132)
plt.imshow(laplace_img,cmap="gray")
plt.axis("off")
plt.title("LaplaceImage")
plt.subplot(133)
plt.imshow(mean_img,cmap="gray")
plt.title("meanImage")
plt.axis("off")
plt.show()

空间域上的平均滤波和低通滤波一样,只要起去掉无关信息,平滑图像的作用。

Roberts,Laplace等滤波则起的提取边缘的作用。

频率域高通滤波器

高斯高通滤波器

频率域高斯高通滤波器的公式如下

\[H(u,v) = 1-e^{\dfrac{-D^2(u,v)}{2D_0^2}}
\]

def GaussianHighFilter(image,d):
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f)
def make_transform_matrix(d):
transfor_matrix = np.zeros(image.shape)
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
for i in range(transfor_matrix.shape[0]):
for j in range(transfor_matrix.shape[1]):
def cal_distance(pa,pb):
from math import sqrt
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
return dis
dis = cal_distance(center_point,(i,j))
transfor_matrix[i,j] = 1-np.exp(-(dis**2)/(2*(d**2)))
return transfor_matrix
d_matrix = make_transform_matrix(d)
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
return new_img

使用高斯滤波器d分别为10,30,50实现的效果

img_d1 = GaussianHighFilter(img,10)
img_d2 = GaussianHighFilter(img,30)
img_d3 = GaussianHighFilter(img,50)
plt.subplot(131)
plt.axis("off")
plt.imshow(img_d1,cmap="gray")
plt.title('D_1 10')
plt.subplot(132)
plt.axis("off")
plt.title('D_2 30')
plt.imshow(img_d2,cmap="gray")
plt.subplot(133)
plt.axis("off")
plt.title("D_3 50")
plt.imshow(img_d3,cmap="gray")
plt.show()

高斯低通滤波器

频率域高斯低通滤波器的公式如下

\[H(u,v) = e^{\dfrac{-D^2(u,v)}{2D_0^2}}
\]

def GaussianLowFilter(image,d):
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f)
def make_transform_matrix(d):
transfor_matrix = np.zeros(image.shape)
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
for i in range(transfor_matrix.shape[0]):
for j in range(transfor_matrix.shape[1]):
def cal_distance(pa,pb):
from math import sqrt
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
return dis
dis = cal_distance(center_point,(i,j))
transfor_matrix[i,j] = np.exp(-(dis**2)/(2*(d**2)))
return transfor_matrix
d_matrix = make_transform_matrix(d)
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
return new_img
img_d1 = GaussianLowFilter(img,10)
img_d2 = GaussianLowFilter(img,30)
img_d3 = GaussianLowFilter(img,50)
plt.subplot(131)
plt.axis("off")
plt.imshow(img_d1,cmap="gray")
plt.title('D_1 10')
plt.subplot(132)
plt.axis("off")
plt.title('D_2 30')
plt.imshow(img_d2,cmap="gray")
plt.subplot(133)
plt.axis("off")
plt.title("D_3 50")
plt.imshow(img_d3,cmap="gray")
plt.show()

空间域的高斯滤波

通常空间域使用高斯滤波来平滑图像,在上一篇已经写过,直接使用上篇文章的代码。

def GaussianOperator(roi):
GaussianKernel = np.array([[1,2,1],[2,4,2],[1,2,1]])
result = np.sum(roi*GaussianKernel/16)
return result def GaussianSmooth(image):
new_image = np.zeros(image.shape)
image = cv2.copyMakeBorder(image,1,1,1,1,cv2.BORDER_DEFAULT)
for i in range(1,image.shape[0]-1):
for j in range(1,image.shape[1]-1):
new_image[i-1,j-1] =GaussianOperator(image[i-1:i+2,j-1:j+2])
return new_image.astype(np.uint8) new_apple = GaussianSmooth(img)
plt.subplot(121)
plt.axis("off")
plt.title("origin image")
plt.imshow(img,cmap="gray")
plt.subplot(122)
plt.axis("off")
plt.title("Gaussian image")
plt.imshow(img,cmap="gray")
plt.subplot(122)
plt.axis("off")
plt.show()

巴特沃斯滤波器

无论是低通滤波器,高通滤波器都是粗暴的一刀切,正如之前那么多空间域的滤波器一样,我们希望它通过的频率和与中心线性相关。

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

def butterworthPassFilter(image,d,n):
f = np.fft.fft2(image)
fshift = np.fft.fftshift(f) def make_transform_matrix(d):
transfor_matrix = np.zeros(image.shape)
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
for i in range(transfor_matrix.shape[0]):
for j in range(transfor_matrix.shape[1]):
def cal_distance(pa,pb):
from math import sqrt
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
return dis
dis = cal_distance(center_point,(i,j))
transfor_matrix[i,j] = 1/((1+(d/dis))**n)
return transfor_matrix
d_matrix = make_transform_matrix(d)
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
return new_img
plt.subplot(231)
butter_100_1 = butterworthPassFilter(img,100,1)
plt.imshow(butter_100_1,cmap="gray")
plt.title("d=100,n=1")
plt.axis("off")
plt.subplot(232)
butter_100_2 = butterworthPassFilter(img,100,2)
plt.imshow(butter_100_2,cmap="gray")
plt.title("d=100,n=2")
plt.axis("off")
plt.subplot(233)
butter_100_3 = butterworthPassFilter(img,100,3)
plt.imshow(butter_100_3,cmap="gray")
plt.title("d=100,n=3")
plt.axis("off")
plt.subplot(234)
butter_100_1 = butterworthPassFilter(img,30,1)
plt.imshow(butter_100_1,cmap="gray")
plt.title("d=30,n=1")
plt.axis("off")
plt.subplot(235)
butter_100_2 = butterworthPassFilter(img,30,2)
plt.imshow(butter_100_2,cmap="gray")
plt.title("d=30,n=2")
plt.axis("off")
plt.subplot(236)
butter_100_3 = butterworthPassFilter(img,30,3)
plt.imshow(butter_100_3,cmap="gray")
plt.title("d=30,n=3")
plt.axis("off")
plt.show()

可以明显的观察出过大的n造成的振铃现象

butter_5_1 = butterworthPassFilter(img,5,1)
plt.imshow(butter_5_1,cmap="gray")
plt.title("d=5,n=3")
plt.axis("off")
plt.show()

python数字图像处理(四) 频率域滤波的更多相关文章

  1. python数字图像处理(17):边缘与轮廓

    在前面的python数字图像处理(10):图像简单滤波 中,我们已经讲解了很多算子用来检测边缘,其中用得最多的canny算子边缘检测. 本篇我们讲解一些其它方法来检测轮廓. 1.查找轮廓(find_c ...

  2. 「转」python数字图像处理(18):高级形态学处理

    python数字图像处理(18):高级形态学处理   形态学处理,除了最基本的膨胀.腐蚀.开/闭运算.黑/白帽处理外,还有一些更高级的运用,如凸包,连通区域标记,删除小块区域等. 1.凸包 凸包是指一 ...

  3. PIE SDK频率域滤波

    1.算法功能简介 频率域滤波的基本工作流程为:空间域图像的傅里叶变换→频率域图像→设计滤波器→傅里叶逆变换→其他应用. 低通滤波,对频率域的图像通过滤波器削弱或抑制高频部分而保留低频部分的滤波方法,可 ...

  4. python数字图像处理(1):环境安装与配置

    一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...

  5. 初始----python数字图像处理--:环境安装与配置

    一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...

  6. c语言数字图像处理(七):频率域滤波

    代码运行了两个小时才出的结果,懒得测试了,这一部分先鸽了,等对DFT算法进行优化后再更

  7. python数字图像处理(14):高级滤波

    本文提供更多更强大的滤波方法,这些方法放在filters.rank子模块内. 这些方法需要用户自己设定滤波器的形状和大小,因此需要导入morphology模块来设定. 1.autolevel 这个词在 ...

  8. python数字图像处理(13):基本形态学滤波

    对图像进行形态学变换.变换对象一般为灰度图或二值图,功能函数放在morphology子模块内. 1.膨胀(dilation) 原理:一般对二值图像进行操作.找到像素值为1的点,将它的邻近像素点都设置成 ...

  9. python数字图像处理(10):图像简单滤波

    对图像进行滤波,可以有两种效果:一种是平滑滤波,用来抑制噪声:另一种是微分算子,可以用来检测边缘和特征提取. skimage库中通过filters模块进行滤波操作. 1.sobel算子 sobel算子 ...

随机推荐

  1. HTML计算机代码元素

    计算机代码 1 2 3 4 5 6 var person = {     firstName:"Bill",     lastName:"Gates",     ...

  2. luogu P1307 数字反转 x

    题目描述 给定一个整数,请将该数各个位上数字反转得到一个新数.新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例2). 输入输出格式 输入格式: 输入 ...

  3. git 代码强行提交

    git add . git commit -m "your comment" git push -u origin master -f

  4. js不区分大小写匹配并代码高亮,且不改变原来文本大小写格式

    //高亮字符串 string: 需要处理的字符串,keyword:键盘输入的内容 function heightLight(string, keyword) { var reg = new RegEx ...

  5. log4j file 路径

    默认以System.getProperty("user.dir")为准 用LOGGER.warn(System.getProperty("user.dir")) ...

  6. mybatis 绑定 statement 失败

    错误信息:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 问题原因:编译时没有将mapp ...

  7. JPEG 存储分割后的图象会产生锯齿

    分割后的图象如果保存为 JPG 格式,物体边界会产生锯齿状的很暗的像素. 如下图所示. 这会给后续处理带了噪声, 因此,保存分割后的图象最好用无损压缩格式,如 bmp, png 等.

  8. .NETFramework:System.Net.WebClient.cs

    ylbtech-.NETFramework:System.Net.WebClient.cs 提供用于将数据发送到和接收来自通过 URI 确认的资源数据的常用方法 1.返回顶部 1. #region 程 ...

  9. redhat 修改yum源

    问题现象: 现有的yum安装git失败,提示yum源连接失败 Error Downloading Packages: git--.el6_4..x86_64: failure: Packages/gi ...

  10. Altium Designer chapter3总结

    绘制电路原理图中需要注意的如下: (1)元件库的操作:元件库的加载和卸载.查找元件. (2)元件操作: 1.放置元件(元件库中,place part,快捷键)中place part中的history可 ...