犍陟 發表於 2025-5-20 23:21:00

《Fundamentals of Computer Graphics》第三章 光栅图像

<h1 id="开篇">开篇</h1>
<p>  绝大多数计算机图形图像都是通过<strong>光栅显示器</strong>(<strong>Raster Display</strong>)呈现在用户面前的,光栅显示器使用由<strong>像素</strong>组成的矩形阵列来显示图像。典型的例子就是平板计算机显示器和TV电视,它们都使用可以被单独设置成不同颜色的发光像素组成的矩形阵列来创造任何期望的图像。不同的颜色是通过混合不同强度的红色、绿色、蓝色三原色光得到的。<br>
  因为光栅在设备中非常流行,<strong>光栅图像</strong>(<strong>Raster Image</strong>)是最常用的方法用来存储和处理图像,一个光栅图像仅仅是为每个像素存储<strong>像素值</strong>的二维数组,通常颜色通过三个数字来分别存储红、绿、蓝三个分量。在内存中存储的光栅图像可以通过它存储的每个像素来控制<strong>显示设备</strong>(<strong>Display Device</strong>)上对应的像素的颜色来显示。<br>
  但是我们不会总是想用这种方式来显示图像,我们可能想要改变图像的<strong>大小</strong>或<strong>朝向</strong>,又或是把图像<strong>粘贴</strong>到移动的三维表面上。甚至在电视中,有时候显示像素的数量不会和图像像素的数量相同。以上这些考量打断了图像像素和显示像素之间的直接联系,因此最好把<strong>光栅图像</strong>当作被显示图像的一个<strong>设备无关的描述</strong>,把<strong>显示设备</strong>当作接近<strong>理想图像</strong>的一种方法。</p>
<h1 id="光栅设备raster-devices">光栅设备(Raster Devices)</h1>
<ul>
<li>
<p>输出</p>
<ul>
<li><strong>透射式</strong>(<strong>Transmissive</strong>):<strong>液晶显示器</strong>(<strong>LCD</strong>)</li>
<li><strong>发射式</strong>(<strong>Emissive</strong>):<strong>发光二极管</strong>(<strong>LED</strong>)显示器</li>
</ul>
</li>
<li>
<p>输入</p>
<ul>
<li><strong>二维阵列传感器</strong>:数字相机</li>
<li><strong>一维阵列传感器</strong>:平板扫描仪</li>
</ul>
</li>
</ul>
<h2 id="显示器displays">显示器(Displays)</h2>
<p>  当前的显示器包括电视、数字影视投影仪还有电脑用的投影仪等等,它们几乎都基于固定大小的<strong>像素阵列</strong>。它们的显示方式可以被分为<strong>发射式</strong>和<strong>透射式</strong>。<strong>发射式</strong>显示器通过能直接发出可控光的像素来显示图像,而<strong>透射式</strong>显示器的像素本身不发光,但是可以改变允许穿过它们的光的量来显示图像。<strong>透射式</strong>显示器需要光源来点亮它们,例如背光和投影仪用到的灯。<strong>发射式</strong>显示器自己就是光源。<br>
  <strong>发光二极管</strong>显示器是<strong>发射式</strong>显示的一种,每个像素都是由一个或多个<strong>发光二极管</strong>组成,这些<strong>发光二极管</strong>是能根据流经它们的电流而发出特定强度的光的半导体设备。像素在显示器中被分为三个单独控制的红、绿、蓝<strong>亚像素</strong>,发出不同光的亚像素的发光二极管是由不同材料制成的。当从一定距离观察时,人眼就不能看清每个亚像素,取而代之看到的是由亚像素合成的颜色。<br>
<img src="https://img2023.cnblogs.com/blog/2774734/202505/2774734-20250519163539959-1193015024.png"><br>
  <strong>液晶显示器</strong>是<strong>透射式</strong>显示的一种,液晶是一种材料,它的分子结构使它能旋转穿过它的光的<strong>偏振</strong>(<strong>Polarization</strong>),旋转的程度可以通过调整施加的电压来控制。<br>
