SRCNN训练流程
- 设X为按stride=14 从91张图片训练数据中裁剪得33 x 33 大小的图片裁剪得24800张, 则X为 High Resolution Image 即Label,使用set5作为验证集(若用ImageNet的训练数据则stride = 33)
- 对X进行高斯内核平滑,再通过缩放因子下采样 再通过同样的缩放因子进行双三次线性插值上采样得到的图片为Y 我们称为Low-Resolution Samples 即训练集
- 只考虑YCrCb颜色通道中的明亮度通道Y进行训练,其他色度通道进行双三次上采样处理,这样做的目的是与传统的方法进行对比,其他通道仅用于展示不用于训练与测试
- 训练过程中为了避免边缘效应,所有卷积层都没padding所以SRCNN的网络output为20 x 20 图片
- 使用MSE损失函数,方便峰值信噪比,只用X的中心 21 x 21 部分来做真正的label
- 测试的时候并不需要进行裁剪处理,只需对测试图片进行padding剪切,取padding=(fsub-f1-f2-f3+3)/2 ,直接取中心图片进行测试,这与只用X的中心 21 x 21 部分来做真正的label是同样的道理
%% work on illuminance only
if size(im,3)>1
im = rgb2ycbcr(im);
im = im(:, :, 1); %只取灰度分量
end
im_gnd = modcrop(im, up_scale);%图像大小需为up_scale整数倍,去掉多余的行和列
im_gnd = single(im_gnd)/255;% Single(单精度浮点型,占4个字节),图像归一化
%% bicubic interpolation
im_l = imresize(im_gnd, 1/up_scale, 'bicubic');%将im_gnd 双三次插值缩小
im_b = imresize(im_l, up_scale, 'bicubic');%将im_gnd 双三次插值缩小后再进行同
%比例放大
% 将低分辨率图像使用双三次差值放大至目标尺寸(如放大至2倍、3倍、4倍)
%% SRCNN
im_h = SRCNN(model, im_b);
%% remove border 边界修剪,四周各去边框,up_scale个像素(如四周各去3个像素)
im_h = shave(uint8(im_h * 255), [up_scale, up_scale]);
im_gnd = shave(uint8(im_gnd * 255), [up_scale, up_scale]);
im_b = shave(uint8(im_b * 255), [up_scale, up_scale]);
%% compute PSNR
psnr_bic = compute_psnr(im_gnd,im_b);
psnr_srcnn = compute_psnr(im_gnd,im_h);
function imgs = modcrop(imgs, modulo)
if size(imgs,3)==1 % 灰度图时
sz = size(imgs);
sz = sz - mod(sz, modulo);% mod为求余数;sz减去余数(准备去掉多余的行&列)
imgs = imgs(1:sz(1), 1:sz(2)); % 重新获取去掉多余的行&列的图像
else
tmpsz = size(imgs);
sz = tmpsz(1:2);
sz = sz - mod(sz, modulo);
imgs = imgs(1:sz(1), 1:sz(2),:);
end
function psnr=compute_psnr(im1,im2)
if size(im1, 3) == 3,
im1 = rgb2ycbcr(im1);
im1 = im1(:, :, 1);
end
if size(im2, 3) == 3,
im2 = rgb2ycbcr(im2);
im2 = im2(:, :, 1);
end
imdff = double(im1) - double(im2); %一定要用double类型,精度高
imdff = imdff(:);
rmse = sqrt(mean(imdff.^2));
psnr = 20*log10(255/rmse);