光栅化图像注记


距离春节假期已经过去两周, 开始逐渐收心投入到新一年的工作当中了. 本周末是新年过后宅家的第一个周末, 目前看完了Shirley P, Ashikhmin M, Marschner S. Fundamentals of computer graphics[M]. AK Peters/CRC Press, 2009.的第三章Raster Images, 发现阅读英文书籍也并没有想象中那么痛苦, 可能也是目前所学的内容比较浅显的缘故2333……

1. 图像, 像素与几何

我们可以将图像抽象为一个函数$$I(x, y) : \mathbb{R} \to V,$$其中$\mathbb{R} \to \mathbb{R}^2$为一个矩形区域, $V$为可能的像素值的集合. 最简单的情况是考虑一张灰度图像, 其中矩形区域中的每个像素值仅为亮度(非颜色值), 此时$V = $$ \mathbb{R}^+$(非负实数集); 而当考虑一张彩色图像时, $V = (\mathbb{R}^+)^3$.

2. 显示器强度与Gamma校正

现代的所有显示器都将像素的颜色值作为数字输入, 并将其转换为强度级别. 真正的显示器在关闭时有一些非零强度, 因为屏幕总会反射一些光. 通常情况下, 我们可以认为显示器在关闭时呈现的颜色为黑色, 而显示器完全打开时呈现的颜色则为白色. 同时, 我们假设像素颜色的每个分量的数值范围为$[0, 1]$, 其中, 黑色对应的向量表示为$(0, $$ 0, 0)^T$, 白色对应的向量表示为$(1, 1, 1)^T$, 介于黑色和白色之间的灰色对应的向量表示为$(0.5, 0.5, 0.5)^T$.
$\\$ 要在显示器上生成正确的图像, 必须了解两个关键点. 首先, 显示器强度关于输入是非线性的. 例如, 如果将三个像素的颜色值$(0, 0, 0)^T$, $(0.5, 0.5, 0.5)^T$与$(1, $$ 1, 1)^T$作为输入, 则显示器的强度可能为0, 0.25与1.0(关闭, 四分之一完全打开与完全打开). 为了拟合这种非线性表示, 显示器提出了Gamma值, 其定义如下所示:$$D = Ma^\gamma,$$其中, $D$为实际的显示强度, $M$为显示器支持的最大强度, $a \in [0, 1]$为输入的像素颜色值的某个分量值. 举个栗子, 如果显示器的Gamma值$\gamma$为2.0, 而输入值为$a = 0.5$, 则实际的显示强度$D$将为显示器支持的最大强度$M$的四分之一($0.5^2 $$ = 0.25$). 注意, 无论Gamma值$\gamma$如何变化, 都需要保证将输入值$a = 0$映射到强度$D = $$ 0$, 将$a = 1$映射到最大强度$D = M$. 用Gamma值$\gamma$定义出来的表达式只是一个近似表达式; 在估计显示器的Gamma值$\gamma$时, 我们不需要非常精确. 一个简单的计算Gamma值$\gamma$的方法为找出一个使得实际显示颜色为灰色的输入值$a$, i.e.$$0.5 = a^\gamma.$$如果我们能找到符合上述条件的输入值$a$, 则我们可以通过对上式两边取自然对数来得到Gamma值$\gamma$:$$\gamma = \frac{ln0.5}{lna}.$$基于上述理论, 目前很多游戏都通过一种标准技术找到一个合适的输入值$a$, 即在一张全灰图像旁边显示一张黑白相间的棋盘图像, 然后让用户调整$a$(如使用滑块), 直到两张图像的平均亮度匹配为止. 此时, 从远处看这两张图像时,两张图像的显示效果差异不大. 这是因为棋盘图像混合了偶数个白色像素与偶数个黑色像素, 故整体颜色将呈现灰色. 下图为游戏《巫师3》中调整Gamma值的界面.

一旦我们知道了Gamma值$\gamma$, 我们就可以通过如下转换对输入进行Gamma校正, 使锝输入值$a = 0.5$的输出颜色为灰色,$$a’ = a^{\frac{1}{\gamma}}.$$从而我们可得$$D = M(a’)^\gamma = M(a^{\frac{1}{\gamma}})^\gamma = Ma.$$另一个关键点为显示器采用量化的输入值. 因此, 虽然我们可以在浮点数范围$[0, $$ 1]$内操作输入值$a$, 但显示器的实际输入是一个固定大小的整数. 这个整数最常见的范围为$[0, 255]$, 其可以存储在8位的存储空间中. 这意味着并非$[0, 1]$中的任何数值均能作为实际输入值$a$, 其可能值集合为$$\{ \frac{0}{255}, \frac{1}{255}, \frac{2}{255}, \cdots, \frac{254}{255}, \frac{255}{255} \}.$$从而可能的显示强度值集合为$$\{ M(\frac{0}{255})^\gamma, M(\frac{1}{255})^\gamma, M(\frac{2}{255})^\gamma, \cdots, M(\frac{254}{255})^\gamma, M(\frac{255}{255})^\gamma \}.$$在需要精确控制实际的显示强度的应用程序中, 我们必须实际测量256种可能的强度, 这些强度在屏幕上的不同位置可能也是不同的, 特别是对于CRT显示器. 此外, 它们也可能随着观察角度的变化而变化. 但一般情况下, 很少有应用需要进行如此精确的校准. 在这种情况下, 我们仅需要计算出显示器的Gamma值$\gamma$, 并将其应用于Gamma校正即可.

3. Alpha合成

将前景对象与背景对象混合所需要的最重要的信息是像素覆盖率, 它告诉我们前景层所覆盖的像素的比例, 我们称这个比例为$\alpha$.如果我们想要合成前景色$c_f$与背景色$c_b$, 并且前景色覆盖的像素的比例为$\alpha$, 那么我们可以使用如下公式进行Alpha合成,$$c = \alpha c_f + (1 – \alpha)c_b.$$对于不透明的前景层, 上式可以理解为: 前景对象覆盖了像素矩形内的$\alpha$区域, 背景对象覆盖剩余区域, 即其覆盖比例为$1 – \alpha$. 而对于透明层(想象一下用半透明颜料画在玻璃或描图纸上的图像), 上式可以理解为: 前景层阻挡了来自背景的部分光(阻挡比例为$\alpha$), 并贡献了自己的部分颜色(贡献比例为$\alpha$) 来替代被阻挡的部分.

4. 常见问题

问: 为什么显示器厂商不将显示器实际的显示强度设置为关于输入的像素颜色值的线性函数, 从而避免Gamma校正的麻烦呢?
$\\$ 答: 理想情况下, 我们希望显示器的256个可能的实际显示强度看起来应该是均匀分布的. 而由于人类对实际的显示强度的感知本身是非线性的, 当Gamma值在1.5到3之间(取决于观测条件) 将使实际的显示强度在主观意义上近似均匀分布.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注