guodong's blog

master@zhejiang university
   

三维重建(2): 渲染工具OpenDR论文和源码部分阅读-1

opendr论文地址:http://files.is.tue.mpg.de/black/papers/OpenDR.pdf

opendr源码地址:https://github.com/mattloper/opendr

本文主要是介绍论文,代码阅读请看这篇

摘要:反向图形尝试获取传感器数据并推断3D几何,照明,材料和运动,使得图形渲染器可以逼真地再现观察到的场景。然而,渲染器旨在解决图像合成的前向过程。为了向另一个方向前进,我们提出了一种近似可微分渲染器(DR),它明确地模拟了模型参数和图像观察的变化之间的关系。我们描述了一个公开的OpenDR框架使得表达前向图形模型变得容易,然后自动获得与模型参数相关的导数并对其进行优化。OpenDR基于新的自动分化包和OpenGL,提供了一种可以合并到概率编程框架中的本地优化方法。我们通过使用它来解决从Kinect深度和RGB数据估计人体形状的问题,展示了使用OpenDR进行编程的强大功能和简单性。

1、简介

计算机视觉作为综合分析具有悠久的传统[9,24],并且仍然是一大类生成方法的核心。在这种自上而下的方法中,视觉被公式化为搜索模型的参数,该模型被渲染以产生图像(或图像的特征),然后将其与图像像素(或特征)进行比较。该模型可以采用多种形式的不同现实主义,但是当模型和渲染过程被设计为产生逼真的图像时,这个过程通常被称为逆图形 [3,33]。从某种意义上说,该方法试图对产生世界图像的物理过程进行逆向工程。

我们将观察函数fΘ)定义为取决于参数Θ的前向渲染过程。最简单的优化将解决最小化渲染图像强度和观察图像强度之间差异的参数,EΘ)= ||fΘ) – I ||2。当然,我们将指定更复杂的功能,包括强大的惩罚和先验,但基本的想法仍然是 – 最小化合成和观察数据之间的差异。虽然已经有很多关于这个过程的文章,并且许多方法属于这个标题,但很少有方法采用逆图形方法。高维度使得优化目标就像上面的挑战一样; 渲染器具有较大的输出空间,而逼真的渲染器需要较大的输入参数空间。从根本上说,前向渲染功能很复杂,包含它的优化方法通常是经过精心设计的。简而言之,图形渲染器通常不会被反转。

