45. 如何获取物体表面的法向量?好好谈谈光度立体法

2020-09-03 16:39:35 浏览数 (3)

本文同步发表在我的微信公众号和知乎专栏“计算摄影学”,欢迎扫码关注,转载请注明作者和来源

如果你认真读了我上一篇文章44. Light Stage: 无限真实的人脸三维扫描——忘记幼稚的AI换脸吧,你一定会对Light Stage的惊人效果印象深刻。

这种逼真的效果,一个很重要的原因是获取到了人脸表面的法向量。在文章中我还提到,当需要在不同的视角下重建反射场时,是“通过表面的漫反射分量”来完成的,但这是如何做到的呢?

这就引入了我们今天想要讲的主题:光度立体法

一、光度立体法原理

光度立体法,即Photometric Stereo, 最早是由当时在MIT的人工智能实验室的Robert J. Woodham教授在1978年左右提出,比较系统的阐述可以看他在1979年的论文《Photometric stereo: A reflectance map technique for determining surface orientation from image intensity》,以及1980年的论文《Photometric Method for Determining Surface Orientation from Multiple Images》。

这种方法的用途是可以重建出物体表面的法向量,以及物体不同表面点的反射率,最关键的是它不像传统的几何重建(例如立体匹配)方法那样需要去考虑图像的匹配问题,因为所需要做的只是采集三张以上,由不同方向的光照射物体的图像。这个过程中,物体和相机都不动,因此图像天然就是对齐的,这使得整个过程非常的简洁。

Woodham的论文有三个假设:

  1. 首先,他假设相机的投影是正交投影。这样图像上的点的坐标可以直接反映三维物体的表面坐标。

如果用 z = f(x, y)表示三维物体的表面坐标关系(世界坐标系原点位于物体与光心连线上),那么表面法向量应该是:

因为三维物体表面的(x, y)点在这种假设下直接对应着图像上的(x, y)点。那么就可以通过图像上的(x, y)点的相关特性求取到物体表面上对应点的法向量了。

比较好的满足这个假设的相机是远心相机,我在文章32. 镜头、曝光,以及对焦(下)中对这种相机由详细介绍,你可以回顾下。

2. Woodham还假设入射光由远处的单一点光源发出,这样照射到物体表面每一点的光的方向一致,强度一致。

3. 同时,Woodham假设物体表面具有lambertian反射特性,即它对入射光产生漫反射,在每个方向上反射的光强都是一致的。

这种情况下,可以把像素值与光源以及物体表面法向量用下图的公式联系到一起。

这里面,

和N代表了物体表面的特性,而L和l则代表了光源的方向和强度,于是可以分别合并表示如下。N和L都是三维空间中的3x1的单位向量,光源的强度可以用常量1表示。像素值t可以直接通过图像获得,右边的光源方向可以提前标定求得。那么,就可以在物体和相机都不动的情况下,用至少三个不共面的光线照射物体表面第i点,从而将N和

求解出来:

设三个光源方向向量构成矩阵

,对应的三个像素值构成向量

,那么有

(假设

存在)

由于光源照射物体表面时,有可能会产生阴影,这样三个光源无法同时照亮的区域就会无法求解出结果。所以通常可以采用更多的光源从不同方向分别照亮物体并成像来解决这个问题。假设有n>=3个光源,那么则有:

那么

二. 使用光度立体法的基本过程

理解了光度立体法的原理后,我们来看看实际操作的过程。威斯康星-麦迪逊大学的课程CS766_09对此有简明扼要的解释(原链接见pages.cs.wisc.edu/~csve),我这里借用相关材料介绍一下。

2.1 光源方向的标定

首先第一步,是进行光源方向的标定,一种可行的方法是在场景中放入一个光滑的球并在不同光源下成像,这样球的表面高亮处就会反映光源的方向

这里光源方向L,球表面法向量N,以及反射方向R之间的关系如下

有L = 2(NR)N-R

其中R是反射向量取为[0, 0, 1],是观察者到物体的向量,

是高亮点的坐标,

是图像上球心的坐标。那么就有N的表达式:

利用N和R,就可以求得光源方向L。

2.2 计算法向量图和深度图

利用第一节的原理和公式,可以很容易求得物体表面上每一个被足够多的光源照亮的点的法向量。接下来的关键则是利用法向量图,获取深度图。

设投影关系如下图所示:

物体表面法向量N与物体表面上的向量V1及V2垂直,那么有:

以及

仔细观察上面两个式子,会构成一个线性表达式:

Mz = v

其中v由各个像素点的法向量技术而得,M则是一个尺寸为(2*m, m)的稀疏矩阵,其中m为像素个数,z则是各个像素点的深度坐标构成。这个式子可以线性二乘法求解,这样就求得了深度图。

