python 傅立叶函数_Python OpenCV 傅里叶变换

图像处理一般分为空间域处理和频率域处理,空间域处理是直接对图像内的像素进行处理。频率域处理是先将图像变换到频率域,然后在频率域对图像进行处理,最后通过反变换将图像变为空间域。傅里叶变换可以将图像变换为频率域, 傅立叶反变换再将频率域变换为空间域。

在频域里,对于一幅图像,高频部分代表了图像的、纹理信息;低频部分则代表了图像的轮廓信息。如果图像受到的噪声恰好在某个特定的频率范围内,就可以使用滤波器来恢复原来的图像。因此傅里叶变换在图像处理中可以做到图像增强和去噪、图像分割之边缘检测、图像特征提取和压缩等。

傅里叶变换对图像处理有两种方式:一种是调用opencv的函数,另一种是调用numpy的函数。虽然opencv算法运算速度快,但是推荐使用numpy做傅里叶变换,简单。Opencv

import cv2

import numpy as np

from matplotlib import pyplot as plt

img = cv2.imread('002.tif', 0)

rows, cols = img.shape

# size为改变滤波大小

crow, ccol = rows//2, cols//2

sizex = 5

sizey = 5

# DFT的性能优化

nrows = cv2.getOptimalDFTSize(rows)

ncols = cv2.getOptimalDFTSize(cols)

right = ncols - cols

bottom = nrows - rows

bordertype = cv2.BORDER_CONSTANT # 只是为了避免PDF文件中的行中断

nimg = cv2.copyMakeBorder(img, 0, bottom, 0, right, bordertype, value=0)

# cv傅里叶变换

dft = cv2.dft(np.float32(nimg), flags=cv2.DFT_COMPLEX_OUTPUT) # 不优化就选img

dft_shift = np.fft.fftshift(dft)

# 显示傅里叶变换图

magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))

plt.imshow(magnitude_spectrum, cmap='gray')

# 高通滤波器HPF删除图像中的低频内容-边缘提取

# 首先创建一个掩码,中心正方形为0,其余全为1

mask_HPF = np.ones((nrows, ncols, 2), np.uint8) # 不优化就选rows,cols

mask_HPF[crow-sizex:crow+sizex, ccol-sizey:ccol+sizey] = 0

# 应用掩码和逆DFT

dft_shift_HPF = dft_shift.copy()

fshift_HPF = dft_shift_HPF * mask_HPF

f_ishift_HPF = np.fft.ifftshift(fshift_HPF)

img_HPF = cv2.idft(f_ishift_HPF)

img_HPF = cv2.magnitude(img_HPF[:, :, 0], img_HPF[:, :, 1])

# 低通滤波器LPF删除图像中的高频内容-图像模糊

# 首先创建一个掩码,中心正方形为1,其余全为0

mask_LPF = np.zeros((nrows, ncols, 2), np.uint8) # 不优化就选rows,cols

mask_LPF[crow-sizex:crow+sizex, ccol-sizey:ccol+sizey] = 1

# 应用掩码和逆DFT

dft_shift_LPF = dft_shift.copy()

fshift_LPF = dft_shift_LPF * mask_LPF

f_ishift_LPF = np.fft.ifftshift(fshift_LPF)

img_LPF = cv2.idft(f_ishift_LPF)

img_LPF = cv2.magnitude(img_LPF[:, :, 0], img_LPF[:, :, 1])

img_HPF = np.array(img_HPF, dtype='uint8')

img_LPF = np.array(img_LPF, dtype='uint8')

cv2.imshow("img_HPF", img_HPF)

cv2.imshow("img_LPF", img_LPF)

cv2.waitKey()

plt.show()

其中,对水平线、垂直线或中心点进行插补的方法:

# 水平线插补

dft_fshift[crow, :, 0] = (dft_fshift[crow+1, :, 0] + dft_fshift[crow-1, :, 0]) / 2

dft_fshift[crow, :, 1] = (dft_fshift[crow+1, :, 1] + dft_fshift[crow-1, :, 1]) / 2

# 垂直线插补

dft_fshift[:, ccol, 0] = (dft_fshift[:, ccol+1, 0] + dft_fshift[:, ccol-1, 0]) / 2

