介绍

大多数图像去噪器技术专注于去除AWGN(高斯白噪声)。 通常,噪声是综合添加的并且涉及各种技术来去除这些图像。 但是随着深度学习的进步,重点已转向为现实世界中的嘈杂彩色图像设计降噪架构。 实际的嘈杂图像是通过具有不同设置或在弱光条件下的不同摄像机获得的。 在较低的相机ISO设置下或在强光条件下,也可以获得相应的清晰图像。 具有干净且嘈杂的图像对,我们可以训练深度学习卷积体系结构以对图像进行降噪。 图像去噪效果可能是肉眼可见的。 我使用PSNR和SSIM指标来衡量图像去噪器性能。

要解决的问题

不能完全保证在摄影中提供高质量的图像。 有时由于光线不足或相机快门速度慢而导致图像损坏。 图像在传输过程中以及压缩时都会被破坏。 对这些低质量图像进行降噪以使其与理想条件下的图像相匹配是一个非常苛刻的问题。

将归纳到DL的问题

我们有两个图像对,一个是嘈杂的,另一个是干净或真实的图像。我们训练卷积架构以消除噪声。这不是分类问题。在分类中,将“ X”视为特征,将“ Y”视为二进制值或分类值。在图像降噪器中,我们将“ X”作为噪点图像,将“ Y”作为真实图像或干净图像。当我们在图像像素级别上进行操作时,我们将平方损耗用作损耗函数。我们试图使总像素级别损失最小化。诸如adadelta,adam之类的任何现代优化器都可以用作优化器。

测量指标:

PSNR:PSNR块计算两个图像之间的峰值信噪比,以分贝为单位。该比率用作原始图像和压缩图像之间的质量度量。 PSNR越高,压缩或重构图像的质量越好。

均方误差(MSE)和峰值信噪比(PSNR)用于比较图像压缩质量。 MSE代表压缩图像和原始图像之间的累积平方误差,而PSNR代表峰值误差的量度。 MSE的值越小,误差越小。

PSNR = 10log10(R * R / MSE)

R =像素的最大值

MSE =干净像素和噪声像素的均方误差

SSIM:这是一种预测数字电视和电影图像以及其他类型的数字图像和视频的感知质量的方法。 SSIM用于测量两个图像之间的相似度。 SSIM索引是完整的参考指标;换句话说,图像质量的测量或预测基于初始未压缩或无失真的图像作为参考。

数据来源

我从下面的链接中收集了“Renoir”和“ NIND”数据集。 归功于准备这些数据集的人员。 从下面的链接中找到有关项目和数据集相关人员的信息。

arxiv:1906.00270

我最初从这些来源收集了约600张图像。 图像平均大小为30 MB,并且大小超过2500 * 2500。 由于在训练时很难将这些图像适配到内存中,因此我将它们的大小调整为256 * 256并训练了模型。 但是后来我发现调整大小并不是一个好主意,因为它会在压缩时增加自身的噪音或信息丢失。 然后,我将原始图像切成小块,这很好,没有任何信息丢失。 例如,如果图像尺寸为2560 * 2560,我将其切成100块256 * 256。 仅用一张图像,我就生成了100多幅图像用于训练。 这样,我准备了3791张图像进行训练而577张图像进行测试的数据集。

数据扩充应用于翻转和旋转数据集。

嘈杂和干净的图像的例子

不同的架构/模型

三星MRDNet

三星团队在NTIRE 2020挑战中使用了此体系结构。

相关论文
arxiv.org:2005.04117。 本文提出了10多种用于现实世界图像降噪的架构,作为2020年CVPRW竞赛的一部分。我使用的是获得第三名的架构。

基于多尺度残差密集块的实像去噪。三星SLSI MSL团队在“NTIRE 2020真实图像降噪挑战”竞赛中提出了MRDN体系结构。

