实现黑白图片自动变成彩色图片

如果你有一幅黑白图片,你该如何上色让他变成彩色的呢?通常做法可能是使用PS工具来进行上色。那么,有没有什么办法进行自动上色呢?自动将黑白图片变成彩色图片?答案是有的,使用深度学习中的Pix2Pix网络就可以实现这一功能。

如图所示,我们可以将黑白动漫图片,通过网络学习,自动变成彩色。对这个Pix2Pix网络是如何实现的,想要进一步了解网络和代码的话,可以点击这个

课程链接

下面,对这个网络进行一点简要介绍。


Pix2Pix网络介绍

pix2pix算是cGAN的一种,但是和cGAN又略有不同,而且,在pix2pix这篇论文中,首次提出了PatchGAN的概念,初次接触到的人可能会略有疑惑。这篇文章,我们就一起来探讨一下,pix2pix中的判别器是如何设计的。

cGAN

提到pix2pix就一定要提一下,他的思想源泉,cGAN。最初我们所熟知的GAN的概念,当属造假钞和验假钞的对抗过程(诞生了DCGAN),造假钞造出来的假钞越来越像真钞,验假钞的越来越能够识别假钞。我们从这个具体故事里面抽象出来,其实就是说,生成器生成的图片够真,就可以骗过判别器。至于这个生成器生成的图片真的是我们想要的?就不一定了。

另外还有一个问题,比如上面这幅图。如果我有一堆火车图片。有正面的也有侧面的,我们都知道这是火车。但是生成对抗网络其实并不理解。如果用最基本的GAN(比如DCGAN)来做的话,很有可能最后就会得到一个normal的图片,就是正面和侧面火车平均之后的一个图片。就会导致训练之后的图片结果很模糊。

cGAN就是来解决这个问题的。c表示conditional,是控制。我想让生成器生成小狗的图片,他就不能生成火车的图片。此时我们的D和G不再是单独的一个输入,而是两种输入。

在生成器部分,我们不仅输入normal distribution,还输入一个条件c(比如cat或者train)。我们在判别器部分,也输入两个,一个是条件c,另外一个是x(生成的数据或者真实的数据)。这里判别器的目的不仅仅要看生成的x数据是否和真实数据分布接近。还要看和条件c是否一致。对于判别器而言,生成的图片不好,还有生成的图片和c不匹配,都要给它低分。

pix2pix的判别器

在pix2pix中我们的判别器构造和cGAN思想基本一致,但稍有不同。

这里,我们的判别器输入两张图像,一张是G的input图像,一张是G的output图像。也就是说,对于判别器而言,不只是输出高质量的图像就可以骗过判别器,必须要两张图像有对应关系才可以。

pix2pix的判别器训练代码

下面,我们从代码详细的看一下,pix2pix是如何对判别器进行计算的。

real_a, real_b = batch[0].to(device), batch[1].to(device)fake_b = net_g(real_a)
optimizer_d.zero_grad()# 判别器对虚假数据进行训练
fake_ab = torch.cat((real_a, fake_b), 1)
pred_fake = net_d.forward(fake_ab.detach())
loss_d_fake = criterionGAN(pred_fake, False)# 判别器对真实数据进行训练
real_ab = torch.cat((real_a, real_b), 1)
pred_real = net_d.forward(real_ab)
loss_d_real = criterionGAN(pred_real, True)# 判别器损失
loss_d = (loss_d_fake + loss_d_real) * 0.5loss_d.backward()
optimizer_d.step()

从代码中我们可以看到,对判别器而言,输入数据需要通过cat来连接之后一起输入。real_a和fake_b的结合数据为假。real_a和real_b结合的数据为真。关于代码中为什么D有detach而G没有detach可以看我写的[2]。

我们来比较一下DCGAN是怎么做的,下面是DCGAN的代码:

# 训练判别器
optimizer_d.zero_grad()
## 尽可能把真图片判别为正
output = netd(real_img)
error_d_real = criterion(output, true_labels)
error_d_real.backward()## 尽可能把假图片判断为错误
noises.data.copy_(t.randn(opt.batch_size, opt.nz, 1, 1))
# 使用detach来关闭G求梯度,加速训练
fake_img = netg(noises).detach()
output = netd(fake_img)
error_d_fake = criterion(output, fake_labels)
error_d_fake.backward()
optimizer_d.step()error_d = error_d_fake + error_d_realerrord_meter.add(error_d.item())

DCGAN和cGAN不太一样的地方就是输入数据不需要concatenate,也就是没有条件c的意思。pix2pix中判别器有两个输入是要求,两个图片必须匹配才算是正确的。