<img src="https://img2023.cnblogs.com/blog/2774734/202505/2774734-20250519161425179-1134074298.png"><br>
由图所示,未偏振的背光被第一层水平过滤的偏光片过滤,从而只有水平偏振的光穿过,在两层偏光片之间的是液晶。第一种情况的液晶使水平偏振光旋转90°,因此能完全通过第二层垂直过滤的偏光片,从而点亮LCD像素。第二种情况的液晶未旋转水平偏振光,从而都被垂直过滤的偏光片过滤掉,因而无法点亮LCD像素。<br>
  任何显示类型都有固定的像素网格。对于显示图像来说,分辨率就是像素网格的维度。如果桌面监视器有1920x1200的分辨率,这就意味着它有230万4千个像素以每行1920个每列1200个的方式排列。</p>
<h2 id="输入设备input-devices">输入设备(Input Devices)</h2>
<p>  <strong>光栅图像</strong>必须有来源,如果不是被计算出来的就是被某些<strong>光栅输入设备</strong>测量的比如摄影机或者扫描仪。甚至是在渲染三维场景的图像的时候,照片持续地被用于纹理映射。一个光栅输入设备必须为每个像素进行光测量,这通常基于<strong>传感器阵列</strong>实现。<br>
  数字摄影机是二维阵列输入设备的一个例子,在摄影机里的图像传感器是有着光感像素阵列的半导体设备。两种常见的类型是<strong>电荷耦合器件图像传感器</strong>(<strong>charge-coupled devices</strong>,<strong>CCD</strong>)和<strong>互补金属氧化物半导体图像传感器</strong>(<strong>complementary metal-oxide-semiconductor</strong>,<strong>CMOS</strong>)。摄影机的镜面如左下图所示,把被拍摄的场景的图像投影到图像传感器上,接着每个光感像素测量击中它的光的能量,最终计算出一个数字写入到输出图像中。像显示器使用红、绿、蓝亚像素显示图像一样,大多数彩色摄影机如右下图所示,使用一个<strong>能过滤颜色的</strong>阵列或者<strong>马赛克</strong>来让每个像素只能看见红光、绿光、蓝光中的一种光,最后让图像处理软件使用一个叫<strong>去马赛克</strong>的过程来填补缺少的值。其它摄影机则使用三个分开的阵列或者在阵列中三个分开的层来独立地测量每个像素的红、绿、蓝值,从而生成不需要后续处理可以直接被使用的图像。<br>
  摄影机的分辨率被固定大小的像素阵列决定,通常使用像素的总数量来描述。假设这里有摄影机它的像素阵列的维度为3000x2000,那么它能生成分辨率为3000x2000的图像,有6百万像素,因此被称为<strong>6MP</strong>(<strong>megapixel</strong>)摄影机。<br>
<img src="https://img2023.cnblogs.com/blog/2774734/202505/2774734-20250519235317154-1234780969.png"><img src="https://img2023.cnblogs.com/blog/2774734/202505/2774734-20250521175128506-595623508.png"><br>
  平板扫描仪也为阵列的每个像素测量红、绿、蓝值,但是是像下图所示,用一维阵列扫过被扫描的页,每秒进行多次测量。分辨率由一维阵列的维度和扫描频率决定。一个颜色扫描仪有<span class="math inline">\(3 \times n_x\)</span>的阵列,<span class="math inline">\(n_x\)</span>为穿过每页的像素数,阵列的三行分别覆盖着红、绿、蓝过滤器,使用恰当的延迟进行测量可以为网格上的每点独立地测量红、绿、蓝三色。扫描仪的分辨率用<strong>像素每英寸</strong>(<strong>PPI</strong>)描述。<br>
