利用深度学习进行黑白照片着色:使用 Keras 构建 GAN 进行照片自动上色的详细实践指南

利用深度学习进行黑白照片着色:使用 Keras 构建 GAN 进行照片自动上色的实践指南

在这篇博客文章中,我们将探讨一个具有挑战性的问题,即如何利用深度学习自动为黑白照片上色。传统的图片上色过程是一个艰苦且劳动密集型的过程,必须由熟练的平面设计师在 Photoshop 中手动完成,整个过程可能需要很长时间,因为它依赖于设计师的想象力和效率来产生逼真的色彩。然而,随着深度学习的发展,我们可以利用生成对抗网络(GAN)来自动完成这个过程。

实战项目下载

什么是生成对抗网络(GAN)?

在我们深入到构建模型的具体过程之前,让我们先来理解一下什么是生成对抗网络(GAN)。GAN 是深度学习领域的一种革命性技术,它由两部分组成:生成器和判别器。生成器的任务是生成逼真的假数据,而判别器的任务是尽可能地区分真实数据和假数据。这两个网络的竞争和合作推动了 GAN 的训练过程,使其能够生成越来越逼真的假数据。

在我们的场景中,我们将利用 GAN 的这种能力,让它学习如何为黑白照片上色。换句话说,生成器的任务是将黑白照片转换为彩色照片,判别器的任务则是区分真实的彩色照片和生成器生成的彩色照片。

准备工作

在开始构建模型之前,我们需要做一些准备工作。首先,我们需要一个大量的彩色图片数据集作为我们的训练数据。这些图片将被转换为黑白,然后用作输入,而原始的彩色图片则用作目标输出。

我们还需要安装一些必要的 Python 库,包括 Keras,NumPy,OpenCV 等。可以通过 pip 来安装这些库:

pip install keras numpy opencv-python

数据准备

首先,我们需要准备好用于训练的数据集。在这个例子中,我们假设我们已经有了一个大量的彩色图片数据集。我们将使用 OpenCV 将这些彩色图片转换为黑白图片,然后将它们用于训练。以下是转换图片的 Python 代码:

import cv2
import os
import glob# 读取图片文件夹
image_folder = 'color_images'# 获取文件夹内所有图片
image_files = glob.glob(os.path.join(image_folder, '*'))for image_file in image_files:# 读取图片img = cv2.imread(image_file)# 将图片转换为灰度(即黑白)gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 将灰度图片保存为新的文件gray_image_file = os.path.join('gray_images', os.path.basename(image_file))cv2.imwrite(gray_image_file, gray_img)

上述代码将图片文件夹内的所有彩色图片转换为黑白,并保存在新的文件夹内。

现在我们已经为黑白照片上色的任务准备好了数据,下一步是构建我们的 GAN 模型。

接下来,我们将详细讲解如何使用 Keras 构建和训练一个 GAN 模型,以及如何使用训练好的模型为黑白照片上色。

构建生成对抗网络 (GAN)

构建生成器

生成器的任务是接收一个黑白图像并生成一个彩色图像。为了实现这个任务,我们将使用一个类似于 U-Net 的网络结构。U-Net 是一个对称的卷积神经网络,它的名字来源于其U形的结构。U-Net 最初被设计用于医学图像分割,但它也非常适合我们的任务。

以下是构建生成器的 Python 代码:

from keras.models import Model
from keras.layers import Input, Conv2D, Activation, BatchNormalization, UpSampling2D, Concatenate# 定义 U-Net 类型的生成器网络
def build_generator():# 输入是一个灰度图像,尺寸为 256x256inputs = Input(shape=(256, 256, 1))# 下采样阶段down1 = Conv2D(64, (3, 3), padding='same')(inputs)down1 = Activation('relu')(down1)down1_pool = MaxPooling2D((2, 2), strides=(2, 2))(down1)# 上采样阶段up1 = UpSampling2D((2, 2))(down1_pool)up1 = Concatenate(axis=3)([down1, up1])up1 = Conv2D(64, (3, 3), padding='same')(up1)up1 = Activation('relu')(up1)# 输出 3 个通道的彩色图像num_output_channels = 3outputs = Conv2D(num_output_channels, (1, 1), activation='tanh')(up1)# 构建模型model = Model(inputs=inputs, outputs=outputs)return model

这段代码定义了一个简单的 U-Net。注意我们的输入是一个灰度图像,输出是一个彩色图像(有3个通道)。在真实的项目中,你可能需要创建一个更复杂的 U-Net,例如增加更多的下采样和上采样层,或者在每个卷积层之后添加批量归一化层。

构建判别器

判别器的任务是区分真实的彩色图像和生成器生成的彩色图像。我们将使用一个简单的卷积神经网络作为我们的判别器。以下是构建判别器的 Python 代码:

