keras学习笔记-黑白照片自动着色的神经网络-Alpha版

如今,上色都是人手工用Photoshop做的,一张图片要花好几个月才能完成,需要进行大量调查研究,光是其中的一张脸就需要多达20层图层。但是,基于深度神经网络的自动着色机器人,可以几秒钟就实现PS几个月的效果,而且成效越来越惊人。

下面,我们将分三个步骤展示如何打造你自己的着色神经网络。第一部分讲解核心逻辑。我们将构建一个40行代码的神经网络,作为“Alpha”着色机器人,这个代码片段实际上没有太多的魔法,但可以让你熟悉基本操作。

然后,我们将创建一个可以泛化的神经网络——“Beta”版本。Beta机器人能对以前没有看到的图像着色。

最后,我们将神经网络与一个分类器相结合,得到“最终”版本。我们将使用120万张图像训练过的Inception Resnet V2。为了让着色效果吸引眼球,我们将使用Unsplash(免费图库,里面的图片非常有艺术感和设计感)的人像作为数据,训练我们的神经网络。

核心技术拆解:自动着色=发现灰度与彩色间的特征

1、黑白图像可以在像素网格中表示。每个像素具有对应于其亮度的值,范围为0 - 255,从黑色到白色。

2、彩色图像由三层组成:红色层,绿色层和蓝色层。直观地,你可能会认为植物只存在于绿色层。但是,如下图所示,绿色的叶子在三个通道中都有。这些层不仅可以确定颜色,还可以确定亮度。

为了得到白色这个颜色,需要将所有颜色均匀分布。通过添加等量的红色和蓝色,绿色会变得更亮。因此,彩色图像使用三层对颜色和对比度进行编码

就像黑白图像一样,彩色图像中每个图层的值也都为0 - 255。值为0意味着该图层中没有颜色。 如果所有颜色通道的值都为0,则图像像素为黑色。

神经网络会创建输入值和输出值之间的关系。更准确地说,着色任务实际上就是网络需要找到链接灰度图像与彩色图像的特征。

因此,着色机器人要寻找的,就是将灰度值网格链接到三色网格的特征。

01

Alpha版本:40行代码,实现基础着色机器人

我们从简单的神经网络开始,给一张女性脸部图像(见下)着色。

只需40行代码,我们就能实现以下转换。中间的图像是用神经网络完成的,右边的图片是原始的彩色照片。当然,这里的网络使用了相同的图像做训练和测试,稍后我们将在Beta版本中再来讲这一点。

颜色空间

首先,我们使用一种算法来改变颜色通道,从RGB到Lab。L表示亮度,a和b分别表示颜色光谱,绿-红和蓝-黄。

如下所示,Lab编码的图像有一层灰度,将三层颜色层压成两层。这意味着我们可以在最终预测中使用原始的灰度图像。 此外,我们只有两个通道做预测。

人类眼睛中有94%的细胞是确定亮度的,这是个科学事实。只有6%的受体被用作颜色的传感器。如上图所示,灰度图像比彩色层更加清晰。这也是我们最终预测中保持灰度图像的另一个原因。

从黑白到彩色

我们的最终预测是这样的。我们有一个输入灰度层,我们想预测Lab中的两个彩色层。要创建最终的彩色图像,我们将纳入用于输入的L/灰度图像,从而创建一个Lab图像。

我们使用卷积滤波器将一层转成两层。你可以将它们视为3D眼镜中的蓝/红滤镜。每个滤波器确定我们在图片中看到的内容,可以突出显示或删除某些东西,从图片中提取信息。网络可以从滤波器中创建新的图像,也可以将多个滤波器组合成一个图像。

卷积神经网络的每个滤波器都自动调整,以帮助预期的结果。我们从堆叠数百个滤镜开始,然后将它们缩小为两层,即a层和b层。

下面是FloydHub代码:

