中值座标及其应用(仅讨论图像变形与纹理参数化)

  本文主要的参考文献为:
1. 游戏编程中的数学——调和函数和中值座标
2. Hormann K, Floater M S. Mean value coordinates for arbitrary planar polygons[J]. Acm Transactions on Graphics, 2006, 25(4):1424-1441.
3. Floater M S. Mean value coordinates[J]. Computer Aided Geometric Design, 2003, 20(1):19-27.
  一般来说,我们不通过一个模型含有的网格(通常为三角形网格或四边形网格)以及顶点去理解它,而是在其网格上建立一个函数,这个函数拥有特定的性质,有助于解决我们面临的难题。那么这次介绍一个在网格上建立函数的方法——中值座标。中值座标是90年代后期产生的,其背后的数学原理却得追述到18、19世纪了,然而直到今天它依然没有受到游戏开发界足够的重视……本文重点是谈谈中值座标的构造与应用。

中值座标的“前菜”

  由Ceva 逆定理可以很容易证明三角形Δv1v2v3 的三条中线交于一点(重心)v ,即重心的存在性得以证明:ω1,ω2,ω3R,s.t.

ω1v1+ω2v2+ω3v3ω1+ω2+ω3=v.

  Mo¨bius 在1827年将ω1,ω2,ω3 定义为v 的重心座标。在实际使用时,通常会对重心座标进行归一化。
  这些归一化后的重心座标在网格上是连续的,并且具有Lagrange 性:
ωi(vj)=δij={1,i=j0,ij.

  这就是为什么它们通常用于对一个三角形区域进行线性插值,并且在计算机图形学中具有广泛的应用(例如Phong 着色,纹理映射),几何建模(例如B 样条插值)以及许多其它领域(例如有限元方法)。
  在许多实际应用中,将重心座标推广到具有任意n 边形上的插值是非常必要的。并且通常用重心座标的下述表现形式:
i=1nωi(v)(viv)=0,

  再将其归一化得
λi(v)=ωi(v)j=1nωj(v),

  这样平面上的任一点v 均可以写成v1,v2,,vn 在权重ω1,ω2,,ωn 下的仿射组合。而且,这些座标应该满足Lagrange 性:
λi(vj)=δij={1,i=j0,ij.

中值座标的构造

  令Ψ 是平面上的一个任意简单多边形(在几何形状中,简单多边形是由直线,非相交的线段或“边”组成的扁平形状,其成对连接以形成封闭路径。 如果两边相交,那么多边形并不简单。定义参考自百度百科简单多边形),其顶点v1,,vn(n3) ,其各边(互不相交)
  

ei=(vi,vi+1)={(1μ)vi+μvi+1:0<μ<1},i=1,n1,

  如图所示为一些简单多边形的小栗子:

  由上图可以看出,简单多边形可以为凹多边形,也支持嵌套操作,并不局限於单个凸多边形。
  对于i=1,,n ,我们定义vR2vi 的距离:

ri(v)=||viv||,

  这是通常的欧氏距离,并用αi(v) 表示vivvi+1 。则
Ai(v)=ri(v)ri+1(v)sin(αi(v))2,Bi(v)=ri1(v)ri+1(v)sin(αi1(v)+αi(v))2,

  它们分别表示Δvvivi+1Δvvi1vi+1 的面积。各符号的直观说明可参考下图:

这里写图片描述  

  易知Ai(v),Bi(v),Ai1(v) 是关于ivi1vivi+1v 的齐次重心座标,即

Ai(v)(vi1v)Bi(v)(viv)+Ai1(v)(vi+1v)=0.()

  通常,这些座标还需要进行归一化,即需要除以Ci=Ai1(v)+Ai(v)Bi(v) 。显然这些重心座标直接依赖于四边形vvi1vivi+1 的各部分面积。这是一个很棒的性质(^▽^)!
  现在让我们来考虑一下v 关于所有三角形1,,n 的齐次重心座标,不妨作如下定义(在后面你们便能够体会到这样的定义是多么地巧妙~):
ωi(v)=bi1(v)Ai2(v)bi(v)Bi(v)+bi+1(v)Ai+1(v),

  其中权重函数bi:R2R 的选择是有一定讲究的(这个会放在后面讨论),则由(*)可以知道函数ωi 是相应于Ψ 的齐次重心座标,这是因为:
i=1nωi(v)(viv)=i=1nbi(v)(Ai(v)(vi1v)Bi(v)(viv)+Ai1(v)(vi+1v))=0.

  欲验证上式,我们首先得解释一下当i=1v0,A0 代表的意义,以及当i=nAn+1 代表的意义。其实用数据结构当中循环队列的观点去看待就很容易理解了:

  由上图可以看出,v0 就相当于vn ,同理可得A0 相当于AnAn+1 相当于A0
  现在的关键步骤是对于齐次重心座标的归一化,必须保证λi(v)=ωi(v)j=1nωj(v) 中的分母不为0。对于凸多边形这是容易实现的。
  事实上,由ωi(v) 的定义我们可以得到

W(v)=i=1nωi(v)=i=1nbi(v)Ci,

  当Ψ 是凸多边形时,所有Ci 都有相同的符号,并且只要权重函数bi(v) 恒正(负),W(v) 不为0。这里权重函数bi(v) 的恒正(负)性是比较重要的(但在后面可以看到,这个并非决定因素),举个栗子,不妨考虑Wachspress 齐次座标或者离散谐波座标,它们可以由下述权重函数产生:
bWi=1Ai1Ai,bDi=r2iAi1Ai.

  然而,在一个非凸多边形中,W(v) 可能取0,很重要的一个原因是此时bi(v) 并不是恒正(负)的。于是归一化后的齐次重心座标λi(v) 将有可能出现间断点。
  为了解决上述问题,通常采用的解决方案是令权重函数bi(v) 为一个常数函数,如令bi=1Ci ,如此一来Wn>0 。尽管这样一个特殊的操作能够给出一个welldefined 的归一化齐次座标λi (只要Ψ 中的任意三个顶点不共线即可),但却出现了一个致命的缺陷!!!它不满足Lagrange 性:
λi(vj)δij={1,i=j0,ij.

  针对上述问题,SukumarMalsch 在2005年提出了度量座标:
bMi=1Ciqi1qi,

  其中qi=ri+ri+1||vi+1vi|| 保证了W(v) 不为0。其相应的归一化座标满足Lagrange 性,但它与离散齐次座标类似,它们都无法保证在一个凸多边形内的取值介于0到1之间。因此,由此产生的插值函数有可能将插值点“放置”在数据集闭包的外边,这在某些应用中是不希望的。
  现在,我们就来介绍一种最常用的重心座标,它就是我们今天这篇文章的主角——中值座标,其权重函数是酱紫定义的:
bMVi=riAi1Ai

  可能看到这里就有人感到不解了,这货长得不就跟Wachspress 齐次座标或者离散谐波座标的权重函数差不多吗?为什么它们有可能使得W=0 ,而中值座标的权重函数就能避免这样的情况发生呢?
  事实上,这个证明是比较复杂的,需要两个引理才能证明,篇幅较长,因此这里不再赘述。有兴趣的同学可以看看第2篇参考文献,文中的定理4.3便给出了答案。
  继续走下去,将bMVi 代入ωi(v) 的定义式,得
ωi(v)=bi1(v)Ai2(v)bi(v)Bi(v)+bi+1(v)Ai+1(v)=ri1AiriBi+ri+1Ai1Ai1Ai,

  再将Ai(v)=ri(v)ri+1(v)sin(αi(v))2,Bi(v)=ri1(v)ri+1(v)sin(αi1(v)+αi(v))2 代入,同时结合一些三角函数的性质可以将ωi 简化为
ωi=2tan(αi1/2)+tan(αi/2)ri,

  上式是Floater 在2003年得到的结果。注意到这些ωi 虽然定义在平面区域上但却具有三个分量(齐次座标),且ωi 只依赖于vi 及其两个邻点vi1,vi+1 。这与Wachspress 齐次座标或者离散谐波座标类似,但却不适用于度量座标,因为它依赖的是vi2,,vi+2 五个座标点。
  至此,离整个中值座标的构造便仅差一步了!!!✿✿ヽ(°▽°)ノ✿

中值座标的性质

  对于任一简单多边形的集合Ψ ,我们称函数λi:R2R,i=1,,n 为中值座标,其中

λi(v)=ωi(v)/nj=1ωj(v), vΨ,(1μ)δi,j+μδi,j+1,v=(1μ)vj+μvj+1ej,δij,v=vj

  中值座标具有如下优美的性质(证明都可以参见第2篇参考文献):
  • 仿射精度:对于任一仿射函数φ:R2Rd 都有i=1nλiφ(vi)=φ
  • Lagrange 性:λi(vj)=δi,j
  • 光滑性:vvj 时,λiC ;而当v=vj 时,λiC0
  • 正则性:i=1nλi1
  • 相似不变性:如果φ:R2R2 是具有相似性的(此处具有相似性的变换定义为该变换是一个平移变换,旋转变换,反射变换,等距缩放变换或者它们的组合),且Ψ^=φ(Ψ) ,则λi(v)=λ^i(φ(v))
  • 线性无关性:如果i=1nciλi(v)=0,vR2 ,则ci=0
  • 如果我们令Ψ^ 是由Ψej 边上增加一点v^=(1μ)vj+μvj+1 ,则λj=λ^j+λ,λj+1=λ^j+1+μλ^ ,且λi=λ^i,ij,j+1
  • 线性性:λiΨ 的任一条边ej 上是线性的;
  • 非负性:λi 在凸多边形的内核上是正的,其中,平面上简单多边形的核是该多边形内部的一个点集,该点集中任意一点与多边形边界上一点的连线都处于这个多边形内部。譬如说,就是一个在一个房子里面放一个摄像 头,能将所有的地方监视到的放摄像头的地点的集合即为多边形的核。(参考自博客半平面交,求解多边形内核

    至此,整个中值座标的构造算是大功告成了!!!✿✿ヽ(°▽°)ノ✿

中值座标的应用

  中值座标最主要的应用便是在给定简单多边形Ψ 的顶点vi 以后,对于整个多边形区域的插值。换句话说,如果fi(v)Rd 是在vi 上的插值基函数,则我们可以将函数F:R2Rd 定义如下:

F(v)=i=1nλi(v)fi(v).

  由于λiLagrange 性和线性性,F(vi)=f(vi) ,且F(v)Ψ 的任一条边ej 上是线性的。
  事实上,接下来所讨论的两个应用本质上还是体现了一种插值思想。

图像变形

  中值座标的一个应用是图像变形,因为中值座标为这个问题提供了一个特别简单的解决方案,可简要地说明如下。
  给定一个矩形区域Ω ,一个源多边形的集合Ψ ,其顶点viΩ ,以及一个拓扑同胚的目标多边形的集合Ψ^ (显然ΨΨ^ 顶点数相同),其顶点v^iΩ ,我们想构建一个平滑的变形函数f:ΩΩ ,它将每一个vi 映射到相应的v^i 。这样一个变形函数f 可以通过令I^=If1 将一个源图像I:ΩCC 是一个颜色空间)转换为一个目标图像I^:ΩC 。我们通常会令I^=If1 而非I^=If ,这样一种思想也称为逆向映射(两者的不同其实即为正映射与逆向映射的区别,具体可以参见博客图像变换——向前映射和向后映射),等等在后面会用一些实验结果图让大家感受一下两种映射方式的不同。
  许多时候,图像变形函数可以用Ψ^ 的中值座标λ^i 去表示:

g(x)=i=1nλ^i(x)vi

  它将每一个v^i 映射到vi 上,如此一来便可以定义一个合适的图像变形函数。举一个不是特别恰当的例子,Shepard 提出了IDWInverse distance weighted interpolation methods )用于图像变形,之所以说它不是很恰当,是因为IDW 并不是严格建立在中值座标的理论基础之上的,准确地说它是沿用了一般的重心座标的思想,该方法要求找到满足以下形式的函数:
g(v^)=i=1nλi(v^)gi(v^).
 
  • gi(x) 满足gi(v^i)=vi ,这是对于点v^i 的插值,i=1,2,,n 。对于插值基函数gi 而言,一般使用线性或者二次多项式,多项式系数可以用插值点处的导数值去确定。
  • λi:R2R 是权函数,须满足条件λi(v^i)=1,i=1nλi(v^i)=1λi(v^)0,i=1,2,,n
      Shepard 提出了以下简单的权函数:

    λi(v^)=ωi(v^)i=1nωj(v^),

      其中ωi(v^)=1ririv^v^i 的距离。
      IDW 是一种全局插值算法,即全部样本点都会参与到与某一插值结点(实际运用当中又叫控制点)的运算当中去,所以它的计算复杂度起码为O(nN) ,其中n 是控制点的数量,N 是整个目标图像的像素点数量。  
      我们不妨来看一下分别令I^=IfI^=Ig 会产生什么不同的神奇现象。(g=f1 ,下面直接令gi(v^)=v^+viv^i
      若采用I^=If ,容易发现生成的目标图像中会出现许多空洞点(为了突出空洞点,图中用深红色点表示空洞点),如下图所示:

    这里写图片描述
    正向映射实验效果图

      对于上述问题,我们需要对空洞进行填补,我分别采用了均值滤波模板、中位数滤波模板与即时填充空洞进行处理:


    这里写图片描述
    均值滤波模板填补效果图



填补后局部放大图

  容易看出,在对图像进行空洞区域的填补以后,出现了一些疑似空洞的点,故仍需要进行改进。先来简要分析一下原因~
  由于存在取平均值的操作,故当一个像素点周围存在不同颜色的像素点时,填补以后容易出现颜色差异较大的点,譬如黑色方块和白色方块相邻边界上的空洞点,填补以后就会变成灰色点。
  找到原因以后便可以有针对性地进行改进,自己采用的解决方案是替换均值滤波模板改用中位数滤波模板,需要注意的是,对一个空洞点填补时并不考虑周围的空洞点,即不应该将空洞点的像素用来求中位数;其次,若一个空洞点周围的非空洞点像素点数量为偶数时,其中位数是需要取平均的,此时容易出现类似使用均值滤波模板的填补错误,于是需要进行如下判断,假设该空洞点周围的非空洞点像素点数组为surrounding_pixels,surrounding_pixels.size()%2==0

if surrounding_pixels[i] =  = surrounding_pixels[i - 1],i=surrounding_pixels.size()/2
  将surrounding_pixels[i]赋给空洞点;
else
  为了避免出现取均值的操作,依然将surrounding_pixels[i]赋给空洞点;


这里写图片描述
中位数滤波模板填补效果图

  在作了上述改进以后,发现仍存在一些问题,如:


这里写图片描述
改进填补后的局部放大图

  可以看出,一些方块边缘会出现“毛边”现象,即方块颜色会“渗入”相邻的方块。究其原因,发现在填补时空洞点周围的空洞点太多,影响了其中位数的取值,因为对空洞点进行中位数滤波时是要舍去周围的空洞像素的,如下图所示:


这里写图片描述

  为了解决上述现象,需要对空洞点进行即时填补,因为在之前的程序当中,找到空洞点对其进行中位数滤波以后,出于当前填补结果若是错误会对后面的填补效果产生影响的考虑,并非直接进行填补,而是先把像素存储起来,等到最后再进行填补。
  而现在则需要对此做出改变,只要保证当前空洞点的填补结果是正确的就可以了。自己的做法如下所示:假设该空洞点周围的非空洞点像素点数组为surrounding_pixels,surrounding_pixels.size()%2==0

if surrounding_pixels[i] =  = surrounding_pixels[i - 1],i=surrounding_pixels.size()/2
  将surrounding_pixels[i]赋给空洞点;
else
  先不进行操作,将这个点记录下来,等对全部点进行中值滤波以后再对这个点进行中值滤波,此时因为之前的空洞点已被填补,故它能获得更多有效的像素点;


这里写图片描述
即时填补空洞效果图

  可以看出,在改进以后实验结果有了一定的改善。那么,我们再来看一下采用I^=Ig 的实验效果:


这里写图片描述
逆向映射实验效果图

  可以看出,实验的效果十分理想。无论是在算法运行时间及算法实现难度上都远胜之前的正向映射+空洞填补算法。当然对于图像变形还有其它优秀的算法,比如径向基函数算法(RBF 算法),限于篇幅此处不再赘述,不过可以弱弱地放张效果图让你们看看哈:


这里写图片描述

纹理参数化

  中值座标的另一个应用是纹理参数化,简要地说明如下。


这里写图片描述
(图片画得并不是很标准哈,见谅(:3 」∠)

  首先需要进行局部参数化:将局部结构映射到平面上,映射过程满足下列条件:

||viv||=||xix||,vivvi+1=2πxixxi+1/θ,

  其中,θ=i=1dxixxi+1
  对于点v ,考虑多边形v1v2vn ,它存在唯一的中值座标,不妨设其中值座标为(λ1,λ2,,λn) ,则有v=i=1nλi(v)vi,λi(vj)=δij
  如此一来,我们便可以定义函数g(v) 来进行纹理参数化:
g(v)=i=1nλi(v)gi(v).

  其中,gi(vi),i=1,2,,n 根据自己的需要进行设置。
  然而,真正将上述方法用于纹理参数化的话会出现计算量太大的问题,因为它需要对模型内每一个点进行计算。因此,在实际运用当中,如果模型是比较规则的或者有足够多的顶点集,则可以弃用上述的中值座标,改用构造一个关于顶点变换的稀疏线性系统,亦可以求出形状变化比较小的参数化结果。

这里写图片描述
原网格


这里写图片描述
参数化结果

总结

  我们已经表明,中值座标将三角形重心座标的概念推广到任意的简单多边形,甚至是这些简单多边形的集合。中值座标具有许多很漂亮的性质(如Lagrange 性),对于在简单多边形的插值别有用。
  我们注意到,中值座标在任意简单多边形的情况下并不是处处都是正的。另一方面,可能是恰恰由于这些性质,中值座标的插值性能才能如此棒,而且在实际应用中发挥着重要作用。(๑•̀ㅂ•́)و✧文中实验的源码会上传到我的Github 上,有兴趣的同学可以自行下载玩玩~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章