多尺度残差密集网络(Multi-scale Residual Dense Network, MRDN)是基于一种新的基本模块——多尺度残差密集块(Multi-scale Residual Dense Block, MRDB),如图2 (a)所示。MRDB结合了来自ASPP的多尺度特征和传统残差密集块(Residual Dense Block, RDB)的其他特征。如图2 (b)所示,ASPP包含四个并行网络块,分别是Conv 1×1、Conv Rate 6、Conv Rate 12和pooling。Conv Rate 6和Conv Rate 12分别表示3×3膨胀卷积,膨胀率为6和12。Conv Rate 6、Conv Rate 12和图像池化可以很好地捕获块输入的多尺度特征。从ASPP输出的特性被连接和压缩以与RDB的其他特性相结合。为了有一个无缝的本地剩余连接,这个连接特性被另一个Conv 1×1压缩在一个元素级加器之前。MRDB的输出保持了输入的通道数不变,从而避免了复杂度的指数级增长。MRDB作为构建模块,MRDN采用与RDN类似的方式构建网络,MRDB之间通过密集连接进行级联。采用Conv 1×1对mrdb的输出进行级联压缩,并采用全局残差连接获取干净特征。

Keras 代码实现

def denseBlock(previous_output,ks,depth):op_x1=Conv2D(depth,(ks,ks),padding='same',kernel_initializer='he_normal',kernel_regularizer=l2(0.03),\bias_regularizer=l2(0.03))(previous_output)op_x2=Activation('relu')(op_x1)conc1=concatenate([previous_output,op_x2],axis=-1)  op_x3=Conv2D(depth,(ks,ks),padding='same',kernel_initializer='he_normal',kernel_regularizer=l2(0.03), \bias_regularizer=l2(0.03))(conc1)op_x4=Activation('relu')(op_x3)conc2=concatenate([previous_output,conc1,op_x4],axis=-1)op_x5=Conv2D(depth,(ks,ks),padding='same',kernel_initializer='he_normal',kernel_regularizer=l2(0.03), \bias_regularizer=l2(0.03))(conc2)op_x6=Activation('relu')(op_x5)conc3=concatenate([previous_output,conc1,conc2,op_x6],axis=-1)op_x7=Conv2D(depth,(ks,ks),padding='same',kernel_initializer='he_normal',kernel_regularizer=l2(0.03), \bias_regularizer=l2(0.03))(conc3)op_x8=Activation('relu')(op_x7)out_aspp=ASPP(previous_output,depth)conc3=concatenate([previous_output,conc1,conc2,conc3,op_x8,out_aspp],axis=-1)mdr_out=Conv2D(128, (1,1), padding='same',kernel_regularizer=l2(0.03), bias_regularizer=l2(0.03))(conc3)final_mdr_out=Add()([mdr_out,previous_output])return final_mdr_out#ASPP block
def ASPP(previous_output,depth):op_x1=Conv2D(depth,(3,3),padding='same',kernel_initializer='he_normal',kernel_regularizer=l2(0.03), \bias_regularizer=l2(0.03))(previous_output)op_x2=Activation('relu')(op_x1)op_x3 = Conv2D(depth, (1,1), padding='same',kernel_regularizer=l2(0.03), bias_regularizer=l2(0.03))(op_x2)op_x3    =  Dropout(0.3)(op_x3)op_x4 = Conv2D(depth, (3,3), padding='same',dilation_rate=6,kernel_regularizer=l2(0.03), \bias_regularizer=l2(0.03))(op_x2)op_x4    =  Dropout(0.3)(op_x4)op_x5 = Conv2D(depth, (3,3), padding='same',dilation_rate=12,kernel_regularizer=l2(0.03), \bias_regularizer=l2(0.03))(op_x2)op_x5    =  Dropout(0.3)(op_x5)op_x6 = MaxPooling2D((3,3), strides=(1,1), padding='same')(op_x2)conc4    = concatenate([op_x3,op_x4,op_x5,op_x6],axis=-1)op_x7    = Conv2D(depth, (1,1), padding='same',kernel_regularizer=l2(0.03), bias_regularizer=l2(0.03))(conc4)return op_x7#Sequential model starts from here.
depth=128
first_input=Input(shape=(256,256,3))
inp1 = Conv2D(depth, (3,3), padding='same',kernel_regularizer=l2(0.03), bias_regularizer=l2(0.03))(first_input)
inp2 = Conv2D(depth, (3,3), padding='same',kernel_regularizer=l2(0.03), bias_regularizer=l2(0.03))(inp1)inp3 = denseBlock(inp2,3,128)
inp3 =  Dropout(0.3)(inp3)
inp4 = denseBlock(inp3,3,128)
inp4 =  Dropout(0.3)(inp4)conc = concatenate([inp2,inp3,inp4],axis=-1)conv3    = Conv2D(depth, (1,1), padding='same',kernel_regularizer=l2(0.03), bias_regularizer=l2(0.03))(conc)
conv4    = Conv2D(depth, (3,3), padding='same',kernel_regularizer=l2(0.03), bias_regularizer=l2(0.03))(conv3)
add      = Add()([inp1,conv4])
conv5    = Conv2D(depth, (3,3), padding='same',kernel_regularizer=l2(0.03), bias_regularizer=l2(0.03))(add)
outfinal    = Conv2D(3, (3,3), padding='same',kernel_regularizer=l2(0.03), bias_regularizer=l2(0.03))(conv5)
#create model
model=Model(inputs=first_input,outputs = outfinal)