在这里,我们完全接受视觉作为逆图形的观点,并提出一个框架,使其更实用。逼真的图形引擎可用于呈现前向过程,并且存在许多辨别方法以直接从图像恢复场景属性。两者都没有明确地模拟可观察量(像素或特征)如何随模型参数平滑变化。这些导数对于优化高维问题是必不可少的,并且为每种应用手工构建这些导数是繁重的。在这里,我们描述了一个基于微分渲染的通用框架。我们定义了一个可微分的渲染器(DR)作为以下过程:(1)提供作为模型参数的函数的像素以模拟物理成像系统;以及(2)提供关于那些参数的像素值的导数。实际上,DR也必须快速; 这意味着它必须具有硬件支持。因此,我们直接使用OpenGL。因为我们公开发布,所以我们称之为OpenDR框架(http://open-dr.org)。

由于许多方法制定了生成模型并微分它们,为什么到目前为止还没有通用的DR框架?也许这是因为渲染似乎不可微分。在某种程度上这是事实,但问题是它在实践中是否重要。所有渲染器都是近似值,我们的DR也不例外。我们在第3节和第4节中描述了我们的近似值,并且认为在实践中,“近似可微分”实际上非常有用。

我们的目标不是渲染,而是反向渲染:我们希望指定并最小化一个目标,其中渲染器只是一个部分。为此,我们的DR基于一个新的自动分化框架,在Python中称为Chumpy,它使编程变得紧凑且相对容易。我们的公共autodiff框架可以轻松扩展OpenDR的基本功能,以解决特定问题。例如,不是将输入几何体指定为顶点,而是可以参数化形状空间中的顶点; 或者在输出中,人们可能想要拉普拉斯金字塔的像素,或边缘或矩,而不是原始像素值。虽然自动分化不会消除编写这些函数的需要,但它确实消除了手动微分它们的需要。

使用它我们定义OpenDR框架,支持计算机视觉中的各种实际问题。OpenDR框架提供了一种紧凑而有效的表达计算机视觉问题的方法,而无需担心如何微分它们。这是第一个用于微分图像生成过程的公开可用框架。

为了评估OpenDR,并说明如何使用它,我们提供了两个例子。第一个是一个简单的“hello world”示例,用于说明OpenDR的基本概念。第二个更复杂的例子涉及将3D人体形状的铰接和可变形模型拟合到来自Kinect的图像和范围数据。在这里,我们优化3D体形,姿势,光照,反照率和相机参数。这是一个复杂而丰富的生成模型,对其进行优化通常具有挑战性; 使用OpenDR,可以直接表达和优化。

虽然微分渲染过程并不能解决计算机视觉问题,但它确实解决了模型参数局部细化的重要问题。我们将此视为与概率规划的随机方法协同的解决方案[22]。我们没有声称视觉上的新颖性是反向图形。我们的新颖之处在于使其实用且易于解决相当广泛的此类问题。我们相信OpenDR是第一个通用的可差异渲染解决方案,它将使人们能够进一步推动综合分析方法。

2 、相关工作

作为逆图形的视觉观点几乎与场本身一样古老[3]。它出现在Grenander关于综合分析的工作中[9],在基于物理学的方法[13]中,在正则化理论[5,32]中,甚至作为人类感知的模型[18,24,27]。这种方法在贝叶斯模型中起着重要作用,而今天这两种观念紧密耦合[19]。在标准贝叶斯公式中,似然函数指定了前向渲染过程,而先验约束(或规范化)模型或参数的空间[19]。通常,可能性不涉及标准图形意义上的实际渲染。在图形中,“逆渲染”通常是指从图像中恢复照明,反射和材料属性(例如,BRDF的估计); 见[26]进行审查。当我们谈论反转渲染过程时,我们指的是更一般的东西,涉及物体形状,相机参数,运动的恢复,

逆图形理论已经很成熟,但缺少的是图像渲染和优化之间的直接联系。图形是关于综合的。推论是从观察到模型(或参数)。可微分渲染通过明确地将观察图像中的变化与模型参数的变化相关联,以具体方式连接这些。

随机搜索与概率规划。 我们的工作与Mansinghka等人的哲学相似。[22]。他们展示了如何编写简单的概率图形程序,描述场景的生成模型以及它与图像观察的关系。然后,他们使用自动和近似随机推断方法从观察中推断出场景模型的参数。虽然我们分享了自动反转场景图形模型的目标,但我们的工作是不同的,互补的。它们解决了随机搜索问题,同时解决了确定性细化问题。虽然随机抽样是接近解决方案的好方法,但通常不是改进解决方案的好方法。完整的解决方案可能包含搜索和优化的这些元素,其中细化阶段可以使用更丰富的模型,确定性优化,

我们的工作在其他方面超越了[22]。他们利用一种非常通用但计算效率低下的Metropolis-Hastings采样器进行推理,这种采样器无法很好地扩展到更复杂的问题。虽然他们的工作始于使用通用图形渲染引擎进行推理的前提,但他们无法应对3D形状,照明,3D遮挡,反射和相机校准; 也就是说,他们没有像我们通常想到的那样渲染图形场景。这些都不会削弱这项工作的重要性,这项工作为概率场景推理奠定了基础。这是概率编程中更一般趋势的一部分,其中一个定义了生成图形模型,并让一般求解器进行推理[8,23,37]。我们的目标是类似的,但对于确定性推理。

最近Jampani等人[15]定义了一个用于解决逆图形问题的通用采样器。他们使用判别方法(自下而上)通知采样器并提高效率。他们的动机与我们类似,因为他们希望通过简单的通用优化方法实现逆图形解决方案。然而,他们的目标不同之处在于他们寻求模型参数的完全后验分布,而我们寻求局部最优。一般来说,他们的方法与我们的方法互补,方法可以结合起来。

微分图形模型。当然,我们不是第一个为视觉问题制定生成图形模型,微分它并解决模型参数的人。这是计算机视觉中一种经过验证的方法。然而,在以前的工作中,这是作为“一次性”解决方案完成的,并且微分模型通常是劳动密集型的。对于给定的场景模型和特定图像特征,定义观察误差函数并且相对于模型参数微分它。针对一个模型获得的解决方案不一定容易应用于另一个模型。一些突出的例子如下。

面部建模: Blanz和Vetter [6]定义了人脸的详细生成模型,并通过综合进行分析以反转模型。他们的模型包括3D脸形,模型纹理,相机姿势,环境照明和定向照明。给定模型参数,它们合成逼真的面部图像,并使用平方和的差异将其与图像像素进行比较。他们明确计算其目标函数的导数,并使用随机梯度下降法计算原因,并帮助避免局部最优。

3D形状估计Jalobeanu等[14]使用差异化渲染过程估计3D行星表面的基本参数(光照,反照率和几何)。他们指出了精确渲染图像和导数以及在物体空间中工作的重要性,以使用计算几何确定每个像素的可见度。与我们一样,他们定义了一个可微分的渲染过程,但重点是贝叶斯推理。

Smelyansky等人[29]定义“分数导数渲染器”并用它在立体重建问题中一起计算摄像机参数和表面形状。与[14]一样,他们使用几何建模来说明不同表面对像素的分数贡献。虽然准确,但这种纯粹的几何方法可能很慢。

Bastian [2]也认为在对象空间中工作避免了处理像素的问题,特别是遮挡是可微分渲染的问题。他建议将图像超级采样作为近似可微分渲染的一种解决方案。相反,他使用MCMC采样并建议采样可以与可微分渲染器结合使用,以避免由于遮挡引起的问题。还参见[34],其解决了具有连续图像表示的图像建模中的类似问题。

重要的是要记住,任何渲染只产生场景的近似值。因此,任何可微分渲染都只会产生近似的导数。无论是在对象空间还是像素空间中工作,都是如此。问题是近似有多好,获得的实用程度如何?我们在下面论证像素空间提供了更好的权衡。

人体姿势和形状 Sminchisecu [31]从单眼视频中制定出清晰的3D人体跟踪问题。他定义了边缘,轮廓和光流的生成模型,并推导出可微分的近似值。在[30]中,Sminchisescu和Telea定义了一个通用编程框架,其中一个指定模型并将这些模型与图像观察联系起来。此框架不会自动微分呈现过程。

de La Gorce等[20]在手部跟踪应用程序中恢复姿势,形状,纹理和光照位置。他们将问题表述为前向图形合成问题,然后微分它,特别注意在对象边界获得导数; 我们采用类似的方法。Weiss等[36]使用来自Kinect的范围数据和对应于人体边界的边缘项来估计人体姿势和形状。他们制定了一个可微分的轮廓边缘项,并提到它有时不可微分,但这只发生在有限多个点上,可以忽略不计。

上述方法都呈现了世界的模型,并且相对于模型参数微分了一些图像误差。尽管它们都可以被视为逆渲染,但在每种情况下,作者都会制定一个目标,然后设计一种近似微分它的方法。我们的主要观点是,我们不是微分每个问题,而是微分渲染。然后,任何可以作为渲染提出的问题,通过构造,(近似)可微分。为了形成一个新问题,人们写下正向过程(由渲染系统表示),自动给出导数,并通过几种局部优化方法之一执行优化。这种微分渲染过程的方法为计算机视觉中的许多问题提供了一般解决方案。

3、定义我们的前向流程

fΘ)为渲染函数,其中Θ是用于创建图像的所有参数的集合。这里我们将Θ分解为顶点位置V,相机参数C和每顶点亮度A:因此Θ = { V,C,A }。逆图形本质上是近似的,在前向过程及其区分中建立近似值非常重要。我们的前向模型具有以下近似值:

