前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >让AI帮助黑白影像焕发色彩

让AI帮助黑白影像焕发色彩

作者头像
代码医生工作室
发布2019-06-21 17:48:10
7790
发布2019-06-21 17:48:10
举报
文章被收录于专栏:相约机器人相约机器人

作者 | Marcelo Rovai

来源 | Medium

编辑 | 代码医生团队

该项目基于Richard Zhang,Phillip Isola和Alexei A. Efros在加州大学伯克利分校开发的研究工作:彩色图像着色

https://arxiv.org/pdf/1603.08511.pdf

本教程是开发一种全自动方法,让黑白照片和视频扩展的生成逼真色彩。正如原始论文中所解释的那样,作者通过在训练时使用类重新平衡来增加结果中颜色的多样性,将问题视为分类任务,从而接受了问题的潜在不确定性。人工智能(AI)方法在测试时作为CNN(“ 卷积神经网络 ”)中的前馈通道实施,并且训练超过一百万个彩色图像。

1906年拍摄了一张照片,展示了Santos Dumont在巴黎的“14-bis”飞机的首次测试:

它的彩色版本使用这些AI技术开发的模型:

相同的技术可以应用于旧视频。这里是1932年巴西里约热内卢市的黑白录像:

和彩色版本:

1.实验室色彩空间

通常习惯使用RGB模型对彩色照片进行编码。RGB颜色模型是一种加色模型,其中红色,绿色和蓝色光以各种方式加在一起,以再现各种颜色。模型的名称来自三种加色原色的首字母,红色,绿色和蓝色。

但是,将在该项目中使用的模型是“LAB”。

在CIELAB颜色空间(也称为CIE的L * a * b *表或有时简称为简单的“实验室”的色彩空间)是由国际照明委员会(CIE)于1976年定义的颜色空间它表达的颜色作为三个数值,L *表示亮度,a *和b *表示绿红色和蓝黄色成分。

颜色空间L * a * b *是在相反颜色理论之后创建的,其中两种颜色不能同时为绿色和红色,或者同时为黄色和蓝色。CIELAB被设计成在人类色觉方面在感知上是均匀的,这意味着这些值中相同数量的数值变化对应于大约相同量的视觉感知变化。

与RGB颜色模型不同,Lab颜色设计用于近似人类视觉。它渴望感性均匀性,其L分量与人类对亮度的感知紧密相关。L分量恰好是用作AI模型的输入,用于估计剩余分量“a”和“b”。

2. AI(深度学习)过程

正如在介绍中所评论的那样,人工智能(AI)方法在测试时被实现为CNN(“卷积神经网络”)中的前馈传递,并且被训练超过一百万个彩色图像。换句话说,使用Lab模型分解了数百万张彩色照片,并用作输入特征(“L”)和分类标签(“a”和“b”)。简单起见将其分为两部分:“L”和“a + b”,如框图所示:

拥有经过训练的模型(可公开获得),可以使用它来为新的黑白照片着色,其中这张照片将是模型或组件“L”的输入。模型的输出将是其他组件“a”和“b”,一旦添加到原始“L”,将返回完整的彩色照片,如下所示:

简而言之,使用来自ImageNet的1.3 Millon照片的广泛且多样化的对象和场景数据集以及应用深度学习算法(前馈CNN),生成最终模型并可在以下位置获得:

彩色图像着色 - 模型

https://github.com/richzhang/colorization/blob/master/models/fetch_release_models.sh

3.工作环境

首先要做的是组织一个将要工作的环境。创建一个文件夹并命名它:

  • Photo_Video_Colorization

在这个主目录下,创建子文件夹:

  • model
  • input_images
  • input_videos
  • colorized_images
  • colorized_frames
  • colorized_videos

转到彩色图像着色模型并下载3个文件并将其加载到创建的子文件夹“/ model”。文件是:

  • colorization_release_v2.caffemodel
  • colorization_release_v2_norebal.caffemodel
  • colorization_release_v1.caffemodel

假设机器上安装了Python(版本3.6)和OpenCV(4.0)。将使用Jupyter笔记本逐步描述所有着色过程。可以去GitHub下载Notebook和测试照片:

Photo_Video_Colorization

https://github.com/Mjrovai/Python4DS/tree/master/Photo_Video_Colorization

4.黑白照片着色

按照步骤着色黑白照片:

导入重要的库:

import numpy as np

import matplotlib.pyplot as plt

import cv2

定义要着色的图像:

IMAGE = "soldiers_1941"

注意:可以在此处使用任何照片。在这种情况下,在第二次世界大战中使用1941年的黑白战士照片。照片可以在GitHub上找到。

定义模型路径:

prototxt = "./model/colorization_deploy_v2.prototxt"

model = "./model/colorization_release_v2.caffemodel"

points = "./model/pts_in_hull.npy"

image =  "./input_images/"+IMAGE

加载序列化黑白颜色模型和集群:

net = cv2.dnn.readNetFromCaffe(prototxt, model)

pts = np.load(points)

将群集中心添加为模型的1x1卷积:

class8 = net.getLayerId("class8_ab")

conv8 = net.getLayerId("conv8_313_rh")

pts = pts.transpose().reshape(2, 313, 1, 1)

net.getLayer(class8).blobs = [pts.astype("float32")]

net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")]

加载输入图像,缩放它并将其转换为Lab:

请注意,首先将图像转换为灰度。这个步骤并不是必需的,但是意识到一些黑白照片,特别是旧照片,在这些年中得到一些治疗,最好稍微清理一下。

image = cv2.imread(image)

image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)

此时有原始图像,但为了在Jupyter单元格上直接显示,应该使用pyplot库:

plt.imshow(image)

plt.axis('off');

提取“L”:

现在采用“图像”并继续着色过程,首先应该重新缩放,转换为Lab以提取组件“L”并将其居中:

scaled = image.astype("float32") / 255.0

lab = cv2.cvtColor(scaled, cv2.COLOR_RGB2LAB)

resized = cv2.resize(lab, (224, 224))

L = cv2.split(resized)[0]

L -= 50

预测“a”和“b”:

net.setInput(cv2.dnn.blobFromImage(L))

ab = net.forward()[0, :, :, :].transpose((1, 2, 0))

ab = cv2.resize(ab, (image.shape[1], image.shape[0]))

创建彩色实验室照片(L + a + b):

L = cv2.split(lab)[0]

colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2)

与对灰度图像一样,检查彩色图像的样子:

plt.imshow(colorized)

plt.axis('off');

plt.title('colorized LAB image');

似乎Lab图像无法告诉我们多少,将其转换为RGB并查看结果:

转换为RGB:

colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2RGB)

colorized = np.clip(colorized, 0, 1)

colorized = (255 * colorized).astype("uint8")

plt.imshow(colorized)

plt.axis('off');

相当了不起!!!!!这是一张1941年的照片,似乎真的是以全彩色拍摄的!保存吧:

保存最终的RGB照片:

cv2.imwrite("./colorized_images/Color_"+IMAGE,

cv2.cvtColor(colorized, cv2.COLOR_RGB2BGR))

还有一个:查尔斯·达尔文于1832年访问巴西里约热内卢:

尝试使用其他黑白照片,看看人工智能有多么神奇!

5.着色视频

一旦对照片进行着色,将视频着色并不是一项复杂的任务。必须遵循以下一般步骤:

  • 获取黑白镜头并将其加载到input_video子目录中
  • 一次一帧地阅读视频
  • 拥有一个框架,应用为照片所做的
  • 拥有彩色框架,将其保存在另一个子文件夹:colorized_video_frames
  • 关闭OpenCv窗口。

来做一个真实的案例:

可以从GitHub下载Notebook B_W_Video_Colorization.ipynb,或按照步骤操作。

https://github.com/Mjrovai/Python4DS/blob/master/Photo_Video_Colorization/B_W_Video_Colorization.ipynb

做的第一件事就是从YouTube下载一部黑白电影,在这种情况下:

https://www.youtube.com/watch?v=InWifglIkQ0

使用了免费工具:VidPaw下载它。把它命名为:“rio_32.mp4”并将其保存在input_video子文件夹中。

https://www.vidpaw.com/

应用上述步骤,最后将所有彩色化的帧存储在子文件夹colorized_video_frames上。

1.开始定义应该着色的文件:

VIDEO = "rio_32.mp4"

2.定义路径,常量和视频变量:

prototxt = "./model/colorization_deploy_v2.prototxt"

model = "./model/colorization_release_v2.caffemodel"

points = "./model/pts_in_hull.npy"

video =  "./input_video/"+VIDEO

width = 500

vs = cv2.VideoCapture(video)

3.加载和准备模型:

net = cv2.dnn.readNetFromCaffe(prototxt,model)

pts = np.load(points)

class8 = net.getLayerId("class8_ab")

