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. java生成128A条形码

    添加maven依赖 <dependency> <groupId>net.sf.barcode4j</groupId> <artifactId>barco ...

  2. Dubbo学习-6-springboot整合dubbo

    1.在前面帖子和工程的基础上,这里使用springboot整合dubbo,首先创建springboot项目: https://start.spring.io/  进入spring Initializr ...

  3. Spark在MaxCompute的运行方式

    一.Spark系统概述 左侧是原生Spark的架构图,右边Spark on MaxCompute运行在阿里云自研的Cupid的平台之上,该平台可以原生支持开源社区Yarn所支持的计算框架,如Spark ...

  4. 862C - Mahmoud and Ehab and the xor(构造)

    原题链接:http://codeforces.com/contest/862/problem/C 题意:给出n,x,求n个不同的数,使这些数的异或和为x 思路:(官方题解)只有n==2&&am ...

  5. string 、char* 、 char []的转换

    1.string->char* (1)data string s = "goodbye"; const char* p=str.data(); (2)c_str() stri ...

  6. 29 基于PCL的点云平面分割拟合算法技术路线(针对有噪声的点云数据)

    0 引言 最近项目中用到了基于PCL开发的基于平面的点云和CAD模型的配准算法,点云平面提取采用的算法如下. 1 基于PCL的点云平面分割拟合算法 2 参数及其意义介绍 (1)点云下采样 1. 参数: ...

  7. div上下左右居中几种方式

    1.绝对定位(常用于登录模块)备注:前提条件div需要有宽高 #html <div class="box"></div> #css .box{ positi ...

  8. 【运维】使用FileZilla搭建FTP服务器

    一.下载Filezilla  Server 官网网址:https://filezilla-project.org 二.安装Filezilla  Server   Filezilla  Server的安 ...

  9. Advanced search keywords

    Advanced search options Find what you're looking for in less time. Use the following symbols to quic ...

  10. Log4j Threshold、Append

    报错ERROR日志单独存放 Threshold属性可以指定日志level Log4j根据日志信息的重要程度,分OFF.FATAL.ERROR.WARN.INFO.DEBUG.ALL 比如我们指定某个a ...