外观(A):每像素表面外观被建模为mipmapped纹理和每顶点亮度的乘积,使得亮度结合了反射和光照的效果。球形谐波和点光源作为OpenDR的一部分提供; 其他直接照明模型易于构建。全局照明(包括互反射和照明的所有复杂效果)未明确支持。

几何(V):我们假设一个3D场景由三角形近似,由顶点V参数化,并选择背景图像(或深度渲染器的深度图像)放置在几何体后面。对象的数量没有明确的限制,DR甚至不“知道”它是否正在渲染一个或多个对象; 它的关键是三角形,而不是对象

相机(C):我们通过它们的采样中心值来近似连续像素强度。我们使用OpenCV的针孔加失真相机投影模型。与其他投影相比,它的主要区别在于图像失真模型的细节[7],而这些模型又从[11]中得出

我们的近似值与现代图形管道的近似值接近。一个重要的例外是外观:现代图形管道根据用户定义的函数支持表面上的像素分配,而这里我们支持每顶点用户定义的函数(在顶点之间插入颜色)。虽然我们也支持纹理贴图,但我们还不支持在纹理贴图上对强度值进行微分。与de La Gorce [20]不同,我们不支持纹理导数; 虽然他们使用双线性插值,但由于我们使用了mipmapping,我们需要三线性插值。这是未来的工作。