from keras.layers import Conv2D, UpSampling2D, InputLayer, Conv2DTranspose
from keras.layers import Activation, Dense, Dropout, Flatten
from keras.layers.normalization import BatchNormalization
from keras.models import Sequential
from keras.preprocessing.image 
import ImageDataGenerator, array_to_img, img_to_array, load_img
from skimage.color import rgb2lab, lab2rgb, rgb2gray, xyz2lab
from skimage.io import imsave
import numpy as np
import os
import random
import tensorflow as tf
Using TensorFlow backend.# Get 
imagesimage = img_to_array(load_img('woman.jpg')) image = np.array(image, dtype=float)  X = rgb2lab(1.0/255*image)[:,:,0] Y = rgb2lab(1.0/255*image)[:,:,1:] Y /= 128X = X.reshape(1, 400, 400, 1) Y = Y.reshape(1, 400, 400, 2)# Building the neural networkmodel = Sequential() model.add(InputLayer(input_shape=(None, None, 1))) model.add(Conv2D(8, (3, 3), activation='relu', padding='same', strides=2)) model.add(Conv2D(8, (3, 3), activation='relu', padding='same')) model.add(Conv2D(16, (3, 3), activation='relu', padding='same')) model.add(Conv2D(16, (3, 3), activation='relu', padding='same', strides=2)) model.add(Conv2D(32, (3, 3), activation='relu', padding='same')) model.add(Conv2D(32, (3, 3), activation='relu', padding='same', strides=2)) model.add(UpSampling2D((2, 2))) model.add(Conv2D(32, (3, 3), activation='relu', padding='same')) model.add(UpSampling2D((2, 2))) model.add(Conv2D(16, (3, 3), activation='relu', padding='same')) model.add(UpSampling2D((2, 2))) model.add(Conv2D(2, (3, 3), activation='tanh', padding='same'))# Finish modelmodel.compile(optimizer='rmsprop', loss='mse')  model.fit(x=X, y=Y, batch_size=1, epochs=1000)
Epoch 1/1000
1/1 [==============================] - 1s - loss: 0.0286 Epoch 2/1000 1/1 [==============================] - 0s - loss: 0.0238  Epoch 318/1000 1/1 [==============================] - 0s - loss: 0.0010 Epoch 319/1000 1/1 [==============================] - 0s - loss: 7.4259e-04  Epoch 590/1000 1/1 [==============================] - 0s - loss: 5.5838e-04 Epoch 591/1000 1/1 [==============================] - 0s - loss: 4.7110e-04 Epoch 592/1000   Epoch 845/1000 1/1 [==============================] - 0s - loss: 3.5430e-04 Epoch 846/1000 1/1 [==============================] - 0s - loss: 2.9861e-04  1/1 [==============================] - 0s - loss: 3.0116e-04 Epoch 996/1000 1/1 [==============================] - 0s - loss: 3.1555e-04 Epoch 997/1000 1/1 [==============================] - 0s - loss: 3.0418e-04 Epoch 998/1000 1/1 [==============================] - 0s - loss: 4.3305e-04 Epoch 999/1000 1/1 [==============================] - 0s - loss: 3.9781e-04 Epoch 1000/1000 1/1 [==============================] - 0s - loss: 5.8701e-04<keras.callbacks.History at 0x11ccb6860>
print(model.evaluate(X, Y, batch_size=1)) output = model.predict(X) output *= 128# Output colorizationscur = np.zeros((400, 400, 3)) cur[:,:,0] = X[0][:,:,0] cur[:,:,1:] = output[0] imsave("img_result.png", lab2rgb(cur)) imsave("img_gray_version.png", rgb2gray(lab2rgb(cur)))
1/1 [==============================] - 0s 0.000459772680188 /usr/local/lib/python3.6/site-packages/skimage/util/dtype.py:122: UserWarning: Possible precision loss when converting from float64 to uint8 
.format(dtypeobj_in, dtypeobj_out))
/usr/local/lib/python3.6/site-packages/skimage/util/dtype.py:122: UserWarning: Possible precision loss when converting from float64 to uint16   .format(dtypeobj_in, dtypeobj_out))
# 可视化数据集
import matplotlib.pyplot as plt %matplotlib inline   plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
img = lab2rgb(cur) title = '黑白照片自动着色的神经网络-Alpha版'plt.imshow(img) plt.title(title)
plt.show()

output_7_0.png

Alpha版本不能很好地给未经训练的图像着色。接下来,我们将在Beta版本中做到这一点——将上面的将神经网络泛化。

原文发布于微信公众号 - 人工智能LeadAI(atleadai)

原文发表时间:2018-01-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏专知

【专知荟萃18】目标跟踪Object Tracking知识资料全集(入门/进阶/论文/综述/视频/专家,附查看)

目标跟踪 (Object Tracking/Visual Tracking) 专知荟萃 入门学习 进阶文章 Benchmark 综述 Tutorial 代码 领...

1.1K5
来自专栏上善若水

003计算机图形学:圆的生成算法

其中$(x_0,y_0)$ 是圆心坐标,r为半径。为了简化可以先考虑圆心和坐标原点重合的情况,其他情况可以在此基础上平移得到。

794
来自专栏落影的专栏

GPUImage详细解析(十二)Sobel边界检测

前言 卷积运算是一个看似复杂的概念,今天来揭开这个神秘的面纱。 卷积矩阵:卷积矩阵是一个由权重数据组成的矩阵,中心像素周围像素的亮度乘以这些权重然后再相加就能...

3815
来自专栏专知

【论文推荐】最新六篇视觉问答相关论文—鲁棒性分析、虚拟意象、双曲注意力网络、R-VQA、关系推理、双线性注意力网络

【导读】专知内容组为大家推出最新六篇视觉问答(Visual Question Answering, VQA)相关论文,欢迎查看!

1114
来自专栏图形学与OpenGL

机械版CG 实验6 简单光照明模型实现

Phong光照明模型是由物体表面上一点P反射到视点的光强I为环境光的反射光强Ie、理想漫反射光强Id、和镜面反射光Is的总和,即

711
来自专栏Java与Android技术栈

模拟油画和铅笔画的滤镜效果

然后使用油画风格的滤镜OilPaintFilter看看效果,OilPaintFilter的使用方式就一句话:)

601
来自专栏技术随笔

[福利] 深入理解 RNNs & LSTM 网络学习资料图解

4179
来自专栏专知

【干货】GAN调研:多极扩展(跨域和条件的GAN扩展模型调研)

本文授权转载于知乎专栏作者:陈乐天 https://zhuanlan.zhihu.com/p/32103958 【摘要】 本文关注跨域(cross-domain...

2757
来自专栏专知

【论文推荐】最新九篇自动问答相关论文—可解释推理网络、上下文知识图谱嵌入、注意力RNN、Multi-Cast注意力网络

【导读】专知内容组推出九篇自动问答(Question Answering)相关论文,欢迎查看!

1625
来自专栏专知

【论文推荐】最新5篇推荐系统相关论文—文档向量矩阵分解、异构网络融合、树结构深度模型、深度强化学习、负二项矩阵分解

【导读】专知内容组整理了最近五篇推荐系统(Recommender System)相关文章,为大家进行介绍,欢迎查看! 1. ParVecMF: A Paragr...

3944

扫码关注云+社区