博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
详细讲解Antialiasing的理论(上)(转)
阅读量:2450 次
发布时间:2019-05-10

本文共 3315 字,大约阅读时间需要 11 分钟。

详细讲解Antialiasing的理论(上)(转)[@more@]

  在这篇文章中,我们会从数位讯号处理的理论角度来看 3D 电脑绘图中的 antialiasing 问题。当然,这并不是教科书(我也没能力写教科书 :P),所以我会尽可能避开数学式,而只是从观念的角度来说明这个问题。

  首先,我们从数位讯号的基础来看。因为我们现在所用的电脑,几乎都是数位电脑,所以它们当然也只能处理数位的资料。所谓的数位资料,其实就是一堆数字,或更正确的说,一堆整数。因为数位电脑只能处理 0 和 1,所以它们所能处理的东西,可以说都是有限的整数。当然,我们可以用一些整数来表示有理数(用分数来表示),所以数位电脑也可以用来处理一些小数。

  

  不过,有很多东西不是用有理数就可以表示的。不过,这还不是最大的问题。最大的问题是,很多讯号都是连续的。这里所谓的连续,并不是微积分里面的那种连续,而只是说讯号就像一个实数函数一样,在任何参数上都有值。这告诉我们,即使是随便一小段讯号,都需要用无限多个数字才能表示。很明显的,数位电脑是不能存放无限多个数字的。下图是一个例子:

  
 
2004.12.28.15.34.8.1.png

  在上图中,垂直方向是讯号的强度,在影像中就是 intensity。而水平方向则是讯号的位置,我们称为 spatial domain。如果是声音讯号的话,那它就不是位置,而是时间了,也就是 time domain。不过,因为我们这里只讨论影像,所以基本上水平方向就是 spatial domain。

  

  不过,因为这样的讯号是连续的,所以,就像前面所说的,需要无限多个数字才能存放这个讯号。但是电脑不能存放无限多个数字,所以,只好取其中的一些数字。比如说,如果上图中垂直方向的虚线,就是 pixel 的边界,那我们可以只取讯号中,在 pixel 正中间的值。这样我们只需要存放八个数字。这就是所谓的取样(sampling)。以上例来说,取样得到的八个数字分别是 0.548、0.468、0.760、0.296、0.400、0.348、0.460、和 0.507。这些取样得到的数字,就形成了数位讯号。

  

  这些数位讯号在经过处理后(所谓的处理,也许只是存放在某个地方,像是光碟片里面),最后还是需要让人看到结果。因为人是没办法光从一堆数字就看得出来那是什么东西,所以,一定要设法把这些数位讯号,再转换成连续的、人可以接受讯号(像是显示在萤幕上,或是对声音讯号来说,用喇叭发出声音)。这个过程就称为重建(reconstruction)。比如说,上面的数位讯号,利用 sample and hold 的方式重建的话(也就是说,在整个 pixel 的范围中,都输出该 pixel 的取样值),会变成如下图:

  
 
2004.12.28.15.34.21.2.png

  不用说,这是一个蛮差的重建方式,因为它重建出来的讯号,和原来的讯号实在是相差太多了。不过,其实这也是没办法的事,因为对一个连续的讯号(原来需要无限多个数字才能表示),只用八个数字来表示,本来就会丢失很多资讯。不过,我们当然还是希望能够尽可能达到最好的效果。这就是理论发挥作用的时候了。

  

  究竟在取样的时候,发生了什么事呢?这就得从 frequency domain 的角度来看了。所谓的 frequency domain,就是指讯号所拥有的各种频率的成份。也就是说,我们可以用一大堆不同频率的正弦波,合成我们所要的讯号。或是说,我们要找出我们所要的讯号,是由哪些不同频率、不同强度、和不同相位的正弦波所组成的。这可以利用 Fourier transform 把一个讯号从 spatial domain 或 time domain 转换成 frequency domain,或利用 inverse Fourier transform 把它从 frequency domain 转回来。

  

  下图是一个讯号和它的 Fourier transform:

  
 
2004.12.28.15.34.35.3.png

  
 
2004.12.28.15.34.54.4.png

  要注意的是,一个讯号的 Fourier transform,对任一个频率实际上有两个成份,一个是讯号的强度(magnitude),另一个是相位(phase)。在上图中只显示出强度,而没有显示出相位。另外,在频率为 0 的地方,称为 DC,等於是整个讯号在 spatial domain(或 time domain)的总合,所以特别大。在后面的图中,有时会把 DC 值切掉,以让其它频率的值更容易看出来。

  

  假设现在要对一个讯号在每个 pixel 的中间进行取样,也就是保留讯号在 pixel 中间的值,而把其它地方的值变成 0。这其实可以利用乘上另一个讯号的方式来做,也就是乘上一个「在每个 pixel 中间为 1、其它地方为 0」的讯号。如下图所示:

  
 
