赞
踩
图像的频率滤波是基于傅里叶变换的,通过二维傅里叶变换把图像从空域转换到频域,对频域的图像的频率进行操作,比如限制某个频率范围的像素通过。
(1)傅里叶变换
其中离散傅里叶变换为:
(2)傅里叶逆变换
其中离散傅里叶逆变换为:
(3)傅里叶变换性质
上述傅里叶变换均为一维傅里叶变换,然而图像中为二维的傅里叶变换,因此我们可以分别在行方向和列方向分别做傅里叶变换,
:
频域滤波的基本流程如下
傅里叶变换一般要中心化,根据二维傅里叶的平移性质:
我们只需要对变换后的图像像素乘以
理想低通滤波器:
理想高通滤波器
butterwoth低通滤波器:
butterwoth高通滤波器:
指数低通滤波 :
指数高通滤波:
- import cv2 as cv
- import numpy as np
- import matplotlib.pyplot as plt
-
- def filter(img, D0, W=None, N=2, type='lp', filter='butterworth'):
- '''
- 频域滤波器
- Args:
- img: 灰度图片
- D0: 截止频率
- W: 带宽
- N: butterworth和指数滤波器的阶数
- type: lp, hp, bp, bs即低通、高通、带通、带阻
- filter:butterworth、ideal、exponential即巴特沃斯、理想、指数滤波器
- Returns:
- imgback:滤波后的图像
- '''
-
- #离散傅里叶变换
- dft=cv.dft(np.float32(img),flags=cv.DFT_COMPLEX_OUTPUT)
- #中心化
- dtf_shift=np.fft.fftshift(dft)
-
- rows,cols=img.shape
- crow,ccol=int(rows/2),int(cols/2) #计算频谱中心
- mask=np.ones((rows,cols,2)) #生成rows行cols列的2纬矩阵
- for i in range(rows):
- for j in range(cols):
- D = np.sqrt((i-crow)**2+(j-ccol)**2)
- if(filter.lower() == 'butterworth'):
- if(type == 'lp'):
- mask[i, j] = 1/(1+(D/D0)**(2*N))
- elif(type == 'hp'):
- mask[i, j] = 1/(1+(D0/D)**(2*N))
- elif(type == 'bs'):
- mask[i, j] = 1/(1+(D*W/(D**2-D0**2))**(2*N))
- elif(type == 'bp'):
- mask[i, j] = 1/(1+((D**2-D0**2)/D*W)**(2*N))
- else:
- assert('type error')
- elif(filter.lower() == 'ideal'): #理想滤波器
- if(type == 'lp'):
- if(D > D0):
- mask[i, j] = 0
- elif(type == 'hp'):
- if(D < D0):
- mask[i, j] = 0
- elif(type == 'bs'):
- if(D > D0 and D < D0+W):
- mask[i, j] = 0
- elif(type == 'bp'):
- if(D < D0 and D > D0+W):
- mask[i, j] = 0
- else:
- assert('type error')
- elif(filter.lower() == 'exponential'): #指数滤波器
- if(type == 'lp'):
- mask[i, j] = np.exp(-(D/D0)**(2*N))
- elif(type == 'hp'):
- mask[i, j] = np.exp(-(D0/D)**(2*N))
- elif(type == 'bs'):
- mask[i, j] = np.exp(-(D*W/(D**2 - D0**2))**(2*N))
- elif(type == 'bp'):
- mask[i, j] = np.exp(-((D**2 - D0**2)/D*W)**(2*N))
- else:
- assert('type error')
-
- fshift = dtf_shift*mask
-
- f_ishift=np.fft.ifftshift(fshift)
- img_back=cv.idft(f_ishift)
- img_back=cv.magnitude(img_back[:,:,0],img_back[:,:,1]) #计算像素梯度的绝对值
- img_back=np.abs(img_back)
- img_back=(img_back-np.amin(img_back))/(np.amax(img_back)-np.amin(img_back))
-
- return img_back
-
- img=cv.imread('lena.jpg',0)
- plt.subplot(121),plt.imshow(img,cmap='gray'),plt.title('origin image')
- img_back = filter(img, 30, type='hp')
- plt.subplot(122),plt.imshow(img_back,cmap='gray'),plt.title('after butterworth highpass filter image')
- plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。