在下面的图中可以看到使用上述模型的预测图像的去噪效果。

MWRCAnet

上述去噪架构由百度Research Vision和HITVPC&HUAWEI团队提出。

arxiv:2005.04117。作为NTIRE 2020年竞赛的一部分,本文介绍了10多个用于真实世界图像去噪的架构。我使用的是一个赢得了第二排名的架构,如上所示。该体系结构包括一个称为Residual Channel attention block的特殊块。

class dwt(Layer):def __init__(self, **kwargs):super().__init__(**kwargs)def get_config(self):config = super().get_config().copy()return configdef call(self, x):x1 = x[:, 0::2, 0::2, :] #x(2i−1, 2j−1)x2 = x[:, 1::2, 0::2, :] #x(2i, 2j-1)x3 = x[:, 0::2, 1::2, :] #x(2i−1, 2j)x4 = x[:, 1::2, 1::2, :] #x(2i, 2j)print(x1)   x_LL = x1 + x2 + x3 + x4x_LH = -x1 - x3 + x2 + x4x_HL = -x1 + x3 - x2 + x4x_HH = x1 - x3 - x2 + x4return Concatenate(axis=-1)([x_LL, x_LH, x_HL, x_HH])class iwt(Layer):def __init__(self, **kwargs):super().__init__(**kwargs)def get_config(self):config = super().get_config().copy()return configdef call(self, x):x_LL = x[:, :, :, 0:x.shape[3]//4]x_LH = x[:, :, :, x.shape[3]//4:x.shape[3]//4*2]x_HL = x[:, :, :, x.shape[3]//4*2:x.shape[3]//4*3]x_HH = x[:, :, :, x.shape[3]//4*3:]x1 = (x_LL - x_LH - x_HL + x_HH)/4x2 = (x_LL - x_LH + x_HL - x_HH)/4x3 = (x_LL + x_LH - x_HL - x_HH)/4x4 = (x_LL + x_LH + x_HL + x_HH)/4 y1 = K.stack([x1,x3], axis=2)y2 = K.stack([x2,x4], axis=2)shape = K.shape(x)return K.reshape(K.concatenate([y1,y2], axis=-1), K.stack([shape[0],\shape[1]*2, shape[2]*2, shape[3]//4]))def channel_attention(input_feature,channel,ratio):x=GlobalAveragePooling2D()(input_feature)x=Reshape((1,1,channel))(x)assert x.shape[1:] == (1,1,channel)x=Conv2D(channel // ratio,1,activation='relu',kernel_initializer='he_normal',\use_bias=True,bias_initializer='zeros')(x)assert x.shape[1:] == (1,1,channel//ratio)x = Conv2D(channel,1,activation='sigmoid',kernel_initializer='he_normal',\use_bias=True,bias_initializer='zeros')(x)x = multiply([input_feature, x])return x
#channel_attention(first_input,64,4)def RCAB(prev_input,filters,kernal_size,blocks):for i in range(blocks):if (i==0):x=Conv2D(filters,kernal_size,padding='same')(prev_input)else:x=Conv2D(filters,kernal_size,padding='same')(lip)x= PReLU(alpha_initializer='he_normal')(x)x=Conv2D(filters,1,padding='same')(x)x=channel_attention(x,filters,4)if (i==0):lip=Add()([prev_input,x])else:lip=Add()([lip,x])x=Conv2D(filters,kernal_size,padding='same')(x)x=Add()([prev_input,x])return x#return Model(inputs=prev_input,outputs=x)def Model_Creation():first_input=Input(shape=(256,256,3))#encoder3first=dwt()(first_input)inp=Conv2D(64,3,padding='same')(first)inp=PReLU(alpha_initializer='he_normal')(inp)second=RCAB(inp,64,3,3)#encoder2out_dwt_second = dwt()(second)inp=Conv2D(256,3,padding='same')(out_dwt_second)inp=PReLU(alpha_initializer='he_normal')(inp)third=RCAB(inp,256,3,3)#encoder1out_dwt_third=dwt()(third)inp=Conv2D(512,3,padding='same')(out_dwt_third)inp=PReLU(alpha_initializer='he_normal')(inp)inp=RCAB(inp,512,3,3)#decoder1inp=RCAB(inp,512,3,3)inp=Conv2D(1024,3,padding='same')(inp)inp=PReLU(alpha_initializer='he_normal')(inp)inp=iwt()(inp)inp=Add()([third,inp])#decoder2inp=RCAB(inp,256,3,3)inp=Conv2D(256,3,padding='same')(inp)inp=PReLU(alpha_initializer='he_normal')(inp)inp=iwt()(inp)inp=Add()([second,inp])#decoder3inp=RCAB(inp,64,3,3)inp=Conv2D(12,3,padding='same')(inp)inp=PReLU(alpha_initializer='he_normal')(inp)inp=iwt()(inp)out=Add()([first_input,inp])return Model(inputs=first_input,outputs=out)model=Model_Creation()

