阴影生成是属于Image compositing的一个小分支,其旨在于将前景“粘贴复制”到背景上时,通过给前景添加合理的阴影以提升融合度,保证最终整个效果的真实感,效果如下:
阴影生成的两大类方法主要是包括基于渲染(如借用3D模型)或者基于生成技术(如GAN或者Diffusion等),本笔记主要是记录了后者大类的阴影生成技术。
ShadowGAN
《ShadowGAN: Shadow synthesis for virtual objects with conditional adversarial networks》
【论文】
算法流程:是第一个提出使用深度神经网络进行阴影生成的算法,主框架基于生成对抗网络完成,包含一个生成器和两个判别器(全局+局部判别),同时基于3D模型和场景渲染得到训练数据集。
算法细节:
训练数据:从3D模型库(ShapeNet)制作12400对三元组pair (
大小) - 合成贴图:被贴上前景主体的背景图,其中背景区域会有其他一些已经拥有阴影的主体
- 前景mask:决定合成图中前景主体的位置
- 阴影GT:前景主体的阴影
网络结构:
- 生成器:3通道RGB合成图 + 单通道前景mask图
单通道阴影 - 全局判别器:3通道RGB合成图 + 单通道前景mask图 + 单通道阴影(生成 or
GT)
Real / Fake - 局部判别器:裁剪后的3通道RGB合成图 +
裁剪后的单通道前景mask图 +
裁剪后的单通道阴影(生成 or GT)
Real / Fake
- 生成器:3通道RGB合成图 + 单通道前景mask图
训练损失:
:预测的前景阴影和 GT之间的L1损失 :整个生成结果的对抗损失 :将前景区域和生成的阴影裁剪出来,计算该部分图像的对抗损失
限制:
- 训练数据集都是虚拟场景的阴影数据,无真实数据
- 不支持多主体的阴影生成
ARShadowGAN
《ARShadowGAN: Shadow Generative Adversarial Network for Augmented Reality in Single Light Scenes》
算法流程:该算法提出了一个两阶段的阴影生成网络,先预测合成图中背景中的主体位置和其阴影,用以辅助生成前景阴影的生成,同时其也是基于3D模型和场景制作阴影生成数据集。
算法细节:
- 训练数据集:同样从3D模型库(ShapeNet)制作3000对三元组pair
(256
256大小) - 和【ShadowGAN】一样:合成贴图、前景mask、带阴影的GT(但是并非把阴影单独抠出来,而是与合成图组成最终的结果)
- 此外,其数据还包括:a.背景中主体mask;b.背景主体的阴影mask
- 网络结构:
- Attention Block:合成贴图+前景mask
两个Attention Map分别表示对背景中主体mask和其阴影mask的预测 - 生成器:合成贴图+前景mask + 两个Attention Map
粗阴影mask refine后阴影结果 - 判别器:合成贴图+前景mask +
合成贴图中前景拼上阴影结果
Real / Fake
- Attention Block:合成贴图+前景mask
- 训练损失:
- Attention 损失
:两个attenion map与对应mask的L2损失 - 阴影生成损失:
:两部分:a.合成图中贴上预测的粗阴影结果与带阴影的GT的L2损失;b.合成图贴上预测的refine阴影结果与带阴影的GT的L2损失 :也是两部分,分别将 中的L2损失改成VGG损失 :对抗损失
- Attention 损失
- 训练策略:先用500对pair训练Attention Block,然后冻住Attention Block参数再用2000张同时训练生成器和判别器。
- 局限:
- 背景中的主体存在大量阴影的case
- 生成的前景阴影与背景主体的阴影无交集
- 没有改变前景主体的光影效果
- 训练数据集:同样从3D模型库(ShapeNet)制作3000对三元组pair
(256
Mask-ShadowGAN
《Mask-ShadowGAN: Learning to Remove Shadows from Unpaired Data》
算法流程:该方法提出了一种阴影去除网络,利用循环一致性损失(cycle-consistency loss)在unpair数据集完成模型训练。
写在前面:该算法本身是用于去除阴影,而且其阴影也并非像前两种算法一样是某个主体在空间环境下的阴影,其更像是一个阴影块/区域(比如草地上/马路上的阴影等)。
算法细节:
数据集:包括2445张含阴影图像和1770张无阴影图像,两个domain没有pair关系
网络结构:
- Shadow-Free生成器
:3通道有阴影图像 3通道无阴影图像 - 阴影生成器
:3通道无阴影图像+单通道阴影mask 3通道有阴影图像 - Shadow-Free判别器
:输入3通道无阴影图像 判断是否不存在阴影 - 阴影判别器
:输入3通道有阴影图像 判断是否存在阴影
- Shadow-Free生成器
训练损失:
- Shadow Cycle-Consistency Loss
:有阴影图像,在经过
去除阴影后,配合阴影mask再经过 生成阴影后的结果等于自己(该阴影mask通过计算经过 前后的有/无阴影) - Shadow Identity
Loss:有阴影图像加上空阴影mask(纯黑)后经过
生成阴影后的结果等于自己 - Shadow-free Adversarial
Loss:Shadow-Free判别器
的对抗损失 - Shadow-free Cycle-Consistency Loss
:无阴影图像,配合任意阴影mask在经过
添加阴影后再经过 去除阴影后的结果等于自己 - Shadow-free Identity Loss:无阴影经过
去除阴影后的结果等于自己 - Shadow Adversarial Loss:阴影判别器
的对抗损失
- Shadow Cycle-Consistency Loss
:有阴影图像,在经过
其他:
打破一对多映射关系:该论文提出,从无阴影映射到有阴影,是存在多个结果(比如不同的形状、方向等),所以要添加一个阴影mask作为引导,组成<无阴影图,阴影mask>这样的pair,共同映射到<有阴影图>,将一对多映射变成一对一映射。
用于阴影生成:上面的ARShadowGAN和后面要介绍的SGRNet将该算法的中mask-guided迁移到
,即生成阴影时候只有3通道无阴影图像,去除阴影时需要mask做额外输入,借此可以达到阴影生成的效果(但是好像效果都不是很好)
SGRNet
《Shadow Generation for Composite Image in Real-World Scenes》
算法流程:提出了一个两阶段的阴影生成网络,这两个阶段包括"阴影mask预测阶段"和"阴影填充阶段",同时也基于SOBA数据集构建了一个用于阴影生成的数据集DESOBA
解决问题:很多图像合成任务只考虑了前景和背景在诸如光线、位置等方面的和谐性,而没有考虑到将前景插入背景时候的阴影所带来的提升效果。
算法细节:
写在前面:相比其他阴影生成,本算法会多一个BOS【Background-Object-Shadow】的概念,即作者认为BOS数据中背景中的一些主体阴影对于生成前景阴影具有一定的帮助作用,此外即便背景内没有主体阴影的BOS-Free数据,其内的光线信息依然对于生成前景阴影是有用的。
数据集构建:SOBA是一个包含840个训练图片2999个训练pair对、160张测试图片624个训练pair对的数据集,pair形式是"object-shadow",即【带阴影的主体-阴影区域】。DESOBA数据集则通过手工的方式去除主体的阴影部份,对于多主体的图像会随机选择其中1~2个作为待生成阴影的主体目标,最终得到了1012张图,含有3623个“前景-阴影”pair对
网络结构:整个算法是一个两阶段的过程:
- 阴影mask预测阶段:背景主体和阴影mask
+合成图 ,前景主体mask +合成图,这两个分别送入各自的编码器然后再通过一个CAI【Cross-Attention Integration】,将背景的光影信息融合到前景中,然后再通过一个解码器得到前景阴影的二值化mask 。【注意这里的合成图 指的是仅仅将前景主体“粘贴复制”到背景图上,不做任何其他融合】 - 阴影填充阶段:接收
与合成图 通过一个编码器得到光线变化参数 ,然后对 做线性变化后得到变暗后的图像 【该理论主要思想来源于Shor.et并做了逆向转换】。然后再过一个U-Net网络预测得到matting 的mask用于线性插值地融合 和 就得到了最终的合成结果 。
- 阴影mask预测阶段:背景主体和阴影mask
训练损失:
:前景阴影mask的L2损失 :光影变化参数 的L2损失。真实的变化参数可以利用 和真实的合成结果 通过简单的线性回归计算得到【同样也是可以参考Shor.et】。 :最终合成结果的L2的损失 :对抗损失
量化评估指标:SSIM、MSE等
DMASNet
《Shadow Generation with Decomposed Mask Prediction and Attentive Shadow Filling》
【论文】
算法流程:本文提出了一种类似SGRNet的阴影生成网络,其在SGRNet的基础上添加了一个前景阴影区域bbox预测网络,用于定位前景阴影的精确区域。此外本算法也提出了一种更大的阴影生成数据集RdSOBA
算法细节:
数据集:使用3D渲染的方法制作数据集,得到144350张图,含有280000 pair对 ,每对数据包含6张图像:
:组合图(前景主体无阴影) 前景主体及其阴影的mask 背景主体及其阴影的mask 将前景主体的阴影添加到 得到
网络结构:
- Decomposed Mask Prediction:接收
作为输入,先通过两个分支 分别预测前景主体阴影的bounding box和抠出来的阴影mask,然后将阴影贴回到原图区域上得到了粗糙的阴影区域mask- ,然后经过refine后得到精确的阴影mask- - Attentive Shadow Filling:和SGRNet作用一样,通过预测图像的光线变化参数,然后得到变暗的
,再线性插值地融合得到最终结果。
- Decomposed Mask Prediction:接收
训练损失:
:阴影包围框的偏移量损失(类似于目标检测中的损失) :抠出的阴影区域与GT阴影区域的L1损失 :refine后的阴影区域与GT阴影区域的L1损失 :在阴影填充后的最终组合结果与原 的MSE损失
SSN
《SSN: Soft Shadow Network for Image Composition》
算法流程:是一个包含两个阶段的阴影生成算法,且主要用于生成软阴影。整个流程先预测前景的AO Map【具体是啥后面会介绍】,然后再预测得到最终的软阴影mask。
算法细节:
数据集构建:从102个3D模型(43个人体模型+59个通用模型)构建2D的阴影数据,在3D环境下得到氛围遮挡图【AO Map】和环境光图【Environment Light Map】和阴影图。
- 氛围遮挡图【AO Map】:描述了一个点是否是被暴露在环境光下的,AO图中值为0表示没暴露在环境光中(比如车底、鞋底等靠近地面的区域),而值为1的点表示被暴露在环境光中了。即物体完全没有被环境光照射到的区域,比如脚底、车底等,比如下面每组中三个图分别是前景mask🆚不含AO区域阴影图🆚含AO区域阴影图:
- 环境光图【Environment Light Map】:描述了光源信息,是一个或者多个高斯分布的光环叠加,注意这里环境光图的高度是一半(比如mask是256x256则其就是256x128),表示光源位置始终保持在物体的上半部分
- 阴影图:在3D空间根据真实遮挡关系渲染出来的阴影结果。
作者对每个物体绕着3D空间的y轴旋转5个角度,并各自从3个视角渲染阴影,最终得到
个数据对。 网络结构:整个算法是一个两阶段的流程:
AO Map预测:接收前景物体的mask作为输入,通过一个U-Net网络预测得到AO图。
阴影渲染:接收AO map和原前景mask作为输入,也是通过一个U-Net网络预测得到最终的阴影图,同时在encoder和decoder中间插入环境光图。
网络损失:
:预测的AO图与其GT的L2损失 :预测的阴影mask与其GT的L2损失
其他细节:
- Inverse Shadow:对阴影图做一个反转保证大部分区域都是黑的,能够帮助模型更加关注非0区域而非阴影之外的高动态范围。
- 分开训练:网络的两个阶段对应的两个网络是分开训练的。
- 随机渲染环境光图:在训练过程中随机生成环境光图和对应的阴影图GT,提高网络泛化能力。
SSG
《Controllable Shadow Generation Using Pixel Height Maps》
算法流程:该算法创新性地提出了一个"Pixel Height"的2.5D图像表征,并在此基础上指定阴影位置参数并通过图形学渲染的方式获取得到硬阴影,然后再通过阴影软度生成对应的软阴影,具有较好的可编辑性与灵活性。整个流程包括三个核心模块:Pixel Height预测、硬阴影渲染、软阴影生成,其中首尾两个模块是可学习的深度神经网络。
算法细节:
Pixel Height预测:
是本文为了解决阴影生成而创新性提出的一个2.5D表征(有点类似于图像的深度图)
- 定义:该高度表示的是图像中主体上某个点距离其垂直落脚点的像素个数,如下图(a)中的
长度就表示 的Pixel Height。 - 数据制作:有两个方式获取Pixel Height,
- 通过3D模型计算:如下图(b)所示,在给定3D几何模型和相机参数的情况下,可以获取得到精确的Pixel Height Map
- 从2D图像进行标注:如下图(c)所示,在2D图像中的前景主体上进行稀疏的高度标注,然后再通过插值的方式获得完整近似的Pixel Height Map
- Pixel Height预测网络:接收前景图、主体mask和Y坐标图的拼接结果为输入,输出Pixel Height Map【Y坐标图应该就是图像中每个像素的y坐标值的图,每一行的元素值应该是一样的,但是论文中对这个没有做过多的介绍。】
- 训练损失:预测的Pixel Height与GT做MSE损失和TV损失(Total Variation Loss)。
- 定义:该高度表示的是图像中主体上某个点距离其垂直落脚点的像素个数,如下图(a)中的
阴影硬渲染(非神经网络):
模拟如下图(a)所示的光照环境,P'、D'是真实世界的点光源及其在地面的落脚点(并且该落脚点是保证在地平线上的),A'、B'是真实世界的物体和落脚点,C'是A'在此环境下的阴影点。将这些点投影映射到图像平面就分别得到了对应的P/D/A/B/C点,在下图(b)所示中根据相似三角形原理有:
再根据上式可以得到阴影点C的坐标为: 遍历前景主体中所有的像素就可以得到所有对应的硬阴影点,也就得到最终完整的硬阴影,该技术在图形学中属于ray tracing。软阴影生成:
- 数据集:数据制作使用SSN的方法去生成软阴影,使用其介绍的高斯分布的光环的大小作为阴影的软度(softness),最终在训练的时候不断得到(hard shadow, soft shadow, and softness)三元组作为本文的软阴影生成网络的训练数据。
- 网络结构:软阴影生成的整个网络接受"<硬阴影,前景mask>"作为输入,并通过embedding嵌入的方式将softness和光源信息注入到网络中用于控制生成阴影的软度,输出最终的软阴影结果。
- 训练损失:预测的软阴影mask与GT计算MSE损失。
其他:
复杂环境下阴影生成:通过调整背景的pixel height图,能够提升阴影生成的多样性,比如设置竖直墙面,设置悬浮阴影等,如下图所示:
PixHt-Lab
《PixHt-Lab: Pixel Height Based Light Effect Generation for Image Compositing》
算法流程:该算法作为SSG算法的进阶版本,所以又叫”SSG++“,构建pixel height map到3D信息的映射,将2D物体“重建”到3D空间,进提升软硬阴影的生成效果,同时也支持倒影的生成。
写在前面:本人对该篇论文的很多细节理解并不透彻,有些添加了自己的一些主观认知进行表达,读者可以详细看代码以更好理解其中的算法细节。
算法细节:
作者认为像素高度可以明确捕捉物体与地面的关系,从而更好地保持物体的垂直性和阴影渲染的接触点。
在将3D空间中的点映射到图像平面之前,先规定一些信息:
- 相机坐标为
, - 图像平面左上顶点往右的方向向量
,左上顶点往下的方向向量 , - 相机到图像平面左上顶点的向量为
- 相机坐标为
为将3D空间某个点
映射到2D图像平面上的坐标为 ,有以下关系: 同样对于P点在3D空间的落脚点 和其在图像平面的映射点 ,我们也有上述同样的关系,这里我们单独把y坐标拿出来即有: 因为Q在3D空间是落脚点,那么其垂直坐标就是0,即 ,那么就能求得w的值: 然后就能根据图像平面的P'求得3D空间P点的坐标: 其中 表示相机的高度。 上述整个过程示意图如下:
此外地平线在的图像平面内的位置也会影响阴影的形状(比如发生扭曲),所以如果地平线发生变化那么相机的角度要做对应的变化,具体是在竖直方向上移动相机到图像平面左上顶点的向量c,作者没有更多介绍怎么移动,具体可以去看代码。
作者认为还需要一些具有3D感知的信息(3D-aware buffer channels)来辅助生成软阴影,除了前后景的高度图外,还包括前景物体距离可能墙面的距离、多个光源下的硬阴影结果,所有要用到的信息:包括:
- 前景pixel height map和背景pixel height map:其中背景的pixel height map用一种类似gradient map的形式表示,有点类似normal图。
- 稀疏硬阴影图:多个点光源对应的多个硬阴影图的集合,描述了带生成软阴影的边界,同时重叠处也指明了阴影更“深”的地方【点光源都照不到的地方】
- 距离图:描述了遮挡物和shadow
receiver之间的距离,越长那么阴影就越软,在图像平面上的两个点p和q的距离可以计算为:
,其中 表示图像平面的横纵坐标, 表示pixel height。
数据集:从ModelNet和ShapeNet挑选100个物体,并构建了不同的shadow receiver【如地面、墙面等】,最终得到2万训练数据,训练过程和SSG一样。
其他细节:
- 作者利用Ray Tracing技术利用pixel height map进行硬阴影渲染,并重写CUDA算子加速计算过程。
- 该算法能够生成不同材质(如光滑镜面、磨砂等)的地面上的物体倒影
- 该算法能够生成较复杂场景下的阴影生成,如普通地面、墙面、角落等
SGDiffusion
《Shadow Generation for Composite Image Using Diffusion Model》
算法流程:本文先提出了提出了一个更大的阴影数据集DESOBAv2,同时基于Diffusion提出了专用于阴影生成的技术,具体使用ControlNet进行阴影生成,并通过专门设计的Shadow Intensity Modulation调节生成阴影的强度和后处理的色偏修复网络,保证整个生成结果更加和谐。
算法细节:
数据构造:
从自然图像
(含多个主体,且每个主体都有各自的阴影)出发,先使用阴影检测网络得到每个主体的阴影mask,然后合并所有阴影mask后作为整体的阴影mask,并使用Inpainting网络抹除阴影区域,然后随机选择其中一个主体和其对应的阴影作为前景区域,其他都作为背景区域,前景区域的阴影抹除得到 ,其他完整地包含前景背景阴影的图像 作为GT。最终得到的数据pair对包括: :其中一个前景主体不含阴影 :前景主体区域mask :前景阴影区域mask :背景区域阴影mask :对 中的主体生成阴影的GT
该数据集最终有21575 张图 ,包含28573“前景-阴影”pair对。其实也可以看出来:整个数据集中,并非所有图片都是有两个及以上的前景实例的。
网络结构:
Adapting ControlNet to Shadow Generation
该模块使用SD配合ControlNet进行阴影生成,几个小细节如下:
ControlNet接收待生成阴影的图像
和前景mask 的拼接为输入得到控制特征prompt对于效果的影响不大,所以整个生图的过程中对prompt置空
为了让生成过程更关注阴影区域,在去噪过程做了一个加权操作,即有一个weight map
,在待生成阴影的区域(即 区域)值为 ,其他区域为1此外作者上述
区域做了膨胀,因为发现如果不膨胀,网络会偏向于生成大范围的阴影,而忽略了原本阴影的形状和边缘轮廓最终该模块的训练损失为:
在ControlNet训练好后,推理过程中因为生成结果中除了阴影区域外其他区域都原则上要和原图保持一致,所以这里使用图生图的方式,对原图
的latent image添加噪声后得到噪声
Shadow Intensity Modulation:
作者发现仅仅通过上述ControlNet生成的阴影,其和背景并不是特别和谐,尤其是当背景也存在阴影的时候,两个阴影的强度[即黑白透明程度]如果不一致,那么整个画面会显得非常不协调,为了解决这个问题,作者则提出了这个“阴影强度调制”模块,具体细节如下:
设计一个Intensity Encoder,其接受不了
和背景阴影mask 作为输入,输出用于调制强度的缩放向量 和偏移向量 。上述两个向量并非直接用在image上的,而是用来调制预测的噪声的强度的,所以向量的长度和噪声的通道数是一样的,然后做channel-wise的数值调制。
缩放向量
和偏移向量 并非是要修改整个noise map的数值的,而是只需要修改生成的阴影区域的数值,但是我们在测试过程中,是无法知道阴影生成区域的,所以还需要一个前景阴影mask预测网络。为了尽量少的引入额外网络,作者使用SD中U-Net的Decoder中间特征图作为前景阴影mask预测的输入,并使用一般的分割损失进行训练:
此外在diffsuion的过程中,U-Net的decoder特征是随着去噪过程变化,越靠近预测后期,特征值约接近噪声,所以这里要使用比较靠前的特征作为分割网络的输入。
最终我们计算diffusion损失的时候,并非直接使用U-Net输出的噪声,而是要经过一些调制操作,具体指:先对预测的噪声
进行缩放,即channel-wise与缩放向量 相乘后再channel-wise与偏移向量 相加,得到 ,然后再与原始噪声做插值得到最后的噪声: ,然后使用这个噪声去做diffusion的去噪,即 就被改写成:
整个网络的训练损失为:
其他细节:
- 作者发现生成结果可能会有一点色偏,然后其训练了一个矫正网络用于修复色偏问题,具体细节可以看原论文的Supplementary Material。
数据集
数据集名称 | 备注 | 展示 |
---|---|---|
DESOBA | 1012 张图,3623个“前景-阴影”pair对 | |
DESOBAv2 | 21575 张图 ,28573“前景-阴影”pair对,其使用阴影检测和SD-inpainting制作shadow-free image | |
RdSOBA | 144350张图,280000 “前景-阴影”pair对 | |
Shadow-AR | 3000个“前景-阴影”pair对(分辨率640×480) | |
Mask-Shadow_USR | 非pair数据集1956有阴影+1770无阴影+489测试集 |