如果对optimzer,loss等流程不太清楚,可以看参考[3]

PatchGAN

pix2pix判别器另外一个设计点,就在PatchGAN了。我们先来看一下PatchGAN的网络结构。


下面是对应代码部分:

class NLayerDiscriminator(nn.Module):"""定义PatchGAN判别器"""def __init__(self, input_nc, ndf=64, n_layers=3, norm_layer=nn.BatchNorm2d, use_sigmoid=False):"""构建PatchGAN判别器参数:input_nc                        --输入图片通道数ndf                             --最后一个卷积层过滤器的数量n_layers                        --判别器卷积层的数量norm_layer                      --标准化层use_sigmoid                     --是否使用sigmoid函数"""super(NLayerDiscriminator, self).__init__()if type(norm_layer) == functools.partial:use_bias = norm_layer.func == nn.InstanceNorm2delse:use_bias = norm_layer == nn.InstanceNorm2dkw = 4  # kernel sizepadw = 1 # paddingsequence = [nn.Conv2d(input_nc, ndf, kernel_size=kw, stride=2, padding=padw),nn.LeakyReLU(0.2, True)]nf_mult = 1nf_mult_prev = 1# 逐渐增加过滤器的数量for n in range(1, n_layers):nf_mult_prev = nf_multnf_mult = min(2**n, 8)sequence += [nn.Conv2d(ndf * nf_mult_prev, ndf * nf_mult,kernel_size=kw, stride=2, padding=padw, bias=use_bias),norm_layer(ndf * nf_mult),nn.LeakyReLU(0.2, True)]nf_mult_prev = nf_multnf_mult = min(2**n_layers, 8)sequence += [nn.Conv2d(ndf * nf_mult_prev, ndf * nf_mult,kernel_size=kw, stride=1, padding=padw, bias=use_bias),norm_layer(ndf * nf_mult),nn.LeakyReLU(0.2, True)]sequence += [nn.Conv2d(ndf * nf_mult, 1, kernel_size=kw, stride=1, padding=padw)]if use_sigmoid:sequence += [nn.Sigmoid()]self.model = nn.Sequential(*sequence)def forward(self, input):return self.model(input)

从网络结构中可以看到,并且结合之前torch.cat我们可以看到,输入的shape是6*256*256,然后输出的shape是1*30*30。

论文中称PatchGAN是一种马尔科夫判别器。关于PatchGAN的理解可以看[6],之前我们说了PatchGAN输出的是一个1*30*30的矩阵。这和我们普通的GAN里面输出一个预测值完全不同。一个矩阵怎么做预测呢?我们的做法是把预测值也扩展成一个1*30*30的矩阵。之后对二者使用最小二乘损失。这相当于对1*30*30的矩阵的每一个点都对应一个label。

通过对图像进行卷积操作,后面的输出矩阵,对前面部分有了更大的感受野(如果不明白感受野,可以看一下这里)。那么,最后输出的30*30的每一个点,相当于最初输入图像的一个Patch,所以命名为PatchGAN。根据论文中描述的,这个Patch大小为70。

这个70是如何计算出来的呢?

感受野计算公式我参考的是[7],下面的表格是PatchGAN网络感受野的计算,可以看到30*30的矩阵,每一个pixel对应的感受野的确是70*70。

Layer Input Size Kernel Size Stride Output Size Receptive Field
Conv1 256*256 4*4 2 128*128 4
Conv2 128*128 4*4 2 64*64 10
Conv3 64*64 4*4 2 32*32 22
Conv4 32*32 4*4 1 31*31 46
Conv5 31*31 4*4 1 30*30 70

另外,可以点击这个网站:Fomoro AI,可以自动帮你分析计算感受野。

这样,使用PatchGAN处理之后,pix2pix就将图像切割成30*30份,每一份对应一个70*70的patch,我们想要每个patch的结果都为真。通过聚焦于一个patch的局部位置,可以更好地提高整体识别和判断效果。

参考