在下图中,使用上述模型可以在预测图像中看到去噪效果。

EDSR模型(Enhanced Deep Residual Network):

arxiv:1707.02921
概念:实际上,这个网络模型是为了提高调整后的图像的质量,当它们再次转换到一个更高的维度。我对上述架构进行了修改,用于对摄影图像进行图像去噪

########################################## EDSR MODEL #####################################
def EDSR(scale, num_filters=256, res_blocks=8, res_block_scaling=None):x_input = Input(shape=(256, 256, 3))# assign value of x to x_res block for further operationsx = x_res_block = Conv2D(num_filters, 3, padding='same')(x_input)# Goes in number of res blockfor i in range(res_blocks):x_res_block = ResBlock(x_res_block, num_filters, res_block_scaling)# convolutionx_res_block = Conv2D(num_filters, 3, padding='same',kernel_initializer='he_normal')(x_res_block)x_res_block=LeakyReLU(alpha=0.1)(x_res_block)# add res_block output and original normalizwd inputx = Add()([x, x_res_block])# upsamplingx = Upsampling(x, scale, num_filters)x = Conv2D(3, 3, padding='same')(x)x=AveragePooling2D(pool_size=(2,2),strides=(2,2),padding='same')(x)x = Conv2D(3, 3, padding='same')(x)return Model(x_input, x, name="EDSR")################################## ResBlock Architecture ################################
def ResBlock(x_input, num_filters):'''This function Implementes Proposed ResBlock Architecture as per EDSR paper'''# proposed ResBlock ==> Conv --> Relu --> Conv --> Scaling(mul) --> Addx = Conv2D(num_filters, 3, padding='same', kernel_initializer='he_normal')(x_input)x=LeakyReLU(alpha=0.1)(x)x = Conv2D(num_filters, 3, padding='same',kernel_initializer='he_normal')(x)x=LeakyReLU(alpha=0.1)(x)x=AveragePooling2D(pool_size=(2,2),strides=(1,1),padding='same')(x)return x
######################################### Upsampling #######################################
def Upsampling(x, scale, num_filters):'''This function upsampling as mentioned in EDSR paper'''def upsample(x, factor, **kwargs):x = Conv2D(num_filters * (factor ** 2), 3, padding='same', **kwargs)(x)return Lambda(shuffle_pixels(scale=factor))(x)if scale == 2:x = upsample(x, 2, name='conv2d_1_scale_2')elif scale == 3:x = upsample(x, 3, name='conv2d_1_scale_3')elif scale == 4:x = upsample(x, 2, name='conv2d_1_scale_2')x = upsample(x, 2, name='conv2d_2_scale_2')return xmodel=EDSR(2, num_filters=128, res_blocks=8, res_block_scaling=None)