conv8 = net.getLayerId("conv8_313_rh")

pts = pts.transpose().reshape(2, 313, 1, 1)

net.getLayer(class8).blobs = [pts.astype("float32")]

net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")]

4.逐帧分割视频并应用模型:

count = 0

success = True

while success:

    success, frame = vs.read()

    if frame is None:

        break

    frame = imutils.resize(frame, 500)

    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB)

    scaled = frame.astype("float32") / 255.0

    lab = cv2.cvtColor(scaled, cv2.COLOR_RGB2LAB)

    resized = cv2.resize(lab, (224, 224))

    L = cv2.split(resized)[0]

    L -= 50



    net.setInput(cv2.dnn.blobFromImage(L))

    ab = net.forward()[0, :, :, :].transpose((1, 2, 0))

    ab = cv2.resize(ab, (frame.shape[1], frame.shape[0]))

    L = cv2.split(lab)[0]

    colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2)

    colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2BGR)

    colorized = np.clip(colorized, 0, 1)

    colorized = (255 * colorized).astype("uint8")

    cv2.imshow("Original", frame)

    cv2.imshow("Colorized", colorized)



    cv2.imwrite("./colorized_video_frames/frame%d.jpg" % count, colorized)

    count += 1

    key = cv2.waitKey(1) & 0xFF

    if key == ord("q"):

        break

vs.release()

cv2.destroyAllWindows()

上述循环过程通常需要一段时间。例如这部视频的彩色化过程(8分钟)有大约14,000帧,在MacBook Pro上花了大约3个小时--2.9GHz Core i7和16GB 2133MHz的RAM。

5.获得带有框架的文件后,必须“重新组装”它以创建视频。bellow功能可以做到:

def convert_frames_to_video(pathIn, pathOut, fps):

    frame_array = []

    files = [f for f in os.listdir(pathIn) if isfile(join(pathIn, f))]



    #for sorting the file names properly

    files.sort(key = lambda x: int(x[5:-4]))



    for i in range(len(files)):

        filename=pathIn + files[i]

        #reading each files

        img = cv2.imread(filename)

        height, width, layers = img.shape

        size = (width,height)

        print(filename)

        #inserting the frames into an image array

        frame_array.append(img)



    out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'MJPG'), fps, size)



    for i in range(len(frame_array)):

        # writing to a image array

        out.write(frame_array[i])

out.release()

请注意,根据在计算机上安装的视频控制器,应更改编解码器(*'MJPG')。请查看OpenCV文档。最后将是“尝试和错误”体验。

现在应该在彩色框架上应用上述功能:

pathIn= './colorized_video_frames/'

pathOut = './colorized_videos/video.avi'

fps = 30.0

convert_frames_to_video(pathIn, pathOut, fps)

由此产生的“原始”视频可以在这里看到:

“文章开始的黑白视频”

请注意,视频显然没有声音。做的是从黑白电影中剥离原始声音,并使用iMovie将其添加到彩色电影中。最终结果如下:

“文章开始的彩色视频”

6.向Santos Dumont致敬

借此机会为旧照片和视频着色,决定向上个世纪的伟大发明家Alberto Santos-Dumont致敬。

Santos-Dumont是巴西的发明家和航空先驱,是为空气轻于空气和重于空气的飞机发展做出重大贡献的极少数人之一。

Santos-Dumont是一个富裕的咖啡生产商家族的继承人,他致力于巴黎的航空研究和实验,在那里度过了他大部分的成年生活。在他早期的职业生涯中,他设计,建造并飞行了热气球和早期的飞船,最终于1901年10月19日赢得了德意志德梅尔特奖,用于绕埃菲尔铁塔航行。然后他转向重于空气的机器,并于1906年10月23日,他的14 - 是欧洲第一个动力重于空中的飞行,由法国Aéro-Club和国际航空联合会认证。他相信航空业将迎来一个全球和平与繁荣的时代,这使他能够自由地发布他的设计并放弃对他的各种创新申请专利。

在上面可以欣赏二十世纪前十年使用本教程中描述的技术着色的一些照片。在下面完成了视频拼贴。希望你能欣赏它。

7.结论

一如既往希望这个项目可以帮助其他人进入数据科学的激动人心的世界!

有关详细信息和最终代码,请访问GitHub存储库:MJRoBot-Python4DS

https://github.com/Mjrovai/Python4DS/tree/master/Photo_Video_Colorization

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 相约机器人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档