from keras.layers import Flatten, Dense# 定义判别器网络
def build_discriminator():# 输入是一个彩色图像inputs = Input(shape=(256, 256, 3))# 卷积层x = Conv2D(64, (3, 3), padding='same')(inputs)x = Activation('relu')(x)# 拉平层x = Flatten()(x)# 全连接层x = Dense(1)(x)# 输出层outputs = Activation('sigmoid')(x)# 构建模型model = Model(inputs=inputs, outputs=outputs)return model

这段代码定义了一个简单的判别器。在真实的项目中,你可能需要创建一个更复杂的判别器,例如增加更多的卷积层,或者使用其他类型的层,如全局平均池化层。

构建 GAN

接下来,我们需要将生成器和判别器组合在一起,形成一个 GAN 模型。我们将使用 Adam 优化器和二元交叉熵损失函数进行训练。

以下是构建 GAN 的 Python 代码:

from keras.optimizers import Adam# 构建 GAN
def build_gan(generator, discriminator):# 在训练过程中,我们不希望判别器参数被更新discriminator.trainable = False# GAN 的输入是灰度图像gan_input = Input(shape=(256, 256, 1))# 通过生成器获得彩色图像colored_img = generator(gan_input)# 通过判别器获得真伪判断validity = discriminator(colored_img)# 构建模型model = Model(gan_input, validity)# 使用 Adam 优化器和二元交叉熵损失函数model.compile(loss='binary_crossentropy', optimizer=Adam())return model

这段代码定义了一个 GAN,它将我们的生成器和判别器连接在一起。在训练 GAN 时,我们将先固定判别器的参数,让它不会在训练过程中更新。

训练 GAN

接下来,我们将使用我们的数据集来训练 GAN。这个过程包括两个步骤:

  1. 训练判别器:在这个步骤中,我们将生成器生成的假图片和真实的彩色图片一起输入判别器,并更新判别器的参数,使其能更好地区分真假图片。

  2. 训练 GAN:在这个步骤中,我们将黑白图片输入 GAN,并更新生成器的参数,使其生成的假图片能更好地欺骗判别器。

这两个步骤将循环进行,直到 GAN 训练完成。

以下是训练 GAN 的 Python 代码:

import numpy as np# 读取灰度图像和彩色图像的函数
def load_gray_and_color_images():# 这里省略了读取图片的代码,返回值应该是两个 numpy 数组,# 分别包含灰度图像(形状为 (n, 256, 256, 1))和彩色图像(形状为 (n, 256, 256, 3))pass# 训练 GAN
def train_gan(gan, generator, discriminator, epochs, batch_size):# 加载灰度图像和彩色图像gray_images, color_images = load_gray_and_color_images()# 真实标签为 1,假标签为 0real_labels = np.ones((batch_size, 1))fake_labels = np.zeros((batch_size, 1))for epoch in range(epochs):# 随机选择一个批量的灰度图像idx = np.random.randint(0, gray_images.shape[0], batch_size)real_gray = gray_images[idx]# 使用生成器生成彩色图像fake_color = generator.predict(real_gray)# 训练判别器discriminator.trainable = Trued_loss_real = discriminator.train_on_batch(color_images[idx], real_labels)d_loss_fake = discriminator.train_on_batch(fake_color, fake_labels)d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)# 训练生成器discriminator.trainable = Falseg_loss = gan.train_on_batch(real_gray, real_labels)# 打印训练过程中的损失print(f'Epoch: {epoch}, Discriminator Loss: {d_loss}, Generator Loss: {g_loss}')# 初始化网络
generator = build_generator()
discriminator = build_discriminator()
gan = build_gan(generator, discriminator)# 训练 GAN
train_gan(gan, generator, discriminator, epochs=10000, batch_size=32)

这个代码中,我们首先加载灰度图像和对应的彩色图像。然后,我们对 GAN 进行多个训练周期,每个周期中都会进行判别器训练和 GAN 训练两个步骤。

使用训练好的模型进行图像着色

一旦 GAN 训练完毕,我们就可以使用训练好的生成器模型对灰度图像进行上色了。以下是进行图像着色的 Python 代码:

from PIL import Image
import numpy as np# 使用训练好的生成器进行图像上色的函数
def colorize_image(generator, gray_image_path, output_path):# 打开灰度图像,并将其调整为模型需要的尺寸和格式gray_image = Image.open(gray_image_path).convert('L')gray_image = gray_image.resize((256, 256))gray_image = np.array(gray_image)gray_image = np.expand_dims(gray_image, axis=-1)gray_image = np.expand_dims(gray_image, axis=0)gray_image = gray_image / 255.0# 用生成器生成彩色图像color_image = generator.predict(gray_image)# 将彩色图像的格式调整为可以保存为图片的格式color_image = np.squeeze(color_image, axis=0)color_image = color_image * 0.5 + 0.5color_image = np.clip(color_image, 0, 1)color_image = (color_image * 255).astype(np.uint8)# 保存彩色图像color_image = Image.fromarray(color_image)color_image.save(output_path)