<img src="https://img2023.cnblogs.com/blog/2774734/202505/2774734-20250519235216836-1481621067.png"></p>
<h1 id="图像像素和几何images-pixels-and-geometry">图像、像素和几何(Images, Pixels, and Geometry)</h1>
<p>  我们知道<strong>光栅图像</strong>是大的<strong>像素阵列</strong>,每个像素存储图像在这个网格点的颜色信息。我们已经了解了不同的显示设备以及输入设备。但是对于计算机中的计算来说,我们需要便捷的抽象的独立于任何设备的图像描述。图像在物理世界中是二维区域内的函数,这个二维区域通常是矩形,因此我们可以把图像抽象成函数<span class="math inline">\(I(x,y):R \rightarrow V\)</span>,其中<span class="math inline">\(R\)</span>满足<span class="math inline">\(R \subset \mathbb{R}^2\)</span>,<span class="math inline">\(V\)</span>为可能的像素值的集合。这时候可能要问了,<strong>光栅图像</strong>是怎么和与位置有关的的连续函数联系起来的呢?联系一下实际例子,来自摄影机或者扫描仪的像素值实际上测量的是像素位置一定区域内的平均颜色,一个显示像素的红、绿、蓝亚像素会被光栅图像上对应的像素控制。在这两个例子中,像素值都是图像的局部平均颜色,叫做图像的<strong>点采样</strong>(<strong>Point Sample</strong>)。用另一句话来说,当我们在像素中找到值<span class="math inline">\(x\)</span>,这意味着图像的值在这个网格点附近的地方取<span class="math inline">\(x\)</span>,在第十章会继续探讨图像作为函数的采样表示这一想法。</p>
<h2 id="像素值pixel-values">像素值(Pixel Values)</h2>
<p>  目前为止我们描述像素值为正实数,来表示图像上某点的强度,而且可能分为红、绿、蓝三个强度值。这就意味着图像应该是浮点数数组,每个像素可以使用一个32位浮点数存储灰度或者使用三个32位浮点数分别存储红、绿、蓝值。在非常需要精度以及表示范围的情况下,这个格式会被使用。但是一个图像通常有非常多的像素,在存储和传输图像时,使用这种格式对<strong>内存</strong>和<strong>带宽</strong>的消耗很大,因此图像需要存储更小的范围而且还能被直接显示,正好每个显示设备能发出的光的强度范围也是有限的,经过综合考量后,实际上我们可以用在区间<span class="math inline">\(\)</span>的数来描述颜色。于是这个时候我们可以使用例如8个比特来表示颜色,<span class="math inline">\(0\)</span>、<span class="math inline">\(1/255\)</span>、<span class="math inline">\(2/255\)</span>、<span class="math inline">\(3/255\)</span>......、<span class="math inline">\(254/255\)</span>、<span class="math inline">\(1\)</span>。使用浮点数存储的图像允许存储更大范围的值,这种图像通常被称作<strong>高动态范围</strong>(<strong>HDR</strong>)图像。相反地,如果存储的是<span class="math inline">\(\)</span>之间的值的图像就是<strong>低动态范围</strong>(<strong>LDR</strong>)图像。下面是一些像素格式和相关的典型应用:</p>
<ul>
<li>1比特灰度:用于文字和图像,只表示0或1没有中间灰度值。</li>
<li>每通道8比特固定范围RGB颜色:用于网络和邮件还有消费级照片。</li>
<li>每通道8或10比特固定范围RGB颜色:用于计算机显示的数字界面。</li>
<li>每通道12到14比特固定范围RGB颜色:用于专业摄影的原始摄影图像。</li>
<li>每通道16比特固定范围RGB颜色:用于专业摄影和打印,此外还是图像处理的中间格式。</li>
<li>每通道16比特“<strong>半精度</strong>(<strong>half-precision</strong>)”浮点RGB颜色:用于高动态范围图像和实时渲染的中间格式。</li>
<li>每通道32比特浮点RGB颜色:用于渲染和处理高动态范围图像的通用中间格式。</li>
</ul>
<p>  减少使用的比特位会导致两种独特的错误或者人为引入缺陷。首先,使用固定范围的值编码图像会产生<strong>裁剪</strong>(<strong>clipping</strong>),例如当写入的值比能存储的值大时。第二,使用有限的精度编码图像时会产生<strong>量化伪影</strong>(<strong>quantization artifact</strong>)或<strong>条带化</strong>(<strong>banding</strong>),当需要把像素值舍入到最近的可表达的值时,会造成在强度或颜色上的可见跳跃。<strong>条带化</strong>在动画和视频中是个独特的潜藏问题,当静止时可能不会让人反感,向前或向后移动时这个问题会变得非常显眼。</p>
<h2 id="监视器强度和伽马monitor-intensities-and-gamma">监视器强度和伽马(Monitor Intensities and Gamma)</h2>
<p>  所有的现代监视器都会把输入的数字信号转化为强度等级的输出,真实的监视器在完全关闭时有非零强度,这是因为屏幕会反射光。对我们来说,可以直接把像素值0当作黑色把像素值1当作白色,介于黑白之间的半程为0.5,要注意的是这里的半程指代的是监视器输出的光强度,而不是观察出的颜色。因为人眼对强度的感知是非线性的。<br>
  这个时候需要理解在监视器上生成正确图像的两个关键问题,首先监视器对于输入的像素值会产生非线性的强度输出,例如输入像素值0、0.5、1.0会输出强度值0、0.25、1.0,以此来让人眼感知到近似线性的颜色。这通常通过<span class="math inline">\(\gamma\)</span>和等式</p>