2004.12.28.15.35.9.5.png

  
原始讯号

  
 
2004.12.28.15.35.23.6.png

  
Comb filter

  
 
2004.12.28.15.35.36.7.png

  
取样后的讯号

  上图是一个原始讯号,在乘上 comb filter 后,得到取样后的讯号。Comb filter 的名字来自於它的形状,因为它在每个 pixel 中间的值为 1,其它地方的值为 0,看起来长得像梳子,所以叫 comb filter。

  

  究竟取样的时候,发生什么事呢?这要从 frequency domain 来看才会清楚。下图是同样的讯号,在 frequency domain 的形状:

  
 
2004.12.28.15.35.50.8.png

  
原始讯号

  
 
2004.12.28.15.36.2.9.png

  
Comb filter

  
 
2004.12.28.15.36.17.10.png

  
取样后的讯号

  可以看到,经过取样后的讯号,在 frequency domain 变成一个不停重覆的东西。不过,它在 -1 和 1 之间的形状,和原来的形状并不相同。这是因为原始讯号在 -1 和 1 之外还有东西(像是 1 和 2 之间的突起,这是来自原始讯号右边的那三个尖角,它们的频率太高了),这些东西「干扰」到原来在 -1 和 1 之间的东西。这个现象使得原来讯号中的高频成份(像是 1 和 2 之间的突起),在取样后,可能会被当成是比较低频的成份。这些多出来的低频成份,就是失真(aliasing)。

  

  要避免高频成份在取样后会被当成低频成份,最简单的方式,就是在取样前,用 low pass filter 把所有的高频成份都去掉,如下图所示:

  
 
2004.12.28.15.36.36.11.png

  
经过 low pass filter 的讯号

  
 
2004.12.28.15.36.49.12.png

  
取样后的讯号

  上图中,先把高频成份去掉之后,在取样时,就不会干扰到低频部份,也就不会产生失真了。不过,要去掉多高频的成份呢?从 comb filter 的表现可以看到,当取样频率是 N 的时候,所有频率大於 N/2 的成份,都会造成失真。所以,要把频率大於 N/2 的成份都去除。反过来说,如果已经知道所需要最高的频率是 N,那就要把取样频率设在 N 的两倍以上。

  

  不过,去除了高频成份之后,讯号会变成什么样子呢?下图是上面的讯号和其经过 low pass filter 后的比较:

  
 
2004.12.28.15.37.3.13.png

  可以看到它和原来的讯号相差蛮多的,不过这是在这个取样频率下(16 个取样点)所能做到最好的结果了。

  

  在前面已经说明了为什么在对一个讯号进行取样之前,要先把高频成份去除。在去除高频成份后,取样时就不会发生失真的现象了。不过,在取样后的数位讯号,只是一堆数字,所以还需要一个重建的动作,才能变回原来的类比讯号。

  

  理论上,重建原来的类比讯号的动作并不太困难。因为,对取样后的讯号进行 Fourier transform 后,会得到一堆重覆的东西。如下图所示:

  
 
2004.12.28.15.37.20.14.png

  
经过 low pass filter 的讯号

  
2004.12.28.15.37.32.15.png

  
取样后的讯号

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8225414/viewspace-951762/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/8225414/viewspace-951762/

你可能感兴趣的文章
如何使用HTML,CSS和JavaScript构建技巧计算器
查看>>
java python算法_用Java,Python和C ++示例解释的搜索算法
查看>>
大数据入门课程_我根据数千个数据点对互联网上的每门数据科学入门课程进行了排名...
查看>>
如何启动软件YouTube频道
查看>>
linux创建sudo用户_Linux终极指南-创建Sudo用户
查看>>
grasshopper_如何使用Google的Grasshopper编码应用程序来学习手机上的编码基础知识...
查看>>
特征阻抗输入阻抗输出阻抗_软件阻抗说明
查看>>
如何成为一个优秀的程序员_如何成为一名优秀的程序员
查看>>
istio 和 kong_如何启动和运行Istio
查看>>
期权数据 获取_我如何免费获得期权数据
查看>>
phpstorm 调试_PhpStorm中的多用户调试
查看>>
typescript 使用_如何使用TypeScript轻松修改Minecraft
查看>>
javascript初学者_针对JavaScript初学者的调试技巧和窍门
查看>>
如何使用ArchUnit测试Java项目的体系结构
查看>>
算法训练营 重编码_编码训练营后如何找到工作
查看>>
心学 禅宗_禅宗宣言,用于有效的代码审查
查看>>
主成分分析 独立成分分析_主成分分析概述
查看>>
电脑如何设置终端设置代理_如何设置一个严肃的Kubernetes终端
查看>>
我从参加#PerfMatters会议中学到的东西
查看>>
第一个应在JavaScript数组的最后
查看>>