基于卷积神经网络的法线贴图生成器

news2024/10/5 19:19:05

在本文中,我们将学习如何训练卷积神经网络从彩色图像生成法线贴图。

在这里插入图片描述

推荐:用 NSDT编辑器 快速搭建可编程3D场景

1、数据和工具

我们正着手训练神经网络从彩色图像生成法线贴图。 我们将以“成对”的方式做到这一点。 这意味着我们将显示相应图像的网络对,在本例中为彩色图像和法线贴图。 我将使用 Pixar 128 和 Pixar 130 数据集,它们都包含 1993 年以来的 Pixar 纹理。

我对这两个数据集进行了一些预处理,以删除 Alpha 通道并将图像重新缩放为 256×256 像素。 这将帮助我们在 Python 中减少一些预处理。 我还将纹理组织到颜色和普通文件夹中,因此它们很容易加载到我们的代码中。

到目前为止,我一直提倡使用 Google Colab 来训练你的网络。 在处理小数据集和易于训练的拓扑时,Colab 还可以,但随着数据变得更大、拓扑变得更复杂,你最好在机器中训练网络,最好使用具有足够内存的 Nvidia GPU。

您始终可以在裸 Python 中运行代码,但如果您想要更优雅的界面(类似于 Google Colab 中的界面),您可以在计算机中安装 Jupyter Notebook。 我强烈推荐它。 笔记本可以轻松可视化数据和注释代码。 我建议您在常规 Python 安装(而不是 mayapy.exe)中安装它,这样您就不需要解决二进制兼容性问题。 您始终可以保存模型并在训练后将其加载到 Mayapy 中。

安装 Jupyter 非常简单:

pip install jupyter

运行 Jupyter 非常简单:

jupyter notebook
(if you have Python\Scripts in your PATH environment variable)

我们将在本教程中使用的其他库:Keras(带有你选择的后端)、Numpy、Matplotlib、Scikit-Image 和 PyThreeJS。 确保你已安装所有这些。

2、加载和预处理图像

此处显示的所有代码都可以作为 Jupyter Notebook 提供,不过,我将回顾一下最重要的部分。

首先,我们加载图像:

data_dir = '../data/pixar/'
color_imgs = skimage.io.ImageCollection(data_dir + '/color/*.tif')
normal_imgs = skimage.io.ImageCollection(data_dir + '/normal/*.tif')

然后我们将其转换为浮点类型。 请记住,这些是旧的 8 位和 16 位纹理。

color_imgs = skimage.img_as_float([color_imgs[x] for x in range(len(color_imgs))])
normal_imgs = skimage.img_as_float([normal_imgs[x] for x in range(len(normal_imgs))])

所有图像均为 256×256。 这样的图像大小的卷积网络对于你的显卡(2GB 或更少)来说可能太大。 在这种情况下,你可能需要稍微降低图像的分辨率。

此阶段的最后一步是将数据集拆分为训练集和测试集。 我们这样做是为了确保我们只在训练期间未见过的样本上测试网络的性能(否则我们就会作弊)。 我们使用单个随机种子随机化 color_imgs 和 normal_imgs,如下所示:

seed = np.random.randint(999)
np.random.seed(seed); np.random.shuffle(color_imgs)
np.random.seed(seed); np.random.shuffle(normal_imgs)

然后我们将每个集合的前 70% 和后 30% 分为训练集和测试集。 最好通过绘制训练集、测试集或两者的输入和输出来检查一切是否正常。 可以使用 Scikit-image 和 Matplotlib 来实现这一点。

skimage.io.imshow(skimage.img_as_ubyte(color_train_set[0]))
plt.show()
skimage.io.imshow(skimage.img_as_ubyte(normal_train_set[0]))
plt.show()

3、创建并训练生成式卷积神经网络

好的,现在定义模型。 我们将使用 Keras 模型 API。 让我们导入需要的一切。

from keras.models import Model
from keras.layers import Input, Conv2D, AveragePooling2D, UpSampling2D, BatchNormalization
from keras.optimizers import Adam

正如你可能已经猜到的那样,Conv2D 是卷积层。 它是 2D 的,因为卷积可以发生在 1D 和 3D 等其他维度空间中。