在下面的图中可以看到使用上述模型的预测图像的去噪效果。

效果总结

PSNR

如上图所示,mwrcanet体系结构显示了PSNR值的最高。

SSIM

如上图所示,samsung_mrdnet显示了SSIM方面的最高改进。

我还做过的其他尝试:

我用adam optimizer尝试了各种初始学习率,0.0001效果最好

尝试了3种不同的架构,涉及不同的研究

最初,我使用了图像后,调整他们,但调整使信息损失。所以我把原始图像切成小块,用它来训练。这对提高结果有很好的效果。

例如,如果图像大小是30003000,我从一个完整的图像中获得了300300总共100张图像,以避免在调整大小后丢失信息

由于mrdn模型是过拟合的,采用了正则化和dropout

使用新的概念,如PRelu激活,iwt和dwt(小波变换)与mwrcanet模型

结论

三种模型均获得了较好的结果。在PSNR值方面,mwrcanet优于其他所有架构。在SSIM方面,三星- mrdn优于其他任何架构。但是mwrcanet架构产生的结果非常接近于人眼的干净图像。从EDSR架构修改中获得的结果也非常好,接近顶层架构,我认为这是一个基线模型

进一步的讨论

在此,将所有三个颜色通道同时输入到模型中,得到去噪图像。我们可以尝试将单独的通道分别输入,得到每个部分对应的去噪图像,然后将它们组合。所以对于每个通道,我们可以获得单独的权值或者给每个通道,使用单一的架构得到去噪后的通道图像,使用于训练的数据点数量增加3倍。
我已经把原始图像切成碎片,但我没有重新组合它们。我们可以对图像的去噪部分进行估计,并将其组合生成一幅大图像。

最后本文的代码:https://github.com/Anand310892/Real-world-photographic-image-denoiser

deephub翻译组