我们强调,如果OpenDR证明有用,用户将希望扩展它,放松许多这些假设。这里我们描述初始版本。

4、微分我们的前向过程

为了描述正向过程的偏导数,我们引入U作为指示2D投影顶点坐标位置的中间变量。微分如下如图1所示链式法则。1.我们的导数可以被分组到外观的效果,并在投影坐标变化 ,和图像空间的变形的效果

4.1 外观微分

由几何投影的像素由纹理T和外观A的乘积着色; 因此可以通过渲染纹理映射的几何体(其中几何体的每个顶点颜色设置为1.0)来快速得到,并通过渲染的重心坐标加权周围顶点的贡献。部分可以是零(如果仅需要环境颜色),可以分配内置球谐函数或点光源,或者可以由用户直接定义。

4.2 投影微分

图像值通过2D坐标与3D坐标和摄像机校准参数相关; 也就是说,U表示顶点的2D坐标,

部分简单,因为投影是明确定义的。方便的是,OpenCV直接提供

4.3 2D图像坐标的强度微分

为了估计,我们首先将像素分割成遮挡边界像素和内部像素,这受到[20]的启发。由边界像素引起的变化主要是由于一个表面被另一个表面替换,而由内部像素引起的变化与表面贴片的图像空间投影平移有关。通过识别边缘上的像素来获得边界像素的分配,其中(a)通过深度测试(由渲染器执行)和(b)连接具有相反法线的三角形:一个面向摄像机的三角形,一个背向摄像机的三角形。我们考虑像素的三个分类:内部,内部/边界和多边界

内部: 像素不包含遮挡边界。因为外观是插值纹理和插值颜色的乘积,所以相对于几何变化,强度变化是分段平滑的。对于内部像素,我们使用[17]采用的图像空间一阶泰勒展开方法。要理解这种方法,请考虑通过像素在图像空间中直接转换的补丁:每个像素由其左手邻居替换,这类似于Sobel滤波器的应用。重要的是,我们不允许此过滤交叉或包含边界像素([17]未处理的情况,因为没有建模遮挡)。

具体地,在不与遮挡边界相邻的像素上,我们使用内核1/2  [-1 , 0 , 1 ] 执行水平滤波。在左侧相邻的遮挡边界像素,我们使用[0  -1  1]水平滤波; 在右侧的相邻边界闭塞像素,我们使用[-1  1  0]; 并且在两侧都有遮挡边界时,我们将导数近似为零 。我们使用相同的内核转置进行垂直过滤。

内部/边界: 像素与一个遮挡边界相交。对于内部/边界情况,我们使用带内核1/2  [-1 , 0 , 1 ] 及其转置的图像空间滤波。这近似于一个差异(前景边界与其后面的表面之间)与另一个差异(在前景边界和与其后面的表面相邻的像素之间)。我们使用相邻的像素作为代理,并假设微分不是太大,而不是在遮挡边界后面“窥视”。实际上,边界梯度几乎总是远大于被遮挡的背景表面斑块的梯度,因此在优化期间占据了主导方向。

多边界: 像素中存在多个遮挡边界。虽然对象空间方法以建模所有几何体为代价为这些像素提供精确的导数,但我们将其视为内部/边界情况。这是合理的,因为很少像素受到这种情况的影响,并且因为精确的对象空间计算将非常昂贵。