AveragePooling2D 是我们将用来降低特征图分辨率的池化类型。

我们将要构建的网络具有对称拓扑,很像自编码器(Autoencoder)。 我们将把彩色图像卷积到潜在空间中,并从中解卷积出法线贴图。 这就是我们导入 UpSampling2D 的原因。 它的作用与池化操作相反。
在这里插入图片描述

具有对称拓扑的卷积自编码器的视觉表示

我们还导入 BatchNormalization; 通过标准化神经网络每一层的激活来增强收敛性的一种行之有效的方法。 最后,我们加载 Adam 作为优化器。

以下是我们定义模型的方式:

input_img = Input(shape=(img_size, img_size, 3))

ng = Conv2D(15, (3, 3), activation='relu', padding='same', use_bias=False)(input_img)
ng = BatchNormalization()(ng)
ng = AveragePooling2D((4, 4), padding='same')(ng)
ng = Conv2D(30, (3, 3), activation='relu', padding='same', use_bias=False)(ng)
ng = BatchNormalization()(ng)
ng = UpSampling2D((4, 4))(ng)
ng = Conv2D(15, (3, 3), activation='relu', padding='same', use_bias=False)(ng)
ng = BatchNormalization()(ng)
ng = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(ng)
normal_generator = Model(input_img, ng)
normal_generator.compile(Adam(amsgrad=True), loss='mse')

请注意,我们的 Conv2D 层的窗口大小为 3×3。 较大的窗口可能会提供更好的结果,但会使用更多的内存。 过滤器的数量也是如此。 谈到过滤器,我们随着特征图维数的减少而增加过滤器的数量,这是定义卷积模型的常见做法。

另外值得注意的是填充,设置为“相同”。 当我们这样做时,Keras 会对图像进行足够的填充,以便卷积不会减小其大小。 这对于保持输出图像的大小等于输入图像的大小非常重要。

我们消除了 BatchNormalization 之前的所有层的偏差。 任何神经网络层中的偏差都用于重新调整激活值的目的; BatchNormalization 操作通过标准化激活来执行类似的操作,因此无需同时启用这两种方法。 请注意,我们没有对最后一层进行归一化,我们还使用 sigmoid 激活而不是 ReLU; 这是因为我们想要强制像素值在 0 到 1 之间。

如果想查看网络的拓扑,可以调用normal_generator.summary()。 你应该得到这样的东西:
在这里插入图片描述

Keras 模型摘要,包含层和每层的参数(神经元)数量

我们使用 fit函数训练网络:

normal_generator.fit(color_train_set, normal_train_set,
                     validation_data = (color_test_set, normal_test_set),
                     batch_size=batch_size,
                     epochs=100)

4、结果可视化

为了更好地可视化网络训练的进度,我创建了这个函数:

def test_net_with_random_image():
    idx = int(np.random.rand(1)*len(color_test_set))
    y_legit = skimage.img_as_float(normal_test_set[idx]).reshape(1,img_size,img_size,3)
    y_fake = generator.predict(skimage.img_as_float(color_test_set[idx]).reshape(1,img_size,img_size,3))
    skimage.io.imshow(skimage.img_as_ubyte(y_legit).reshape(img_size,img_size,3))
    plt.show()
    skimage.io.imshow(skimage.img_as_ubyte(y_fake).reshape(img_size,img_size,3))
    plt.show()

通过使用它,我们可以将真实的法线贴图与给定相应彩色图像的网络输出进行比较。 正如你所期望的,随机启动且未经训练的网络提供了高熵结果:

在这里插入图片描述

不过训练 200 个 epoch 后,再次调用测试函数时会得到以下结果:
在这里插入图片描述

相当令人印象深刻!

另一种可视化结果的方法是使用 PyThreeJS。 你可能知道 ThreeJS,即 WebGL 框架。 PyThreeJS 是一个包,可让你调用 ThreeJS 并在 Jupyter Notebook 中使用它,这非常适合快速可视化 3D 内容。

使用 PyThreeJS,我们可以加载彩色图像和合成法线贴图到纹理,然后可以在我们想要的任何材质中使用。 通过创建 DataTexture 对象并将 Numpy 数组作为“数据”传递,可以直接从我们经常使用的 Numpy 数组中声明纹理。

