消除噪声的一种方法是将原始图像与表示低通滤波器或平滑操作的掩模进行卷积。例如,高斯掩模包含由高斯函数确定的元素。这种卷积使每个像素的值与其相邻像素的值更加协调。一般来说,平滑滤波器将每个像素设置为其自身及其附近相邻像素的平均值或加权平均值,高斯滤波器只是一组可能的权重。
块匹配和三维滤波是一种主要用于图像降噪的 3-D 块匹配算法。它是非局部均值方法的扩展之一。其中有两个级联:硬阈值和维纳滤波阶段,均涉及以下部分:分组、协同过滤和聚合。该算法依赖于变换站点中的增强表示。
图像片段根据相似性分组,但与标准 k 均值聚类和此类聚类分析方法不同,图像片段不一定是分离的。这种块匹配算法对计算的要求较低,并且在以后的聚合步骤中很有用。但是,片段的大小相同。如果片段与参考片段的差异低于指定阈值,则将其分组。这种分组技术称为块匹配,通常用于对数字视频不同帧中的相似组进行分组。而块匹配和三维滤波可能会对单个帧内的宏块进行分组,然后将组中的所有图像片段堆叠以形成 3D 圆柱形。
MATLAB去除模糊算法片段
imagename = 'cameraman256.png';
y = im2double(imread(imagename));
experiment_number = 4;
if experiment_number==1
sigma=sqrt(2)/255;
for x1=-7:7; for x2=-7:7; v(x1+8,x2+8)=1/(x1^2+x2^2+1); end, end; v=v./sum(v(:));
end
if experiment_number==2
sigma=sqrt(8)/255;
s1=0; for a1=-7:7; s1=s1+1; s2=0; for a2=-7:7; s2=s2+1; v(s1,s2)=1/(a1^2+a2^2+1); end, end; v=v./sum(v(:));
end
if experiment_number==3
BSNR=40; sigma=-1;
v=ones(9); v=v./sum(v(:));
end
if experiment_number==4
sigma=7/255;
v=[1 4 6 4 1]'*[1 4 6 4 1]; v=v./sum(v(:)); % PSF
end
if experiment_number==5
sigma=2/255;
v=fspecial('gaussian', 25, 1.6);
end
if experiment_number==6
sigma=8/255;
v=fspecial('gaussian', 25, .4);
end
y_blur = imfilter(y, v(end:-1:1,end:-1:1), 'circular'); % performs blurring (by circular convolution)
if sigma == -1; %% check whether to use BSNR in order to define value of sigma
sigma=sqrt(norm(y_blur(:)-mean(y_blur(:)),2)^2 /(size(y_blur, 1)*size(y_blur, 2)*10^(BSNR/10))); % compute sigma from the desired BSNR
end
z = y_blur + sigma*randn(size(y_blur));
y_est = BM3DDEB(z, sigma, v);
psnr = getPSNR(y, y_est)
psnr_cropped = getCroppedPSNR(y, y_est, [16, 16])
figure,
subplot(1, 3, 1);
imshow(y);
title('y');
subplot(1, 3, 2);
imshow(z);
title('z');
subplot(1, 3, 3);
imshow(y_est);
title('y_{est}');
Python去除模糊算法片段
import numpy as np
from experiment_funcs import get_experiment_noise, get_psnr, get_cropped_psnr
from scipy.ndimage.filters import correlate
from PIL import Image
import matplotlib.pyplot as plt
def main():
imagename = 'cameraman256.png'
y = np.array(Image.open(imagename)) / 255
experiment_number = 3
if experiment_number == 1:
sigma = np.sqrt(2) / 255
v = np.zeros((15, 15))
for x1 in range(-7, 8, 1):
for x2 in range(-7, 8, 1):
v[x1 + 7, x2 + 7] = 1 / (x1 ** 2 + x2 ** 2 + 1)
v = v / np.sum(v)
elif experiment_number == 2:
sigma = np.sqrt(8) / 255
s1 = 0
v = np.zeros((15, 15))
for a1 in range(-7, 8, 1):
s1 = s1 + 1
s2 = 0
for a2 in range(-7, 8, 1):
s2 = s2 + 1
v[s1-1, s2-1] = 1 / (a1 ** 2 + a2 ** 2 + 1)
elif experiment_number == 3:
bsnr = 40
sigma = -1
v = np.ones((9, 9))
v = v / np.sum(v)
elif experiment_number == 4:
sigma = 7 / 255
v = np.atleast_2d(np.array([1, 4, 6, 4, 1])).T @ np.atleast_2d(np.array([1, 4, 6, 4, 1]))
v = v / np.sum(v)
elif experiment_number == 5:
sigma = 2 / 255
v = gaussian_kernel((25, 25), 1.6)
else: # 6 +
sigma = 8 / 255
v = gaussian_kernel((25, 25), 0.4)
y_blur = correlate(np.atleast_3d(y), np.atleast_3d(v), mode='wrap')
if sigma == -1:
sigma = np.sqrt(np.linalg.norm(np.ravel(y_blur - np.mean(y_blur)), 2) ** 2 / (y.shape[0] * y.shape[1] * 10 ** (bsnr / 10)))
z = y_blur + sigma * np.random.normal(size=y_blur.shape)
y_est = bm3d_deblurring(z, sigma, v)
psnr = get_psnr(y, y_est)
print("PSNR:", psnr)
psnr_cropped = get_cropped_psnr(y, y_est, [16, 16])
print("PSNR cropped:", psnr_cropped)
y_est = np.minimum(np.maximum(y_est, 0), 1)
z_rang = np.minimum(np.maximum(z, 0), 1)
plt.title("y, z, y_est")
plt.imshow(np.concatenate((y, np.squeeze(z_rang), y_est), axis=1), cmap='gray')
plt.show()
if __name__ == '__main__':
main()