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正则去噪效果图(从左到右依次是原图,噪声图,去噪效果图)