Files
digital-image-processing/8/2/Restore.py
T
2024-05-23 10:50:05 +08:00

318 lines
11 KiB
Python

import matplotlib.pyplot as plt
import numpy as np
from numpy import fft
import math
import sys
import cv2
import random
import Fourier
#此函数生成的运动模糊核是由旋转来控制运动方向
def motion_PSF(kernel_size=15, angle=60):
PSF = np.diag(np.ones(kernel_size))# 初始模糊核的方向是-45度
angle = angle + 45 # 抵消-45度的影响
M =cv2.getRotationMatrix2D((kernel_size/2,kernel_size/2), angle, 1) # 生成旋转矩阵
PSF = cv2.warpAffine(PSF, M, (kernel_size, kernel_size), flags=cv2.INTER_NEAREST)
PSF = PSF / PSF.sum() #模糊核的权重和为1
return PSF
#生成高斯模糊核
def Gaussian_PSF(kernel_size=15,sigma=0.1): #生成高斯模糊核
kx = cv2.getGaussianKernel(kernel_size, sigma)
ky = cv2.getGaussianKernel(kernel_size, sigma)
return np.multiply(kx, np.transpose(ky))
#生成大气湍流模糊核
def turbulence_PSF(input,k):
[m, n] = input.shape
PSF = np.zeros((m, n))
p = m / 2
q = n / 2
for u in range(m):
for v in range(n):
PSF[u, v]=math.exp(-k*((u-p)*(u-p)+(v-q)*(v-q))**(5/6))
PSF1= fft.ifft2(PSF)
PSF1 = np.abs(PSF1)
PSF1 = PSF1 / PSF1.sum() # 模糊核的权重和为1
return PSF1
#此函数扩展PSF0,使之与image0一样大小
def extension_PSF(image0,PSF0):
[img_h,img_w] = image0.shape
[h,w] = PSF0.shape
PSF=np.zeros((img_h,img_w))
PSF[0:h, 0:w] =PSF0[0:h, 0:w]
return PSF
# 在频域对图片进行运动模糊
def make_blurred(input, PSF, eps=0.01):
input_fft = fft.fft2(input) # 进行二维数组的傅里叶变换
PSF_fft = fft.fft2(PSF) + eps
blurred = fft.ifft2(input_fft * PSF_fft)
blurred=np.abs(blurred)
return blurred
def inverse(input, PSF, eps=0.01): # 逆滤波
input_fft = fft.fft2(input)
PSF_fft = fft.fft2(PSF) +eps
Output_fft =input_fft/ PSF_fft #在频域进行逆滤波
result =fft.ifft2(Output_fft) # 计算F(u,v)的傅里叶反变换
result = np.abs(result)
return result
# def improved_inverse(input, PSF,w=70, k=0.1, eps=0.01): # 逆滤波
# input_fft = fft.fft2(input)
# input_fftshift=fft.fftshift(input_fft)
# PSF_fft = fft.fft2(PSF)
# PSF_fftshift=fft.fftshift(PSF_fft)+eps
# rows,cols = input_fftshift.shape[:2]
# duv = Fourier.fft_distances(rows,cols)
# for u in range(rows):
# for v in range(cols):
# if duv[u,v]<w:
# PSF_fftshift[u,v]=1/PSF_fftshift[u,v]
# else:
# PSF_fftshift[u,v]=k
# # PSF_fftshift=1/PSF_fftshift
# output_fftshift =input_fftshift* PSF_fftshift #在频域进行逆滤波
# output_fft=fft.ifftshift(output_fftshift)
# result =fft.ifft2(output_fft) # 计算F(u,v)的傅里叶反变换
# result = np.abs(result)
# return result
def improved_inverse(input, PSF, w=70, k=0.1, eps=0.01):
input_fft = fft.fft2(input)
input_fftshift=fft.fftshift(input_fft)
PSF_fft = fft.fft2(PSF)
PSF_fftshift=fft.fftshift(PSF_fft)+eps
rows,cols = input_fftshift.shape[:2]
duv = Fourier.fft_distances(rows,cols)
for u in range(rows):
for v in range(cols):
if duv[u,v]<w:
PSF_fftshift[u,v]=1/PSF_fftshift[u,v]
else:
PSF_fftshift[u,v]=k
# PSF_fftshift=1/PSF_fftshift
output_fftshift = input_fftshift*PSF_fftshift
output_fft=fft.ifftshift(output_fftshift)
result = fft.ifft2(output_fft)
result = np.abs(result)
return result
def wiener(input, PSF, K=0.1, eps=0.01): #维纳滤波
input_fft = fft.fft2(input)
PSF_fft = fft.fft2(PSF) + eps
PSF_fft = np.conj(PSF_fft) / (np.abs(PSF_fft) ** 2 + K)
result = fft.ifft2(input_fft * PSF_fft)
result = np.abs(result)
return result
def constrained_least_squares(input, PSF, r, eps=0.01): #最小二乘滤波
input_fft = fft.fft2(input)
PSF_fft = fft.fft2(PSF) + eps
Q=np.array([[ 0,-1,0], #这个是设置的滤波,也就是卷积核
[ -1,4,-1],
[ 0,-1,0]])
Q= extension_PSF(input, Q)
Q_fft = fft.fft2(Q)
PSF_fft = np.conj(PSF_fft) / (np.abs(PSF_fft) ** 2 + r * np.abs(Q_fft) ** 2)
result = fft.ifft2(input_fft * PSF_fft)
result=np.abs(result)
return result
def standardization(img,L=255): #将0-255范围的图像转化为0-1,将彩色图像转换为灰度图像
if len(img.shape)>2 :#判断img.shape元组的长度
if img.shape[2]!=1:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = img / L
return img
def meanSquare(image0,image1,L=255):#求均方误差
image0 = standardization(image0)
image1 = standardization(image1)
[m, n] = image0.shape
MSE=0
for i in range(m):
for j in range(n):
MSE=MSE+(image0[i,j]-image1[i,j])**2
MSE=MSE/(m*n)*(L**2)
return MSE
def SignalNoiseRatio(image0,image1):#求信噪比,输出单位:dB
image0 = standardization(image0)
image1 = standardization(image1)
[m, n] = image0.shape
Np=0
Sp=0
for i in range(m):
for j in range(n):
Np=Np+(image0[i,j]-image1[i,j])**2
Sp=Sp+image1[i,j]**2
SNR=10*math.log(Sp/(Np+1e-14),10) #防止除数为0
return SNR
def PeakSignalNoiseRatio(image0,image1,L=255):#求峰值信噪比,输出单位:dB
MSE=meanSquare(image0,image1)
PSNR=10*math.log(L**2/(MSE+1e-14),10) #防止除数为0
return PSNR
if __name__=="__main__": #主程序判断语句
image = cv2.imread('2.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
plt.figure('运动模糊')
plt.subplot(231)
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.gray()
plt.imshow(image) # 显示原图像
PSF = motion_PSF() # 生成运动模糊核
PSF = extension_PSF(image, PSF) # 在频域进行运动模糊,需要扩展PSF,使其与图像一样大小
blurred = make_blurred(image, PSF)
blurred = blurred + 0.1 * blurred.std() * np.random.standard_normal(blurred.shape)
plt.subplot(232)
plt.imshow(blurred)
plt.title('Motion blurred'), plt.xticks([]), plt.yticks([])
result1 = inverse(blurred, PSF) # 逆滤波
plt.subplot(233)
plt.imshow(result1)
plt.title('inverse '), plt.xticks([]), plt.yticks([])
result2 = improving_inverse(blurred, PSF, 30, 1) # 改进的逆滤波
plt.subplot(234)
plt.title('improving_inverse '), plt.xticks([]), plt.yticks([])
plt.imshow(result2)
result3 = wiener(blurred, PSF, 0.01) # 对添加噪声的图像进行维纳滤波
plt.subplot(235)
plt.title('wiener '), plt.xticks([]), plt.yticks([])
plt.imshow(result3)
result4 = constrained_least_squares(blurred, PSF, 0.002)
plt.subplot(236)
plt.title('constrained_least_squares'), plt.xticks([]), plt.yticks([])
plt.imshow(result4)
plt.figure('大气湍流模糊')
plt.subplot(231)
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.gray()
plt.imshow(image) # 显示原图像
PSF1 = daqi_PSF(image, 0.0025)
PSF1 = extension_PSF(image,PSF1)
da_blurred = make_blurred(image, PSF1)
da_blurred = da_blurred + 0.1 * da_blurred.std() * np.random.standard_normal(da_blurred.shape)
plt.subplot(232)
plt.title('daqi_blurred'), plt.xticks([]), plt.yticks([])
plt.imshow(da_blurred)
result5=inverse(da_blurred, PSF1)
plt.subplot(233)
plt.title('inverse'), plt.xticks([]), plt.yticks([])
plt.imshow(result5)
result6 = improving_inverse(da_blurred, PSF1, 30, 1) # 改进的逆滤波
plt.subplot(234)
plt.title('improving_inverse'), plt.xticks([]), plt.yticks([])
plt.imshow(result6)
result7 = wiener(da_blurred, PSF1, 0.01) # 对添加噪声的图像进行维纳滤波
plt.subplot(235)
plt.title('wiener'), plt.xticks([]), plt.yticks([])
plt.imshow(result7)
result8 = constrained_least_squares(da_blurred, PSF1, 0.002)
plt.subplot(236)
plt.title('constrained_least_squares'), plt.xticks([]), plt.yticks([])
plt.imshow(result8)
plt.figure('高斯模糊')
plt.subplot(231)
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.gray()
plt.imshow(image) # 显示原图像
G_PSF = G_PSF(9,10)
G_PSF = extension_PSF(image, G_PSF)
G_blurred = make_blurred(image, G_PSF)
G_blurred = G_blurred + 0.1 * G_blurred.std() * np.random.standard_normal(G_blurred.shape)
plt.subplot(232)
plt.imshow(G_blurred)
plt.title('Gaussian blurred'), plt.xticks([]), plt.yticks([])
result9 = inverse(G_blurred, G_PSF)
plt.subplot(233)
plt.title('inverse'), plt.xticks([]), plt.yticks([])
plt.imshow(result9)
result10 = improving_inverse(G_blurred, G_PSF, 30, 1) # 改进的逆滤波
plt.subplot(234)
plt.title('improving_inverse'), plt.xticks([]), plt.yticks([])
plt.imshow(result10)
result11 = wiener(G_blurred, G_PSF, 0.01) # 对添加噪声的图像进行维纳滤波
plt.subplot(235)
plt.title('wiener'), plt.xticks([]), plt.yticks([])
plt.imshow(result11)
result12 = constrained_least_squares(G_blurred, G_PSF, 0.0025)
plt.subplot(236)
plt.title('constrained_least_squares'), plt.xticks([]), plt.yticks([])
plt.imshow(result12)
plt.show()
'''
x = np.arange(0, 0.0015, 0.00001)
length = len(x)
y = np.zeros(length)
for i in range(length):
result = wiener(blurred, PSF, x[i])
y[i] = meanSquare(image, result, L=255)
plt.figure('运动模糊维纳滤波均方误差')
plt.plot(x, y, color='green', label='meanSquare')
plt.legend()
x = np.arange(0, 0.0015, 0.00001)
length = len(x)
y = np.zeros(length)
for i in range(length):
result = wiener(blurred, PSF, x[i])
y[i] = SignalNoiseRatio(image, result)
plt.figure('运动模糊维纳滤波信噪比')
plt.plot(x, y, color='red', label='SignalNoiseRatio')
plt.legend()
x = np.arange(0, 0.0015, 0.00001)
length = len(x)
y = np.zeros(length)
for i in range(length):
result = wiener(blurred, PSF, x[i])
y[i] = PeakSignalNoiseRatio(image, result, L=255)
plt.figure('运动模糊维纳滤波峰值信噪比')
plt.plot(x, y, color='blue', label='PeakSignalNoiseRatio')
plt.legend()
x = np.arange(0.001, 0.02, 0.0001)
length = len(x)
y = np.zeros(length)
for i in range(length):
result = constrained_least_squares(image, PSF, x[i])
y[i] = meanSquare(image, result, L=255)
plt.figure('运动模糊约束最小二乘滤波均方误差')
plt.plot(x, y, color='green', label='constrained_least_squares')
plt.legend()
x = np.arange(0, 0.02, 0.0001)
length = len(x)
y = np.zeros(length)
for i in range(length):
result = constrained_least_squares(image, PSF, x[i])
y[i] = SignalNoiseRatio(image, result)
plt.figure('运动模糊约束最小二乘滤波信噪比')
plt.plot(x, y, color='red', label='SignalNoiseRatio')
plt.legend()
x = np.arange(0.001, 0.02, 0.0001)
length = len(x)
y = np.zeros(length)
for i in range(length):
result = constrained_least_squares(image, PSF, x[i])
y[i] = PeakSignalNoiseRatio(image, result, L=255)
plt.figure('运动模糊约束最小二乘滤波峰值信噪比')
plt.plot(x, y, color='blue', label='PeakSignalNoiseRatio')
plt.legend()
plt.show()
'''