idx = int(np.random.rand(1)*len(color_test_set))
x = color_test_set[idx]
y = normal_generator.predict(skimage.img_as_float(color_test_set[idx]).reshape(1,img_size,img_size,3)).reshape(img_size,img_size,3)

color_tex = DataTexture(
    data=x,
    format="RGBFormat",
    type="FloatType",
)

normal_tex = DataTexture(
    data=y,
    format="RGBFormat",
    type="FloatType",
)

然后,我们用简单的材质、相机和灯光创建一个球。
在这里插入图片描述

5、结束语

在本教程中,我们学习了如何创建能够进行成对图像翻译的卷积神经网络。 在此过程中,我们学习了如何在 Keras 中创建和连接卷积层,以及如何使用 Scikit-image 可视化 2D 数据和使用 PyThreeJS 可视化 3D 数据。

这些技能对于为不同类型的应用构建和测试许多其他神经网络拓扑至关重要。 卷积网络可用于时间序列、3d 体素和几何。 PyThreeJS 可用于可视化图元、显式网格和铰接图形。 我们正在建立坚实的基础,以便尽快解决更令人兴奋的模型。


原文链接:用CNN生成法线贴图 — BimAnt

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

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

相关文章

程序人生 / 散文分享 / 生活感悟——【追光的日子】《爷爷的12本日历》,若你也共情,欢迎在评论区分享你的故事、观点、感悟和思考!

在一切变好之前,我们总要经历一些不开心的日子,这段日子也许很长,也许只是一觉醒来。有时候,选择快乐,更需要勇气。 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌿[2] 2023年城市之星领跑者TOP1(哈尔滨)🌿 🌟[3]…

Spring Cloud OpenFeign 性能优化的4个方法

OpenFeign 是 Spring 官方推出的一种声明式服务调用和负载均衡组件。它的出现就是为了替代已经进入停更维护状态的 Netflix Feign,是目前微服务间请求的常用通讯组件。 1.超时设置 OpenFeign 底层依赖Ribbon 框架,并且使用了 Ribbon 的请求连接超时时间…

打表找规律与分析判断:ARC144C

https://atcoder.jp/contests/arc144/tasks/arc144_c?langen 一开始我猜的结论是前后 k k k 个预处理,中间贪心。 通过打表: 可以发现是前面 2 k 2k 2k 连续块直接暴配,最后一段再用我想的贪心。 究其原因,其实是我们本质上…

安卓开发中遇到的奇奇怪怪的问题(四)

好久没有写这个系列了,感觉还是需要把日常开发中遇到的问题做一个记录总结,因为有些问题我当时遇到时,搜都搜不到,只能慢慢摸索。帮助他人的同时也能给自己留个备忘录。话不多说,凡是近一年的奇怪问题,我想…

Rust中的枚举和模式匹配

专栏简介:本专栏作为Rust语言的入门级的文章,目的是为了分享关于Rust语言的编程技巧和知识。对于Rust语言,虽然历史没有C、和python历史悠远,但是它的优点可以说是非常的多,既继承了C运行速度,还拥有了Java…

24 mysql all 查询

前言 这里主要是 探究一下 explain $sql 中各个 type 诸如 const, ref, range, index, all 的查询的影响, 以及一个初步的效率的判断 这里会调试源码来看一下 各个类型的查询 需要 lookUp 的记录 以及 相关的差异 此系列文章建议从 mysql const 查询 开始看 测试表结构…

【网络】路由器和交换机的区别

🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁 🦄 个人主页——🎐开着拖拉机回家_Linux,大数据运维-CSDN博客 🎐✨🍁 🪁🍁 希望本文能够给您带来一定的帮助&#x1…

小谈设计模式(21)—迭代器模式

小谈设计模式(21)—迭代器模式 专栏介绍专栏地址专栏介绍 迭代器模式对象分析聚合对象(Aggregate)迭代器对象(Iterator) Java程序示例程序分析12 优缺点分析优点简化了聚合对象的接口统一的遍历方式增加了代…

20秒基于Chat GPT完成工作中的小程序