在这个代码中,我们首先打开一张灰度图像,并将其调整为模型需要的尺寸和格式。然后,我们用训练好的生成器生成彩色图像。最后,我们将生成的彩色图像保存下来。

结论

在这篇文章中,我们介绍了如何使用 Keras 和生成对抗网络(GAN)来自动为黑白图像上色。我们展示了如何构建生成器和判别器,如何训练 GAN,以及如何使用训练好的 GAN 进行图像上色。

需要注意的是,虽然 GAN 能够生成令人印象深刻的结果,但训练 GAN 通常需要大量的时间和计算资源。此外,GAN 生成的图像质量也取决于许多因素,如训练数据的质量和数量,网络结构的选择,以及训练参数的设置。因此,如果你在实践中遇到了问题,或者对 GAN 有进一步的疑问,都可以留言告诉我们,我们将尽力为你解答。

希望这篇文章能帮助你理解 GAN 的工作原理,以及它在图像处理中的应用。我们鼓励你亲自动手实现这个项目,以更好地理解这些概念。如果你有任何疑问,或者对其他相关主题感兴趣,欢迎在下方留言讨论。我们期待在下一篇文章中再次与你相见。

参考资料

  • Goodfellow, I., Pouget-Abadie, J., Mirza, M., Xu, B., Warde-Farley, D., Ozair, S., … & Bengio, Y. (2014). Generative adversarial nets. In Advances in neural information processing systems (pp. 2672-2680).

  • Ronneberger, O., Fischer, P., & Brox, T. (2015, October). U-net: Convolutional networks for biomedical image segmentation. In International Conference on Medical image computing and computer-assisted intervention (pp. 234-241). Springer, Cham.

  • Kingma, D. P., & Ba, J. (2014). Adam: A method for stochastic optimization. arXiv preprint arXiv:1412.6980.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/4101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cannot get a STRING value from a NUMERIC cell

Cannot get a STRING value from a NUMERIC cell 错误一: 导入Excel表格数据,该列设置数据类型为String,输入数据是int类型 解决方法:cell.setCellType(CellType.STRING); 错误二:日期类型需要定义格式 解决方法如下&a…

朝花夕拾 - 2023 精神错乱记录

jsliang 的精神错乱记录,一点 2023 小思考。 也许我们曾偏离航道,但请不要放弃抵达终点 前言 在 2020.11 过来珠海,来到金山工作 2 年半的时间里: 在工作上,更换了 3 个小团队,达到了每年一换在工作上&…

autok3s k3d rancher研究

参考 功能介绍 | Rancher文档AutoK3s 是用于简化 K3s 集群管理的轻量级工具,您可以使用 AutoK3s 在任何地方运行 K3s 服务。http://docs.rancher.cn/docs/k3s/autok3s/_index 什么是 AutoK3s k3s是经过完全认证的 Kubernetes 产品,在某些情况下可以替…

沉淀自己的pro-table组件,并发布到npm(Vue3、element-plus)

文章目录 沉淀自己的pro-table组件,并发布到npmQuick Start开发过程笔记add TS Support 参考资料 沉淀自己的pro-table组件,并发布到npm 传送门 约定:npm包名vue3-el-pro-table,引用vue3-el-pro-table的包名为“本项目”。 声明…

Oracle EBS 客制化AP发票无法验证和关联交易的AR事务处理无法创建

背景: 在某项目上,国外账套上线以后,国外法人所有单据使用英文(US);涉及关联交易时,如国外公司使用英文环境创建AP发票,国内公司使用中文环境创建AR事务处理。 问题症状: 1、客制化AP发票接口API采用异步方式处理,每次从客制化AP发票接口表中取一定记录条数批量处理,…

iOS开发 - appstore评价与app内展示appstore

iOS开发 - appstore评价与app内展示appstore 之前开发中遇到app内通过广告直接展示某个app的appstore信息页面。StoreKit提供了SKStoreProductViewController可以app中直接访问app store 而不需要跳转到app store 一、代码实现 #import "SDStoreProductManager.h"…

linux之Ubuntu系列(四)用户管理 用户和权限 chmod 超级用户root, R、W、X、T、S 软链接和硬链接 shell

r(Read,读取):对文件而言,具有读取文件内容的权限;对目录来说,具有浏览目 录的权限。 w(Write,写入):对文件而言,具有新增、修改文件内容的权限;对目录来说,具有删除、移…

MySQL切分函数substring()的具体使用