dft_fshift[:, ccol, 1] = (dft_fshift[:, ccol+1, 1] + dft_fshift[:, ccol-1, 1]) / 2

# 中心点插补

# dft_fshift[crow, ccol, 0] = (dft_fshift[crow+1, ccol+1, 0] + dft_fshift[crow-1, ccol+1, 0]

# + dft_fshift[crow-1, ccol+1, 0] + dft_fshift[crow-1, ccol-1, 0]) / 4

# dft_fshift[crow, ccol, 1] = (dft_fshift[crow+1, ccol+1, 1] + dft_fshift[crow-1, ccol+1, 1]

# + dft_fshift[crow-1, ccol+1, 1] + dft_fshift[crow-1, ccol-1, 1]) / 4

dft_fshift[crow, ccol, 0] = (dft_fshift[crow+1, ccol, 0] + dft_fshift[crow-1, ccol, 0]

+ dft_fshift[crow, ccol+1, 0] + dft_fshift[crow, ccol-1, 0]) / 4

dft_fshift[crow, ccol, 1] = (dft_fshift[crow+1, ccol, 1] + dft_fshift[crow-1, ccol, 1]

+ dft_fshift[crow, ccol+1, 1] + dft_fshift[crow, ccol-1, 1]) / 4

# 显示傅里叶变换图

magnitude_spectrum_f = 20 * np.log(cv2.magnitude(dft_fshift[:, :, 0], dft_fshift[:, :, 1]))

plt.subplot(1, 2, 2)

plt.imshow(magnitude_spectrum_f, cmap='gray')

2. Numpy 推荐使用

import cv2

import numpy as np

import matplotlib.pyplot as plt

img = cv2.imread("Ingass1.tif", 0)

cv2.imshow("img", img)

rows, cols = img.shape

crow, ccol = int(rows/2), int(cols/2) # 计算中心位置

# -------Numpy傅里叶变换

f = np.fft.fft2(img)

fshift = np.fft.fftshift(f)

# magnitude_spectrum = 20 * np.log(np.abs(fshift))

# plt.subplot(1, 2, 1)

# plt.imshow(magnitude_spectrum, cmap='gray')

dft_fshift = fshift.copy()

sizex = 10

sizey = 10

# 高通滤波器HPF删除图像中的低频内容-边缘提取

# 首先创建一个掩码,中心正方形为0,其余全为1

mask = np.ones(img.shape, np.uint8)

mask[crow-sizex:crow+sizex, ccol-sizey:ccol+sizey] = 0

dft_fshift = fshift * mask

# 低通滤波器LPF删除图像中的高频内容-图像模糊

# 首先创建一个掩码,中心正方形为1,其余全为0

mask = np.zeros(img.shape, np.uint8)

mask[crow-sizex:crow+sizex, ccol-sizey:ccol+sizey] = 1

dft_fshift = fshift * mask

# magnitude_spectrum2 = 20 * np.log(np.abs(dft_fshift))

# plt.subplot(1, 2, 2)

# plt.imshow(magnitude_spectrum2, cmap='gray')

f_ishift = np.fft.ifftshift(dft_fshift)

img_back = np.fft.ifft2(f_ishift)

img_back = np.abs(img_back)

img_back = img_back.astype(np.uint8)

cv2.imshow("img_back", img_back)

img_back_equ = cv2.equalizeHist(img_back)

cv2.imshow("dst", img_back_equ)

plt.show()

cv2.waitKey()

其中,对水平线、垂直线或中心点进行插补的方法:

# 水平

dft_fshift[crow, ccol-number:ccol+number] = (dft_fshift[crow+1, ccol-number:ccol+number] + dft_fshift[crow-1, ccol-number:ccol+number]) / 2

# 垂直

dft_fshift[crow-number:crow+number, ccol] = (dft_fshift[crow-number:crow+number, ccol+1] + dft_fshift[crow-number:crow+number, ccol-1]) / 2

# 中心点

dft_fshift[crow, ccol] = (dft_fshift[crow+1, ccol+1] + dft_fshift[crow-1, ccol+1] + dft_fshift[crow-1, ccol+1] + dft_fshift[crow-1, ccol-1]) / 4原图10*10高通滤波10*10低通滤波

你可能感兴趣的:(python,傅立叶函数)