赞
踩
第一次来请先看这篇文章:【超分辨率(Super-Resolution)】关于【超分辨率重建】专栏的相关说明,包含专栏简介、专栏亮点、适配人群、相关说明、阅读顺序、超分理解、实现流程、研究方向、论文代码数据集汇总等)
论文地址:Image Super-Resolution Using Deep Convolutional Networks
论文精读:【图像超分】论文精读:Image Super-Resolution Using Deep Convolutional Networks(SRCNN)
请配合上述论文精读文章使用,效果更佳!
代码地址:图像超分辨率SRCNN和FSRCNN复现代码,除基本的网络实现外,还有特征图可视化,PSNR曲线图可视化,测试自己的图像数据等
不想理解原理,希望直接跑通然后应用到自己的图像数据的同学,请直接下载上面的代码,有训练好的模型,直接用即可。具体使用方式见代码中的README!有问题来本文评论区留言!
深度学习的模型训练一般遵循以下步骤:
下面让我们根据通用流程,一步一步复现SRCNN吧!目标是:输入大小为 h×w 的图像 X,输出为一个 sh×sw 的图像 Y,s 为放大倍数。论文中s取值为2,3,4。
注:放大倍数为1,则图像分辨率不变,只是图像变清晰!如果你只是想将模糊图像通过SRCNN超分后变清晰,那么请将该参数设置为1。
硬件环境:windows11+RTX 2060(比这个高肯定没问题,我这个配置本机跑500个epoch一点问题没有,一会就跑完。但超分自己的图像时,如果图像很大,可能有内存溢出的错误)
运行环境:jupyter notebook/pycharm(前者好处是分代码段运行,测试方法,适合学习用;后者适合跑完整项目用)
pytorch环境:torch1.9.1+cuda11.1(其他版本没测试过,应该问题不大)
简单回顾论文中出现过的数据集:
由于91 images的数据处理有些繁琐,对于新手不太友好,而ImageNet数据集过大,可能不利于硬件设备不好的同学,所以本文使用折中的BSD200数据集,包含200张图像训练集和200张图像测试集。
根据论文中第4节实验部分开头所述,RGB 颜色模式色调、色度、饱和度三者混在一起难以分开,超分只用于YCbCr的Y通道,即亮度分量。因此,需要将图像数据由RGB模型转换成 YCbCr 颜色模式,Y 是指亮度分量,Cb 表示 RGB 输入信号蓝色部分与 RGB 信号亮度值之间的差异,Cr 表示 RGB 输入信号红色部分与 RGB 信号亮度值之间的差异。
此外,通过观察BSD200数据集中的图像可知,数据集中的图像宽高并不一致,每张图像的大小也千差万别。而SRCNN要求输入图像的长宽一致,所以在训练之前,需要将图像裁剪成宽高一致的图像。采用的策略是按图像中心外扩,resize成300×300的图像。
数据预处理的代码如下:
# 判断某个文件是否是图像 # enswith判断是否以指定的.png,.jpg,.jpeg结尾的字符串 # 可以根据情况扩充图像类型,加入.bmp、.tif等 def is_image_file(filename): return any(filename.endswith(extension) for extension in [".png", ".jpg", ".jpeg"]) # 读取图像转为YCbCr模式,得到Y通道 def load_img(filepath): img = Image.open(filepath).convert('YCbCr') y, _, _ = img.split() return y # 裁剪大小,宽高一致为300 # 如果想训练自己的数据集,请根据情况修改裁剪大小 CROP_SIZE = 300 # 封装数据集,适配后面的torch.utils.data.DataLoader中的dataset,定义成类似形式 # 类参数为图像文件夹路径和放大倍数 # __len__(self) 定义当被len()函数调用时的行为(返回容器中元素的个数) #__getitem__(self) 定义获取容器中指定元素的行为,相当于self[key],即允许类对象可以有索引操作。 #__iter__(self) 定义当迭代容器中的元素的行为 # 返回输入图像和标签,传入DataLoader的dataset参数 class DatasetFromFolder(Dataset): def __init__(self, image_dir, zoom_factor): super(DatasetFromFolder, self).__init__() self.image_filenames = [join(image_dir, x) for x in listdir(image_dir) if is_image_file(x)] # 图像路径列表 crop_size = CROP_SIZE - (CROP_SIZE % zoom_factor) # 处理放大倍数,防止用户瞎设置,本例只能设置为2,3,4,大小不变 # 数据集变换 # 还有一些其他的变换操作,如归一化等,遇到一个积累一个 self.input_transform = transforms.Compose([transforms.CenterCrop(crop_size), # 从图片中心裁剪成300*300 transforms.Resize( crop_size // zoom_factor), # Resize, 输入应该是缩放倍数后的图像,因为先缩小后放大 transforms.Resize( crop_size, interpolation=Image.BICUBIC), # 双三次插值 transforms.ToTensor()]) # 图像转成tensor # label标签,超分不是分类问题,定义成一样的就行 self.target_transform = transforms.Compose( [transforms.CenterCrop(crop_size), transforms.ToTensor()]) def __getitem__(self, index): input = load_img(self.image_filenames[index]) # 输入是图像的Y通道,即亮度通道 target = input.copy() input = self.input_transform(input) target = self.target_transform(target) return input, target def __len__(self): return len(self.image_filenames) # 图像个数
至此,数据预处理完成,训练之前就可以传入DataLoader的dataset参数中。
训练过程中,每个epoch会得到一个SRCNN的模型。那么如何评价该模型的性能呢?需要两个评价指标:PSNR和SSIM。由于训练时需要用到,所以需要提前将计算PSNR和SSIM的代码准备好。
PSNR(Peak Signal to Noise Ratio)为峰值信噪比,计算公式如下:
M
S
E
=
1
H
×
W
∑
i
=
1
H
∑
j
=
1
W
(
X
(
i
,
j
)
−
Y
(
i
,
j
)
)
2
M S E=\frac{1}{H \times W} \sum_{i=1}^{H} \sum_{j=1}^{W}(X(i, j)-Y(i, j))^{2}
MSE=H×W1i=1∑Hj=1∑W(X(i,j)−Y(i,j))2
P
S
N
R
=
10
log
10
(
(
2
n
−
1
)
2
M
S
E
)
P S N R=10 \log _{10}\left(\frac{\left(2^{n}-1\right)^{2}}{M S E}\right)
PSNR=10log10(MSE(2n−1)2)
其中,MSE是均方误差。两个图像对应像素位置的值相减再平方和最后取平均。n是每像素的比特数,一般取256。PSNR的单位是dB,该值越大表示图像的失真越小。
通常认为,PSNR在38以上的时候,人眼就无法区分两幅图片了。
PSNR的计算代码如下:
def psnr(loss):
return 10 * log10(1 / loss.item())
损失函数使用的就是MSE,所以这么定义。log10是python的math库中的包。
做实验的时候,PSNR一般保留两位小数。
SSIM(Structural Similarity,结构相似性)由三个对比模块组成:亮度、对比度、结构。
(1) 亮度对比函数
图像平均灰度:
μ
X
=
1
H
×
M
∑
i
=
1
H
∑
j
=
1
M
X
(
i
,
j
)
\mu_{X}=\frac{1}{H \times M} \sum_{i=1}^{H} \sum_{j=1}^{M} X(i, j)
μX=H×M1i=1∑Hj=1∑MX(i,j)
亮度对比函数:
l
(
x
,
y
)
=
2
μ
x
μ
y
+
C
1
μ
x
2
+
μ
y
2
+
C
1
l(x, y)=\frac{2 \mu_{x} \mu_{y}+C_{1}}{\mu_{x}^{2}+\mu_{y}^{2}+C_{1}}
l(x,y)=μx2+μy2+C12μxμy+C1
(2) 对比度对比函数
图像的标准差:
σ
X
=
(
1
H
+
W
−
1
∑
i
=
1
H
∑
j
=
1
M
(
X
(
i
,
j
)
−
μ
X
)
2
)
1
2
\sigma_{X}=\left(\frac{1}{H+W-1} \sum_{i=1}^{H} \sum_{j=1}^{M}\left(X(i, j)-\mu_{X}\right)^{2}\right)^{\frac{1}{2}}
σX=(H+W−11i=1∑Hj=1∑M(X(i,j)−μX)2)21
对比度对比函数:
c
(
x
,
y
)
=
2
σ
x
σ
y
+
C
2
σ
x
2
+
σ
y
2
+
C
2
c(x, y)=\frac{2 \sigma_{x} \sigma_{y}+C_{2}}{\sigma_{x}^{2}+\sigma_{y}^{2}+C_{2}}
c(x,y)=σx2+σy2+C22σxσy+C2
(3) 结构对比函数
s
(
x
,
y
)
=
σ
x
y
+
C
3
σ
x
σ
y
+
C
3
s(x, y)=\frac{\sigma_{x y}+C_{3}}{\sigma_{x} \sigma_{y}+C_{3}}
s(x,y)=σxσy+C3σxy+C3
综合上述三个部分,得到 SSIM 计算公式:
SSIM
(
x
,
y
)
=
f
(
l
(
x
,
y
)
,
c
(
x
,
y
)
,
s
(
x
,
y
)
)
=
[
l
(
x
,
y
)
]
α
[
c
(
x
,
y
)
]
β
[
s
(
x
,
y
)
]
γ
其中,
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。