[1]李宏毅生成对抗网络2018
[2]训练生成对抗网络的过程中,训练gan的地方为什么这里没有detach,怎么保证训练生成器的时候不会改变判别器
[3Pytorch中的optimizer.zero_grad和loss和net.backward和optimizer.step的理解
[4]pix2pix主要代码学习
[5][GAN笔记] pix2pix
[6]关于PatchGAN的理解
[7]关于感受野的理解与计算

如何利用Pix2Pix将黑白图片自动变成彩色图片相关推荐

  1. [转]图片自动缩放 js图片缩放

    转自:http://hi.baidu.com/crystalhx/blog/item/deba9b2320274340ac34de09.html 图片自动缩放 js图片缩放 2008-03-27 10 ...

  2. java 生成纯色图片_java实现切图并且判断图片是不是纯色/彩色图片

    java实现切图并且判断图片是不是纯色/彩色图片 发布时间:2020-08-30 15:45:30 来源:脚本之家 阅读:92 作者:点墨花花 整理文档,搜刮出一个java实现切图并且判断图片是否是纯 ...

  3. MATLAB应用实战系列(七十一)-MATLAB实战应用案例:图像处理将灰度图片变成负片彩色图片转换成灰度图片

    前言 本文目录 获取图片的信息 将灰度图片变成负片 彩色图片转换成灰度图片 图像噪声的添加 加10次噪声 colorbar的使用 将数据转换为图片 clc clearA是结构体名,用来存储读入的图像数 ...

  4. html5+实现图片自动切换,js图片自动切换效果处理代码

    var curIndex=0; //时间间隔 单位毫秒 var timeInterval=1000; var arr=new Array(); arr[0]="1.jpg"; ar ...

  5. html 图片自动大小,css图片自适应_用css让图片自动适应大小

    摘要 腾兴网为您分享:用css让图片自动适应大小,政务易,悦读小说,优学堂,悟空识字等软件知识,以及小伴龙,水彩笔刷,昕薇,八门,暴雪战网app,我的世界启动器,中税网继续教育,湖南文交所,我的世界头 ...

  6. python怎么输出图片_python输出彩色图片python 时间处理

    在实际中遇到一个时间处理问题,需要将 Sep 06, 2014 19:30 (UTC 时间) 和 当前时间比较早晚,知道 此 2014-09-06 19:30 格式时间的运算.因此,在处理时,就想 w ...

  7. html页面图片自动缩放比例,html 图片按比例缩放

    声明:本文章摘自网上一位友人的,但由于意外,网页被关闭,没有及时记录他的信息,如有发现原作者,请告知,本人尽快将原作者以及原文章地址补充进来 .thumbnail{overflow:hidden;wi ...

  8. python使用opencv方法将签名图片自动插入到图片任意位置

    三.将签名图片插入到图片底部 方法一:通过操作像素点将图片遍历到原图 原理: 现有待插入图片(jpg\png)格式.手写签名png图片 0.利用opencv修改图片大小 1.使用numpy将两张图片的 ...

  9. html图片自动适应盒子,图片尺寸自动适应div(div控制图片大小自适应)

    全部代码: htmlPUBLIC"-//W3C//DTDXHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/D ...

  10. php图片自动裁剪工具,php图片自动裁剪工具,解决图片变形问题,缩略图问题

    class ImageCut { public $path = ''; public $key = ''; public function __construct() { } public funct ...

最新文章

  1. Flink从Kafka 0.8中读取多个Topic时的问题
  2. 【转载】Python日期时间模块datetime详解与Python 日期时间的比较,计算实例代码
  3. 【快应用篇01】快应用它来了!带你了解什么是快应用!
  4. adb logcat 查看日志
  5. 文件操作相关的系统函数
  6. python特定数之和_python-在特定时间范围内来自pandas数据帧的值的总和
  7. tensorrt报错 [F] [TRT] Assertion failed: Unsupported SM.
  8. Win + Appium + Android/IOS + Python环境搭建
  9. day04.2-迭代器
  10. 关于最新的APP上架流程
  11. 太牛了,2万字用Python深度探索金庸小说世界!
  12. 网络电视机顶盒测试软件,调试接口查找方法,机顶盒刷成全网通盒子,实现免费看电视...
  13. R语言 正态性检验 Q-Q plot shapiro test
  14. 拍拍贷2019Q1财报:核心用户转化率上升 迎战资本竞争力略显不足
  15. xmapp phpstorm xdebug安装
  16. 技术是如何创造价值的
  17. 计算机科学与技术用惠普星15,11代酷睿满血出击 快来GET蔡徐坤同款惠普星14吧...
  18. 决策树(2.回归树)
  19. 互联网公司的中台实践:网易杭研的中台往事
  20. 秒的换算:皮秒、纳秒、微秒、毫秒

热门文章

  1. 中国地图json 文件下载
  2. 魔兽模型【说明/使用方法】
  3. oracle 客户端配置
  4. fedora 19 安装中文语言包
  5. 新浪xweibo代码架构分析
  6. 泛微协同办公e-cology9.0的Ecode二次开发实例说明
  7. 【.Net MF网络开发板研究-06】以太网转串口
  8. 开源网络爬虫程序(spider)一览
  9. linux下部署selenium爬虫程序
  10. vs2015如何建立c语言程序,C语言快速入门——使用Visual Studio 2015创建控制台应用程序...