python实现传统的TV正则去噪
最近的任务是实现传统的TV正则去噪,但是找了半天只找到了matlab和C++版本,⽽且调试的时候问题也有点多,所以这⾥写⼀下Python的实现,只需要改⼀下图⽚的路径就可以直接复制使⽤了。
这次改进的程序,需要先建⽴⼀个⽂件夹如‘train2’⾥⾯放⼲净图像集,然后建⽴空⽩⽂件夹,命名如‘result’⽤来装去噪结果图,我将lamb设置为超参可调,加⾼斯噪声的操作也在程序中⾃动完成。输出会有每张图⽚每⼗次迭代产⽣的loss,可以据此判断是否收敛,迭代结束后,也会有去噪图与原图的psnr计算显⽰。
参考链接:
python实现
import cv2
import math
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
import glob,os
import xlwt
pat.v1 as tf
from scipy.signal import convolve2d
def TV(number, m_imgData, iter, dt, epsilon,lamb):
NX = m_imgData.shape[0]
NY = m_imgData.shape[1]
ep2 = epsilon * epsilon
I_t=np.s((NX,NY)))
I_tmp = np.s((NX,NY))) # ⽤来迭代的噪声图
I_t = m_imgData.astype(np.float64)
I_tmp = m_imgData.astype(np.float64)
data = []
for t in range(0, iter):
for i in range(0, NY): # ⼀次迭代
for j in range(0, NX):
iUp = i - 1
iDown = i + 1
jLeft = j - 1
jRight = j + 1 # 边界处理
if i == 0:
iUp = i
if NY - 1 == i:
iDown = i
if j == 0:
jLeft = j
if NX - 1 == j:
jRight = j
tmp_x = (I_t[i][jRight] - I_t[i][jLeft]) / 2.0
tmp_y = (I_t[iDown][j] - I_t[iUp][j]) / 2.0
tmp_xx = I_t[i][jRight] + I_t[i][jLeft] - 2 * I_t[i][j]
tmp_yy = I_t[iDown][j] + I_t[iUp][j] - 2 * I_t[i][j]
tmp_xy = (I_t[iDown][jRight] + I_t[iUp][jLeft] - I_t[iUp][jRight] - I_t[iDown][jLeft]) / 4.0
tmp_num = tmp_yy * (tmp_x * tmp_x + ep2) + tmp_xx * (tmp_y * tmp_y + ep2) - 2 * tmp_x * tmp_y * tmp_xy tmp_den = math.pow(tmp_x * tmp_x + tmp_y * tmp_y + ep2, 1.5)
鸟的眼睛I_tmp[i][j] += dt * (tmp_num / tmp_den + (0.5+lamb[i][j])* (m_imgData[i][j] - I_t[i][j]))
for i in range(0, NY):
for j in range(0, NX):
I_t[i][j] = I_tmp[i][j] # 迭代结束
loss=((I_t - simage) ** 2).mean()
if(t%10==0):
print(loss)
积羽成舟
data.append(loss)
data=np.array(data)
return I_t # 返回去噪图
def add_gaussian_noi(image_in, noi_sigma):
temp_image = np.py(image_in))
h = temp_image.shape[0]
w = temp_image.shape[1]
noi = np.random.randn(h, w) * noi_sigma
noisy_image = np.zeros(temp_image.shape, np.float64)
if len(temp_image.shape) == 2:
noisy_image = temp_image + noi
el:
黑暗传noisy_image[:,:,0] = temp_image[:,:,0] + noi
noisy_image[:,:,1] = temp_image[:,:,1] + noi
noisy_image[:,:,2] = temp_image[:,:,2] + noi
中苏珍宝岛战役"""
print('min,max = ', np.min(noisy_image), np.max(noisy_image))
print('type = ', type(noisy_image[0][0][0]))
"""
return noisy_image
def save_result(result,path):#保存结果
path = path if path.find('.') != -1 el path+'.png'
ext = os.path.splitext(path)[-1]
if ext in ('.txt','.dlm'):
np.savetxt(path,result,fmt='%2.4f')
el:
imsave(path,np.clip(result,0,1))
def cal_psnr(im1, im2):
m = ((im1 - im2) ** 2).mean()
psnr = 10 * np.log10(255 ** 2 / m)
return psnr
def save_images(filepath, denoi_image, noisy_image, clean_image):#保存图⽚
denoi_image = np.squeeze(denoi_image)
noisy_image = np.squeeze(noisy_image)家居主张
clean_image = np.squeeze(clean_image)
if not clean_image.any():
cat_image = denoi_image
el:
cat_image = np.concatenate([clean_image, noisy_image, denoi_image], axis=1)
cv2.imwrite(filepath,cat_image)
def datagenerator(data_dir):#⽣成图⽚集
file_list = glob.glob(data_dir+'/*.png') # get name list of all .png files data = []
print (file_list)
哄老婆的话
for i in range(len(file_list)):
img = cv2.imread(file_list[i],0)
data.append(np.array(img).reshape(img.size[1], img.size[0]))
return data
def load_images(filelist):
file_list = glob.glob(data_dir+'/*.png') # get name list of all .png files data = []
print (file_list)
for i in range(len(file_list)):
im = Image.open(file_list[i]).convert('L')
data.append(np.array(im).reshape(im.size[1], im.size[0]))
return data
if __name__ == '__main__':
高德荣noi_sigma = 25
data_dir='train2'
data=load_images(data_dir)
psnr0=[]
psnr1=[]
for i in range(10):#对图像集进⾏处理
str1=str(i)
使至塞上王维
image = add_gaussian_noi(data[i], noi_sigma=noi_sigma) simage=data[i].astype(np.float64)#原图像
NX=data[i].shape[0]
NY=data[i].shape[1]
lamb=np.s((NX,NY)))
for t in range(NY):
for j in range(NX):
lamb[t][j]=0
Img = TV(i,image,300,0.1,1,lamb)
psnr=cal_psnr(Img, simage)
path=os.path.join('result',str1+'.png')#保存图像集的路径
save_images(path,Img,image,simage);#保存结果
#cv2.imwrite(path,Img)
print("image :" ,i, "psnr : ",psnr)
TV正则去噪效果图(从左到右依次是原图,噪声图,去噪效果图)