1. 写在前面 GPT自从去年爆发以来,各大公司在大模型方面持续发力,行业大模型也如雨后春笋一般发展迅速,日常工作中比较多的应用场景还是问答模式,作为写程序的辅助也偶尔使用。今天看到一篇翻译的博客“我用 ChatGPT,…

更新Xcode 版本后运行项目出现错误 Unable to boot the Simulator 解决方法

错误截图 出现 Unable to boot the Simulator 错误原因很多,以下方法不一定都适用,我是通过以下方法解决的 打开命令终端输入以下命令,可能需要你输入开机密码 sudo rm -rf ~/Library/Developer/CoreSimulator/Caches

Android---字节码层面分析Class类文件

Java 提供了一种可以在所有平台上都能使用的一种中间代码---字节码文件(.class文件)。有了字节码,无论是那个平台只要安装了虚拟机都可以直接运行字节码文件。有了虚拟机,解除了 java 虚拟机与 java 代码之间的耦合。 Java 虚拟机当初被设计出来时就不单…

【设计模式】访问者模式

文章目录 1.访问者模式定义2.访问者模式的角色3.访问者模式实战案例3.1.场景说明3.2.UML类图3.3.代码实现 4.访问者模式优缺点5.访问者模式适用场景6.访问者模式总结 主页传送门:💁 传送 1.访问者模式定义 访问者模式(Visitor Pattern&#x…

【MATLAB源码-第43期】基于matlab的turbo码误码率仿真比较不同迭代次数,采用logmap/sova算法。

操作环境: MATLAB 2022a 1、算法描述 Turbo码是一种前向纠错码 (Forward Error Correction, FEC),在 1993 年由法国的两位研究员 Claude Berrou 和 Alain Glavieux 提出。这种编码技术以其接近 Shannon 极限的高性能而受到广泛关注。以下是关于 Turbo…

黑马JVM总结(二十六)

(1)异常-catch 下面看一下字节码里面怎么做异常的处理 (2)异常-多个catch astore_2:就是把异常对象的地址存到局部变量表2号曹位上 (3)异常-multicatch (4)异常-finally &#xff0…

uniapp 实现地图头像上的水波纹效果

最近实现了uniapp 地图头像水波纹的效果,话不多说,先来看看视频效果吧:链接 在这里具体的代码就不放出来了,还是利用了uniapp的 uni.createAnimation 方法,因为cover-view 不支持一些css 的动画效果,所以这…

探秘布隆过滤器:高效数据查找与去重利器

探秘布隆过滤器:高效数据查找与去重利器 引言 在现代计算机科学中,数据的查找与去重是一个至关重要的问题。本文将介绍一种高效的数据结构——布隆过滤器,它能够在海量数据中快速判断某个元素是否存在,同时具有出色的空间效率。…

动态调整系统主题色(4): CssVar 与 Variant 方案的探索

动态调整系统主题色(4): CssVar 与 Variant 方案的探索 动态调整系统主题色(4): CssVar 与 Variant 方案的探索 前言方案的介绍与比较 CssVar (CSS 变量方案)CSS 变量方案与 tailwindcss 的结合Variant 方案 2种方案在小程序上的示例之前的几篇 前言 这篇已经是动态调整系统…

深度学习模型部署与优化:策略与实践;L40S与A100、H100的对比分析

★深度学习、机器学习、生成式AI、深度神经网络、抽象学习、Seq2Seq、VAE、GAN、GPT、BERT、预训练语言模型、Transformer、ChatGPT、GenAI、多模态大模型、视觉大模型、TensorFlow、PyTorch、Batchnorm、Scale、Crop算子、L40S、A100、H100、A800、H800 随着生成式AI应用的迅猛…

python打开浏览器并模拟搜索

打开已存在的浏览器 打开已存在的浏览器有个很重要的作用就是,可以对于一些登录场景,提前登录好,不需要模拟登录了。 在命令行中执行打开chrome的命令,在图标上找到chrome的安装位置 在cmd命令行下执行命令 C:\Program Files\…

工厂管理软件中的计划排产是什么

一、计划排产的定义: 计划排产是指根据工厂的生产能力、订单需求和资源限制等因素,合理安排生产任务和时间,以实现高效的生产计划。它涉及到生产订单的分配、生产线的调度和资源的优化利用,旨在提高生产效率、缩短交货时间和降低…