import cv2
import numpy as np
imga = cv2.imread('../../data/fish.bmp')
imgb = cv2.imread('../../data/submarine.bmp')
d0=40
def single_channel(img):
rows, cols = img.shape[:2]
# 计算最优尺寸
nrows = cv2.getOptimalDFTSize(rows)
ncols = cv2.getOptimalDFTSize(cols)
# 根据新尺寸,建立新变换图像
nimg = np.zeros((nrows, ncols))
nimg[:rows,:cols] = img
# 得到的fft_mat有2个通道,实部和虚部
fft_mat = cv2.dft(np.float32(nimg), flags = cv2.DFT_COMPLEX_OUTPUT)
# 反换位,低频部分移到中间,高频部分移到四周
fft_mat = np.fft.fftshift(fft_mat)
return fft_mat
def fft_distances(m, n):
u = np.array([i - m/2 for i in range(m)], dtype=np.float32)
v = np.array([i - n/2 for i in range(n)], dtype=np.float32)
ret = np.ones((m, n))
for i in range(m):
for j in range(n):
ret[i][j] = np.sqrt(u[i]*u[i] + v[j]*v[j])
u = np.array([i if i<=m/2 else m-i for i in range(m)], dtype=np.float32)
v = np.array([i if i<=m/2 else m-i for i in range(m)], dtype=np.float32)
return ret
def change_filter(flag):
# 理想低通滤波器
if flag == 1:
# 初始化滤波器,因为fft_mat有2个通道,filter_mat也需要2个通道
filter_mat = np.zeros((nrows, ncols ,2), np.float32)
# 将filter_mat中以(ncols/2, nrows/2)为圆心、d0为半径的圆内的值设置为1
cv2.circle(filter_mat, (np.int(ncols/2), np.int(nrows/2)) , d0, (1,1,1), -1)
# 布特沃斯低通滤波
elif flag == 2:
n = 2 # 2阶
filter_mat = None
duv = fft_distances(*fft_mat.shape[:2])
filter_mat = 1 / (1+ np.power(duv/d0, 2*n))
filter_mat = cv2.merge((filter_mat, filter_mat)) # fliter_mat 需要2个通道
# 高斯低通滤波(σ为d0)
else:
filter_mat = None
duv = fft_distances(*fft_mat.shape[:2])
filter_mat = np.exp(-(duv*duv) / (2*d0*d0))
filter_mat = cv2.merge((filter_mat, filter_mat)) # fliter_mat 需要2个通道
return filter_mat
def ifft(fft_mat):
# 反换位,低频部分移到四周,高频部分移到中间
f_ishift_mat = np.fft.ifftshift(fft_mat)
# 傅里叶反变换
img_back = cv2.idft(f_ishift_mat)
# 将复数转换为幅度, sqrt(re^2 + im^2)
img_back = cv2.magnitude(*cv2.split(img_back))
# 标准化到0~255之间
cv2.normalize(img_back, img_back, 0, 255, cv2.NORM_MINMAX)
return np.uint8(np.around(img_back))[:rows,:cols]
def blur(img):
#低频
b,g,r = cv2.split(img)
fft_mat_b = single_channel(b)
fft_mat_g = single_channel(g)
fft_mat_r = single_channel(r)
img1 = ifft(change_filter(3) * fft_mat_b) # 高斯低通
img2 = ifft(change_filter(3) * fft_mat_g) # 高斯低通
img3 = ifft(change_filter(3) * fft_mat_r) # 高斯低通
img = cv2.merge([img3,img2,img1])
return img
def sharp(img, num): # num是用来选择哪种滤波器的
# 高频
b,g,r = cv2.split(img)
fft_mat_b = single_channel(b)
fft_mat_g = single_channel(g)
fft_mat_r = single_channel(r)
img1 = ifft((1 - change_filter(num)) * fft_mat_b) # 高斯低通
img2 = ifft((1 - change_filter(num)) * fft_mat_g) # 高斯低通
img3 = ifft((1 - change_filter(num)) * fft_mat_r) # 高斯低通
img = cv2.merge([img3,img2,img1])
return img
def hybrid(img1,img2):
img_blur = blur(img1)
img_sharp = sharp(img2,2)
result = img_blur+img_sharp
plt.figure(figsize=(10,8))
plt.subplot(131)
plt.imshow(img_blur)
plt.title('blur')
plt.yticks([])
plt.axis('off')
plt.subplot(132)
plt.imshow(img_sharp)
plt.title('sharp')
plt.yticks([])
plt.axis('off')
plt.subplot(133)
plt.imshow(result)
plt.title('hybrid')
plt.yticks([])
plt.axis('off')
plt.savefig("myresult.jpg")
return result
result = hybrid(imga,imgb)
Hybrid效果如下图所示,貌似 高通滤波器的效果不是很好。。。
img1 = sharp(imgb,1)
img2 = sharp(imgb,2)
img3 = sharp(imgb,3)
plt.figure(figsize=(12,10))
plt.subplot(131)
plt.imshow(img1)
plt.axis("off")
plt.subplot(132)
plt.imshow(img2)
plt.axis("off")
plt.subplot(133)
plt.imshow(img3)
plt.axis("off")