使用深度学习模型对摄影彩色图像进行去噪相关推荐

  1. 深度学习模型压缩与加速综述

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 导读 本文详细介绍了4种主流的压缩与加速技术:结构优化.剪枝.量化 ...

  2. 一文看懂深度学习模型压缩和加速

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:opencv学堂 1 前言 近年来深度学习模型在计算机视 ...

  3. 【视频课】先搞懂你用的模型,深度学习模型分析课程来了!

    前言 欢迎大家关注有三AI的视频课程系列,我们的视频课程系列共分为5层境界,内容和学习路线图如下: 第1层:掌握学习算法必要的预备知识,包括Python编程,深度学习基础,数据使用,框架使用. 第2层 ...

  4. 【百家稷学】深度学习在计算摄影中的方法与应用(vivo技术分享)

    继续咱们百家稷学专题,本次是有三AI在vivo公司分享的技术讲座.百家稷学专题的目标,是走进100所高校和企业进行学习与分享. 分享主题 本次分享是在vivo AI研究院进行,主题是<深度学习在 ...

  5. 使用ANNdotNET GUI工具创建CIFAR-10深度学习模型

    目录 编辑说明 数据准备 在Anndotnet中创建新的图像分类项目文件 在ANNdotNET中创建mlconfig 创建网络配置 结论 在这篇文章中,我们将为CIFAR-10数据集创建和训练深度学习 ...

  6. [转载] 使用Keras和TensorFlow 2.0建立深度学习模型对图像进行分类

    参考链接: Keras中的深度学习-建立深度学习模型 在本文中,我们将构建一个深度学习模型来对图像中的对象进行分类.为了构建卷积神经网络,我们将使用Kaggle提供的这个数据集.(https://ww ...

  7. CUDA上深度学习模型量化的自动化优化

    CUDA上深度学习模型量化的自动化优化 深度学习已成功应用于各种任务.在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要.网络量化是加速深度学习模型的有效方法.在量化模型中,数据和模型参数 ...

  8. CUDA上的量化深度学习模型的自动化优化

    CUDA上的量化深度学习模型的自动化优化 深度学习已成功应用于各种任务.在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要.网络量化是加速深度学习模型的有效方法.在量化模型中,数据和模型参 ...

  9. TVM将深度学习模型编译为WebGL

    TVM将深度学习模型编译为WebGL TVM带有全新的OpenGL / WebGL后端! OpenGL / WebGL后端 TVM已经瞄准了涵盖各种平台的大量后端:CPU,GPU,移动设备等.这次,添 ...

最新文章

  1. 如何用mysql创建orders表_《MySQL必知必会》学习笔记
  2. boost::edge_coloring用法的测试程序
  3. inputstream是否一定要close_汽车加装行李架后,总被交警拦下,类似改装,是否一定要备案...
  4. 【Python】如何在python中执行另一个py文件
  5. 使用jxl来读取Excel中的数据
  6. CSS3 控制Tab宽度 tab-size属性
  7. 【hue】 Access denied to hive-未解决
  8. [蓝桥杯]基础练习 十六进制转八进制
  9. c+智能指针源码分析_C ++中的智能指针
  10. C++ 中缀表达式转后缀表达式(两种方式:栈、二叉树)
  11. 蓝屏代码查询及代码分析
  12. 常用的锂电池充电芯片
  13. ode45的常用和扩展用法
  14. 从网线到网页之物理层一网线网口
  15. Appium-Get Orientation(获取定位)
  16. 《剑指offer》刷题笔记(发散思维能力):求1+2+3+...+n
  17. google专利的脚步
  18. 【Keycloak 简述】
  19. TMPGEnc 4.0 XPress(小日本4)优化安装教程
  20. 【小工具】 - 修复软raid阵列状态为inacitve的方法

热门文章

  1. 时间编程Chrono库 - C++11
  2. paper plane fly away
  3. GHOST备份文件消失的原因及解决方法
  4. bilbili自动点赞脚本(python)开发
  5. 亿级数据的高并发通用搜索引擎架构设计(转-张宴)
  6. 新能源商用车2022变局:电池能源形式的“技术革命”
  7. 2020年马上要来了,90后寒冬裸辞指南,你将作何选择
  8. PayPal 支付-Checkout 收银台和 Subscription 订阅计划全过程分享
  9. Mac OS下Appium环境搭建及Genymotion模拟器安装
  10. 郑卢高速洛阳至洛宁段路基路面综合设计K14+000-K15+400设计计算书+cad图纸