总而言之,微分过程的最重要的近似发生在边界像素处,其中我们将一个差值(附近的像素减去遮挡的像素)与另一个(附近的像素减去几乎遮挡的像素)近似。我们发现这在实践中有效,但重要的是要认识到更好的近似是可能的[20]。

作为实现细节,我们的方法在请求原始渲染图像时需要一个渲染过程,并且在请求导数时需要另外三个过程(用于边界识别,三角形识别和重心坐标)。每次传递都需要从GPU读回。

4.4 软件基础

灵活性对于可微分渲染器的通用性至关重要; 自定义功能易于设计,无需手动微分。为此,我们使用自动微分[10]来计算只给出正向过程规范的导数,而不采用有限差分方法。作为OpenDR版本的一部分,我们包括一个新的自动求微化框架(Chumpy)。这个框架本质上是Numpy [25],它是Python中的一个数字包,可以求微。通过共享Numpy的大部分API,这允许使用流行的API来解决问题的前向规范。这反过来允许模型的前向规范不是渲染器的一部分,并且允许最小化地指定渲染器的上层。虽然考虑了替代自动分化框架[4,35,21],我们将Numpy的易用性包装起来。我们的整体系统依赖于Numpy [25],Scipy [16]和OpenCV [7]。

5 、在OpenDR中编程:Hello World

首先,我们用全局的纹理映射3D网格来说明渲染器的构造。在第3节 ,我们引入f作为{ V,A,U } 的函数; 在图2中,依次构造VAUf。虽然我们使用球面谐波和一组静态顶点,但是在Chumpy中可以表达的任何东西都可以分配给这些变量,只要维度有意义:给定N个顶点,那么VA必须是N ×3,U必须是N × 2 

from opendr.simple import *
w, h = 320, 240

import numpy as np
m = load_mesh(’nasa_earth.obj’)

# Create V, A, U, f: geometry, brightness, camera, renderer
V = ch.array(m.v)
A = SphericalHarmonics(vn=VertNormals(v=V, f=m.f),
                       components=[3.,1.,0.,0.,0.,0.,0.,0.,0.],
                       light_color=ch.ones(3))
U = ProjectPoints(v=V, f=[300,300.], c=[w/2.,h/2.], k=ch.zeros(5),
                  t=ch.zeros(3), rt=ch.zeros(3))
f = TexturedRenderer(vc=A, camera=U, f=m.f, bgcolor=[0.,0.,0.],
                     texture_image=m.texture_image, vt=m.vt, ft=m.ft,
                     frustum={’width’:w, ’height’:h, ’near’:1,’far’:20})

图3显示了优化地球模型以匹配图像证据的代码。我们通过平移和旋转重新参数化V,将误差表示为高斯金字塔之间的差异,并找到能量函数的局部最小值,同时优化平移,旋转和光参数。注意,高斯金字塔可以写成线性滤波操作,因此可以简单地微分。该过程在图4中可视化。

在这个例子中,只有一个对象; 但正如第3节所述,对象的数量没有明显的限制,因为几何只是三角形的集合,其顶点由用户的参数化驱动。三角形面连接是必需的,但可能是不相交的。

图像像素是唯一一个感兴趣的。应用于图像的任何可微分操作都可以应用于渲染,因此我们可以最小化图像的功能之间的差异。图5说明了如何最小化图像边缘和渲染边缘之间的差异。有关更多示例,软件版本中的opendr.demo()函数显示图像矩,轮廓和边界的渲染,所有这些都具有与输入相关的导数。

# Parameterize the vertices
translation, rotation = ch.array([0,0,4]), ch.zeros(3)
f.v = translation + V.dot(Rodrigues(rotation))

# Create the energy
difference = f - load_image(’earth_observed.jpg’)
E = gaussian_pyramid(difference, n_levels=6, normalization=’SSE’)

# Minimize the energy
light_parms = A.components
ch.minimize(E, x0=[translation])
ch.minimize(E, x0=[translation, rotation, light_parms])

Fig. 3. Minimizing an objective function given image evidence. The derivatives from the renderer are used by the minimize method. Including a translation-only stage typically speeds convergence.

 

 

 




上一篇:
下一篇:

头像

guodong

说点什么

avatar
  Subscribe  
提醒