<p></p><div class="math display">\[\mathrm{display \,\, intensity} = (\mathrm{maximum\,\,intensity}) \times a^{\gamma}
\]</div><p></p><p>来描述,其中<span class="math inline">\(a\)</span>为输入的像素值且满足<span class="math inline">\(a \in \)</span>。使用<span class="math inline">\(\gamma\)</span>描述的非线性只是一个近似,我们其实不需要非常精确地为设备来估计<span class="math inline">\(\gamma\)</span>值。不过有个非常好的视觉方法找到非线性度<span class="math inline">\(\gamma\)</span>。就是在监视器以半程强度输出时,进行颜色匹配从而找到像素值<span class="math inline">\(a\)</span>,接着就能计算出非线性度<span class="math inline">\(\gamma\)</span>。利用如下等式</p>
<p></p><div class="math display">\[0.5 = a^{\gamma}
\]</div><p></p><p></p><div class="math display">\[\gamma = \frac{\ln 0.5}{\ln a}
\]</div><p></p><p>接下来要解决的问题是如何得到监视器在半程强度输出时,眼睛感受到的颜色并以此进行匹配。解决方法很简单,我们首先让屏幕左侧显示由黑白像素交替组成的棋盘图像,让屏幕右侧显示由像素值<span class="math inline">\(a\)</span>决定的纯色图像。接着在远处进行观察,这个时候就会发现棋盘图像的黑白交替颜色变成了屏幕在半程强度输出时所观察到的颜色,然后我们调整像素值<span class="math inline">\(a\)</span>进行颜色匹配,得到像素值<span class="math inline">\(a\)</span>后就能利用第二个等式计算非线性度<span class="math inline">\(\gamma\)</span>。<br>
<img src="https://img2023.cnblogs.com/blog/2774734/202505/2774734-20250520165522034-1926999744.png"></p>
<h1 id="rgb颜色rgb-color">RGB颜色(RGB Color)</h1>
<p>  绝大多数计算机图形图像的颜色都是通过红、绿、蓝三色定义的,RGB颜色是简单的空间,用来直接控制绝大多数计算机屏幕,这个部分会从用户的视角讨论RGB颜色。关于RGB颜色空间一个基础的想法是,颜色显示是通过混合三<strong>原色光</strong>(<strong>Primary Light</strong>)得到的,三原色光分别为红光、绿光、蓝光,通过<strong>累加</strong>的方式合成。使用累加合成可以得到:</p>
<p></p><div class="math display">\[红色+绿色=黄色
\]</div><p></p><p></p><div class="math display">\[绿色+蓝色=青色
\]</div><p></p><p></p><div class="math display">\[蓝色+红色=紫色
\]</div><p></p><p></p><div class="math display">\[红色+绿色+蓝色=白色
\]</div><p></p><p><img src="https://img2023.cnblogs.com/blog/2774734/202505/2774734-20250520171249021-12558182.png"><br>
如果可以让原色光从明亮变昏暗,这样我们就可以创造所有能被显示器显示的颜色。因此红、绿、蓝像素值创造了一个以红、绿、蓝为坐标轴的RGB颜色组成的颜色方块。<br>
<img src="https://img2023.cnblogs.com/blog/2774734/202505/2774734-20250520171719098-1839912541.png"></p>
<h1 id="阿尔法合成alpha-composition">阿尔法合成(Alpha Composition)</h1>
<p>  有时我们可能只想部分覆盖像素的内容,一个最简单的例子发生在<strong>颜色合成</strong>里。当我们有背景并且想插入前景图像时,对于不透明的前景像素来说我们直接替换掉背景像素,而对于完全透明的前景像素来说我们保留背景像素。对于那些<strong>部分</strong>透明的像素,我们应该采取某种应对措施。部分透明的像素能出现在前景物体有部分透明区域的时候,但是大多数要进行混色的情况是前景物体部分覆盖像素的时候。<br>
  对于混合前景物体和背景物体来说,最重要的信息就是<strong>像素覆盖值</strong>(<strong>Pixel Coverage</strong>),它告诉了我们前景层覆盖了像素的多少,我们称之为分数<span class="math inline">\(\alpha\)</span>。如果前景颜色为<span class="math inline">\(\mathbf{c}_f\)</span>、背景颜色为<span class="math inline">\(\mathbf{c}_b\)</span>、覆盖分数为<span class="math inline">\(\alpha\)</span>,此时输出的颜色应该为<span class="math inline">\(\mathbf{c}=\alpha\mathbf{c}_f+(1-\alpha)\mathbf{c}_b\)</span>。对于不透明的前景层来说,这个公式可以理解为前景物体占据了像素的<span class="math inline">\(\alpha\)</span>的部分,背景物体占据了像素的<span class="math inline">\((1-\alpha)\)</span>部分。对于透明的前景层来说,这个公式可以理解为前景物体阻挡了背景贡献的光的<span class="math inline">\(\alpha\)</span>部分,替换成了自己颜色的<span class="math inline">\(\alpha\)</span>部分。公式<span class="math inline">\(\mathbf{c}=\alpha\mathbf{c}_f+(1-\alpha)\mathbf{c}_b\)</span>的一个示例图如下。<br>