这里有一些示例图,说明了整个流程。

这个数据集是同一佛像由12个不同方向光源分别照射成像的结果。

利用光度立体法,可以计算得到反照率图如下,注意这里我们对图像的每个颜色通道都做了独立运算,而不是把图像转换为灰度图计算。

利用前面介绍的原理,可以获取到表面法向量,进一步获取到相对深度图,甚至还可以做三维渲染,如下图所示:

下面是另外一个示例图集

重建结果:

三. 光度立体法和传统几何重建方法的对比

正如Woodham的论文中所说,光度立体法并不是用于取代传统几何重建方法的,而是和几何重建方法构成了互补关系。下面我列出了这两类方法的对比:

四. 光度立体法在机器视觉中的应用

光度立体法不仅仅在Light Stage这样的系统中使用,在机器视觉、工业生产领域它的应用也非常广泛,我来给你看一些实际应用。如果你具有机器视觉的背景,那么你们一定知道一款非常非常流行的软件系统 Halcon。

HALCON是德国MVtec公司开发的一套完善的标准的机器视觉算法包,拥有应用广泛的机器视觉集成开发环境。它节约了产品成本,缩短了软件开发周期——HALCON灵活的架构便于机器视觉,医学图像和图像分析应用的快速开发。在欧洲以及日本的工业界已经是公认具有最佳效能的Machine Vision软件。 ---- 引自百度百科

Halcon内置了大量机器视觉的教学案例,有好几个例子都跟光度立体法相关,我们看看几个实例:

示例1:检测平坦平面上的缺陷块

这个例子展示了用光度立体法获取平坦平面的反照率,以及法向量图(即梯度图),并由此计算表面高斯曲率图,在这个图上通常比较容易检测出异常块(但在反照率图,以及原图上很难检测出来)

示例2:检测洗发水瓶上的缺陷

这个例子展示了用光度立体法获取洗发水瓶上的缺陷。也是一样的,用不同方向的光照射瓶子,然后利用光度立体法获取表面反照率图,以及法向量(从而获得曲率图)。在反照率图上很难看出的缺陷,在后者却可以轻松检测出来。

示例3:读取盲文

读取药包装上的盲文,也可以由光度立体法来办到,还是一样,盲文这样的表面凸起,比较容易在曲率图或法向量图上检测出来:

Halcon里面关于光度立体法的算子是photometric_stereo,其帮助文档写的很清晰,有一些信息可以补充我们对这个技术的理解。

要点1:光源的方向和数量

Halcon建议将远心相机正对着目标物表面,光源相对相机光心与目标的连线倾角呈Slant度,一般是30到60度。在改变光源方向时,倾角不变,将光源绕物体的中轴线旋转Tilt度即可。如上图所示。通常来说需要4~6个不同的光源方向,因此可以认为Tilt大概是60度~90度之间,保证各个光源方向均匀覆盖物体表面一周。

要点2:相机成像的线性性

我在文章2. 从入射光到JPEG相片-数码相机内部的秘密和27. HDR - 高动态范围成像中都讲过,相机内部成像时有从线性的响应转换为非线性的最终图像的过程

而光度立体法的隐含假设则是图像像素的值是线性反应了光源和反射的强度,因此有必要采用RAW格式图像来获得准确的结果。Halcon还专门提供了算子radiometric_self_calibration用于获取相机的特性,以及算子lut_trans来将非线性的像素值转换为线性的,这里就不展开讲解了。

五. 总结

今天我详细介绍了光度立体法这种独特的获取物体表面法向量的反照率的方法,它和利用几何信息重建三维表面的视觉方法(例如立体匹配)形成了互补关系。这个方法从提出到现在已经过去了40年左右了,但现在还在工业界广泛应用,比如我们上一课介绍的Light Stage系统就采用了光度立体法来获取人脸表面的法向量,而工业视觉软件Halcon则展示了用此方法来进行缺陷检测。Woodham教授功不可没!

希望这篇文章开阔了你的眼界,带给你新的启发,别忘了点赞哦?

六. 参考资料

  • CMU 2017 Fall Computational Photography Course 15-463, Lecture 22
  • 44. Light Stage: 无限真实的人脸三维扫描——忘记幼稚的AI换脸吧
  • Woodham et al., “Photometric stereo: A reflectance map technique for determining surface orientation from image intensity,” IUSIA 1979.
  • 32. 镜头、曝光,以及对焦(下)
  • 威斯康星-麦迪逊大学的课程CS766_09项目
  • Sticky在问题"光度立体三维重建,根据光照模型算出物体表面法线后如何计算出深度?"下的回答
  • Halcon HDevelop 19.11 Progress的示例和帮助文档

0 人点赞