目录 一、LEFT() 函数 二、RIGHT() 函数 三、SUBSTRING() 函数 四、SUBSTRING_INDEX() 函数 五、实战操作 MySQL字符串截取函数主要有:left(), right(), substring(), substring_index() 四种。各有其使用场景。今天,让我带大家花几分钟时间来熟知它…

恢复配置并减少网络停机时间

随着众多公司努力在商业世界中崭露头角,拥有可靠的 IT 基础架构比以往任何时候都更加重要。组织需要维护一个稳定的网络环境,避免不合时宜的网络中断以及网络连接中断、声誉受损、应用程序不可用和数据丢失。 Network Configuration Manager 提供了一种…

打磨投资论(宏观指标篇)|底层逻辑

前言: 根据某次美国社融通胀数据,预期CPI 3.1,实际3.0,说明通货膨胀水平减缓,有改善,加息概率减少,降息概率加大,钱流入市场的概率增加,利好股市,也利好黄金…

LLM微调 | LoRA: Low-Rank Adaptation of Large Language Models

🔥 发表于论文:(2021) LoRA: Low-Rank Adaptation of Large Language Models 😄 目的:大模型预训练微调范式,微调成本高。LoRA只微调新增的小部分参数。 文章目录 1、背景2、动机3、LoRA原理4、总结 1、背景 adapter…

LSTM对比Bi-LSTM的电力负荷时间序列预测(Matlab)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Linux 学习记录52(ARM篇)

Linux 学习记录52(ARM篇) 本文目录 Linux 学习记录52(ARM篇)一、汇编语言相关语法1. 汇编语言的组成部分2. 汇编指令的类型3. 汇编指令的使用格式 二、基本数据处理指令1. 数据搬移指令(1. 格式(2. 指令码类型(3. 使用示例 2. 立即数(1. 一条指令的组成 3. 移位操作指令(1. 格式…

[QT编程系列-13]:QT快速学习 - 1- 初识

目录 第1章 QT的介绍 1.1 QT VS MFC 1.2 QT历史 1.3 QT的应用 1.4 QT学习方法 1.5 QT对象树 1.6 2-8定律 1.7 QT优势: 1.8 QT支持的平台 第2章 QT UI是各种控件对象的堆积 第3章 QT UI是各种控件的堆积 第4章 控件窗口的控制 第1章 QT的介绍 1.1 QT V…

回归预测 | MATLAB实现Attention-GRU多输入单输出回归预测(注意力机制融合门控循环单元,TPA-GRU)

回归预测 | MATLAB实现Attention-GRU多输入单输出回归预测----注意力机制融合门控循环单元,即TPA-GRU,时间注意力机制结合门控循环单元 目录 回归预测 | MATLAB实现Attention-GRU多输入单输出回归预测----注意力机制融合门控循环单元,即TPA-G…

GUI-Menu菜单实例(颜色+线型菜单)

运行代码: //GUI-Menu菜单实例(颜色线型菜单) #include"std_lib_facilities.h" #include"GUI/Simple_window.h" #include"GUI/GUI.h" #include"GUI/Graph.h" #include"GUI/Point.h"struc…

JS-27 前端数据请求方式;HTTP协议的解析;JavaScript XHR、Fetch的数据请求与响应函数;前端文件上传XHR、Fetch;安装浏览器插件FeHelper

目录 1_前端数据请求方式1.1_前后端分离的优势1.2_网页的渲染过程 – 服务器端渲染1.3_网页的渲染过程 – 前后端分离 2_HTTP协议的解析2.1_HTTP概念2.2_网页中资源的获取2.3_HTTP的组成2.4_HTTP的版本2.5_HTTP的请求方式2.6_HTTP Request Header2.7_HTTP Response响应状态码 3…

创建、发布npm包,并且应用在项目里面

实现一个函数去监听dom宽高的变化,并且发布NPM包,然后使用到项目中 步骤 1.5W3H 八何分析法 2.如何监听dom宽高变化 3.如何用vite 打包库 4.如何发布npm 一、NPM包新建过程 查看完整目录 1.生成 package.json npm init生成TS配置文件 tsconfig.js…

第二十一章:CCNet:Criss-Cross Attention for Semantic Segmentation ——用于语义分割的交叉注意力

0.摘要 全图像依赖关系为视觉理解问题提供了有用的上下文信息。在这项工作中,我们提出了一种称为Criss-Cross Network(CCNet)的方法,以更有效和高效的方式获取这种上下文信息。具体而言,对于每个像素,CCNet…

禁止浏览器自动填充密码功能,设置自动填充背景色。

禁止浏览器自动填充密码功能,设置自动填充背景色 1、禁止浏览器自动填充密码功能2、设置自动填充背景色(阴影效果) 1、禁止浏览器自动填充密码功能 text设置autocomplete“off” password设置 autocomplete“new-password” 两个一起设置&am…