计算机图形学中不可避免的会涉及到图像分析与处理的相关知识,前些时间也重温了下常用到的采样、重建以及纹理贴图等内容,并对其中的走样与反走样有了更多的认识,这里小结一下。
1. 基本问题
信号的采样与重建过程中首先面临着两个基本的问题:
- 给定一个连续的信号g(x)以及它的离散采样信号gs(x),能否通过gs(x)来完整的描述g(x) 的信息;
- 如果可以,如何通过gs(x)来重建出原始信号g(x)。
这些通过对信息进行频域的分析即可得到相应的结论。
2. 采样
将一处于空间域(或时域)内的信号向频域进行转换,可以使用傅立叶变换(Fourier Transformation)来实现。给定空间域信号为g(x),其对应的频域信号为G(f),则其对应的傅立叶变换关系为:
其中的x 表示相应的空间位置,f 表示对应的频率。原始信号g(x)对应的频域空间中的函数G(f)(可能)如下图所示:
频域G(f)
图中的横轴f 表示相应的频率,越往两端对应的频率越大。其中可以看出,G(f) 的有效值主要限定于频率|fmax|之内,其余频率位置上均为0,对于这样的情况可以称G(f)是带限(bandlimited)于fmax 的。这是信号采样与重建中一个较为重要的属性。
对原始信号g(x)进行采样得到离散采样信号gs(x),采样的过程主要是通过一个基于脉冲函数的脉冲采样器来实现,其表述如下所示:
其中的Ts就是采样周期。在s(x) 下就可以得到原始信号与采样信号之间的关系:
为了更方便的观察gs(x)的一些属性,可以将其转换到频域空间内进行分析,这里可以借助傅立叶变换中的几个重要属性:
- 函数在空间域(或时域)内的乘积对应于它们在频域空间内的卷积:
- 累积脉冲函数的傅立叶变换的特殊形式(证明可见这里):
利用这些属性就可以推导gs(x)的频域函数Gs(f) 如下:
从推导结果的表达式中可以看出:Gs(f)中包含了完整的原始信号G(f) 的信息;Gs(f)的值相对于原始G(f) 有作相应比例的缩放;另外,其以fs 为周期对G(f) 进行了全频空间上的叠加。最终,Gs(f) 对应的频域空间函数波形如下图所示:
3. 重建
通过上述对Gs(f) 的频域分析后发现,可以用另外一种形式来表述G(f)与Gs(f) 之间的关系:
其中的Ghigh(f) 表示在|fmax|之外的较高频率上对G(f)进行叠加的部分。如此一来,通过使用某种手段去除其中的超过频率|fmax|的叠加部分之后就可以从Gs(f)实现对原始信号的还原,即重建。
但是在某些情况下,并不能从Gs(f)中完整地分离出G(f)与Ghigh(f)部分,这样的话就无法滤去其中的高频部分得到原始信号,因而可以实现重建的信号采样需要满足下述条件才可:
- 原始信号必须是带限的。通过Gs(f)的频域函数图可以看出,如果原始信号不是带限的(即G(f)向两端无限扩展),则必然会出现G(f)和\Ghigh(f)两个波谱之间的相互交叠;这样就无法完整还原出原始信号。
- 采样频率必须是原始信号最大频率fmax 的2倍(Nyquist rate)。同样通过Gs(f) 的频域函数图可以看出,如果采样频率fs 过低,也会造成两侧的Ghigh(f)与G(f)的交叠,进而导致无法还原。
3.1 理想频域滤波函数
如果有了满足重建条件的采样信号,也即上述分离表达式可行时,如何从中分离出目标G(f)即成为一个比较简单的问题。只需要根据\(f_{max}\)的分布,构造一个频域中形如下式的函数,并将其施加于Gs(f) 即可:
这里的\(H(f)\)被称理想低通滤波器(Ideal Low-pass Filter),因为它可以完整地从Gs(f) 中分离出G(f)部分而不会带来噪声或信号的损失。将H(f) 施加到Gs(f) 上的情形如下图所示(表现为频域空间中两个函数的乘积):
频域中通过向Gs(f) 施加H(f) 来滤出其中的G(f) 部分
3.2 理想空间域滤波函数
将上述频域中的理想低通滤波函数向空间域进行傅立叶逆变换即可得到对应的空间域理想滤波函数,该函数也被称为sinc函数,其形式如下:
空间域中的sinc函数如下图所示:
Sinc函数
利用滤波函数进行频域和空间域的重建操作如下所示:
从上述关于g(x) 的表达式中可以看出,使用sinc函数来重建g(x) 时需要计算当前采样点周围无限多个相邻采样点的累积,这种计算在实际应用中当然是不可行的。因而这里的理想滤波函数sinc就不能被直接应用,这于是就引出了非理想滤波函数。
3.3 非理想滤波函数下的重建
非理想的滤波函数并不能像sinc函数那样完全滤去Gs(f) 中的高频Ghigh(f) 部分,而是一定程度上有所保留;同时,也不能完全保留其中的目标低频G(f) 部分,而是一定程度上有所损失。但整体上,非理想的滤波函数可以以一种可行的方案来实现对原始信号在可接受程度上的重建。频域上的一个非理想滤波函可能如下图所示:
其中的Hr(f)即为非理想的频域滤波函数:其在|fmax|内部的部分并不能完全地还原出G(f),而是在接近|fmax|处有所损失(曲线向下导致);同时,在到达|fmax|后并没有截止而是继续向外扩展,这样就在结果中引入了频率超过|fmax|的高频部分。
在空间域上,使用非理想的滤波函数来实现重建则是通过在目标点周围施加一个一定尺寸(维度不一定)的Kernel并累积其中的有限采样点(对比sinc中的无限)来完成。其形式一般如下所示:
上式就表示在目标点x 周围通过K个采样点、在重建核心h(x)下(具现为权重)实现对当前点的信号估值。
4. 重建Kernel
由上述对于空间域内重建函数的分析可以看出,在经由采样点对信号进行重建的过程中,重建核心的设计至关重要。在实践中经常使用的重建核心主要有以下几种:
4.1 Box Filter
该滤波器的函数形式如下所述:
这是最简单的一种Filter,其对应的空间域及频域函数波形图如下:
Box Filter
将其应用到重建函数中可以看出:其对于目标点的估值只会使用若干采样点中的一个,而并没有采用多个采样点之间的插值,因而重建效果较差,最终会得到如下图所示的阶梯状波形(称之为锯齿边缘或Jagged Edges)。
Box滤波器重建效果
4.2 Triangle Filter
该滤波器的函数形式如下所述:
其也被称为Tent Filter,其对应的空间域及频域函数波形图如下:
Triangle Filter
相对来说,其重建效果会比Box Filter要好(如下图所示),但其中的锯齿边缘依然明显,这主要是由于该Filter对采样点之间的插值力度仍然不够所致。对应的H(f)对超过fmax的高频部分抑制力度不够所致。
Triangle滤波器重建效果
4.3 Cubic Convolution
该滤波器是以一种三阶多项式的方法来对sinc函数进行近似,效果蛮不错,而且还可以暴露出参数以供效果调节。其形式如下:
Cubic Filter
Cubic滤波器重建效果
从图中可以看出,相对于前两种滤波器,使用Cubic滤波器可以明显地减少重建信号中的锯齿规模与数量,这主要是由于其对采样点之间采用了更高阶的插值计算,因而效果相对更好。
4.4 Windowed Sinc Function
这里回过头来再看理想的空间域sinc滤波函数,其最重要的应用障碍就是其中对无限多相邻采样点的累积,反映在空间域sinc函数上则是曲线向横轴两侧的无限延伸;因而,如果可以去掉其在空间域中向两侧的延伸部分(相当于对sinc函数进行滤波,过滤其中空间位置较大的部分),则其近似的sinc函数就变得应用可行。该方法与频域空间中的滤波(施加H(f) 的影响)类似,只不过这里是在空间域上对sinc函数施加一个窗口过滤操作,最终只使用窗口内(含有限个采样点)的修正sinc函数。
常见的几种空间域sinc窗口函数如下:
4.4.1 Hann Hamming
该窗口函数形式如下所述:
其中的N用来控制窗口中采样点的数量,a 用来控制窗口函数曲线的外形。对应的函数形状如下:
Hann&Hamming窗口函数
从可以看出,最终得到的H(f)函数质量比前述几种非sinc窗口类型的要更好。
4.4.2 Blackman
该窗口函数形式如下所述:
其中的N同样为窗口中的采样点数量,只不过这里相对于H&H少了一个可控的参数。对应的函数形状如下:
Blackman窗口函数
4.4.3 Lanczos
该窗口函数形式如下所述:
其中的n用来控制窗口过滤域的范围。对应的函数形状如下(其中的n = 2):
Lanczos窗口函数
在应用中,将这些窗口函数施加于sinc函数上,即可得到近似于sinc函数效果的窗口滤波函数,进而实现更好的图像信号重建。
5. 走样与反走样
5.1 走样原因
在前面介绍了使用采样信号来完全重建原始信号所需的两个基本条件:1. 原始信号是带限的;2. 采样频率要满足Nyquist频率。如果这两个条件中有任一条不被满足则即便是使用理想的低通 滤波器也不可能完全重建出原始信号,这种情况下的现象就称为走样(Aliasing)。
对于图形学中的图像渲染而言,Nyquist率是由可像素化显示的最高频率决定,也即为2 pixels / cycle(两个像素间有一个非像素间隔),对应的频率则为0.5,因而fmax=1,这也就对应:无走样渲染时的采样最低频率不应该小于1。一个明显的例子就是后处理中常见的案例:将一个N X N大小的缓冲区纹理贴到一个屏幕空间中N
X N的Quad上渲染时并不会有走样,因为其采样频率满足Nyquist要求。
另外,也要区分走样与锯齿之间的差异,两者在图形学中易被混淆(这主要是由于图像渲染时的走样也常常具化为锯齿现象)。锯齿主要是由于重建Kernel不够好,进而使得在重建信号中出现了插值不平滑的情况,但是如果在其采样信号上施加一个理想的重建Kernel时则还是可以完全地还原出原始信号(比如纹理贴图中的Magnification);反之,走样则是由于不满足信号重建的两个基本条件,这样即使在其采样信号上使用理想的重建Kernel也不能够重建出原始信号。通过其中的差异可以看出:锯齿现象可以通过一些Blur算法来加以消除,但走样却不行。
5.2 反走样方法
当采样不满足上述重建的基本条件时就会产生走样,而针对走样产生的原因,通过各种方法与途径来消除走样的产生即是反走样。通常来说,一般的图像信号均是带限的,但是其却可能限制于一个较大的fmax,进而导致第二个条件难以达到,因而两个条件是相关的。根据走样的来源,就可以有两种方法来实现反走样:
- 在原始信号的带限上做处理。该方法主要是在采样前对信号进行一些预滤波(Prefiltering)处理来修改原始信号的带限,比如同样使用一个低通滤波器来将原始信号的带限降到一个更低的范围,这样的话就可以使重建的第二个条件更容易满足。
- 在采样频率上做处理。该方法就是直接增大采样的频率来使其尽可能地满足第二个重建条件。
其中第二种方法虽然比较直接,但其应用场合却有所限制,比如向一个屏幕固定像素数量的区域渲染图像时无法增大其对应的采样频率,这时就只能使用Prefiltering的方法来实现反走样。这里需要注意Prefiltering的操作是在采样之前进行的。
5.3 Prefiltering方法的几个应用
5.3.1 Edge Antialiasing
基于Prefiltering方法的边缘反走样主要是利用Area sampling的手段来实现。该方法将目标输出像素与原始图像信号中的一个子区域对应,可以称此区域为preimage。然后用一个低通滤波器来对该子区域进行滤波,如下所示:
这样就可以整体降低图像数据源的带限,进而达到反走样的目的。基于此方法的应用有很多,比如像Supersampling, Multisampling等。首先,经过GPU硬件管线渲染后得到一个比屏幕分辨率大的颜色缓冲区,然后将目标输出点与颜色缓冲区中的一个子区域对应(子区域中的像素分布可能并不是规则的),如下图所示。然后对该子区域中的像素做低通滤波操作来降低缓冲区图像信号的带限,之后将结果输出到屏幕像素中即可实现反走样。
5.3.2 Texture Antialiasing
纹理贴图中的走样主要产生在Minification时(如前所述的像素采样频率不足),针对这种走样最常用的操作也是Prefiltering方法,典型应用就是Mipmap。Mipmap方法是在纹理贴图生成时,计算出个几不同Level的子贴图,比如第0级对应N X N大小,第1级对应N/2 X N/2大小,等等;当前级中的像素由上一级相关位置上的四个像素来决定。这样,每个Level的子贴图也就对应着不同的带限,在实际使用时通过Level选择算法定位到合适的贴图级别,使得贴图渲染时的采样频率满足Nyquist条件,进而达到反走样的目的。
Mipmap
使用Mipmap需要预先生成原始贴图在若干级别下的子贴图,因而会带来一定的额外空间占用量(大约33%);同时,在使用时需要定位到合适的贴图级别,这个计算过程也会比较复杂(也值得好好研究,不过还好,可以有API或硬件帮助完成)。整体上来说,Mipmap方法以一种较经济的Prefiltering手段解决了纹理贴图中的走样现象,且效果较好。