<img src="https://img2023.cnblogs.com/blog/2774734/202505/2774734-20250520181843988-1736460465.png"><br>
  每个像素都应该有一个对应的<span class="math inline">\(\alpha\)</span>值,如果存储在另外一个灰阶图像中,这就是为人所知的<strong>阿尔法蒙版</strong>(<strong>alpha mask</strong>)或<strong>透明度蒙版</strong>(<strong>transparency mask</strong>)。如果存储在RGB图像的第四通道中就叫<strong>阿尔法通道</strong>(<strong>alpha channel</strong>),这种图像被称为RGBA图像,它的每个像素占据32比特位,这种大小在许多计算机架构中处理起来很便捷。</p>
<h1 id="图像存储image-storage">图像存储(Image Storage)</h1>
<p>  绝大多数RGB图像的格式使用每通道8比特位分别存储红、绿、蓝三通道的值,这就导致了1百万像素的图像的原始信息有3mb大小,为了降低存储的要求,绝大多数的图像格式允许某种类型的压缩。在高层次上看,有无损压缩和有损压缩这两种,流行的图像存储格式有:</p>
<ul>
<li><strong>jpeg/jpg</strong>:有损压缩格式,压缩图像基于人类视觉系统的阈值。</li>
<li><strong>tiff</strong>:这种格式通常被用于容纳二进制图像或者无损压缩的8或16比特RGB图像。</li>
<li><strong>ppm</strong>:非常简单的无损未压缩格式,通常用于8比特RGB图像。</li>
<li><strong>png</strong>:这是一系列无损压缩格式,而且有着非常好的一系列开源的管理工具。</li>
</ul>


</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:TiredInkRaven,转载请注明原文链接:https://www.cnblogs.com/TiredInkRaven/p/18882538</p><br><br>
来源:https://www.cnblogs.com/TiredInkRaven/p/18882538
頁: [1]
查看完整版本: 《Fundamentals of Computer Graphics》第三章 光栅图像