<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated on Thu, 09 Feb 2012 18:31:01 -0800 -->
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://software.intel.com/zh-cn/articles/visual-computing/all/feed" rel="self" type="application/rss+xml" />
    <title>英特尔软件网络 articles FEED</title>
    <link>http://software.intel.com/zh-cn/articles/visual-computing/all/feed</link>
    <description></description>
    <language>zh-cn</language>
    <item>
      <title>数字图像基础之图像基本概念</title>
      <description><![CDATA[ 
<p><strong><span >2.2 图像基本概念</span></strong></p>
<br /><br />
<p align="center"><strong><span >2.2.1 像素与灰度</span></strong></p>
<p><strong>像素和分辨率</strong> 在计算机中，有两个大家都熟悉的概念：像素（pixel）和分辨率（resolution）。我们将图像进行采样的单位称为像素，像素是是组成图像的最基本元素，是数字图像显示的基本单位。像素是一个逻辑尺寸单位，比如一台计算机，其屏幕大小为17英寸，可以用800行*1280列个像素（格子）来显示桌面的图像，也可以用768行*1024列来显示桌面图像，不过显示的图像的清晰度会有差别。在计算机编程中，由像素组成的图像也通常叫“位图”或“光栅图像”。而分辨率狭义的是指显示器所能显示的像素的多少，当用户设置桌面分辨率为1280*800时，表示的意思就是在这个屏幕大小的物理尺寸上，显示器所显示的图像由800行*1280列个像素组成；可以看出，在同样大小的物理尺寸上，分辨率越高的图像，其像素所表示的物理尺寸越小，画面也就越精细，整个图像看起来也就越清晰。广义的分辨率是指对一个物体成像数字时化时进行采样的物理尺寸的大小，比如我们嫦娥一号卫星拍摄的月亮的照片，其分辨率是个很大的数（通常称分辨率很低），如几千平方公里，意思是说，在拍摄的月球的照片上，一个像素点相当于月球上几千公里见方。</p>
<br /><br />
<p align="center"><strong><span >2.2.2 采样量化</span></strong></p>
<p>将空间上连续的图像变换成离散点的操作称为采样。采样间隔和采样孔径的大小是两个很重要的参数。当对图像进行实际的抽样时，怎样选择各抽样点的间隔是个非常重要的问题。关于这一点，图像包含何种程度的细微的浓淡变化，取决于希望忠实反映图像的程度。</p>
<p>经采样图像被分割成空间上离散的像素，但其灰度是连续的，还不能用计算机进行处理。将像素灰度转换成离散的整数值的过程叫量化。表示像素明暗程度的整数称为像素的灰度级（或灰度值或灰度）。一幅数字图像中不同灰度级的个数称为灰度级数，用G表示。灰度级数就代表一幅数字图像的层次。图像数据的实际层次越多视觉效果就越好。一般来说，G=2<sup>g</sup> ，g就是表示存储图像像素灰度值所需的比特位数。若一幅数字图像的量化灰度级数G=256=2<sup>8</sup>级，灰度取值范围一般是0~255的整数，由于用8bit就能表示灰度图像像素的灰度值，因此常称8 bit 量化。从视觉效果来看，采用大于或等于6比特位量化的灰度图像，视觉上就能令人满意。 一幅大小为M×N、灰度级数为G的图像所需的存储空间，即图像的数据量，大小为 M×N×g （bit）。</p>
<table align="center">
<tbody>
<tr align="center">
<td><img src="http://software.intel.com/file/41471" /></td>
<td><img src="http://software.intel.com/file/41472" /></td>
</tr>
<tr align="center">
<td>图2.4 分辨率与图像清晰度</td>
<td>图2.5 量化等级与图像清晰度</td>
</tr>
</tbody>
</table>
<br />
<p>一般来说，采样间隔越大，所得图像像素数越少，空间分辨率低，质量差，严重时出现像素呈块状的国际棋盘效应； 采样间隔越小，所得图像像素数越多，空间分辨率高，图像质量好，但数据量大，如图2.4所示，图像越来越模糊。同样，量化等级越多，所得图像层次越丰富，灰度分辨率高，图像质量好，但数据量大；量化等级越少，图像层次欠丰富，灰度分辨率低，会出现假轮廓现象，图像质量变差，但数据量小。如图2.5所示，图像的质量越来越差，左上角的图像质量最好，但数据量也越大。但在极少数情况下对固定图像大小时，减少灰度级能改善质量，产生这种情况的最可能原因是减少灰度级一般会增加图像的对比度。例如对细节比较丰富的图像数字化。数字图像根据灰度级数的差异可分为：黑白图像、灰度图像和彩色图像。</p>
<p><strong>彩色图像、灰度图像与二值图像</strong> 按所能呈现的色彩和灰度等级我们可以将任何图像（物理的和数字的）图像分为彩色图像、灰度图像和二值图像。彩色图像是指图像中含有色彩信息的图像，在数字图像中，每一个像素都有相应的数值来表示该像素的信息，彩色图像的信息就是颜色信息。根据三基色原理，任何颜色都可以表示为三个基本颜色红、绿、蓝（RGB）按不同比例合成产生。通常所说的24位（bit）位图（windows画图器程序中有相应的保存选项）就是每个像素由24位信息来表示颜色的位图，R、G、B每种颜色通道信息各8位，因此有224（16777216）种不同的颜色（人眼对色彩的分辨能力大致是一千万色），这些颜色足以表达出人眼能够辨别的所有信息，因此也叫做真彩色图像。而灰度图像是指只有亮度差别，而没有颜色差别的图像，例如黑白的老照片。由于人眼能够辩出的亮度等级是有限的，因此数字图像中也可以用有限的等级来描述一副图像。例如，每个像素采用一个字节来表示其亮度信息，就有256级的亮度（2<sup>8</sup>），等级越多的图像效果越好。当灰度图像的灰度只有两个等级的时候，这种图像就叫做二值图像（黑白图像）。可以只用“全黑”和“全白”两种方式对图像进行描述和记录。二值图像所含的信息较少，占用的存储空间也相应较少，但二值图像也有不少的应用，如指纹图像以及文字的识别等，都需要获得二值图像。</p>
<table align="center">
<tbody>
<tr align="center">
<td><img src="http://software.intel.com/file/41473" /></td>
<td><img src="http://software.intel.com/file/41474" /></td>
</tr>
<tr align="center">
<td>（a）黑白图像的像素值</td>
<td>（b）灰度图像的像素值</td>
</tr>
</tbody>
</table>
<br />
<p align="center"><img src="http://software.intel.com/file/40875" /></p>
<p align="center">（c）彩色图像的像素值</p>
<p align="center">图2.6 图像与像素值</p>
<br />
<p><strong>黑白图像</strong> 图像的每个像素只能是黑或白，没有中间的过渡，故又称为二值图像。二值图像的像素值为0或1。如图2.6（a）所示</p>
<p><strong>灰度图像</strong> 灰度图像是指灰度级数大于2的图像。但它不包含彩色信息。如图2.6（b）所示</p>
<p><strong>彩色图像</strong> 彩色图像是指每个像素由R、G、B分量构成的图像，其中R、B、G是由不同的灰度级来描述（后面我们知道，还有其他的颜色空间来描述彩色图像）。每个分量的值如图2.6（c）所示。</p>
<br /><br />
<p align="center"><strong><span >2.2.3 三基色原理</span></strong></p>
<p><strong>相加混色与RGB </strong>在中学的物理课中我们可能做过棱镜的试验，白光通过棱镜后被分解成多种颜色逐渐过渡的色谱，颜色依次为红、橙、黄、绿、青、蓝、紫，这就是可见光谱。其中人眼对红、绿、蓝最为敏感，人的眼睛就像一个三色接收器的体系，大多数的颜色可以通过红、绿、蓝三色按照不同的比例合成产生，同样绝大多数单色光也可以分解成红绿蓝三种色光。这是色度学的最基本原理，即三基色原理（如图2.7所示）。三种基色是相互独立的，任何一种基色都不能由其它两种颜色合成。红绿蓝是三基色，这三种颜色合成的颜色范围最为广泛。红绿蓝三基色按照不同的比例相加合成混色称为相加混色。其中一些混色的规律有：</p>
<p>红色+绿色=黄色；绿色+蓝色=青色；红色+蓝色=品红；红色+绿色+蓝色=白色；另外： 红色+青色=白色；绿色+品红=白色 ；蓝色+黄色=白色 。</p>
<br />
<p align="center"><img src="http://software.intel.com/file/41476" /></p>
<p align="center">图2.7 三基色原理</p>
<br />
<p>当两种光按照适当比例混合得到白光时，称这两种光为互补光。所以，按照上述的混色规律我们可以得到，青色、黄色、品红分别是红色、蓝色、绿色的补色。</p>
<p>由于每个人的眼睛对于相同的单色感受不同，所以，如果用相同强度的三基色混合时，假设得到白光的强度为100%，这时，人的主观感受是，绿光最亮，红光次之，蓝光最弱。如果用Y表示景物的亮度，则通常有：</p>
<p align="center">Y=0.299R+0.587G+0.114B</p>
<p>因为红、绿、蓝三基色能够合成自然界所有的色彩，因此在电子设备和软件中，经常使用红绿蓝三基色合成五颜六色的图像。用以上的相加混色所表示的颜色模式成为RGB模式。</p>
<p><strong>相减混色与CMY（CMYK）</strong> 大家知道，显示器采用RGB模式，就是因为显示器是电子光束轰击荧光屏上的荧光材料发出亮光从而产生颜色。当没有光的时候为黑色，光线加到最大时为白色。而打印机呢？它的油墨不会自己发出光线。因而只有采用吸收特定光波而反射其它光的颜色，所以需要用减色法来解决。CMYK颜色模式是一种印刷模式。其中四个字母分别指青（Cyan）、洋红（Magenta）、黄（Yellow）、黑（Black），在印刷中代表四种颜色的油墨。CMYK模式在本质上与RGB模式没有什么区别，只是产生色彩的原理不同，在RGB模式中由光源发出的色光混合生成颜色，而在CMYK模式中由光线照到有不同比例C、M、Y、K油墨的纸上，部分光谱被吸收后，反射到人眼的光产生颜色。由于C、M、Y、K在混合成色时，随着C、M、Y、K四种成分的增多，反射到人眼的光会越来越少，光线的亮度会越来越低，所有CMYK模式产生颜色的方法又被称为色光减色法。</p>
<p>在白光照射下，青色颜料能吸收红色而反射青色，黄色颜料吸收蓝色而反射黄色，品红颜料吸收绿色而反射品红。也就是：</p>
<p >白色-红色=青色；白色-绿色=品红；白色-蓝色=黄色</p>
<p>如果把青色和黄色两种颜料混合，在白光照射下，由于颜料吸收了红色和蓝色，而反射了绿色，对于颜料的混合我们表示如下：</p>
<p >颜料(黄色+青色)=白色-红色-蓝色=绿色；</p>
<p >颜料(品红+青色)=白色-红色-绿色=蓝色；</p>
<p >颜料(黄色+品红)=白色-绿色-蓝色=红色</p>
<p>以上的都是相减混色,相减混色就是以吸收三基色比例不同而形成不同的颜色的。所以有把青色、品红、黄色称为颜料三基色。CMYK模式是一种颜料模式,所以它属于印刷模式,但本质上与RGB模式没有区别,只是产生颜色的方式不同。</p>
<br /><br />
<p align="center"><strong><span >2.2.4 彩色模型（RGB、YUV、YCbCr、HSV、HLS）</span></strong></p>
<p>正如几何上用坐标空间来描述坐标集合, 色彩空间用数学方式来描述颜色集合。常见的3 个基本色彩模型是RGB , CMYK和YUV。</p>
<p><strong>RGB</strong> RGB色彩模式是工业界的一种颜色标准，是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的，RGB即是代表红、绿、蓝三个通道的颜色，这个标准几乎包括了人类视力所能感知的所有颜色，是目前运用最广的颜色系统之一。</p>
<p>RGB色彩模式使用RGB模型为图像中每一个像素的RGB分量分配一个0~255范围内的强度值。例如：纯红色R值为255，G值为0，B值为0；灰色的R、G、B三个值相等（除了0和255）；白色的R、G、B都为255；黑色的R、G、B都为0。RGB图像只使用三种颜色，就可以使它们按照不同的比例混合，在屏幕上重现16777216（2<sup>24</sup>）种颜色。</p>
<p><strong>YUV</strong> 在现代彩色电视中，通常采用三管彩色摄像机或彩色CCD摄像机，它把得到的彩色图像信号，经分色、分别放大校正得到RGB，再经过矩阵变换电路得到亮度信号Y和两个色差信号R-Y、B-Y，最后发送端将三个信号分别进行编码，用同一信道发送出去。这就是我们常用的YUV颜色空间。</p>
<p>YUV是被欧洲电视系统所采用的一种颜色编码方法（属于PAL），是PAL和SECAM模拟彩色电视制式采用的颜色空间。其中的Y，U，V几个字母不是英文单词的组合词，Y代表亮度，U，V代表色差，U和V是构成彩色的两个分量。采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有 Y信号分量而没有U、V信号分量，那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的相容问题，使黑白电视机也能接收彩色电视信号。YUV主要用于优化彩色视频信号的传输，使其向后兼容老式黑白电视。与RGB视频信号传输相比，它最大的优点在于只需占用极少的频宽（RGB要求三个独立的视频信号同时传输）。其中“Y”表示明亮度（Luminance或Luma），也就是灰阶值；而“U”和“V” 表示的则是色度（Chrominance或Chroma），作用是描述影像色彩及饱和度，用于指定像素的颜色。“亮度”是透过RGB输入信号来建立的，方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面─色调与饱和度，分别用Cr和Cb来表示。其中，Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而Cb反映的是RGB输入信号蓝色部分与RGB信号亮度值之同的差异。</p>
<p>采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有Y信号分量而没有U、V分量，那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题，使黑白电视机也能接收彩色电视信号。</p>
<p>YUV相关色彩模型与RGB的转换方程如下：</p>
<br />
<p align="center"><img src="http://software.intel.com/file/41477" /></p>
<br />
<p align="center"><img src="http://software.intel.com/file/41478" /></p>
<br />
<p><strong>YCbCr</strong>　在DVD、摄像机、数字电视等消费类视频产品中，常用的色彩编码方案是YCbCr，其中Y是指亮度分量，Cb指蓝色色度分量，而Cr指红色色度分量。YCbCr是在世界数字组织视频标准研制过程中作为ITU - R BT1601 建议的一部分，其实是YUV经过缩放和偏移的翻版。在YUV 家族中，YCbCr 是在计算机系统中应用最多的成员, 其应用领域很广泛，JPEG，MPEG均采用此格式。因此，一般人们所讲的YUV大多是指YCbCr。其中Y与YUV 中的Y含义一致，Cb，Cr 同样都指色彩, 只是在表示方法上不同而已。常用的从RGB到YCbCr的转换公式如下：</p>
<br />
<p align="center"><img src="http://software.intel.com/file/41479" /></p>
<br />
<p><strong>图像子采样（Image Downsampling） </strong>由于人的肉眼对视频的Y分量更敏感，因此我们在（YUV、YCbCr）亮度和色度来表示颜色的颜色空间中，我们可以对色度信息进行弱化，而不会改变肉眼观察的结果。因此在通过对色度分量进行子采样来减少色度分量后，肉眼将察觉不到图像质量的变化。具体来说，我们可以对图像中每个像素设置一个单独的亮度值，而按照某些特定的规则，将一组像素赋予相同的色度值。我们将这个过程称为子采样。Intel® IPP的函数支持下列子采样的格式：</p>
<p><strong>4:4:4 YUV (YCbCr) </strong>该格式是传统的未采取子采样的格式，对每一个像素的Y、U（Cb）、V（Cr）都进行采样。每个成份通常包含8位，每个像素需要24位，这种格式因此也通常称为4：4：4格式。</p>
<p><strong>4:2:2 YUV (YCbCr)</strong> 采用2：1的水平方向子采样，它的含义是，对每个像素的亮度值Y进行采样，对水平方向连续两个像素的U（Cb） V（Cr）进行采样。如果每一个通道占用8位，那么每两个像素占有8*2+8+8=32位的空间，因此每个像素比4：4：4格式少用8位空间。</p>
<p><strong>4:1:1 YCbCr</strong> 采用4：1的水平方向子采样，它的含义是，对每个像素的亮度值Y进行采样，对水平方向连续4个像素的U（Cb） V（Cr）进行采样。如果每一个通道占用8位，那么每4个像素占有8*4+8+8=48位的空间，因此每个像素比4：4：4格式少用12位空间。</p>
<p><strong>4:2:0 YUV (YCbCr)</strong> 采用水平和垂直方向2：1子采样，它的含义是，对每个像素的亮度值Y进行采样，每2*2个像素块进行一次U(Cb) 和 V(Cr)采样。如果每一个通道占用8位，则每4个像素占有8*4+8+8=48位的空间，因此每个像素比4：4：4格式少用12位空间。</p>
<p>4:2:0格式是便携式视频设备(MPEG-4)以及电视会议(H.263)最常用格式；4：2：2格式是DVD、数字电视、HDTV 以及其它消费类视频设备的最常用格式；4：4：4格式用于高质量视频应用、演播室以及专业视频产品。</p>
<p>在图像压缩算法中，JPEG采用了一种特定的子采样方法。在JPEG算法中，子采样的格式会决定最小编码单元的结构（minimal coded units, or MCUs），因此在IPP中，支持JPEG算法的函数支持下列的子采样格式：</p>
<p><strong>4:4:4 YCbCr</strong> 针对每个8*8像素块大小，有8*8块大小的Y值，同时，也分别有一个8*8块大小的Cb和Cr值。</p>
<p><strong>4:2:2 YCbCr </strong>针对两个水平方向连续的8*8像素块，有两个8*8块大小的Y值，也分别有一个8*8块大小的Cb值和Cr值。</p>
<p><strong>4:1:1 YCbCr </strong>针对每4个8*8块（水平和垂直各两块8*8大小的像素块），有4个8*8块大小的Y值，也分别有一个8*8块大小的Cb值和Cr值。</p>
<br />
<p align="center"><img src="http://software.intel.com/file/41480" /></p>
<p align="center">图2.8 平面图像示意图</p>
<br />
<p><strong>HSV颜色模型 </strong>在生活中，我们感知和关于颜色的讨论其实和RGB颜色模型并不是直接相关，举个例子来说，如果我们装修房子，我们对房子装饰的颜色并不是说R，G，B成份各是多少，而会说我们打算用什么颜色，多亮，颜色是柔和一些的还是鲜明一些的。通常来说，我们第一个关注的就是颜色（Hue，色相或色彩），色相描述了具体的颜色，如红、黄、紫等，即其在光谱上的位置（该可见光的波长是多少）。如图2.9所示，用从0到3600的圆圈代表了不同的颜色； 第二个会关注的是颜色的饱和度（S，纯度），饱和度衡量该颜色相对于白色的多少，比如，一个全部是红色而没有白色成份的颜色是完全饱和的，如果将白色加入到红色中去，红色会变得更加柔和，我们感知的颜色也会从红色相粉红色变化，此时的颜色（色相）仍然是红色，但是该颜色变得不饱和。如图所示，纵轴表示了不同的饱和度；最后，我们也会经常说明颜色的亮度，我们可以拿一个红色的跑车为例，当天气晴朗，足够的光线反射到我们的眼睛，这时，车子看起来很亮，很色也很鲜艳，但是，到了傍晚，光线很弱，车子看起来也很暗淡，看起来偏黑。如图所示，横轴表示了不同的亮度，和饱和度一样，其范围也是0-100%，亮度表示了有多少光线照射在该颜色上，我们从图中也可以看出，当亮度增加是，红色跟鲜艳，当亮度降低时，红色变得更黑。因此，和RGB颜色空间类似，HSV是另一种描述颜色空间的颜色模型，RGB颜色空间和HSV颜色空间之间可以互相转化（有相互转化的公式）。该模型的描述方法更接近于人类对于颜色的感知。下图为将RGB模型分解为H、S、V后的灰度图。</p>
<p>为了更好的理解HSV和RGB颜色空间的概念。我们将详细描述他们之间的关系。</p>
<p>我们首先从亮度的概念着手，亮度的概念在前面也有描述，它是对某一个区域发出光线多少的感知。市场上有一种可控灯，我们可以这种灯的亮度，不管这个灯是红色的光还是白色的光。在RGB颜色空间中，亮度是用RGB三种颜色值的和来表示。对与某一等级的亮度，其代表了垂直于正方体的对角线的平面（R+B+G=Constant），如图所示，我们选取了RGB颜色空间的三个垂直于对角线的平面，图（a）显示了三个当中最暗的平面，图（c）是三个当中最亮的，我们注意到，虽然在每一个平面中的颜色是千变万化的，但是他们的亮度是相同的。在对角线的两个端点是两种特殊的颜色，黑色和白色，他们在RGB空间中只有一个点（而不是平面）。其实，（R+G+B）/ 3虽然是亮度的严格定义，但是人类感知颜色的亮度并不是这样的，人类感知亮度的公式是Luminance，Y = 0.30R + 0.59G + 0.11B。因为这些权值比较准确的衡量了人类眼睛对红、绿、蓝三种颜色的敏感度。</p>
<br />
<p align="center"><img src="http://software.intel.com/file/41481" /></p>
<p align="center">图2.9 HSV颜色模型</p>
<br /><br />
<p align="center"><img src="http://software.intel.com/file/41482" /></p>
<p align="center">图2.10 图片及其H、S、V分量图</p>
<br />
<p>接下来我们阐述饱和度的概念。饱和度的定义依赖于亮度，饱和度定义为彩色度（colorfulness）与亮度的比值。用什么衡量彩色度呢？我们仍然可以借助RGB正方体空间和该正方体的对角线来描述。正方体的这条对角线的颜色值范围从0R0G0B到255R255G255B，对角线上所有的R，G，B分量都相同，构成了从黑到白的所有灰度值。因此在这条轴上，没有颜色信息，因此，在RGB空间中，任何一点的彩色度，与该点到这条轴的距离成正比。离这条轴的距离越近，该点看上去彩色度就很小，看上去偏灰，离这条轴的距离越远，该点看上去颜色也就越丰富。而饱和度就是彩色度与亮度的比值（也即每一个颜色点与黑点、即远点所成的直线与中心轴的夹角大小）。因此在图中的每一个平面中的点，离中心轴越远，饱和度越大。如图所示。左图和右图分别对应于20%和70%的饱和度，饱和度越高，颜色越鲜艳，从图中可以看出，右图比左图明显要鲜艳很多。</p>
<table align="center">
<tbody>
<tr align="center">
<td><img src="http://software.intel.com/file/41483" /></td>
<td><img src="http://software.intel.com/file/41484" /></td>
</tr>
<tr align="center">
<td>(a)</td>
<td>(b)</td>
</tr>
<tr align="center">
<td><img src="http://software.intel.com/file/41485" /></td>
<td><img src="http://software.intel.com/file/41486" /></td>
</tr>
<tr align="center">
<td>(c)</td>
<td>(d)</td>
</tr>
<tr align="center">
<td colspan="2">图2.11 HSV分量图</td>
</tr>
</tbody>
</table>
<br />
<p>最后，我们看看颜色（Hue），我们将颜色定义为其与轴线的夹角的方向（大小为饱和度），如图所示，红色、青色、黄色、绿色等颜色在绕轴线的360度角上均匀地分配。如图所示，（a）图的Hue值为330度，其颜色为紫色；（b）图的Hue值为0度，其颜色为红色；（c）图的Hue值为30度，其颜色为橙色。</p>
<p>如图所示，为RGB空间和HSV空间的映射关系。</p>
<p><strong>HLS</strong>许多人认为HLS色彩模型比较直觉化，因为它在定义色彩时根据的是「色调」、「明亮」(或亮度)及「饱和度」。 若要指定色彩，请在彩虹频谱上挑选色调、选取其饱和度(色彩的纯度)，并设定亮度(亮或暗)。 鲜红色是高度饱和的明亮色彩。 粉蜡笔般的粉红色较不饱和。 色调以度数(0到360度)指定，而饱和度和明亮则是以0到100%的百分比指定。 任何饱和度为零的HLS色彩就是中性灰。</p>
<br /><br />
<p align="center"><strong><span >2.2.5 IPP库所支持的图像格式</span></strong></p>
<p>在IPP函数库中，对上述彩色模型都有很好的支持。为了支持上述的颜色各种模型，IPP对数字图像个格式有多种广泛的支持。我们在本节做一个 具体的介绍。</p>
<p><strong>基于像素的图像格式 </strong>基于像素格式图像的特点是其每一个像素的各个通道的信息数据放在一起，IPP库支持多种颜色空间的图像表示方式。我们首先简单介绍一下啊RGB颜色空间的像素表示法。除了每像素24位RGB /BGR的图像格式外，IPP的颜色变换函数里还支持32位（RGB通道加上alpha通道）的RGB/BGR图像格式，其基于像素点的格式如表2.1所示（其中，在像素序列一列中，下划线标识的一组代表一个像素的颜色值，不同的下划线组表示相邻像素点的颜色值）：</p>
<p align="center"><strong>表</strong><strong>2.1   24</strong><strong>位和</strong><strong>32</strong><strong>位</strong><strong>RGB</strong><strong>图像数据格式及</strong><strong>IPP</strong><strong>函数支持</strong><strong> </strong></p>
<table align="center" cellpadding="0" cellspacing="0" border="1">
<tbody>
<tr>
<td width="83" valign="top"><strong>图像格式</strong><strong> </strong></td>
<td width="76" valign="top">
<p align="center"><strong>通道个数</strong><strong> </strong></p>
</td>
<td width="227" valign="top">
<p align="center"><strong>像素序列</strong><strong> </strong></p>
</td>
<td width="183" valign="top">
<p align="center"><strong>IPP</strong><strong>函数实例</strong><strong> </strong></p>
</td>
</tr>
<tr>
<td width="83" valign="top">
<p>RGB</p>
</td>
<td width="76" valign="top">
<p>3</p>
</td>
<td width="227" valign="top">
<p><span >R0 G0 B0</span> <span >R1 G1 B1</span> <span >R2 G2 B2</span></p>
</td>
<td width="183" valign="top">
<p>ippiRGBToYUV_8u_C3R</p>
</td>
</tr>
<tr>
<td width="83" valign="top">
<p>RGB</p>
</td>
<td width="76" valign="top">
<p>4</p>
</td>
<td width="227" valign="top">
<p><span >R0 G0 B0 A0</span> <span >R1 G1 B1 A1</span></p>
</td>
<td width="183" valign="top">
<p>ippiRGBToYUV_8u_AC4R</p>
</td>
</tr>
<tr>
<td width="83" valign="top">
<p>BGR</p>
</td>
<td width="76" valign="top">
<p>3</p>
</td>
<td width="227" valign="top">
<p><span >B0 G0 R0</span> <span >B1 G1 R1</span> <span >B2 G2 R2</span></p>
</td>
<td width="183" valign="top">
<p>ippiYCbCrToBGR_8u_P3C3R</p>
</td>
</tr>
<tr>
<td width="83" valign="top">
<p>BGR</p>
</td>
<td width="76" valign="top">
<p>4</p>
</td>
<td width="227" valign="top">
<p><span >B0 G0 R0 A0</span> <span >B1 G1 R1 A1</span> <span ></span></p>
</td>
<td width="183" valign="top">
<p>ippiBGRToHLS_8u_AC4R</p>
</td>
</tr>
</tbody>
</table>
<p>针对16位（每个像素颜色值用16位两个字节来表示）图像格式，由于三个通道只占用两个字节的空间，因此，每一个通道占用不到1个字节，IPP库中支持16位的RGB像素格式有以下几种，如表2.2所示。</p>
<p align="center"><strong>表</strong><strong>2.2   16</strong><strong>位</strong><strong>RGB</strong><strong>图像数据格式及</strong><strong>IPP</strong><strong>函数支持</strong><strong> </strong></p>
<table align="center" cellpadding="0" cellspacing="0" border="1">
<tbody>
<tr>
<td width="66" valign="top">
<div align="center"><strong>图像格式</strong></div>
</td>
<td width="161" valign="top">
<p align="center"><strong>高地址字节</strong><strong> </strong><br /><strong>（</strong><strong>High-order byte</strong><strong>）</strong><strong> </strong></p>
</td>
<td width="161" valign="top">
<p align="center"><strong>低地址字节</strong><strong> </strong><br /><strong>（</strong><strong>Low-order byte</strong><strong>）</strong><strong> </strong></p>
</td>
<td width="217" valign="top">
<p align="center"><strong>IPP</strong><strong>函数实例</strong><strong> </strong></p>
</td>
</tr>
<tr>
<td width="66" valign="top">
<p>RGB565</p>
</td>
<td width="161" valign="top">
<p>B4 B3 B2 B1 B0 G5 G4 G3</p>
</td>
<td width="161" valign="top">
<p>G2 G1 G0 R4 R3 R2 R1 R0</p>
</td>
<td width="217" valign="top">
<p>ippiYCbCrToRGB565_8u16u_C3R</p>
</td>
</tr>
<tr>
<td width="66" valign="top">
<p>RGB555</p>
</td>
<td width="161" valign="top">
<p><strong>X </strong>B4 B3 B2 B1 B0 G4 G3 0</p>
</td>
<td width="161" valign="top">
<p>G2 G1 G0 R4 R3 R2 R1 R</p>
</td>
<td width="217" valign="top">
<p>ippiYCbCrToRGB555_8u16u_C3R</p>
</td>
</tr>
<tr>
<td width="66" valign="top">
<p>RGB444</p>
</td>
<td width="161" valign="top">
<p><strong>X X X X </strong>B3 B2 B1 B0 G3 <strong></strong></p>
</td>
<td width="161" valign="top">
<p>G2 G1 G0 R3 R2 R1 R0</p>
</td>
<td width="217" valign="top">
<p>ippiYCbCrToRGB444_8u16u_C3R</p>
</td>
</tr>
<tr>
<td width="66" valign="top">
<p>BGR565</p>
</td>
<td width="161" valign="top">
<p>R4 R3 R2 R1 R0 G5 G4 G3 <strong></strong></p>
</td>
<td width="161" valign="top">
<p>G2 G1 G0 B4 B3 B2 B1 B0</p>
</td>
<td width="217" valign="top">
<p>ippiYCbCrToBGR565_8u16u_C3R</p>
</td>
</tr>
<tr>
<td width="66" valign="top">
<p>BGR555</p>
</td>
<td width="161" valign="top">
<p><strong>X </strong>R4 R3 R2 R1 R0 G4 G3 <strong></strong></p>
</td>
<td width="161" valign="top">
<p>G2 G1 G0 B4 B3 B2 B1 B0</p>
</td>
<td width="217" valign="top">
<p>ippiYCbCrToBGR555_8u16u_C3R</p>
</td>
</tr>
<tr>
<td width="66" valign="top">
<p>BGR444</p>
</td>
<td width="161" valign="top">
<p><strong>X X X X </strong>R3 R2 R1 R0 G3 <strong></strong></p>
</td>
<td width="161" valign="top">
<p>G2 G1 G0 B3 B2 B1 B0</p>
</td>
<td width="217" valign="top">
<p>ippiYCbCrToBGR444_8u16u_C3R</p>
</td>
</tr>
<tr>
<td colspan="4" valign="top">
<p align="center">R - Red, G - Green, B - Blue, X - free bit（空闲位）</p>
</td>
</tr>
</tbody>
</table>
<p>其它部分颜色空间的图像格式如表2.3所示（读者可以进一步参考IPP使用手册）。</p>
<p align="center"><strong>表</strong><strong>2.3   </strong><strong>其它颜色空间图像数据格式及</strong><strong>IPP</strong><strong>函数支持</strong><strong> </strong></p>
<table align="center" cellpadding="0" cellspacing="0" border="1">
<tbody>
<tr>
<td width="95" valign="top">
<div align="center"><strong>图像格式</strong></div>
</td>
<td width="76" valign="top">
<p align="center"><strong>通道个数</strong></p>
</td>
<td width="202" valign="top">
<p align="center"><strong>像素序列</strong></p>
</td>
<td width="243" valign="top">
<p align="center"><strong>IPP</strong><strong>函数实例</strong></p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p>YUV</p>
</td>
<td width="76" valign="top">
<p>3</p>
</td>
<td width="202" valign="top">
<p><span >Y0 U0 V0</span> <span >Y1 U1 V1</span> <span >Y2 U2 V2</span></p>
</td>
<td width="243" valign="top">
<p>ippiYUVToRGB_8u_C3R</p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p>YUV</p>
</td>
<td width="76" valign="top">
<p>4</p>
</td>
<td width="202" valign="top">
<p><span >Y0 U0 V0 A0</span> <span >Y1 U1 V1 A1</span> <span ></span></p>
</td>
<td width="243" valign="top">
<p>ippiYUVToRGB_8u_AC4R</p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p>4:2:2 YUV</p>
</td>
<td width="76" valign="top">
<p>2</p>
</td>
<td width="202" valign="top">
<p><span >Y0 U0</span> <span >Y1 V0</span> <span >Y2 U1</span> <span >Y3 V1</span></p>
</td>
<td width="243" valign="top">
<p>ippiYUV422T0RGB_8u_C2C3R</p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p>YCbCr</p>
</td>
<td width="76" valign="top">
<p>3</p>
</td>
<td width="202" valign="top">
<p><span >Y0 Cb0 Cr0</span> <span >Y1 Cb1 Cr1</span></p>
</td>
<td width="243" valign="top">
<p>i ppiYCbCrToRGB_8u_C3R</p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p>YCbCr</p>
</td>
<td width="76" valign="top">
<p>4</p>
</td>
<td width="202" valign="top">
<p><span >Y0 Cb0 Cr0 A0</span> <span >Y1 Cb1 Cr1 A1</span></p>
</td>
<td width="243" valign="top">
<p>ippiYCbCrToRGB_8u_AC4R</p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p>4:2:2 YCbCr</p>
</td>
<td width="76" valign="top">
<p>2</p>
</td>
<td width="202" valign="top">
<p><span >Y0 Cb0</span> <span >Y1 Cr0</span> <span >Y2 Cb1</span> <span >Y3 Cr1</span></p>
</td>
<td width="243" valign="top">
<p>ippiYCbCr422ToRGB_8u_C2C3R</p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p align="left">4:2:2 YCrCb</p>
</td>
<td width="76" valign="top">
<p>2</p>
</td>
<td width="202" valign="top">
<p><span >Y0 Cr0</span> <span >Y1 Cb0</span> <span >Y2 Cr1</span> <span >Y3 Cb1</span></p>
</td>
<td width="243" valign="top">
<p align="left">ippiYCrCb422ToYCbCr422_8u_C2P3R</p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p align="left">4:2:2 CbYCr</p>
</td>
<td width="76" valign="top">
<p>2</p>
</td>
<td width="202" valign="top">
<p><span >Cb0 Y0</span> <span >Cr0 Y1</span> <span >Cb1 Y2</span> <span >Cr1 Y3</span></p>
</td>
<td width="243" valign="top">
<p align="left">ippiCbYCr422ToRGB_8u_C2C3R</p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p align="left">HLS</p>
</td>
<td width="76" valign="top">
<p>3</p>
</td>
<td width="202" valign="top">
<p><span >H0 L0 S0</span> <span >H1 L1 S1</span> <span >H2 L2 S2</span></p>
</td>
<td width="243" valign="top">
<p align="left">ippiHLSToRGB_16u_C3R</p>
</td>
</tr>
<tr>
<td width="95" valign="top">
<p align="left">HSV</p>
</td>
<td width="76" valign="top">
<p>3</p>
</td>
<td width="202" valign="top">
<p><span >H0 S0 V0</span> <span >H1 S1 V1</span> <span >H2 S2 V2</span></p>
</td>
<td width="243" valign="top">
<p align="left">ippiHSVToRGB_16s_C3R</p>
</td>
</tr>
</tbody>
</table>
<p><strong>平面图像格式（Pixel and Planar Image Formats）</strong> 存储一个数字图像可以按像素格式或按照平面格式来存储，在像素格式的情况下，每个像素的多个通道的颜色值被放在一起，它们的存放的结构依颜色模型和子采样模式而定。上述的三个表格列出了部分的像素格式的存储方式及IPP有关处理这种格式的库函数实例。而IPP的库函数中关于颜色变换的一些函数也支持平面格式的存储方式。如下表所示（还有更多的平面格式，可以参考手册，平面图像数据在图像编码、数字视频处理等领域有很多应用）。</p>
<p>像素格式是一种交叉的格式（如在内存中RGB值间隔循环放置），交叉格式和平面格式是两种数据存放的格式。有时候，平面格式更容易对图像进行处理。如在图像压缩中，通常都是对每个通道单独处理，这个时候，交叉存放格式明显会带来不便。因此，IPP也提供了一些这两种数据格式之间的转换函数。表2.4列出了一些支持图像数据格式转换的IPP函数。</p>
<p align="center"><strong>表</strong><strong>2.4   </strong><strong>不同图像数据格式之间的转换及</strong><strong>IPP</strong><strong>函数支持</strong><strong> </strong></p>
<table align="center" cellpadding="0" cellspacing="0" border="1">
<tbody>
<tr>
<td width="111" rowspan="2" valign="top"><br /><strong>图像</strong><strong> </strong><br /><strong>格式</strong><strong> </strong></td>
<td width="38" rowspan="2" valign="top">
<p align="center"><strong>通道</strong><strong> </strong></p>
</td>
<td colspan="3" width="227" valign="top">
<p align="center"><strong>平面排列方式</strong><strong> </strong></p>
</td>
<td width="192" rowspan="2" valign="top">
<p align="center"><strong>IPP</strong><strong>库函数</strong><strong> </strong></p>
</td>
</tr>
<tr>
<td width="66" valign="top">
<p align="center"><strong>平面</strong><strong>1</strong></p>
</td>
<td width="76" valign="top">
<p align="center"><strong>平面</strong><strong>2</strong></p>
</td>
<td width="85" valign="top">
<p align="center"><strong>平面</strong><strong>3</strong></p>
</td>
</tr>
<tr>
<td width="111" valign="top">
<p align="center">RGB（a）</p>
</td>
<td width="38" valign="top">
<p align="center">3</p>
</td>
<td width="66" valign="top">
<p align="center">R</p>
</td>
<td width="76" valign="top">
<p align="center">G</p>
</td>
<td width="85" valign="top">
<p align="center">B</p>
</td>
<td width="192" valign="top">
<p align="center">ippiRGBToYUV_8u_P3R</p>
</td>
</tr>
<tr>
<td width="111" valign="top">
<p align="center">YUV（a）</p>
</td>
<td width="38" valign="top">
<p align="center">3</p>
</td>
<td width="66" valign="top">
<p align="center">Y</p>
</td>
<td width="76" valign="top">
<p align="center">U</p>
</td>
<td width="85" valign="top">
<p align="center">V</p>
</td>
<td width="192" valign="top">
<p align="center">ippiYUVToRGB_8u_P3R</p>
</td>
</tr>
<tr>
<td width="111" valign="top">
<p align="center">4:2:2YUV（b）</p>
</td>
<td width="38" valign="top">
<p align="center">3</p>
</td>
<td width="66" valign="top">
<p align="center">Y</p>
</td>
<td width="76" valign="top">
<p align="center">U</p>
</td>
<td width="85" valign="top">
<p align="center">V</p>
</td>
<td width="192" valign="top">
<p align="center">ippiYUV422ToRGB_8u_P3</p>
</td>
</tr>
<tr>
<td width="111" valign="top">
<p align="center">4:2:0YUV （d）</p>
</td>
<td width="38" valign="top">
<p align="center">3</p>
</td>
<td width="66" valign="top">
<p align="center">Y</p>
</td>
<td width="76" valign="top">
<p align="center">U</p>
</td>
<td width="85" valign="top">
<p align="center">V</p>
</td>
<td width="192" valign="top">
<p align="center">ippiYUV420ToRGB_8uP3C3R</p>
</td>
</tr>
<tr>
<td colspan="6" width="568" valign="top">
<p align="center">（a）、（b）、（c）、（d）所对应的平面格式分别如图2.12中（a）、（b）、（c）、（d）所示</p>
</td>
</tr>
</tbody>
</table>
<br />
<p align="center"><img src="http://software.intel.com/file/41487" /></p>
<p align="center">图2.12 表2.4对应的平面数据排列方式</p>
<br /><br />
<p align="center"><strong><span >2.2.6 图像增强基础</span></strong></p>
<p><strong>图像增强 (image enhancement) </strong>图像在采集过程中不可避免的会受到传感器灵敏度、噪声干扰以及模数转化时量化问题等等因素影响而导致图像无法达到人眼的视觉效果，为了实现人眼观察或者机器自动分析的目的，对原始图像所做的改善行为，就被称作图像增强技术。为此图像增强技术虽然是改善图像质量的通用方法，但是它也同样带有针对性，它必须是针对某一特定的需要而采用的特定的算法来实现图像质量的改善。</p>
<p>由于图像增强技术现在还没有统一为一种算法，因此图像增强技术由于各种不同目的而产生了多种算法，把这些算法可以根据处理空间的不同分为基于空间域的图像增强算法和基于变换域的图像增强算法。基于空间域的图像增强算法又可以分为空域的变换增强算法、空域的滤波增强算法以及空域的彩色增强算法；基于变换域的图像增强算法可以分为频率域平滑增强算法、频率域的锐化增强算法以及频域彩色增强算法，由于彩色增强算法现在研究的不是很成熟，所以笔者在这里把空域算法和频域算法联合起来构成一块来学习。</p>
<p>增强图象中的有用信息，它可以是一个失真的过程，其目的是要增强视觉效果。将原来不清晰的图像变得清晰或强调某些感兴趣的特征，抑制不感兴趣的特征，使之改善图像质量、丰富信息量，加强图像判读和识别效果的图像处理方法。</p>
<p>图像增强按所用方法可分成频率域法和空间域法。前者把图像看成一种二维信号，对其进行基于二维傅里叶变换的信号增强。采用低通滤波（即只让低频信号通过）法，可去掉图中的噪声；采用高通滤波法，则可增强边缘等高频信号，使模糊的图片变得清晰。具有代表性的空间域算法有局部求平均值法和中值滤波（取局部邻域中的中间像素值）法等，它们可用于去除或减弱噪声。</p>
<p>图像增强的目的是改善图像的视觉效果，针对给定图像的应用场合，有目的地强调图像的整体或局部特性，扩大图像中不同物体特征之间的差别，满足某些特殊分析的需要。其方法是通过一定手段对原图像附加一些信息或变换数据，有选择地突出图像中感兴趣的特征或者抑制(掩盖)图像中某些不需要的特征，使图像与视觉响应特性相匹配。在图像增强过程中，不分析图像降质的原因，处理后的图像不一定逼近原始图像。图像增强技术根据增强处理过程所在的空间不同，可分为基于空域的算法和基于频域的算法两大类。基于空域的算法处理时直接对图像灰度级做运算基于频域的算法是在图像的某种变换域内对图像的变换系数值进行某种修正，是一种间接增强的算法。</p>
<p>基于空域的算法分为点运算算法和邻域去噪算法。点运算算法即灰度级校正、灰度变换和直方图修正等，目的或使图像成像均匀，或扩大图像动态范围，扩展对比度。邻域增强算法分为图像平滑和锐化两种。平滑一般用于消除图像噪声，但是也容易引起边缘的模糊。常用算法有均值滤波、中值滤波。锐化的目的在于突出物体的边缘轮廓，便于目标识别。常用算法有梯度法、算子、高通滤波、掩模匹配法、统计差值法等。</p> ]]></description>
      <link>http://software.intel.com/zh-cn/articles/book-Visual-Computing_image_basic_concept/</link>
      <pubDate>Wed, 08 Feb 2012 08:00:00 -0800</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/book-Visual-Computing_image_basic_concept/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/book-Visual-Computing_image_basic_concept/</guid>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
    </item>
    <item>
      <title>数字图像基础之数字图像概述</title>
      <description><![CDATA[ 
<p><strong><span >2.1 数字图像概述</span></strong></p>
<br /><br />
<p align="center"><strong><span >2.1.1 什么是数字图像</span></strong></p>
<p>我们常说的计算机（电脑）指的是数字计算机，数字计算机处理的信息都是“数字”信息，而现实物理世界中的信息基本都是“模拟”信息，“数字”信息和“模拟信息”的主要区别是信息的“离散性”和“连续性”。拿图像举例， 物理世界中的图像是连续的，图像中任何两点之间（不论这两个点之间如何接近）都含有颜色等信息，其信息的量是无限的，因此不可能在计算机中来表示物理世界中连续的图像。幸运的是，在现实生活中，人类肉眼的观察事物的能力是有限的，比如，当电影胶片以每秒24格画面匀速转动，一系列静态画面就会因视觉暂留作用而造成一种连续的视觉印象，产生逼真的动感；同样，人眼分辨图像细节的能力是有限的，如当空间平面上两个黑点相互靠拢到一定程度时，离开黑点一定距离的观察者就无法区分它们；当空间中足够近的两个点的颜色不同时，我们肉眼看到的是这两个颜色“叠加（光的合成原理）”起来的效果，因此可以将其看一个点，其颜色为合成后的颜色。根据人眼的视觉机理，我们将显示物理世界的图像按一定的密度进行采样，比如我们将物理图像按1mm*1mm的方格大小进行采样，每一个格子都有相应的颜色信息（可以用数字表示），这样用一个个“像素（格子）”信息组成的图像在人的肉眼看来和现实的物理图像是没有区别的。我们将计算机用这种用离散的、数值的方式表示的图像称为数字图像。</p>
<br /><br />
<p align="center"><strong><span >2.1.2 数字图像的获取与表示</span></strong></p>
<p><strong>成像原理</strong> 摄像机（Camera，摄像头、相机等）和眼睛的成像原理是类似的，在这里我们放在一起介绍。这两者的成像机制都是基于两个主要的组成部分：一组镜片和成像传感器。镜片会部分获取从物体发射出来的光线，将其聚焦到成像传感器（视网膜）上，成像传感器然后将光线视频信号，以电子（Camera）或神经（Eyes，Nerve）的方式。</p>
<br />
<p align="center"><img src="http://software.intel.com/file/41467" /></p>
<p align="center">图2.1 聚焦成像原理图</p>
<p>我们以图示的方式介绍棱镜的作用。如图所示，从滑冰者身上反射出的光线被棱镜聚焦到右边的屏幕上，形成一个倒立的像。聚焦的有着特定的含义，它意味着从滑冰者身上任何一点（如脚趾尖上的一个点）所反射的经过棱镜的光线通过棱镜折射后，仍在屏幕上相交于一点，而不会在屏幕上形成一个区域。</p>
<p>我们用图示的方式说明电子摄像机和人眼的组成结构（分别如图所示）。如前所述，两者在结构组成上时相似的，前端都有由一组棱镜组成，后端由成像传感器组成。连接两端的分别是空气和透明液体。两者的棱镜系统都有两个可调的参数：焦点（focus）和光圈（iris，眼睛对应于虹膜）。如果棱镜没有对焦，物体上的一点经过棱镜那部分的光线就会在屏幕上（成像传感器上）形成一个圆形区域，使得所成像趋于模糊。在照相机中，我们可以通过移动棱镜和成像传感器之间的距离使之聚焦。而人的眼睛包含两个棱镜，在眼球前方的棱镜称为角膜（cornea），在眼睛的内部还有一个可以调节的棱镜。角膜的主要起折射光线的作用，但是角膜的位置和形状是不变的。调焦是通过眼睛内部的棱镜实现的，内部棱镜是一个更加灵活的组织，它能够通过睫状体的肌肉的活动来使之变形，当肌肉收缩的时候，使得内部棱镜变得更加扁平，使得焦距变短。因此，通过这种肌肉的活动，达到调焦的目的。</p>
<table align="center">
<tbody>
<tr align="center">
<td><img src="http://software.intel.com/file/41468" /></td>
<td><img src="http://software.intel.com/file/41469" /></td>
</tr>
<tr align="center">
<td colspan="2">图2.2 成像原理</td>
</tr>
</tbody>
</table>
<p>在这两个成像系统中，光圈（iris，眼睛对应于虹膜）的作用是控制棱镜多大部分暴露在光线下，这样可以控制在呈现传感器上成像的亮度。虹膜是由非透明的肌肉组织形成的，通过这种肌肉组织的收缩，可以使瞳孔变大（摄入的光线更多），光圈的作用类似。</p>
<p>这些光学系统的参数常常以意想不到的方式在起作用，举例来说，考虑到光线的多少和光线传感器的灵敏度对所成像的清晰度的影响，我们通常通过调整光圈（虹膜）的大小和曝光时间来让合适量的光线折射到成像传感器（视网膜）上，如果光线的亮度太强，就可以减小光圈的半径，这样会导致更大的景深（景深的概念请参考附录二），更大的景深会使在一个较大的距离空间内的成像都比较清晰，同时，光线太强，可以允许曝光时间缩短，从而可以减少由于手的都通和物体的运动造成模糊的成像。光学系统是这些参数之间的完美平衡。</p>
<p><strong>数字化器 </strong>数字图像的获取主要是通过数字化器来实现的。常用的数字化器有扫描仪、数码相机和数码摄像机。数字化器必须能够将图像划分为若干小块（像素），能够度量每一像素的灰度或颜色并量化为整数，并能够将这些整数写入存储设备。数字化器基本上由下列部件组成。</p>
<ul >
<li>采样孔：保证单独观测特定的像素而不受其它部分的影响。</li>
<li>图像扫描机构：使采样孔按预先确定的方式在图像上移动。</li>
<li>光传感器：通过采样孔测量图像的每一个像素的亮度。</li>
<li>量化器：将传感器输出的连续量转化为整数值。</li>
<li>输出存储体：将像素灰度值存储起来。它可以是固态存储器，或磁盘等。 </li>
</ul>
<p><strong>电荷耦合器件（Charge coupled device，CCD） </strong>很多数字相机采用电荷耦合器件（CCD）作为其感光元器件（光传感器）。我们可以把CCD想象成一个没有盖子的芯片，上面整齐地排列着很多小的感光单元，光线中的光子撞击每个单元后，在这些单元中会产生电子（光电效应），而且光子的数目与电子的数目互成比例。曝光结束后，这些电子被从 CCD 芯片中读出，并由相机内部的微处理器进行初步处理。此时由该微处理器输出的就是一幅数字图像了。由于CCD光敏元可做得很小(约10um)，所以它的图象分辨率很高。</p>
<p>CCD器件是一个集成电路，CCD的核心是一个很薄的硅片，通常为1cm2大小，图2.3所示为其断面图，我们以三相CCD结构为例，简单的三相CCD结构如图所示，其上方覆盖了一层很薄的绝缘体（insulator）和一排电极（electrode），相隔两个的所有电极都连在一起(如1、4、7……,2、5、8……,3、6、9……)，由三个相位相差1200时钟脉冲φ1、φ2、φ3来驱动，故称三相CCD。图a为断面图；图(b)为俯视图；图(d)给出了三相时钟之间的变化。在时刻t1，第一相时钟φ1处于高电压，φ2、φ3处于低压。这时第一组电极1、4、7……下面形成深势阱（由于正向电压排斥正电荷，所以形成一个空穴，称为势阱），CCD的每一个势阱都是很好的光传感器，因为当一个光子撞击硅片的时候，会将其能量转化为两个带电粒子，一个为正电荷，一个为负电荷，根据同性相斥，异性相吸的原理，在这些势阱中可以贮存负电荷电荷形成“电荷包”，如图(c)所示。在t2时刻φ1电压线性减少，φ2为高电压，在第一组电极下的势阱变浅，而第二组(2、5、8……)电极下形成深势阱，信息电荷从第一组电极下面向第二组转移，直到t3时刻，φ2为高压，φ1、φ3为低压，信息电荷全部转移到第二组电极下面。重复上述类似过程，信息电荷可从φ2转移到φ3，然后从φ3转移到φ1电极下的势阱中。当三相时钟电压循环时，电荷包会向右转移一级，依次类推，信号电荷一直由电极1、2、3……N向右移，直到输出。</p>
<br />
<p align="center"><img src="http://software.intel.com/file/41470" /></p>
<p align="center">图2.3 CCD原理图</p>
<p>但在这一过程中，光子的波长并没有被转换为任何形式的电信号，换言之，CCD 裸芯片实际上都没有把色彩信息转换为任何形式的电信号。那么采用 CCD 作为感光元件的彩色数字相机是如何生产彩色图像的？在这种情况下，如果我们希望使用 CCD 作为相机感光芯片，并输出红、绿、蓝三色分量，就可以采用一个分光棱镜和三个 CCD。棱镜将光线中的红、绿、蓝三个基本色分开，使其分别投射在一个 CCD 上。这样以来，每个 CCD 就只对一种基本色分量感光。这种解决方案在实际应用中的效果非常好，但它的最大缺点就在于，采用3个 CCD 加棱镜的搭配必然导致价格昂贵。因此科研人员在很多年前就开始研发只使用一个 CCD 芯片也能输出各种彩色分量的相机，其实现机理请参考其他资料。</p>
<br /><br />
<p align="center"><strong><span >2.1.3 数字图像的特点</span></strong></p>
<p>数字图像具有一些显著的特点，首先表现为数字图像所占的数据空间大。一个普通的遥感图像的信息量大概在几兆左右，在雷达监测领域，一个小时所积累的雷达数据一般占有几G的硬盘空间。因此，数字图像处理的难度大，成本也会较高。这就对图像压缩提出了必须（很高）的要求。</p> ]]></description>
      <link>http://software.intel.com/zh-cn/articles/book-Visual-Computing_digital_image_overview/</link>
      <pubDate>Tue, 07 Feb 2012 08:00:00 -0800</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/book-Visual-Computing_digital_image_overview/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/book-Visual-Computing_digital_image_overview/</guid>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
    </item>
    <item>
      <title>视觉计算软件开发基础之软件开发与优化基础</title>
      <description><![CDATA[ 
<p><strong><font >1.2  软件开发与优化基础</font></strong></p>
<br /><br />
<p align="center"><strong><font >1.2.1	C语言概述</font></strong></p>
<p>计算机的发展离不开软件的发展，在软件的发展历史但中，高级语言的出现无疑是一个里程碑，在高级语言出现之前，科学工作者主要通过机器语言（机器执行时的0，1）或汇编语言来操纵计算机，由于这些语言非常底层，计算机容易理解这些语言，但是对人来说非常抽象、不直观、难度大、效率等，因此一种更高级的语言是计算机软件发展的必然需求，高级语言能摆脱低级语言的束缚，使得人们只用关注应用的逻辑，而不用关注这些逻辑在计算机上具体是怎样通过0，1来实现的（比如我们要实现一个加法功能，我们可以很容易用高级语言的表示式来实现，而不用关系加法在处理器中怎样通过寄存器实现的）</p>
<p>Fortran是第一个电脑高级语言，它是1954年美国的IBM的IT成果。Ｃ语言是在70年代初问世的。一九七八年由美国电话电报公司(AT&T)贝尔实验室正式发表了Ｃ语言。早期的C语言主要是用于UNIX系统。由于Ｃ语言的强大功能和各方面的优点逐渐为人们认识，到了八十年代，C开始进入其它操作系统，并很快在各类大、中、小和微型计算机上得到了广泛的使用。成为当代最优秀的程序设计语言之一。</p>
<p>Ｃ语言是一种结构化语言。它层次清晰，便于按模块化方式组织程序，易于调试和维护。Ｃ语言的表现能力和处理能力极强。它不仅具有丰富的运算符和数据类型，便于实现各类复杂的数据结构。它还可以直接访问内存的物理地址，进行位(bit)一级的操作。由于Ｃ语言实现了对硬件的编程操作，因此Ｃ语言集高级语言和低级语言的功能于一体。既可用于系统软件的开发，也适合于应用软件的开发。此外，Ｃ语言还具有效率高，可移植性强等特点。因此广泛地移植到了各类各型计算机上，从而形成了多种版本的Ｃ语言。</p>
<p>C语言的数据类型包括基本数据类型（整型、实型等）、构造数据类型（数组类型、结构类型、联合类型）、指针类型（其值用来表示某个量在内存储器中的地址）。</p>
<p>C语言的运算符有算术运算符、关系运算符、位操作运算符、条件运算符、指针运算符等。</p>
<p>C语言的语句分为表达式语句、函数调用语句、控制语句（条件判断语句、循环语句、转向语句）、复合语句等。</p>
<br /><br />
<p align="center"><strong><font >1.2.2	软件开发基本步骤</font></strong></p>
<p>在20世纪60，70年代，出现了“软件危机”。很多的软件项目开发时间大大超出了规划的时间表。一些项目导致了财产的流失，甚至某些软件导致了人员伤亡。软件开发人员发现随着软件产品规模的扩大，软件开发的难度越来越大，维护、更新起来也越来越困难。为了解决“软件危机”时代软件开发的这种突出矛盾，产业界和研究界借鉴传统的工业工程管理的方法来管理软件开发整个过程的思想得到了肯定和发展，从而有效地提高了大型软件开发的可管理性。较好地解决了这次“软件危机”。这一套思想和方法学称为“软件工程”。</p>
<p>软件工程的思想比较直观、易懂。同任何事物一样，一个软件产品或软件系统也要经历孕育、诞生、成长、成熟、衰亡等阶段，一般称为软件生存周期（软件生命周期）。把整个软件生存周期划分为若干阶段，使得每个阶段有明确的任务，通过一系列的有效的控制办法和措施，使得规模大，结构复杂和管理复杂的软件开发变的容易控制和管理。通常，软件生存周期包括可行性分析与开发计划、需求分析、设计（概要设计和详细设计）、编码、测试、维护等活动，可以将这些活动以适当的方式分配到不同的阶段去完成。我们简单的阐述一下软件生命周期六个阶段，我们将其称为软件开发的基本步骤。</p>
<ol>
<li>问题的定义及规划</li>
<p>此阶段是软件开发方与需求方共同讨论，主要确定软件的开发目标及其可行性。</p>
<li>需求分析</li>
<p>在确定软件开发可行的情况下，对软件需要实现的各个功能进行详细分析。需求分析阶段是一个很重要的阶段，这一阶段做得好，将为整个软件开发项目的成功打下良好的基础。"唯一不变的是变化本身。"，需求也是在整个软件开发过程中不断变化和深入的，因此我们必须制定需求变更计划来应付这种变化，以保护整个项目的顺利进行。</p>
<li>软件设计</li>
<p>此阶段主要根据需求分析的结果，对整个软件系统进行设计，如系统框架设计，数据库设计等等。软件设计一般分为总体设计和详细设计。好的软件设计将为软件程序编写打下良好的基础。</p>
<li>程序编码</li>
<p>此阶段是将软件设计的结果转换成计算机可运行的程序代码。在程序编码中必须要制定统一，符合标准的编写规范。以保证程序的可读性，易维护性，提高程序的运行效率。</p>
<li>软件测试</li>
<p>在软件设计完成后要经过严密的测试，以发现软件在整个设计过程中存在的问题并加以纠正。整个测试过程分单元测试、组装测试以及系统测试三个阶段进行。测试的方法主要有白盒测试和黑盒测试两种。在测试过程中需要建立详细的测试计划并严格按照测试计划进行测试，以减少测试的随意性。</p>
<li>运行维护</li>
<p>软件维护是软件生命周期中持续时间最长的阶段。在软件开发完成并投入使用后，由于多方面的原因，软件不能继续适应用户的要求。要延续软件的使用寿命，就必须对软件进行维护。软件的维护包括纠错性维护和改进性维护两个方面。【百度百科】</p>
</ol>
<br /><br />
<p align="center"><strong><font >1.2.3	软件测试与优化技术</font></strong></p>
<p><strong>软件测试</strong>  在软件开发基本步骤的每一个过程中，都需要通过适当的方式加以验证，确保整个过程的安全、有效实施。因此，这里需要说明的是，软件测试的对象不仅仅是程序测试，软件测试应该包括整个软件开发期间各个阶段所产生的文档，如需求规格说明、概要设计文档、详细设计文档等，当然软件测试的主要对象还是源程序。关于软件测试有一套完整的方法学和相关技术，各软件公司也都有自己的测试文档和规范。下面主要对软件开发过程中源程序的测试做详细的说明。</p>
<p>软件开发工程师在代码实现的时候，难免会出现一些疏漏和错误，这些疏漏和错误有些是没有考虑周全，有些是不经意间的一些输入错误。这些错误如果在软件发布之前没有得到改正，将会出现意想不到的、甚至是非常严重的损失。因此在软件发布之前，严格的测试整个软件将是一个必不可少而且非常重要的过程，在软件的实现和测试阶段，开发工程师和测试工程师都要对软件进行测试。其分工虽有不同，但是测试的目的都是为了确保软件的正确性和高效性。正确性保证软件在使用的过程中不会出现计算上的错误，并且保证无运行时错误而导致程序非法退出等非常致命的错误；高效性是关于软件运行效率的测试，测试工程师会根据软件的性能要求对软件的运行效率进行测试，用户通常会没有耐心运行速度非常慢的程序，这样会降低用户对软件的体验（User Experience），从而降低软件的可用性（Usability）。</p>
<p>软件测试工程师的主要工作是利用测试工具按照测试方案和流程对产品进行功能和性能测试，甚至根据需要编写不同的测试工具，设计和维护测试系统，对测试方案可能出现的问题进行分析和评估。执行测试用例后，需要跟踪故障，以确保开发的产品适合需求。</p>
<p>软件测试的方式可以分为静态确认和动态确认两种方式。静态确认：不在计算机上实际执行程序，通过人工或程序分析来证明软件的正确性；动态确认：通过执行程序做分析，测试程序的动态行为，以证实软件是否存在问题。大部分的测试主要是动态确认的方式。</p>
<p>在软件测试领域，有两个非常有名和通用的名词：“白盒测试”和“黑盒测试”。</p>
<p>白盒测试也称结构测试或逻辑驱动式测试，它是按照程序内部的结构测试程序，通过测试来检测产品内部动作是否按照设计规格说明书的规定正常进行，检验程序中的每条通路是否都能按预定要求正确工作。这一方法是把测试对象看作一个打开的盒子（White Box），测试人员依据程序内部逻辑结构相关信息，设计或选择测试用例，对程序所有逻辑路径进行测试，通过检查程序在各种条件下的运行状态，确定实际的状态是否与预期的状态一致。</p>
<p>黑盒测试也称功能测试，它是通过测试来检测每个功能是否都能正常使用。在测试中，把程序看作一个不能打开的黑盒子，测试人员看不见程序的内部逻辑结构（Black Box）。因此，在完全不考虑程序内部结构和内部特性的情况下，在程序接口进行测试，它只检查程序功能是否按照需求规格说明书的规定正常使用，程序是否能适当地接收输入数据而产生正确的输出信息。黑盒测试着眼于程序外部结构，不考虑内部逻辑结构，主要针对软件界面和软件功能进行测试。黑盒测试是以用户的角度，从输入数据与输出数据的对应关系出发进行测试的。很明显，如果外部特性本身有问题或规格说明的规定有误，用黑盒测试方法是发现不了的。黑盒测试法注重于测试软件的功能需求，主要试图发现下列几类错误。1：功能不正确或遗漏； 2：界面错误； 3：数据库访问错误； 4：性能错误；5：初始化和终止错误等。</p>
<p><strong>软件优化技术</strong>  优化的思想自古有之，大家都熟悉的一个例子是著名的数学家高斯计算从1到100之和的例子，从这个例子中我们可以体会不同的方法对于计算速度的重要影响。在计算机领域，优化的思想贯穿于各个应用领域。对于图像处理领域，快速傅里叶变换被公认为是二十世纪的十大最著名的算法之一，其主要的思想是采用了优化的思想，大大提高了傅里叶变换的运行效率，可以让机器比较快地执行数据量比较大的二维傅里叶变换（图像处理的典型应用），使得傅里叶变换更加有意义。</p>
<p>软件优化技术是在保证软件正确运行的状态下，进一步提高程序的效率，使得用户能够享受采用优化技术改进的软件的使用体验，同时，对于很多应用领域（如数字信号处理），这些领域的数据量的规模非常大，同时要求一定的实时性，要求在一定时间内需要完成处理任务（如前一段时间，通过雷达传送的关于四川的堰塞湖的数据，一个小时就有7、8G的数据，需要计算机在较快的时间能够处理这些数据，为堰塞湖的安全做好决策支持）。如果没有高效处理这些数据的程序，其计算也将不能在一定时间完成，将使得这些数据变得没有意义。</p>
<p>在软件优化领域，算法的优化是个很广泛的概念，涉及不同的领域，各种各样的优化算法应运而生，有很多算法需要很深的数学领域的知识（如最优化方法是关于算法优化的一系列的方法）。这些领域也一直是应用和研究的热点。随着计算机硬件技术的发展，多核处理器逐渐得到发展，现有的大部分PC都是双核处理器（双CPU）。4核和8核的处理器也将会普遍流行。因此，如何能高效利用这些多核计算资源，将任务或者将数据分配到多个处理器中同时并行执行，从而整体上缩小程序的执行时间，提高程序的运行效率。</p>
<p>随着多核技术的发展，在软件开发领域，并行算法程序必将趋于流行，我们应该从一开始编程的时候就应该树立程序并行执行的思想。现在很多高校的本科都开设了并行程序设计的课程。很多的应用领域都成功地运用了并行程序算法来提高程序运行的性能。但是，程序本身不会自动从串行执行转化为并行执行。将串行程序转化为并行程序（程序的并行化）需要程序员对程序进行精心的设计，设计的过程需要考虑很多的因素，比如采用多大的并行的粒度效果最好，采用什么样的并行策略：是将多个任务进行并行，还是将数据进行分割（但处理数据的任务是相同的）？好的并行算法会大大提高程序的性能，比如现在已经开发出快速傅里叶变换的并行程序，进一步提高了变换的处理速度。在软件开发过程中，一些辅助软件的使用会有效地帮助程序员来并行化程序。为了辅助程序员进行并行程序设计，英特尔提供了全方位的技术支持， 英特尔 的parallel studio是一个包含辅助并行软件开发的工具包，这些辅助软件能够有效地帮助程序员分析串行程序，辅助程序员找出可以并行的代码段，以及辅助检查并行化程序中的效能和错误等。我们在下一节会详细介绍。</p> ]]></description>
      <link>http://software.intel.com/zh-cn/articles/book-Visual-Computing_software_development_and_optimization/</link>
      <pubDate>Wed, 04 Jan 2012 08:00:00 -0800</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/book-Visual-Computing_software_development_and_optimization/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/book-Visual-Computing_software_development_and_optimization/</guid>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
    </item>
    <item>
      <title>视觉计算软件开发基础之视觉计算软件开发平台</title>
      <description><![CDATA[ 
<p><strong><span >1.3 视觉计算软件开发平台</span></strong></p>
<br /><br />
<p align="center"><strong><span >1.3.1 可视化集成开发环境（IDE）</span></strong></p>
<p>在程序设计的早期阶段，程序员需要借助不同的软件来编写程序，程序员在编程的过程中首先需要用文本编辑软件进行，然后通过编译器软件进行编译，用调试器软件进行调试。因此，在软件过程中，程序员往往需要在不同的软件间来回切换。比如当程序员发现程序执行的结果有错误的时候，他会通过调试器来跟踪程序执行的过程，发现出错的地方后，需要返回文本编辑器对源程序进行修改；修改后的源程序需要再次编译形成可执行文件；如果发现新的可执行程序还出现错误，程序员需要再次进行调试。因此，不同的软件间切换的过程会贯穿软件开发过程中代码实现的整个环节。这无疑给程序员带来了诸多不便，严重影响了软件开发的效率。</p>
<p>因此，如果有一个工具，能将软件开发过程中的代码编辑、编译、调试等功能集成在一个软件中，程序员不需要在不同的软件间来切换，代码的编辑、编译、调试的功能可以无缝的衔接在一起。比如，在这种软件工具中，程序员通过调试发现代码有错的时候，他能够马上对错误的代码进行编辑修改、再编译、调试。相比早期的程序开发而言，程序员会节省大量的时间，使得程序员将更多的经历集中在程序代码的逻辑结构上而不会分散太多的注意力在软件工具的来回切换和使用上。</p>
<p>集成开发环境就是具有上述特点的一个软件工具。集成开发环境（Integrated Development Environment，简称 IDE，也有人称为Integration Design Environment、Integration Debugging Environment）是一种辅助程序开发人员开发软件的应用软件。它将代码编辑、编译、调试的过程集成在一个完整的软件工具中，使得开发过程变得简单明了。大大的提高了软件开发工作人员的工作效率，使得编程的工作变得更加轻松、愉悦。</p>
<p>IDE通常包括编程语言编辑器、编译器／解释器、通常还包括调试器。有时还会包含版本控制系统和一些可以设计图形用户界面的工具。虽然目前有一些IDE支持多种编程语言（例如Eclipse*、NetBeans*、Microsoft Visual Studio*）。</p>
<p>Microsoft Visual Studio是微软公司推出的集成开发环境，是目前最流行的 Windows 平台应用程序开发环境。目前已经开发到 9.0 版本，也就是 Visual Studio 2008。早期的Visual Studio版本中主要有Visual Basic和Visual C++两种程序开发语言，随后，微软引入了建立在 .NET 框架上的托管代码机制以及一门新的面向对象语言 C#（最新的C#语言的版本是3.5），原先的Visual Basic也进化成完全支持面向对象的编程语言Visual Basic .NET。</p>
<p>在Visual Studio的开发环境中，我们可以很方便的建立工程、编辑和组织代码、通过图形用户界面设置编译选项、调试等。Visual Studio将这些功能集成在一起，程序员可以通过图形用户界面很方便的设置相应的功能，特别熟练的程序员还可以通过很多的快捷键来完成任务，使得程序开发的工作方便、快捷。Visual Studio还提供了很有特色的功能，比如智能代码预测功能（Intel® liSense），程序员在代码编辑的时候仅仅只需要输入少量字符，系统会提供较好的预测，帮助自动键入相应的代码，可以减少程序员编辑代码的时间和输入错误。</p>
<p>本书的所有代码示例，都是通过Visual Studio 2008来开发完成的。</p>
<br /><br />
<p align="center"><strong><span >1.3.2 控制台应用程序开发</span></strong></p>
<p>现有的软件开发中，很多的应用都是需要开发图形用户界面（GUI）的，在早期，开发图形用户界面是非常冗繁的工作，窗口的大小、位置、菜单等的摆放等都需要程序员用代码来规定和实现。为了使程序员摆脱这些千篇一律的工作，加快工作效率，很多的集成开发环境提供了可视化编程环境。比如，在Visual Studio中，程序员可以通过界面编辑器拖放相应的界面元素（如按钮，菜单、文本框等）到窗口上，很快的设计出界面的各种布局、通过所见即所得的方式（what you see is what you get，程序运行的界面效果等同于设计时的界面），很容易使得界面的设计达到理想的效果。</p>
<p>相对而言，控制台应用程序比较简单，一般没有独立的窗口，在命令行运行。控制台程序的输入输出通过标准IO进行，而不像界面程序可以通过鼠标点击进行操作。一般后台运行（不需要界面显示）的程序可作为控制台应用程序。因此控制台应用程序无需使用任何图形用户界面即可读取标准输入和输出 (I/O) 中的数据并向其写入数据。</p>
<p>开发底层,游戏等（包括后台程序）的时候通常用到控制台程序来编写，一般在学校教学时，老师们初期讲语法，流程时也用到控制台应用程序。</p>
<br /><br />
<p align="center"><strong><span >1.3.3 Intel® C++编译器</span></strong></p>
<p>在计算机技术发展的早期，控制计算机所用的机器所能够处理的机器语言（0，1代码）。虽然计算机能够很好的处理机器语言，但是机器语言对与计算机工程师或科研工作者来说，太过抽象，不容易理解，且编写起来很困难。因此，计算机的先驱们发明了高级程序语言。高级程序语言是方便人们编辑、阅读和维护的程序语言，它摆脱了0，1机器语言的束缚，使得程序的代码更加注重于实际应用的逻辑，方便了程序设计的过程。但是，高级程序语言又并不是计算机能够识别并能执行的语言。因此，必须有一种程序，它能起到从高级语言翻译到计算机所能识别的低级语言的作用，我们将这样的程序称为编译程序，将实现这样程序的软件通常称为编译器。</p>
<p>高级语言有很多种，最早的高级语言是Fortran语言，其主要的目的是用来科学计算，后来又出现了C语言。这些语言都是面向结构的程序语言。在国内，已故的国防科技大学中科院院士陈火旺教授是编译原理的先驱，他于上世纪70年代独立自主的实现了国内的首个Fortran语言的编译器。C++是面向对象的高级程序语言。它是C语言的超集（兼容C语言的所有功能）。市场上有很多公司各自推出的C++的编译器，主要有Microsoft 的C++编译器，Borland公司的C++编译器和英特尔公司的C++ 编译器。编译器的不同在于其支持不同的特色功能和生成的目标代码的质量上。</p>
<p>英特尔编译器可提升软件的性能。它能够针对不同CPU型号来生成更有效率的代码，并且通过自动并行处理机制来优化代码，帮助程序员以较快的速度来运行软件。同时，英特尔编译器与其他工具保持兼容，可以集成到广泛使用的开发环境，比如，英特尔编译器能够方便的集成到Visual Studio集成开发环境中。</p>
<br /><br />
<p align="center"><strong><span >1.3.4 Intel® Debugger调试工具</span></strong></p>
<p>在程序编写的过程中，错误是在所难免的。我们将程序的错误分为语法错误和语义错误两大类，语法错误通常是指用户输入错了关键词和变量名等，使得编译器不能正确解释程序员的代码，因此不能生成目标代码。编译器都能够指出程序员的语法错误出在什么地方，因此程序员很容易定位并能够修改语法错误。语义错误是更难修改的一类错误（俗称Bug），很多情况下是因为程序员在代码输入的时候不小心使得代码出现逻辑错误（如代码“a==b” 错误地写成了“a=b”），这类错误在代码进行编译的时候是不能被发现的，这样的程序能够执行，只是在执行的时候并不是按照程序员本来的意图来执行，结果也自然会出现错误，甚至在某些状况下会出现严重的损失（导致程序非法退出等）。因此，这类错误的危险性更大。</p>
<p>如果程序员能够跟踪代码的执行过程，从而发现并修改程序执行中出现的语义错误（俗称Debug）。这将是一个非常关键的功能，编译器工具Debugger（调试器）提供了此类功能，程序员可以通过调试器一步一步跟踪代码的执行过程，或者设置断点（程序会在断点处停留下来让程序员观察程序执行的状态，如一些变量值等）来跟踪程序的运行，从而最终定位并修改程序中出现的语义错误。</p>
<p>在安装英特尔的编译器时可以选择是否安装Intel® Debugger。</p>
<br /><br />
<p align="center"><strong><span >1.3.5 Intel® VTune性能分析器</span></strong></p>
<p>程序员们应该非常清楚，在很多场合，仅仅写出能够正确处理的程序时不够的，很多场合下，程序的性能非常关键，特别是在大数据量处理的环境下，好的算法程序有时候在时间上会有几个数量级的提高。但是程序员写程序的过程是一个递进的过程，开始写出的程序其性能并不是最优的。因此，如果有一个工具能够发现程序执行的过程中的瓶颈（比如找到执行最长时间的函数），并且对整个程序的运行过程进行分析，用图形化的结果显示出来，将对程序员是一个非常大的帮助。</p>
<p>英特尔公司提供的VTune性能分析器是一个强大的性能分析和优化工具，它能确定你的程序的hotspot（执行最长时间的函数），帮助你找到导致性能不理想的原因，从而让你能据此对程序进行优化。该工具支持不同的操作系统，在Windows系统下，最新的有Intel® VTune Performance Analyzer 9.1版本。该版本已经集成到Visual Studio集成开发环境中，使用图形界面，支持英特尔最新的四核处理器。能够对程序库、驱动程序和应用程序进行性能分析。Intel® VTune 不依赖于程序语言和特定的编译器，能够对C，C++，Fortran，以及C#等编写的程序进行分析，这些程序不需要重新编译，而且分析的过程只需要极低的系统开销，便可以确定性能瓶颈。同时Intel® VTune将英特尔® 线程档案器（Intel® Thread Profiler）也包含在内，线程档案器可以帮助您调试多线程代码，从而可以在当今的多核处理器上获得最佳性能。VTune只是一个工具，它只会给出一堆数据，要靠程序员从这些数据中分析代码中哪些是程序的瓶颈，哪些是可以大大优化的，而哪些是虽然很占时间但是没有什么优化余地的。</p>
<br /><br />
<p align="center"><strong><span >1.3.6 Intel® Parallel Studio 并行工作室</span></strong></p>
<p>英特尔在提供了C++的编译器、调试器和性能分析工具VTune外，近期又推出了新的软件工具包Intel® Parallel Studio。Intel® Parallel Studio是一个针对Microsoft Visual Studio C/C++开发者的综合并行开发套件，由Intel® Parallel Composer, Intel® Parallel Advisor、 Intel® Parallel Inspector和Intel® Parallel Amplifier构成，使得基于Windows的开发人员能够更加简便、快捷地创建、调试和优化多核应用软件。</p>
<p align="center"><img src="http://software.intel.com/file/40868" /></p>
<p align="center">图1.5 Intel® Parallel Studio 软件套件组成</p>
<p><strong>Intel® Parallel Composer</strong> Intel® Parallel Composer为并行化编程提供了广泛的选择。包括编译器、库和并行化调试器。无论是串行应用软件还是并行应用软件，Intel® Parallel Composer都可以简化和加速Microsoft Visual Studio C/C++ 开发人员在多线程的工作。</p>
<p><strong>Intel® Parallel Advisor</strong> Parallel Advisor可以告诉开发者哪些顺序代码可以并行执行。但Parallel Advisor并不是自动生成并行代码的灵丹妙药，它只是帮助开发者对顺序程序进行分析，从而帮助开发者决定在哪里引入并行机制，而且可以检查出将顺序代码转化为并行代码时发生的数据冲突。</p>
<p><strong>Intel® Parallel Inspector</strong> Intel® Parallel Inspector为Microsoft Visual Studio C/C++ 开发人员提供了最简单的检查多线程程序错误的工具。和其它错误检查工具不同，该产品不仅速度最快，选择最多，而且可以精确找到潜在的多线程编程问题和内存错误。</p>
<p><strong>Intel® Parallel Amplifier</strong> 无须了解处理器的架构和内置编码，Intel® Parallel Amplifier可以快速找到多核性能瓶颈，并为优化性能，充分利用每一个处理器的功能。</p>
<br /><br />
<p align="center"><strong><span >1.3.7 Intel® IPP</span></strong></p>
<p>软件开发库（SDK，Software Development Kit） 软件开发如果没有库函数的支持，其成本将是不可想象的。以Windows系统应用开发为例，早期，如果程序员想开发windows应用程序，他可以调用Windows API（Application Programming Interface,应用程序编程接口，是一些预先定义的函数，目的是提供应用程序与开发人员来调用一些系统的功能，而又无需访问源码，或理解内部工作机制的细节），熟悉Windows API的程序员会发现，用Windows API来写应用程序的时候，编程过于复杂，需要将很多精力花费在怎样建立窗口，怎样处理消息等一系列高重复性和复杂度的工作上，程序员的工作效率较低，而且分散了程序员编程的注意力，使得他们不得不将很多的经历花在这些琐碎的细节上（API函数实在太多了，而且名称很乱，从零创建一个窗口动辄就是上百行的代码。）。为了解决这个问题，微软实现了MFC（软软基础类库，Microsoft Foundation Classes)，MFC将Windows API同C++相结合，对Windows API进行了封装，大大简化了程序员的工作。STL（Standard Template Library，标准模板库）也是一个开发库，它是一个标准的C++开发包，使得程序员更容易开发标准的C++应用程序。</p>
<p>面向特定领域的开发库也有很多，大家都熟悉，在标准C中，有一系列的数学库函数，这些函数的声明放包含在“math.h”头文件中，市场上的库函数还有很多。我们也可以针对自己的行业需求编写自己的库函数，加快行业应用软件的开发。</p>
<p align="center"><img src="http://software.intel.com/file/40869" /></p>
<p align="center">图1.6 Intel® IPP的应用领域</p>
<p><strong>Intel® IPP</strong>（英特尔® 集成性能元件）是一个面向多个应用领域的开发库，它支持多核CPU，是一个高度优化的函数集合（包括并行优化处理、特定处理器结构的优化等优化处理技术），能够处理包括多媒体处理（语音处理、图像处理、视频处理等）、数据处理、通信等应用。Intel® IPP提供了几千个优化的函数，这些函数涵盖多个领域的通用算法（如上图所示），这些领域包括：图像和视频、通信和信号处理、数据处理等。在Intel® Parallel Studio一节可以看出，Intel® IPP已经集成到Intel® Parallel Studio工具套件中。Intel® IPP库的目录结构如表1.1所示。</p>
<p><strong>Intel® IPP的链接方式 </strong></p>
<p>Intel® IPP由三种函数库组成 ：</p>
<ol >
<li>Dynamic，包括对各种处理器的优化代码动态库，如ipps.lib，ippst7.dll；</li>
<li>Static Emerged， 包括对各种处理器的优化代码静态库，如ippsemerged.lib；</li>
<li>Static Merged， 包括对指定处理器的优化代码静态库 。</li>
</ol>
<p>对于不同的需求，这些函数库提供以下四种链接模式：</p>
<ol>
<li>动态链接（Dynamic linkage），简便易用，但可执行文件和库文件总量大； </li>
<li>定制的动态链接（Custom dynamic linkage），抽取指定函数的优化代码组成新动态库，减少可执行文件和库文件大小；</li>
<p align="center"><strong>表1.1 Intel® IPP库的目录结构图</strong></p>
<p align="center"><img src="http://software.intel.com/file/40870" /></p>
<br />
<p align="center"><strong>表1.2 IPP图像处理函数分类及在本书中的体现</strong></p>
<table align="center" cellpadding="0" cellspacing="0" border="1">
<tbody>
<tr>
<td width="179" valign="top">
<p align="center"><strong>函数分类</strong><strong> </strong></p>
</td>
<td width="156" valign="top">
<p align="center"><strong>主要功能作用</strong><strong> </strong></p>
</td>
<td width="189" valign="top">
<p align="center"><strong>典型函数名</strong><strong> </strong></p>
</td>
<td width="127" valign="top">
<p align="center"><strong>在本书的体现</strong><strong> </strong></p>
</td>
</tr>
<tr>
<td width="179" valign="top">
<p>Image Data Exchange and Initialization Functions</p>
</td>
<td width="156" valign="top">
<p>图像数据的分配、初始化、赋值、拷贝、转换</p>
</td>
<td width="189" valign="top">
<p>ippiMalloc<br />ippiCopy ippiConvert</p>
</td>
<td width="127" valign="top">
<p>2.5.2小节 <br />2.6.1小节</p>
</td>
</tr>
<tr>
<td width="179" valign="top">
<p>Image Arithmetic and<br />Logical Operations</p>
</td>
<td width="156" valign="top">
<p>图像的算术和逻辑运算</p>
</td>
<td width="189" valign="top">
<p>IppiAnd<br />IppiAdd</p>
</td>
<td width="127" valign="top">
<p>2.5.3小节 <br />5.5.1小节</p>
</td>
</tr>
<tr>
<td width="179" valign="top">
<p>Image Color Conversion</p>
</td>
<td width="156" valign="top">
<p>颜色空间转换</p>
</td>
<td width="189" valign="top">
<p>ippiRGBToYCbCr<br />ippiRGBToGray</p>
</td>
<td width="127" valign="top">
<p>2.2.4小节、2.2.5小节、2.6.2小节、3.4.2小节、4.2.2小节、4.3.3小节</p>
</td>
</tr>
<tr>
<td width="179" valign="top">
<p>Threshold and Compare<br />Operations</p>
</td>
<td width="156" valign="top">
<p>阈值和比较操作</p>
</td>
<td width="189" valign="top">
<p>ippiThreshold_GT<br />ippiCompareC</p>
</td>
<td width="127" valign="top">
<p>2.5.3小节、5.5.1小节</p>
</td>
</tr>
<tr>
<td width="179" valign="top">
<p>Filtering Functions</p>
</td>
<td width="156" valign="top">
<p>空间滤波器、提供各种空间滤波算子（平滑、锐化）的实现</p>
</td>
<td width="189" valign="top">
<p>ippiFilter<br />ippiFilterGauss<br />ippiFilterSobelCross</p>
</td>
<td width="127" valign="top">
<p>5.1节、5.2节 <br />5.4节、5.5节</p>
</td>
</tr>
<tr>
<td width="179" valign="top">
<p>Image Linear Transforms</p>
</td>
<td width="156" valign="top">
<p>图像线性变换，包括离散傅里叶变换（DFT）、快速傅里叶变换（FFT）和离散余弦变换（DCT）等</p>
</td>
<td width="189" valign="top">
<p>ippiFFTFwd<br />ippiDFTFwd<br />ippiDCTFwd</p>
</td>
<td width="127" valign="top">
<p>2.3节、3.4节、3.5.1 <br />3.5.3小节、5.3、5.5.2小节</p>
</td>
</tr>
<tr>
<td width="179" valign="top">
<p>Image Statistics Functions</p>
</td>
<td width="156" valign="top">
<p>图像统计函数</p>
</td>
<td width="189" valign="top">
<p>ippiHistogramEven</p>
</td>
<td width="127" valign="top">
<p>4.1、4.3.1</p>
</td>
</tr>
<tr>
<td width="179" valign="top">
<p>Image Geometry <br />Transforms</p>
</td>
<td width="156" valign="top">
<p>图像几何变换</p>
</td>
<td width="189" valign="top">
<p>ippiResize<br />ippiRotate<br />ippiWarpAffine</p>
</td>
<td width="127" valign="top">
<p>第六章</p>
</td>
</tr>
<tr>
<td width="179" valign="top">
<p>Image Compression<br />Functions</p>
</td>
<td width="156" valign="top">
<p>图像压缩功能（如JPEG）</p>
</td>
<td width="189" valign="top">
<p>ippiDCTQuantFwd8x8<br />ippiEncodeHuffman8x8<br />ippiRGBToYCbCr422LS_MCU</p>
</td>
<td width="127" valign="top">
<p>3.4、3.5</p>
</td>
</tr>
</tbody>
</table>
<br />
<li>支持单种处理器的静态链接（Single processor static linkage），可执行文件最小，只含适用于指定处理器的优化代码；</li>
<li>支持多种处理器的静态链接（Static linkage with dispatching），可执行文件较小，只含适用于所有处理器的优化代码。</li>
</ol>
<p><strong>使用动态链接方式引用</strong><strong>IPP</strong><strong>库时所需设置的环境变量</strong>  在Microsoft Visual Studio中，要用Intel® IPP库进行编程，首先需要安装IPP，Intel® IPP已经集成到Intel® C++ Complier中，因此，只需要安装了Intel® C++的编译器，就可以使用IPP库进行编程。编程的时候需要在Visual Studio中设置两个引用，第一个设置时引用IPP的头文件路径（Include files），设置的方法：在Visual Studio的主菜单中选择<strong>Tools &gt; Options</strong><strong>，</strong><strong>Options</strong>的对话框会打开，在该对话框的左边的列表中选择<strong>Projects and Solutions&gt;VC++ Directories</strong><strong>，</strong>接着在右上角的“<strong>Show directories for</strong><strong>：</strong>”选项中选择“<strong>Include files</strong>”，同时在<strong>Options</strong>对话框右边中间的选项点击空余的选项，选择Intel® IPP的安装路径下的“<strong>include”</strong>目录。第二个设置是引用Intel® IPP的链接文件的路径，其方法和引用头文件相似，只是选择在右上角的“<strong>Show directories for</strong><strong>：</strong>”选项中选择“<strong>Library files</strong>”，同时在<strong>Options</strong>对话框右边中间的选项点击空余的选项，选择Intel® IPP的安装路径下的lib目录。</p>
<p><strong>Intel® IPP</strong><strong>函数命名规则</strong>  在本书中、图像处理的实现都是基于IPP的调用。IPP有几千个函数，为了方便程序员使用这些函数，IPP中所有的函数名都遵循统一的命名规则。程序员很容易区分信号处理（一维处理）和图形和视频处理，因为他们的前缀是不一样的。用来信号处理的函数的前缀是“<strong>ipps</strong>”（ipp signal）<strong>，</strong>而用来处理图像和视频的函数的前缀是“<strong>ippi</strong>”（ipp image）。Intel® IPP中的图像处理的函数命名规则可以参考附件一。</p>
<br /><br />
<p align="center"><strong><span >1.3.8 Intel® MediaSDK</span></strong></p>
<p>随着计算机硬件技术和软件技术的发展，数字媒体技术发展迅速，但是数字视频等为代表的关键技术的开发和应用有着较大的难度。如在软件开发方面，数字视频的编解码工作就是一件非常耗时、繁琐的工作。一方面，数字视频编解码本身的算法具有复杂性，而且行业内的数字视频编解码的标准也有很多；另一方面，针对不同的硬件平台的特点和优势，往往在实现上也会有所不同。因此，这种复杂性可能会迫使很多软件开发团队将精力花在这些细节上，而妨碍了它们将精力投入到产品的其它的更能吸引客户的特色上。</p>
<p>针对上述软件存在的问题，英特尔媒体开发库（Intel® Media Software Development Kit）提供了一个对数字视频的通用解决方案，该解决方案支持多种图形平台（graphics platforms），实现了通用功能，能对数字视频进行预处理、编解码、以及不同编码格式的转换。该开发包支持现有的英特尔图形组件以及未来的英特尔图形架构Larrabee，Larrabee与AMD、NVIDIA的GPGPU（通用计算图形处理器）技术不同，后两者分别使用Stream Processing（流处理）和CUDA（统一计算设备架构）来满足对GPGPU计算的需求。而Larrabee基于传统的x86架构，它既可用在显卡上，也可用作一个特殊的x86处理器），同时，该开发包还支持纯软件的实现方式，第三方编解码器以及其他的具有硬件加速的图形产品（graphics products）</p>
<p>以前，开发人员可能需要掌握各种各样的图形架构（graphics architectures）并做具体的实现。Media SDK的问世可以让开发人员从这种繁琐的事务中解放出来。一些软件业的巨头已经采用Media SDK来充分利用他们的硬件加速和多核多线程的优势。</p>
<p>在Media SDK中，对数字视频的一些关键核心的编码、解码算法来自于Intel® IPP库，并在此基础上对处理性能进行了优化和提高。通过整合，Intel® Media SDK提供了一组容易使用，功能强大丰富的API。这种丰富性特别表现在其支持开放的体系结构，除能支持英特尔 的图形处理芯片和体系结构外，很容易扩展，从而支持任何第三方的图形硬件解决方案（graphics hardware solutions）和编解码方案。</p>
<p><strong>Intel® Media SDK的软件体系结构</strong></p>
<p>Media SDK高层的软件体系结构如图1.7所示，SDK的编程结构是通过库的分发层（Dispatcher layer）暴露给应用程序的。该层提供了通用的数字视频预处理、编解码的接口。同时，该层还有一个重要的重定向的功能，该功能的实现步骤为：</p>
<ol>
<li>分发器（dispatcher）定位当前的显卡的设备和驱动； </li>
<li>根据定位去SDK中查找最合适的实现方式； </li>
<li>如果没有找到适合的平台相关的实现方式，dispatcher会定位到SDK中用软件实现的方式。 </li>
</ol>
<p align="center"><img src="http://software.intel.com/file/40871" /></p>
<p align="center">图1.7 Intel® Media SDK体系架构图</p>
<p><strong>Intel® Media SDK的安装</strong></p>
<p>Intel® Media SDK的下载地址为：<strong><a href="http://software.intel.com/en-us/articles/media/">http://software.intel.com/en-us/articles/media/</a> </strong>。在下载的软件包中有两种软件版本，分别对应于Windows的32位和64位操作系统。用户可以根据自己的机器配置选择相应的安装，安装完成后，Media SDK的目录结构如表1.3所示。</p>
<p align="center"><strong>表1.3 Meida SDK安装后目录结构图</strong></p>
<table align="center" cellpadding="0" cellspacing="0" border="1">
<tbody>
<tr>
<td width="198" valign="top">
<p align="center"><strong>目录</strong><strong> </strong></p>
</td>
<td width="359" valign="top">
<p align="center"><strong>目录说明</strong><strong> </strong></p>
</td>
</tr>
<tr>
<td width="198" valign="top">
<p>&lt;Media SDK Directory&gt;</p>
</td>
<td width="359" valign="top">
<p>Media SDK安装主目录，如： <br />C:\Program Files (x86)\intel\Media SDK\1.0.11.12792</p>
</td>
</tr>
<tr>
<td width="198" valign="top">
<p>&lt;Media SDK Directory&gt;/<br />Intel Media SDK EULA.rtf</p>
</td>
<td width="359" valign="top">
<p>用户License协议书</p>
</td>
</tr>
<tr>
<td width="198" valign="top">
<p>&lt;Media SDK Directory&gt;/bin</p>
</td>
<td width="359" valign="top">
<p>Media SDK DLLs（包含samples中的filter，或plug-in）</p>
</td>
</tr>
<tr>
<td width="198" valign="top">
<p>&lt;Media SDK Directory&gt;/doc</p>
</td>
<td width="359" valign="top">
<p>Media SDK开发资料说明，包含手册等</p>
</td>
</tr>
<tr>
<td width="198" valign="top">
<p>&lt;Media SDK Directory&gt;/include</p>
</td>
<td width="359" valign="top">
<p>Media SDK头文件说明</p>
</td>
</tr>
<tr>
<td width="198" valign="top">
<p>&lt;Media SDK Directory&gt;/lib<strong></strong></p>
</td>
<td width="359" valign="top">
<p>Media SDK库文件，用于链接Dlls<strong></strong></p>
</td>
</tr>
<tr>
<td width="198" valign="top">
<p>&lt;Media SDK Directory&gt;/samples</p>
</td>
<td width="359" valign="top">
<p>Media SDK示例代码，包含编解码、filter（plug-in）等</p>
</td>
</tr>
</tbody>
</table>
<br />
<p><strong>使用动态链接方式引用</strong><strong>IPP</strong><strong>库时所需设置的环境变量</strong><strong>  </strong>开发者基于Media SDK进行应用开发时，首先要设置开发工具中的环境变量。因此需要在Visual Studio中设置两个引用，第一个设置时引用Media SDK的头文件路径（Include files），设置的方法：在Visual Studio的主菜单中选择<strong>Tools &gt; Options</strong><strong>，</strong><strong>Options</strong>的对话框会打开，在该对话框的左边的列表中选择<strong>Projects and Solutions&gt;VC++ Directories</strong><strong>，</strong>接着在右上角的“<strong>Show directories for</strong><strong>：</strong>”选项中选择“<strong>Include files</strong>”，同时在<strong>Options</strong>对话框右边中间的选项点击空余的选项，选择Media SDK的安装路径下的“<strong>include”</strong>目录。第二个设置是引用Intel® IPP的链接文件的路径，其方法和引用头文件相似，只是选择在右上角的“<strong>Show directories for</strong><strong>：</strong>”选项中选择“<strong>Library files</strong>”，同时在<strong>Options</strong>对话框右边中间的选项点击空余的选项，选择Media SDK的安装路径下的<strong>lib</strong>目录。</p>
<p>在本书的第七章的第五节，我们对Media SDK的开发做了一个简单介绍功大家参考。</p> ]]></description>
      <link>http://software.intel.com/zh-cn/articles/book-Visual-Computing_software_development_platform/</link>
      <pubDate>Wed, 04 Jan 2012 08:00:00 -0800</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/book-Visual-Computing_software_development_platform/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/book-Visual-Computing_software_development_platform/</guid>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
    </item>
    <item>
      <title>视觉计算软件开发基础之上机实验</title>
      <description><![CDATA[ 
<p><strong><span >1.4 上机实验</span></strong></p>
<p>图像和视频处理是一门实践性很强的课程，需要学生具有强将的动手实践的能力。因此掌握用工具来开发实际应用也是对学生的起码要求，在本节，我们通过两个实验让学生具体感受一下具体的编程应用环境。为接下来的实践编程做好准备。在本章及以后的章节中我们的开发环境为Visual Studio IDE及Intel® Parallel Studio。</p>
<br /><br />
<p align="center"><strong><span >1.4.1 实验一 编写简单的C/C++程序并进行优化</span></strong></p>
<p><strong>[实验目的]</strong></p>
<ol>
<li>掌握Visual Studio IDE开发环境下的C/C++的开发；</li>
<li>掌握程序性能优化的基本方法；</li>
</ol>
<p><strong>[预备知识]</strong></p>
<ol>
<li>比较熟练掌握C /C++语言；</li>
<li>了解多线程即优化的一些基本概念和思想</li>
</ol>
<p><strong>[实验原理] </strong></p>
<p>  通过IDE下用Parallel Studio来优化程序性能</p>
<p><strong>[实验内容及步骤]</strong></p>
<p><strong>实验内容：</strong>用C/C++根据积分公式求圆周率，并对程序进行优化</p>
<p><strong>实验步骤：</strong></p>
<ol>
<li>将积分公式离散化，以便计算机进行实现；</li>
<li>用VS 新建一个Windows Console工程；</li>
<li>用C语言实现计算。其代码如下；</li>
<li>用Parallel Amplifier来分析程序性能，选择IDE总“工具”菜单后调用Amplifier的功能如图所示：我们用该工具来查找一下程序的热区（Hotspots）在什么地方。</li>
<br />
<p align="center"><img src="http://software.intel.com/file/40872" /></p>
<p align="center">图1.8 Parallel Amplifier分析菜单图</p>
<br />
<p align="center"><img src="http://software.intel.com/file/40873" /></p>
<p>分析得出的结果如图1.9所示：我们从图中可以看出，程序执行的时间大部分花子了累计求和的表达式上，花了17.739秒，并且通过Amplifier中的“Summary”图我们可以看出，该计算机为双核（Core Count为2），创建的线程数为1。这次计算总共耗时22.292秒（CPU时间资源应该为22.292*2秒），其中CPU只使用了21.762秒，而22.822秒的CPU时间都没有利用（因为），这是因为该程序为串行程序，在计算的过程中，只用到了一个CPU资源，而另一CPU资源没有得到利用，因此总耗时会比较长。</p>
<p align="center"><img src="http://software.intel.com/file/40874" /></p>
<p align="center">图1.9 Intel® Parallel Amplifier分析图</p>
<li>对热区进行分析、考虑引入多线程，进行优化的可行性。</li>
<p>通过分析，我们会发现，这10亿次循环的运行都只用到了一个CPU，这无疑没有充分利用资源，如果我们将这10亿次计算进行分工，每个CPU运行5亿次，然后将运算的结果进行规约（reduction，综合的意思）。这样计算的时间可能会较少。因此我们引入了OpenMP（介绍一下<span ><strong>OpenMP</strong></span>）对上述的串行程序进行并行优化，优化的代码如下所示。</p>
<table align="center">
<tbody>
<tr align="center">
<td><img src="http://software.intel.com/file/40875" /></td>
<td><img src="http://software.intel.com/file/40876" /></td>
</tr>
<tr align="center">
<td colspan="2">图1.10 CPU运行时间统计</td>
</tr>
</tbody>
</table>
<br />
<p align="center"><img src="http://software.intel.com/file/40877" /></p>
<p>我们对上述代码中的一句： 做一下说明，该句代码引入OpenMP预编译指导语句对程序进行并行化；x为私有变量，每个线程有自己的拷贝；因此不同的线程间不会出现写冲突，由于sum是公有变量；如果不进行约束，会出现写冲突，在OpenMP中用reduction表明其为规约项,规约可以理解成在每个线程中，sum都有私有拷贝，但是最后会将这些私有拷贝的值按加法的运算赋值到sum全局变量。</p>
<li>检查并行程序的正确性、分析其所花的时间，对其并行优化的结果做分析。</li>
<p>Parallel Studio中的Inspector工具可以用来检查并行程序中潜在的危险，比如读写竞争冲突，会不会存在死锁等。如果程序员在并行化的过程中，由于不小心使得程序出现这些错误，可以用Inspector工具进行查错。在保证程序正确性的前提下，我们再次通过Amplifier对程序进行了性能分析，其中“Summary”的结果如图所示。解释如下：机器为双核，创建了两个线程；整个耗时为11.419秒（大概为串行程序执行时间的一半）；两个CPU计算时间的总和为21.976秒，其中还有0.861秒的CPU时间资源没有利用，这表明在整个计算时间内，绝大部分的时间两个CPU都在同时计算，因此，总体上大大减少了计算的时间、提高了程序运行的效率。</p>
</ol>
<p><strong>[实验总结]</strong></p>
<p>本实验通过程序用积分求pi的运算展示了编写程序以及用工具将程序进行优化的过程。并行编程是计算机学科的综合领域，涉及计算机体系结构、软件等一系列相关领域，掌握好并灵活运用是需要大家不断的学习和总结的。在这里，我们采用了OpenMP对串行程序进行了并行化，同学们也可以考虑直接采用Windows多线程编程API来进行编程。OpenMP提供了对并行算法的高层的抽象描述，程序员通过在源代码中加入专用的pragma来指明自己的意图，由此编译器可以自动将程序进行并行化，并在必要之处加入同步互斥以及通信。当选择忽略这些pragma，或者编译器不支持OpenMP时，程序又可退化为通常的程序（一般为串行），代码仍然可以正常运作，只是不能利用多线程来加速程序执行。</p>
<br /><br />
<p align="center"><strong><span >1.4.2 实验二 用IPP库编写简单的C/C++程序</span></strong></p>
<p><strong>[实验目的] </strong></p>
<ol>
<li>熟悉IPP库的结构，熟练基于IPP库的功能、特点、数据类型、函数命名规则；</li>
<li>学会通过手册查看对应的IPP函数说明，学会调用合理的IPP函数解决实际问题；</li>
</ol>
<p><strong>[预备知识]</strong></p>
<ol>
<li>比较熟练掌握C /C++语言；</li>
<li>Intel® IPP的基本知识；</li>
</ol>
<p><strong>[实验原理]</strong></p>
<p>  通过IDE下用条用IPP函数来实现特定的功能</p>
<p><strong>[实验内容及步骤] </strong></p>
<p>  <strong>实验内容：</strong>调用不同的IPP函数，实现矩阵的加法运算，理解IPP不同函数的特点。</p>
<p>  <strong>实验步骤：</strong></p>
<ol>
<li>在IDE中设置IPP环境变量；在代码文件中加入IPP库的应用，包含IPP的头文件#include &lt;IPP.h&gt;；</li>
<li>分别调用ipp两个库函数，实现矩阵的加法，并对两个实现做一下简要的分析。其中代码如下：IPP中的数据类型的定义，可以查看手册，基本都是以IPP开头，接着的数字表明其所占得位数，最后表明该数据的类型，u表示无符号性，s表示符号性，f表示单精度浮点型等。</li>
<p align="center">
<p align="center"><img src="http://software.intel.com/file/40878" /></p>
</p>
<li>分析两个函数调用的计算结果，并分析其运行效率。</li>
</ol>
<p><strong>[实验总结]</strong></p>
<p>我们会发现虽然两个函数都能实现同样的功能，但是其效率是不一样的，我们也可以猜测出ippsAdd_32f这个函数要快，因为其参数简单，功能也相对简单。ippmAdd_mm_32f所能实现的不仅仅是向量的加法，它还能实现矩阵的加法，我们也可以看出，其参数很多，代表其能实现很多向量加法不能实现的功能。具体可以参考手册。</p> ]]></description>
      <link>http://software.intel.com/zh-cn/articles/book-Visual-Computing_experiment/</link>
      <pubDate>Tue, 03 Jan 2012 08:00:00 -0800</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/book-Visual-Computing_experiment/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/book-Visual-Computing_experiment/</guid>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
    </item>
    <item>
      <title>视觉计算软件开发基础之视觉计算概述</title>
      <description><![CDATA[ 
<p align="center"><span >视觉计算软件开发基础</span></p>
<p><strong><span >1.1 视觉计算概述</span></strong></p>
<p>众所周知，早期的计算机的发明是科学计算的需要，其使用者主要是从事科学计算的科技工作者。随着计算机软硬件技术的发展，计算机的功能也在进一步扩展，开始从科技的象牙塔走向大众，并已经成功应用于生产（如工业控制、企业生产执行系统MES）、办公（无纸化办公）、生活（网上冲浪、购物）以及娱乐（数字电影、游戏）等各个方面。普适计算（Ubiquitous Computing）是二十一世纪的计算模式，计算将变得无处不在。</p>
<p>在计算机接近、走向大众的过程中，计算机对图形图像、音视频的捕捉（Capture）、设计（Design）、存储（Storage）、处理（Process）、传输（Transfer）等关键的视觉计算技术功不可没。</p>
<p>视觉计算（Visual Computng）技术的研究和应用对象并不是很清晰、严格，因此视觉计算技术在不同的上下文中可能会涉及多个领域，如数据可视化（Data Visualization）、计算机图形学（Computer Graphics）、数字图像处理（Image Processing）、多媒体技术（MultiMeida）、计算机视觉（Computer Vision）等，这些都可以称为视觉计算技术。</p>
<p>随着视觉计算技术的发展，对具备设计和开发视觉计算软件能力的工程师的需求也在进一步扩大。由于视觉计算技术涉及较深的数学等理论知识和计算机编程技术，因此，对程序员的要求也会相对较高，程序员从零起步开发视觉计算软件的难度较大。因此一个具备高性能的、支持多种软件平台（多种操作系统）和硬件平台（同时支持嵌入式开发）的视觉计算软件开发库是从事视觉计算软件开发的必然需求。</p>
<p>英特尔公司在多年的技术积累的基础上，为视觉计算软件开发人员提供了满足上述特性的软件开发库，包括Intel® IPP（Integrated Performance Primitives，集成性能元件）和Intel® Media SDK（Software Development Kit，媒体开发库）。</p>
<p>为了向程序员普及或推广视觉计算软件开发技术，降低视觉计算软件开发的门槛，我们这本书将介绍图像和视频处理的基础理论知识和英特尔公司提供的视觉计算软件开发库相结合，注重理论联系实际，强调实践。文字、图例、实验、程序代码互为补充，向大家介绍图像和视频处理开发中的技术及应用。</p>
<p>本书的前修课程是C、C++程序设计语言，要求读者有一定的计算机编程基础和实践经验，能较为快速阅读C/C++语言程序代码，并且C/C++程序编程比较熟练，对面向对象技术最好要有一定了解，没有信号处理的基础知识也可以阅读。</p>
<br /><br />
<p align="center"><strong><span >1.1.1 图像</span></strong></p>
<p><strong>数字图像</strong> 图像是人类接触世界、获取信息的重要途径。用图像来表达信息直观、形象、丰富，因此，才有“一图胜千言”（A Picture Paints a Thousand Words），“百闻不如一见”（One picture is worth more than ten thousand words）等俗语说法。</p>
<p>图像在传达信息方面有其它媒介（文字、声音等）无法替代的优越性，因此，在现代网络信息时代下，计算机能够表示、处理图像是必然的需求。纵观各类网站，其内容都是图文并茂，栩栩如生。我们将计算机能够显示、存储、处理的图像称为数字图像。</p>
<p>同时，在信息时代，计算机能够处理的图像将不仅仅限于人类肉眼局限的可见光（人类肉眼感知的图像仅限于比较小的一段电磁波谱），数字图像可以通过各种成像途径获取，这些途径可以覆盖几乎整个电磁波谱。如图所示为用微波获取的金星图像。</p>
<p align="center"><img src="http://software.intel.com/file/40863" /></p>
<p align="center">（a）金星图片     （b）某一块区域放大后效果     （c）该区域图像灰度值</p>
<p align="center">图1.1 微波反射形成的金星图像</p>
<p>图：对金星通过微波反射形成的灰度图像，中图为左图一块10像素见方区域的灰度图，右图为中图的图像灰度值（值的范围为0~255，有256个灰度等级），灰度的值的大小与微波反射能量的级别相对应。</p>
<p><strong>数字图像处理</strong> 数字图像处理作为一门学科大约形成于20世纪60年代初期。早期的图像处理的目的是改善图像的质量，它以人为对象，以改善人的视觉效果为目的。但是数字图像处理不仅可以对人类肉眼可观察的图像进行加工处理，还可以对包括超声波、电子显微镜等成像机器产生的图像进行处理。因此，数字图像处理设计的领域将非常广泛，如70年代生物医学中的CT技术（如图所示），对人类做出了划时代的贡献，数字图像还在航空航天（如图1.3所示）、生物医学工程、工业检测、机器人视觉等领域有着非常多的应用，使图像处理成为一门引人注目、前景远大的新型学科 。</p>
<table align="center">
<tbody>
<tr align="center">
<td><img src="http://software.intel.com/file/40864" /></td>
<td><img src="http://software.intel.com/file/40865" /></td>
</tr>
<tr align="center">
<td>图1.2 医学CT成像</td>
<td>图1.3 嫦娥一号卫星传回的月面图片</td>
</tr>
</tbody>
</table>
<p>图1.2：CT成像，这幅图是一个人体肚脐部位的腹部成像的切片。图中可以看到很多器官，如（L）肝脏、（K）肾脏、（A）主动脉、（S）脊柱、（C）膀胱（盖住了右侧的肾脏）。CT成像能够比传统的医学X射线对人体内部组织有更好的可视效果。</p>
<p>图像处理中，常用的图像处理方法有图像变换、图像编码和压缩、图像增强、图像分割、图像分类（识别）等。我们做一下简要介绍。</p>
<p>图像增强 图像增强的目的是为了提高图像的质量，如去除噪声，提高图像的清晰度等。图像增强突出图像中所感兴趣的部分。如怎样处理可使图像中物体轮廓清晰，细节明显；怎样进行处理可减少图像中噪声的影响。如图1.4所示，在经过图像增强处理后，（b）图从整体上感觉更清晰。</p>
<table align="center">
<tbody>
<tr align="center">
<td><img src="http://software.intel.com/file/40866" /></td>
<td><img src="http://software.intel.com/file/40867" /></td>
</tr>
<tr align="center">
<td>（a）原图</td>
<td>（b）图像增强处理后效果图</td>
</tr>
<tr align="center">
<td colspan="2">图1.4 图像增强处理效果图</td>
</tr>
</tbody>
</table>
<p><strong>图像变换</strong> 由于图像阵列很大，直接在空间域中进行处理，涉及计算量很大（由于数据存在着空间冗余信息）。因此，往往采用各种图像变换的方法，如傅立叶变换、沃尔什变换、离散余弦变换等间接处理技术，将空间域的处理转换为变换域处理，不仅可减少计算量，而且可获得更有效的处理（如傅立叶变换可在频域中进行数字滤波处理）。目前新兴研究的小波变换在时域和频域中都具有良好的局部化特性，它在图像处理中也有着广泛而有效的应用。</p>
<p><strong>图像编码和压缩</strong> 图像编码压缩技术可减少描述图像的数据量（即比特数），以便节省图像传输、处理的时间和减少所占用的存储器容量。压缩可以在不失真的前提下获得，也可以在允许失真的条件下进行（在允许失真的情况下压缩比率通常会更高）。编码是压缩技术中最重要的方法，它在图像处理技术中是发展最早且比较成熟的技术。</p>
<p><strong>图像分割</strong> 图像分割是数字图像处理中的关键技术之一。图像分割是将图像中有意义的特征部分提取出来，其有意义的特征有图像中的边缘、区域等，这是进一步进行图像识别、分析和理解的基础，也是计算机视觉中常用到图像处理方法。虽然目前已研究出不少边缘提取、区域分割的方法，但还没有一种普遍适用于各种图像的有效方法。因此，对图像分割的研究还在不断深入之中，是目前图像处理中研究的热点之一。</p>
<p><strong>图像分类（识别）</strong> 图像分类（识别）属于模式识别的范畴，其主要内容是图像经过某些预处理（增强、复原、压缩）后，进行图像分割和特征提取，从而进行判决分类。图像分类常采用经典的模式识别方法，有统计模式分类等。</p>
<p>在本书的数字图像处理部分，我们重点强调图像的增强、图像变换、压缩编码部分。</p>
<br /><br />
<p align="center"><strong><span >1.1.2 视频</span></strong></p>
<p><strong>视频</strong> 当电影胶片以每秒24格画面匀速转动，一系列静态画面就会因“视觉暂留”作用而造成一种连续的视觉印象，产生逼真的动感，电影就是基于人的视觉暂留作用原理制作成的，视频的基本原理也是一样的，拿电视来说，虽然有两个不同的标准PAL（25帧，我国和东南亚及欧洲等地方使用的制式）和NTSC（30帧，美国、日本等国的制式），其帧率都是大于24帧。因此，我们将这种一个个静态的图像经过快速的播放而形成动态、连续的画面叫做视频。视频是人们最熟悉的名词之一，我们生活当中电视机、录像机等都有视频输出接口。</p>
<p><strong>数字视频</strong> 电影、电视（传统模拟电视机）和录像已经属于传统的试听媒体，其视频信号属于模拟信号，随着现代科技的发展，已经出现了数字电视技术，与原来的模拟电视相比，数字电视有高清晰的电视画面，可与DVD相媲美；有优质的音响效果，由于采用了数字技术，使得数字电视的伴音更趋逼真；有抗干扰功能，数字电视受其它电器的干扰很小，因此画面稳定；扩展功能多，可增加上网、点播等。数字视频的编辑通常是通过非线性编辑(NLE for non-linear editing)系统进行的。几乎你看到的所有的电视节目、某些电影、广告都是用非线性编辑系统制作的，由于计算机网络和多媒体技术的发展，在个人计算机上也可以进行数字视频的编辑，越来越多的人利用计算机制作自己的小电影。同时，在因特网上的流式视频和点对点视频传输也都是新近的热点，土豆*、YouTube*等是关于数字视频的互联网网站，用户可以上载分享自己的视频，也能看到别人分享的视频。数字视频（Digital video）信息技术已经成为我们生活中不可或缺的组成部分，已经渗透到工作、学习、娱乐的各个方面。</p>
<p>有很多不同的数字视频编码方法和文件容器格式，支持不同大小、质量、分辨率、色度精度和编码功能的图像编码。在本书的第七章，我们将详细介绍这些编码原理知识和相关标准。</p>
<br /><br />
<p align="center"><strong><span >1.1.3 音频</span></strong></p>
<p>和视频一样，音频也分为模拟音频和数字音频。其实任何我们可以听见的声音经过音频线或话筒的传输都是一系列的模拟信号。模拟信号是我们可以听见的。而数字信号就是用一堆数字记号(其实只有二进制的1和0)来记录声音，而不是用物理手段来保存信号（用普通磁带录音就是一种物理方式）。我们实际上听不到数字信号。</p>
<p>音频是个专业术语，人类能够听到的所有声音都称之为音频，它可能包括噪音等。声音被录制下来以后，无论是说话声、歌声、乐器都可以通过数字音乐软件处理，或是把它制作成CD，这时候所有的声音没有改变，因为CD本来就是音频文件的一种类型。而音频只是储存在计算机里的声音。如果有计算机再加上相应的音频卡——就是我们经常说的声卡，我们可以把所有的声音录制下来，声音的声学特性如音的高低等都可以用计算机硬盘文件的方式储存下来。反过来，我们也可以把储存下来的音频文件用一定的音频程序播放，还原以前录下的声音。</p>
<p>模拟时代的录音制作与数码时代的区别：模拟时代是把原始信号以物理方式录制到磁带上（当然在录音棚里完成了），然后加工、剪接、修改，最后录制到磁带、LP等广大听众可以欣赏的载体上。这一系列过程全是模拟的，每一步都会损失一些信号，到了听众手里自然是差了好远，更不用说什么HI-FI(高保真)了。数码时代是第一步就把原始信号录成数码音频资料，然后用硬件设备或各种软件进行加工处理，这个过程与模拟方法相比有无比的优越性，因为它几乎不会有任何损耗。对于机器来说这个过程只是处理一下数字而已，当然丢码的可能性也有，但只要操作合理就不会发生。最后把这堆数字信号传输给数字记录设备如CD等，损耗自然小很多了！</p>
<p>在计算机内播放或是处理音频文件，也就是要对声音文件进行数、模转换，这个过程同样由采样和量化构成，人耳所能听到的声音，最低的频率是从20Hz起一直到最高频率20KHZ，20KHz以上人耳是听不到的，因此音频的最大带宽是20KHZ，音频有很多中格式，CD格式（接近无损），wav、MP3等。</p>
<p>在本书中我们不对音频的相关技术进行详细阐述。</p>
<br /><br />
<p align="center"><strong><span >1.1.4 游戏</span></strong></p>
<p>自从人类诞生的时候就有游戏，自古至今人类发明的游戏不计其数，比如各式各样的棋牌类游戏、体育竞技游戏、甚至古罗马的竞技场上残忍的搏斗，在有些人的眼里，也是一种轻松的游戏。</p>
<p>在信息时代，传统的游戏得到了延伸和扩展。电脑游戏现在已经非常非常流行，在行业者的眼里已经是一个巨大的产业。电脑游戏是指在电子计算机上运行的游戏软件，是一种本身提供娱乐功能的电脑软件。电脑游戏产业与电脑硬件（视频显示卡等）、电影、电脑软件、互联网的发展联系甚密。电脑游戏为游戏参与者提供了一个虚拟的空间，从一定程度上让人可以摆脱现实世界，在另一个世界中扮演真实世界中扮演不了的角色（如CS、星际等）。同时电脑多媒体技术的发展，使游戏给了人们很多体验和享受。</p>
<p>电脑游戏的发展离不开计算机软硬件的发展，特别是游戏软件开发，涉及到游戏创意、网络、音视频、嵌入式软件（如手机游戏等）、人机交互、人工智能等各个领域，是和视觉计算分不开的。也是一项非常具有挑战性的工作。</p> ]]></description>
      <link>http://software.intel.com/zh-cn/articles/book-Visual-Computing_overview/</link>
      <pubDate>Mon, 02 Jan 2012 08:00:00 -0800</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/book-Visual-Computing_overview/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/book-Visual-Computing_overview/</guid>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
    </item>
    <item>
      <title>MLAA：高效地将抗锯齿处理从 GPU 迁移至 CPU</title>
      <description><![CDATA[ <h2 class="sectionHeading">下载文章和源代码<br /></h2>
英文版下载 <a href="http://software.intel.com/file/37411">MLAA：高效地将抗锯齿处理从 GPU 迁移至 CPU</a> (PDF 1.2MB)<br />访问 <a href="http://software.intel.com/zh-cn/articles/mlaa/">MLAA 示例页</a>可下载源代码。<br /><br /><br />
<h2 class="sectionHeading">简介</h2>
<p>高效的抗锯齿技术是进行高品质、实时渲染的重要工具。MSAA（多点采样抗锯齿处理）是目前使用的标准技术，但有一些严重的缺点：</p>
<ul>
<li>与延迟照明不兼容，后者在实时渲染中使用得越来越多；</li>
<li>高内存和处理开销，这使其在一些流行平台（如索尼 Playstation* PS3*）上的使用受限 [Perthuis 2010]。这种开销还直接与渲染场景的复杂性关联；</li>
<li>除非与阿尔法覆盖通道一起使用，否则无法对非几何边界进行平滑处理。</li>
</ul>
<p>英特尔实验室开发的一项新技术形态学抗锯齿处理（Morphological Antialiasing，MLAA) [Reshetov 2009] 解决了这些限制。MLAA 是一种基于图像的后处理过滤技术，它可以标识不连续模式，并混合这些模式的相邻模式中的色彩来执行有效的抗锯齿处理。它是新一代实时抗锯齿技术的先驱，可与 MSAA 抗衡 [Jimenez et al., 2011] [SIGGRAPH 2011]。</p>
<p>此示例基于由 Reshetov 提供的基于 CPU 的原始 MLAA 实施，并进行了改进以大幅提高性能。这些改进包括：</p>
<ul>
<li>集成一种高效且易用的新任务处理系统，在英特尔® 线程构建模块（Threading Building Blocks，TBB）上实施。 </li>
<li>集成一种高效且易用的新管道传输系统，用于 CPU 图形任务装载。 </li>
<li>通过新转置通道改进数据存取模式。</li>
<li>增加使用英特尔® SSE 指令以优化中断检测和颜色混合。 </li>
</ul>
<br />
<h2 class="sectionHeading">MLAA 算法</h2>
<p>本节将概述 MLAA 算法的原理；请参阅 [Reshetov 2009] 了解详尽说明。从概念上说，MLAA 分三步处理图像缓冲：</p>
<ol>
<li>查找指定图像中的像素间中断。</li>
<li>标识 U 形、Z 形和 L 形模式。</li>
<li>混合这些模式的相邻模式中的颜色。</li>
</ol>
<p>第一步（查找中断）通过将每个像素与其相邻像素比较实现。横向中断通过将像素与其下方相邻像素比较进行识别，纵向中断通过比较像素与其右方相邻像素进行识别。在我们的实施中我们比较了颜色值，但适合应用程序特点的任何其他方法也完全有效。</p>
<p>第一步结束时，如果检测到中断，则相应的每个像素都会用横向中断标志和/或纵向标志进行标记。在下一步中，我们会沿标记的像素来确定中断线（标记有相同中断标志的连续像素序列），并确定它们如何组合成 L 形模式，如下图中所示：</p>
<p ><img src="http://software.intel.com/file/37399" alt="Figure 1" title="Figure 1"  /> <br /><b>图 1：</b><i> MLAA 图像处理，图像具有左侧原始图像中所示的 Z 形、U 形和 L 形形状</i></p>
<p>第三步（即最后一步）是对每个标识的 L 形模式进行混合。</p>
<p>一般的想法是将 L 形形状主线段（下图中的水平绿线）的中点连接到次线段（垂直绿线）的中点（连线为红线）。连线将每个像素分成两个梯形；对于每个像素，对应梯形的面积确定混合权重。例如，在下图中，像素 c5 的梯形面积是 1/3；因此，c5 的新颜色计算方式为 2/3 *（c5 的颜色）+ 1/3 *（c5 下面相邻像素的颜色）。</p>
<p ><img src="http://software.intel.com/file/37400"  /> <br /><b>图 2：</b> <i>计算混合权重</i></p>
<p>在实践中，为了确保有平滑的轮廓外观，我们需要最大程度地减少连续 L 形形状结合位置的颜色差异。为此，我们根据结合点周围的像素颜色对中间位置周围的 L 形线段上的连接点进行细微调整。</p>
<p> </p>
<h2 class="sectionHeading">使用示例</h2>
<p>镜头可以通过拖动和点击围绕场景移动，鼠标滚轮可用于进行放大或缩小。此外，在示例窗口的右侧还有三个控制块：</p>
<p ><img src="http://software.intel.com/file/37401"  /> <br /><b>图 3：</b><i>操作中示例的屏幕快照 </i></p>
<p>第一个块控制场景渲染：</p>
<ul>
<li><i>“暂停场景”</i>切换场景动画的开关； </li>
<li><i>“显示缩放框”</i>切换缩放框开关，用户可用于更近距离地观察像素区域以更好地比较抗锯齿处理技术。对于感兴趣的区域，用于可以通过右键单击更改为要检查的新区域； </li>
<li><i>“场景复杂性”</i>通过重绘来模拟提高场景复杂性的效果。值（在 1 和 100 之间，可通过滑块调整）代表场景的每帧渲染次数（通过重绘）。</li>
</ul>
<p>第二个块用于选择要应用的抗锯齿处理技术：MLAA、MSAA (4x) 或无抗锯齿处理。这当然也可用于比较各种技术的性能和质量（默认选择为 MLAA）；</p>
<p>最后一个控制块仅在使用 MLAA 作为抗锯齿处理技术时可用，用于控制算法的运行方式：</p>
<ul>
<li><i>“仅复制/映射/解除映射”</i>在 GPU 内存与 CPU 内存之间来回复制颜色缓冲，但不会在两次复制操作之间执行任何 MLAA 处理。这样可以测量复杂操作对整个算法整体性能的影响；</li>
<li><i>“CPU 任务管道传输”</i>为 CPU 图形任务负载打开/关闭管道传输系统（默认为打开），以便可以看到管道传输的优势；</li>
<li><i>“显示找到的边界”</i>运行算法的第一部分（查找像素之间的中断），但混合通道替换成调试通道，其中： 
<ul >
<li>如果发现某个像素与相邻像素间存在横向中断，则该像素变成纯绿色；</li>
<li>如果发现某个像素与相邻像素间存在纵向中断，则该像素变成纯蓝色；</li>
<li>如果发现某个像素与相邻像素间同时存在横向中断和纵向中断，则该像素变成纯红色；</li>
<li>如果未发现中断，则像素无变化。</li>
</ul>
</li>
</ul>
<p ><img src="http://software.intel.com/file/37402"  /> <br /><b>图 4. </b><i>采用 MLAA 并启用“显示找到的边界”选项的齿轮塔场景</i></p>
<p ><i><br /></i></p>
<h2 class="sectionHeading">架构示例</h2>
<p>在没有管道优化的情况下，每个帧的事件序列如下：</p>
<p> </p>
<ol >
<li >
<div ><b>激活并渲染测试场景</b></div>
</li>
<li >
<div ><b>MLAA 阶段（如果启用了 MLAA）</b> 
<ul >
<li>
<div >将渲染场景处的颜色缓存复制到临时缓冲</div>
</li>
<li>
<div >映射临时缓冲用于 CPU 端访问</div>
</li>
<li>
<div >MLAA 后处理（临时缓冲同时是输入和输出）</div>
</li>
<li>
<div >取消临时缓冲映射</div>
</li>
<li>
<div >将临时缓冲复制回 GPU 端颜色缓冲</div>
</li>
<li>
<div >渲染缩放框（如果适用）</div>
</li>
</ul>
</div>
</li>
<li >
<div ><b>渲染示例的 UI，呈现帧</b></div>
</li>
</ol>
<p>除了“执行 MLAA 后处理工作”步骤（暂时不考虑管道），以上所有步骤都使用标准 Microsoft DirectX* 方法实现。</p>
<p> </p>
<h2 class="sectionHeading">任务处理 API</h2>
<p>MLAA 算法本质是易于并行处理。对于中断检测和通道混合，我们都可以用独立的块（连续的行或列块）来处理颜色缓冲。MLAA 可采用基于任务的解决方案实现；这种解决可自动充分利用可用的 CPU 核心，同时无需让代码知道核心数量</p>
<p>此示例使用了一个基于 C 语言的简单任务处理 API，在英特尔® 线程构建模块 (Intel® TBB) 调度程序的基础上实现。创建这种封装程序 API 的目的是简化与已经采用类似任务处理 API（如跨平台游戏引擎）的现有代码库的技术集成。其优势是可有效提高主源文件 <i>MLAA.cpp</i> 的可读性。</p>
<p>封装程序 API 的两个重要函数为：</p>
<pre name="code" class="cpp">    BOOL CreateTaskSet(
        TASKSETFUNC                 pFunc,      //  Function pointer to the 
                                                //  Taskset callback function
        VOID*                       pArg,       //  App data pointer (can be NULL)
        UINT                        uTaskCount, //  Number of tasks to create 
        TASKSETHANDLE*              pDepends,   //  Array of TASKSETHANDLEs that 
                                                //  this taskset depends on.  The 
                                                //  taskset will not be scheduled
                                                //  until all tasksets in this list
                                                //  complete.
        UINT                        uDepends,   //  Count of the depends list
        OPTIONAL LPCSTR             szSetName,  //  [Optional] name of the taskset
                                                //  the name is used for profiling
        OUT TASKSETHANDLE*          pOutHandle  //  [Out] Handle to the new taskset
        );
</pre>
<p>和：</p>
<pre name="code" class="cpp">    //  WaitForSet will yield the main thread to the tasking system and return
    //  only when the taskset specified has completed execution.
    VOID WaitForSet(
        TASKSETHANDLE               hSet        // Taskset to wait for completion
        );
</pre>
<p>回调函数具有以下特征：</p>
<pre name="code" class="cpp">typedef VOID (*TASKSETFUNC)(VOID* TaskInfo, INT iContext, UINT uTaskId, UINT uTaskCount);</pre>
<p> </p>
<p>MLAA 需要三个连续任务集的相关性图形：</p>
<ul>
<li>第一个任务集查找颜色缓冲中像素之间的中断；</li>
<li>第二个任务集执行横向混合通道，并依赖于获取中断信息的第一个任务集的完成；</li>
<li>第三个任务集执行纵向混合通道，它依赖于获取中断信息的第一个任务集的完成，但同时还依赖于第二个任务集的完成，因为要进行转置优化（请参阅对应章节以了解详细信息）。</li>
</ul>
<p>这种相关性图形在 <em>MLAA.cpp</em> 中表示为对 CreateTaskSet 的三个调用序列；任务集回调函数（在 <em>MLAAPostProcess.cpp</em> 中实现）分别为 MLAAFindDiscontinuitiesTask、MLAABlendHTask、MLAABlendVTask。</p>
<p>如果未启用管道传输，我们要通过使用上一次任务集的句柄调用 WaitForSet 来等待上一个任务集完成。调用返回时，对帧的 MLAA 操作就完成了。在使用管道时，事情的复杂性会稍有提高。</p>
<p> </p>
<h2 class="sectionHeading">CPU/GPU 管道</h2>
<p>要从我们的实施中获得最大性能，我们必须保持 CPU 端和 GPU 端都得到充分利用。由于任务集之间存在数据依赖性，因此可以通过穿插多个帧的处理来实现充分利用，如下图中所示：</p>
<p ><img src="http://software.intel.com/file/37410"  /><br /><b>图 5：</b><i>通过管道移动的帧。CPU 主线程时间线上的红色块说明主线程将在应用程序受 CPU 限制时执行 MLAA 处理。</i></p>
<p ><i><br /></i></p>
<p>换言之，我们必须构建一个管道传输系统，其中的一个管道是一个 CPU 阶段（工作负荷）和 GPU 阶段的序列，可以同时运行前述管道的多个实例。</p>
<p>在我们的示例中，每个管道实例对应于一个帧处理。我们分三个步骤：</p>
<p>第 1 步（GPU 阶段）：</p>
<ul>
<li>创建动画并渲染测试场景；</li>
<li>将颜色缓冲复制到临时缓冲（使用异步 GPU 端 CopyResource）。</li>
</ul>
<p>第 2 步（CPU 阶段）：</p>
<ul>
<li>映射临时缓冲；</li>
<li>执行 MLAA 后处理（临时缓冲同时是输入和输出）。</li>
</ul>
<p>第 3 步（GPU 阶段）：</p>
<ul>
<li>取消临时缓冲映射，将临时缓冲复制回 GPU 端颜色缓冲； </li>
<li>完成帧渲染（缩放框、UI）并呈现。</li>
</ul>
<p>为了实现此概念，我们设计了一个简单的管道类。每个阶段用一个 PipelineFunction 结构代表，该结构指定要调用的函数以及阶段类型。回调函数必须具有以下特征：</p>
<pre name="code" class="cpp">typedef void (*PPIPELINEFUNC)( UINT uInstance, ID3D11DeviceContext* pContext )</pre>
<p> </p>
<p>其中 uInstance 指示要从中调用函数的管道实例。GPU 阶段使用 DirectX* 查询（类型为 D3D11_QUERY_EVENT）来发送其完成信号，但 CPU 阶段必须显式调用管道的类 CompleteCPUWait 方法来发送完成信号：</p>
<pre name="code" class="cpp">    //  CompleteCPUWait signals an instance that expects an CPU wait in order
    //  to complete. When the Pipeline reaches that instance, it will be complete
    //  for that stage in the pipeline.
    VOID
    CompleteCPUWait(
        UINT                    uInstance );
</pre>
<p>创建管道实例时需要调用一次 Init 方法。在我们的示例中，代码如下：</p>
<pre name="code" class="cpp">	PipelineFunction Func[ 2 ];
	Func[0].Type = PIPELINE_EVENT_COMPLETE;
	Func[0].pFunc = AnimateAndRenderScene;
	Func[1].Type = PIPELINE_CPU_COMPLETE;
	Func[1].pFunc = MLAAPostProcessing;

	g_Pipeline.Init(g_NumPipelineInstances, ARRAYSIZE( Func ), Func, g_pPipelineQueries );
</pre>
<p>其中 g_NumPipelineInstances 是要创建的管道实例数量（本例中为 3 个）。</p>
<p>为了运行这些管道，我们为每个帧调用 Start 方法：</p>
<pre name="code" class="cpp">    //  Start is used to execute the Pipeline.  Processing will continue until
    //  an instance in the pipeline completes.  The index of that instance is
    //  return.  PIPELINE_INVALID is returned if the Pipeline was set to flush
    //  and there are no more instances left in the Pipeline.
    UINT
    Start(
        ID3D11DeviceContext*    pContext,       //  Context to issue Event query on.
        
        BOOL                    bFlush = FALSE  //  If bFlush is TRUE, the Pipeline
                                                //  will not create new instances.
                                                //  Specify TRUE if you want to flush
                                                //  the Pipeline.
        );
</pre>
<p>因为 Start 方法会返回已完成管道实例的索引，因此不必通过管道类来第三步（即最后一步）。最后一步的代码在调用 Start 方法后立即执行，使用 Start 返回的索引来建立数据结构索引。</p>
<p>管道传输不依赖于任务处理 API WaitForSet 调用，因为它会起阻止作用，不允许发生管道传输。解决方法是使用一个“完成任务集”，这是一种依赖于所有 MLAA 任务完成的任务，其唯一作用是调用 CompleteCPUWait 方法。</p>
<p> </p>
<h2 class="sectionHeading">英特尔® SSE 优化</h2>
<p>第一个 MLAA 算法通道是确定像素间的中断。从概念上讲，每个像素会检查其颜色并将其与下方相邻像素（在查找横向中断时）或右侧相邻像素（在查找纵向中断时）进行比较 [Reshetov09，第 2.2.1 节]。</p>
<p>在此示例中，我们保留了参考实施的简单中断检测内核。如果两个像素的 RGB 颜色分量差异至少达到 16（采用 RGBA8 格式的 0-255 标量），则这两个像素之间存在中断。</p>
<p>这个定义在示例中有着出色的表现，可以实现非常简洁高效的 SIMD。但是，也可以采用更加复杂的方法（有时是必要的）来获得最佳可能结果。例如，可以使用像素的亮度而不直接比较颜色值，可变阈值重新计算每个帧以考虑场景的整体亮度和对比度 [Luminance]。深度值可以用来帮助进行边界检测，也可使用任何一种自定义数据从处理中排除特定的颜色缓冲区域。</p>
<p>因为这一步是独立于其余算法的，因此将在 CPU 上运行，可以将来自程序的任何数据直接用作输入数据。检测算法仅有的限制包括：</p>
<ul>
<li>算法必须为每个像素提供一位输出，指示是否检测到中断；</li>
<li>性能与质量/复杂性之间的权衡；</li>
<li>程序员的想像力。</li>
</ul>
<p>与原始参考实施一样 [Reshetov09，第 2.4 节]，我们使用 RGBA8 渲染目标格式，由 MLAA 计算得出的“纵向中断”和“横向中断”位标志按原状存储在像素数据的两个高位中（即，不受 MLAA 混合运算影响的两个阿尔法分量高位中）。这样可让实施保持简单，同时有助于减少内存占用，并可在算法的下一步中实现优化（请参阅下面的“转置优化”一节）。</p>
<p>因为每个像素是 32 位数据，并且可在此步骤中互相独立地处理每个像素，因此我们可以使用英特尔® SSE 内部指令同时处理 4 个像素。检测代码很短。</p>
<pre name="code" class="cpp">	
	//---------------------------------------------------------------------------------------
	// Given a row of pixels, check for color discontinuities between a pixel and its
	// neighbor. Intel SSE implementation, so we process all 4 pixels in the row at a time.
	// If a discontinuity is detected, the corresponding flag is set in the alpha component of the pixel.
	//---------------------------------------------------------------------------------------
	inline void ComparePixelsSSE(__m128i&amp; vPixels0, __m128i vPixels1, const INT EdgeFlag)
	{
	// Each byte of vDiff is the absolute difference between a pixel's color channel value, and the one from its neighbor.
		__m128i vDiff = _mm_sub_epi8(_mm_max_epu8(vPixels0, vPixels1), 
									 _mm_min_epu8(vPixels0, vPixels1));
	// We are only interested if the diff. is &gt;16, and not interested in alpha differences.
		const INT Threshold = 0x00F0F0F0;
		__m128i vThresholdMask = _mm_set1_epi32(Threshold);
		vDiff = _mm_and_si128(vDiff, vThresholdMask);
	// Each of the four lanes of the selector is 0 if no discontinuity detected RGB, 0xFFFFFFFF else.
		__m128i vSelector = _mm_cmpeq_epi32(vDiff, _mm_setzero_si128());
</pre>
<p>然后，参考实施继续更新每个像素的阿尔法分量，但使用低效串行代码来执行此运算。我们可以使用以下英特尔® SSE 代码优化此序列：</p>
<pre name="code" class="cpp">	
	__m128i vEdgeFlag = _mm_set1_epi32(EdgeFlag);
	vEdgeFlag = _mm_andnot_si128(vSelector, vEdgeFlag);
	// vEdgeFlag now contains EdgeFlag for the pixels where a discontinuity was detected, 0 otherwise.
	vPixels0 = _mm_or_si128(vPixels0, vEdgeFlag);
</pre>
<p>我们还替换了 MixColors 函数（用于计算两种颜色的线性插值）以使用完整的英特尔® SSE 实施内容。</p>
<p> </p>
<h2 class="sectionHeading">转置优化</h2>
<p>算法的下一步是查找“中断行”，即在处理颜色缓冲的行和列过程中标记了相同中断标志（横向混合通道的横向标志，纵向混合通道的纵向标志）的连续像素序列 [Reshetov09，第 2.1 节]。</p>
<p>因为中断行一般都很短，凭直觉可以知道（并通过分析数据确认）此运算开销最大的部分是在中断行之间扫描，即扫描没有设置中断标志的大范围连续像素区域。</p>
<p>有利的一面是，当满足以下条件时，我们可以用 _mm_movemask_ps Intel® SSE 内部指令一次检查 4 个像素：</p>
<ol>
<li>正在扫描存储在连续地址上的 4 个像素；</li>
<li>第一个像素的地址是“英特尔® SSE 对齐的”（16 字节对齐）；</li>
<li>中断标志存储为 32 位像素数据的高位。</li>
</ol>
<p>在横向混合通道传送过程中，(1) 为真（我们扫描以像素数据的 2D 线性阵列表示的颜色缓冲中的横向像素行）；(2) 几乎总是为真（请记住，当缓冲正确对齐时，16 字节对齐等效于“缓冲中起始像素的索引是 4 的倍数）；当我们选择位 31 来表示横向中断标志时 (3) 为真。</p>
<p>如果所有条件都为真，我们将计算标志：</p>
<pre name="code" class="cpp">	__m128 PixelFlags = *(reinterpret_cast&lt;__m128*&gt;(WorkBuffer + OffsetCurrentPixel));
	// Creates a 4-bit mask from the most significant bits
	int HFlags = _mm_movemask_ps(PixelFlags);	
</pre>
<p>可能会有五个结果，具体取决于 Hflags 的值：</p>
<ul>
<li>0（目前为止最常见的情况）：在这组 4 个像素中没有设置中断标志，转至下一组 4 个像素。</li>
<li>设置位 0：中断行始于该组的第一个像素。</li>
<li>设置位 1：中断行始于该组的第二个像素。</li>
<li>设置位 2：中断行始于该组的第三个像素。</li>
<li>设置位 3：中断行始于该组的第四个像素。</li>
</ul>
<p>此项优化是参考实施内容的一部分，适用于横向混合通道传送，但不适用于纵向混合通道传送。当代码对缓冲进行纵向扫描时，(1) 为假（列中的相邻像素不是存储在连续地址中），(3) 也为假（纵向中断标志存储在像素数据的位 30 上）。</p>
<p>如果我们处理的是纵向标志，则通过引入简单的“向左转换一位”运算轻松解决 (3) 的问题，将上面的代码转换为：</p>
<pre name="code" class="cpp">	int Shift = (EdgeFlag == EdgeFlagV) ? 1 : 0;
	__m128 PixelFlags = *(reinterpret_cast&lt;__m128*&gt;(WorkBuffer + OffsetCurrentPixel));
	PixelFlags = _mm_castsi128_ps( _mm_slli_epi32(_mm_castps_si128(PixelFlags), Shift) );
	int HFlags = _mm_movemask_ps(PixelFlags);
</pre>
<p>但 (1) 仍然是个问题。此外，纵向扫描对缓存的要求极高。由于存在以上两个问题，在参考实施中纵向混合通道传送的开销大约是横向混合通道传送的 3 倍（300%！），如数据分析所示。</p>
<p>我们解决此问题的方法是让纵向混合通道传送使用缓存以及适合英特尔® SSE 指令的横向混合通道传送数据存取模式，将颜色缓冲看作像素阵列并将其在通道之间进行转置：</p>
<ul>
<li>执行横向混合通道传送</li>
<li>转置（横向混合的）颜色缓冲</li>
<li>执行纵向混合通道传送</li>
<li>逆转置颜色缓冲</li>
</ul>
<p>这样一来，两种混合通道传送的代码就完全相同了（增加了简单性/可读性方面的优势），唯一的差异是要扫描的标志，我们将受益于所有优化以及较低的横向通道传送缓存要求。</p>
<p>在实践中，转置运算并不以单独的通道/任务集形式实施，而是作为其对应混合通道的最后一部分实施。这样可让我们利用缓存结果。</p>
<p>两种转置运算都需要开销。开销包括额外的代码执行时间、一个额外的工作缓冲以及横向和纵向通道之间的一个同步点（我们必须等到所有横向任务完成后才能开始任何纵向任务，因为我们必须等到颜色缓冲完全转置后才能开始纵向通道传送工作）。</p>
<p>即使有这些额外的开销，整体性能也明显好于以前的方法。数据分析结果与预期相符，两种混合通道有同等的性能。</p>
<p> </p>
<h2 class="sectionHeading">性能结果</h2>
<p>MLAA 性能是在以下两种配置上测量的：</p>
<ul>
<li>代码名称“Huron River”：英特尔® 酷睿™ i7-2820QM 处理器（英特尔® 微架构代码名称 Sandy Bridge，4 核 8 线程，2.30 GHz）以及 GT2 图形处理器，4 GB 内存，Windows 7 旗舰版 64 位 Service Pack 1 </li>
<li>代码名称“Kings Creek”：英特尔® 酷睿™ i5-660 处理器（代码名称“Clarkdale”，双核 4 线程，3.33 Ghz），采用 GMA HD 图形处理器（代码名称“Ironlake”），2 GB 内存，Windows 7 旗舰版 64 位 Service Pack 1</li>
</ul>
<p>我们测量了示例代码的平均帧渲染时间，并以不同抗锯齿处理设置的场景复杂性函数表示。我们还测量了“仅复制/映射/取消映射”模式的渲染时间，以突出颜色缓冲复制运算对算法整体性能的影响。</p>
<p> </p>
<h2 class="sectionHeading">结果</h2>
<p>数据显示，对于 Huron River 计算机，MSAA 4x 和额外开销随场景复杂性呈线性上升（事实上，对于所有分辨率，使用 MSAA 4x 渲染测试场景时的帧时间几乎是不使用抗锯齿处理时帧时间的两倍）。相比之下，MLAA 的开销几乎不变（在 1280x800 分辨率下为 4 毫秒/帧左右）。这与我们的预期一致，因为 MLAA 不像 MSAA 4x，它是每帧仅执行一次，不考虑场景复杂性/绘制调用次数。</p>
<p>我们还观察到，除了很低的复杂性值（即小于 5 左右），不管何种分辨率，MLAA 的表现都始终优于 MSAA 4x，性能上的差异随复杂性增加（因为如前所述，MSAA 4x 的开销随复杂性呈线性上升，而 MLAA 的开销则不会）。</p>
<p>对于 Kings Creek 计算机，我们无法比较 MLAA 与 MSAA 4x 的开销，因为 Ironlake 硬件未提供后者。因此，此项测量的目的是确定 MLAA 是否允许我们提供软件抗锯齿处理作为替代以获得可接受的性能。我们在 1280x800 分辨率下的测量显示，MLAA 的开销仍然主要与场景复杂性相关，平均值为 7.5 毫秒左右（不考虑复杂性 = 100 时的外部数据点）。</p>
<p>有趣的是，如果我们将此结果与具有和 Huron River 几乎相同的性能配置文件（MSAA 4x 帧时间约等于 2 倍无锯齿处理的帧时间）的假设 MSAA 4x 实施比较，我们再次注意到 MLAA 在几乎所有复杂性值（本例中为 ≥4）下的表现都优于 MSAA 4x。</p>
<p ><img src="http://software.intel.com/file/37405"  /> <br /><b>表 1. </b><i>我们在 Kings Creek 计算机上的测试场景的渲染时间。</i></p>
<p ><img src="http://software.intel.com/file/37406"  /> <br /><b>表 2.</b><i>我们在 Huron River 计算机上的测试场景的渲染时间。</i></p>
<p ><img src="http://software.intel.com/file/37407"  /> <br /><b>图 6：</b><i>我们针对每种抗锯齿处理技术的测试场景的渲染时间，以场景复杂性的函数表示。在底部，平缓曲线是“打开管道的 MLAA”曲线与“无抗锯齿处理”曲线之间的差异，测量使用 MLAA 的开销 [Huron River，分辨率 1280x800]</i></p>
<p ><img src="http://software.intel.com/file/37408"  /> <br /><b>图 7：</b><i>我们针对每种抗锯齿处理技术的测试场景的渲染时间，以场景复杂性的函数表示。在底部，平缓曲线是“打开管道的 MLAA”曲线与“无抗锯齿处理”曲线之间的差异，测量使用 MLAA 的开销 [Huron River，分辨率 1600x1200]</i></p>
<p ><img src="http://software.intel.com/file/37409"  /> <br /><b>图 8：</b><i>我们打开和关闭 MLAA 的测试场景的渲染时间，以场景复杂性的函数表示。在底部，平缓曲线是“打开管道的 MLAA”曲线与“无抗锯齿处理”曲线之间的差异，测量使用 MLAA 的开销 [Kings Creek，分辨率 1280x800]</i></p>
<h2 class="sectionHeading">参考资料</h2>
<p>[Reshetov 2009] RESHETOV, A. 2009. “<a href="http://visual-computing.intel-research.net/publications/papers/2009/mlaa/mlaa.pdf">Morphological Antialiasing</a>”</p>
<p>[Perthuis 2010] PERTHUIS, C. 2010. MLAA in God of War 3. Sony Computer Entertainment America, PS3 Devcon, Santa Clara, July 2010.</p>
<p>[Jimenez et al., 2011] JIMENEZ, J., MASIA, B., ECHEVARRIA, J., NAVARRO, F. and GUTIERREZ, D. 2011. Practical Morphological Anti-Aliasing. In Wolfgang Engel, ed., GPU Pro 2. AK Peters Ltd.</p>
<p>[SIGGRAPH 2011] JIMENEZ, J., GUTIERREZ D., YANG, J., RESHETOV, A., DEMOREUILLE, P., BERGHOFF, T., PERTHUIS, C., YU, H., MCGUIRE, M., LOTTES, T., MALAN, H., PERSSON, E., ANDREEV, D. and SOUSA T. 2011. Filtering Approaches for Real-Time Anti-Aliasing. In <i>ACM SIGGRAPH 2011 Courses.</i></p>
<p>[Luminance] CRT 类设备的照明清晰度：</p>
<p>国际照明委员会。1971 年。统一颜色空间、色差方程式、心理颜色推荐术语。对 CIE 15 号出版物 15 (E.-1.3.1), TC-1.3, 1971 的第二个补充。</p>
<p>针对 LCD：</p>
<p>ITU-R 推荐。BT.709-5. 2008. 第 18 页 1.3 条和 1.4 条</p> ]]></description>
      <link>http://software.intel.com/zh-cn/articles/mlaa-efficiently-moving-antialiasing-from-the-gpu-to-the-cpu/</link>
      <pubDate>Wed, 14 Sep 2011 09:00:00 -0700</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/mlaa-efficiently-moving-antialiasing-from-the-gpu-to-the-cpu/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/mlaa-efficiently-moving-antialiasing-from-the-gpu-to-the-cpu/</guid>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
    </item>
    <item>
      <title>动态分辨率渲染文章</title>
      <description><![CDATA[ <h2 class="sectionHeading">下载文章和源代码<br /></h2>
英文版下载：<a href="http://software.intel.com/file/37639">动态分辨率渲染</a> [PDF 1.1MB]<br />访问<a href="http://software.intel.com/zh-cn/articles/dynamic-resolution-rendering">动态分辨率示例页</a>可下载源代码。<br /><br /><br />
<h2 class="sectionHeading">简介</h2>
自从 3D 游戏诞生以来，分辨率选择屏幕已经成 PC 游戏的一项特色内容。在本白皮书以及随附的示例代码中，我们证明了这种情况将会逐渐消失；开发者将可以动态改变其渲染的分辨率，而不必进行静态的分辨率选择。<br /><br />动态分辨率渲染需要通过以下方式调整 3D 场景的渲染分辨率：使用视口将渲染限制到渲染目标的一部分，然后将此部分缩放到输出后置缓冲。然后，图形用户界面组件可以用后置缓冲分辨率进行渲染，这些元素的绘制开销一般较低。最终，场景可以使用高质量的 GUI 获得稳定的高帧速率。<br /><br />我们将在本文中展示性能结果和屏幕快照，这些结果和快照取自预发行的第二代移动英特尔® 酷睿™ i7 处理器（英特尔® 微架构代码名称 Sandy Bridge，D1 步进四核 2.4 GHz CPU，4GB DDR3 1333MHz 内存）和英特尔® 核芯显卡 3000。<br /><br />本文和随附的示例最初曾在 2011 年旧金山游戏开发者大会 (GDC) 上展示，展示视频可在 GDC Vault [GDC Vault 2011] 上找到，该展示的幻灯片可在英特尔网站 [英特尔 GDC 2011] 上找到。自该次展示以后，笔者发现已经有几家游戏公司在游戏机上使用此技术；来自 LucasArts Dmitry Andreev 关于抗锯齿处理的展示是唯一公开的数据源，但有关使用的动态分辨率技术详情很少 [Andreev 2011]。<br /><br />
<p ><img src="http://software.intel.com/file/37642" /></p>
<div ><b>图 1：</b> <i>通过其中一个静态镜头视口看到的示例场景。<br /></i></div>
<h2 class="sectionHeading">动机</h2>
游戏在不同分辨率下的性能变化非常多样，渲染复杂性的增加以及后处理技术的发展，使得每像素开销继续在最新游戏中占据重要地位。提高分辨率还会增加纹理采样和渲染目标的带宽。因此，设置适合系统性能的分辨率非常重要。如果可以动态地改变分辨率，开发者就可以获得额外的性能控制选项，可以让游戏保持稳定而合适的帧速率，从而提高整体体验质量。<br /><br />以原始屏幕分辨率渲染图形用户界面对角色扮演、实时战略和大型多人游戏尤其重要。突然之间，即使是在低端系统上，游戏玩家都可以在观察其队友的统计数据的同时，使用复杂的聊天消息处理功能。<br /><br />最后，随着 PC 游戏逐渐移植到笔记本电脑上，功耗问题开始成为与游戏开发相关的问题。当计算机从使用电源转到使用电池时，性能设置可能导致降低 CPU 和 GPU 频率，而采用动态分辨率渲染以后，游戏可以自动调整分辨率进行补偿。有些游戏可能需要向用户提供低功耗配置方案，以进一步降低功耗，实现延长游戏时间。样本实验发现，在启用垂直同步以保持帧速率的情况下，将分辨率降低一半可将处理器正常功耗降低 30%。<br /><br /><br />
<h2 class="sectionHeading">基本准则</h2>
动态分辨率渲染的基本准则是使用视口将渲染限制为屏幕外渲染目标的一部分，然后缩放视图。例如，渲染目标的大小可能是 (1920, 1080)，但视口可能有一个原点 (0, 0)，大小为 (1280, 720)。<br /><br />
<p ><img src="http://software.intel.com/file/37643" /></p>
<div ><b>图 2：</b> <i>使用视口限制渲染</i><br /></div>
<br />通过创建大于后置缓冲的渲染目标，动态分辨率可以从二次采样变为超级采样。此处需要注意确保需要的全部渲染目标和纹理在显存的支持范围之内，但基于英特尔® 微架构（代码名称 Sandy Bridge）处理器图形的系统通常有相当大的显存，因为它们使用系统内存。<br /><br />
<p ><img src="http://software.intel.com/file/37808" alt="DRR_figure3.jpg" title="DRR_figure3.jpg" /></p>
<div ><b>图 3：</b> <i>动态分辨率可以从二次采样变为超级采样</i><br /></div>
<br />正常渲染到动态视口时，不需要进行任何更改，光栅化规则可确保这种情况得到处理。但是，在渲染目标中读取时，需要注意相应地缩放坐标，并处理右边界和底边界上的锁定。<br /><br />以下像素渲染示例代码展示了如何锁定 UV。这主要用于进行相关读取时（即，当在 UV 上按像素运行时，这随后会用于从动态渲染目标中采样）。<br /><br />
<pre name="code" class="cpp">// Clamp UVs to texture size
// PSSubSampleRTCurrRatio is the fraction of the render target in use.
float2 clampedUV = min( unclampedUV,  g_PSSubSampleRTCurrRatio.xy );
</pre>
如果出现需要额外运算的运动模糊（一种常见的后处理运算，使用来自渲染目标的相关读取），这不会对性能有多少影响，因为渲染受纹理提取的制约。<br /><br />
<p ><img src="http://software.intel.com/file/37809" alt="DRR_figure4.jpg" title="DRR_figure4.jpg" /></p>
<div ><b>图 4：</b> <i>由于运动模糊而在屏幕边缘产生的颜色泄露，这可以通过使用锁定解决</i><br /></div>
<br />除了锁定，确保渲染中使用的分辨率代表实际视口比率而不仅是应用程序所需的比率也很重要。这一点可通过根据动态视口尺寸重新计算比率很容易地实现。例如，在示例代码函数 DynamicResolution::SetScale 中，在确保缩放达到边界标准后会执行以下内容：<br /><br />
<pre name="code" class="cpp">// Now convert to give integer height and width for viewport
m_CurrDynamicRTHeight	= floor( (float)m_DynamicRTHeight * m_ScaleY / m_MaxScalingY );
m_CurrDynamicRTWidth	= floor( (float)m_DynamicRTWidth *  m_ScaleX / m_MaxScalingX );

// Recreate scale values from actual viewport values
m_ScaleY = m_CurrDynamicRTHeight * m_MaxScalingY / (float)m_DynamicRTHeight;
m_ScaleX = m_CurrDynamicRTWidth *  m_MaxScalingX / (float)m_DynamicRTWidth;<br /> </pre>
<br /><b>缩放过滤器</b><br />在渲染了 3D 场景后，视口区域需要缩放到后置缓冲分辨率。多种过滤器可用于执行此操作，示例代码采用了此处描述的多个示例。<br /><br /><b>点过滤</b><br />点过滤是一种快速的基本过滤选项。从 0.71 倍比率动态视口缩放为 1280x720 耗时大约 0.4 毫秒。<b><br /><br />双线性过滤</b><br />因为有硬件支持，双线性过滤的速度几乎与点过滤一样快，它可以通过平滑处理减少边缘的失真伪影，但也会模糊场景。从 0.71 倍比率动态视口缩放为 1280x720 耗时大约 0.4 毫秒。<br /><br /><b>双立体过滤</b><br />双立体过滤仅在 0.5 倍后置缓冲分辨率时明显优于双线性过滤，即使使用快速双立体过滤器，其性能也将下降 7 倍 [Sigg 2005]。从 0.71 倍比率动态视口缩放为 1280x720 耗时大约 3.5 毫秒。<br /><br /><b>噪声过滤</b><br />在点过滤中增加一些噪声有助于增加高频率，这样可用较低的开销略微改善失真。示例中是相当基本的实现内容，改进后的胶片颗粒过滤可能适合于进行艺术渲染。从 0.71 倍比率动态视口缩放为 1280x720 耗时大约 0.5 毫秒。<br /><br /><b>噪声偏移过滤</b><br />在缩放过程中为采样位置增加一个很小的随机偏移可降低失真边界的不规则性。这种方法常用于阴影贴图快速过滤。从 0.71 倍比率动态视口缩放为 1280x720 耗时大约 0.7 毫秒。<br /><br /><b>临时抗锯齿处理过滤</b><br />此缩放过滤器需要在初始渲染路径中的额外支持，在 X 和 Y 轴上以半个像素渲染奇偶帧偏移。通过智能过滤消除伪影时，获得的图像质量会因为两位像素的采样而获得充分改善。这种过滤方法将在下面的相应章节中进行更加深入的介绍。从 0.71 倍比率动态视口缩放为 1280x720 耗时大约 1.1 毫秒，其质量与渲染为最高分辨率的质量几乎相同。<br /><br /><b>临时抗锯齿处理详细信息</b><br />临时抗锯齿处理出现已经有一段时间了；但是，由于连续帧中物体位置的差异而导致的拖影问题限制了它的使用。最新的渲染技术最终因为它的低性能开销而使其成为一个有吸引力的选择。<br /><br />基本的方法是在 X 和 Y 轴上渲染半个像素的奇偶帧抖动（偏移）。示例代码通过转换投影矩阵实现这点。然后，最终缩放会组合当前帧和上一个帧，通过反转它们抖动的量对其进行偏移。这样，最终图像通过将以类似于骰子上第五面上点排列模式排列的像素数加倍实现。<br /><br />
<p ><img src="http://software.intel.com/file/37646" /></p>
<div ><b>图 5：</b> <i>临时抗锯齿处理基本准则</i><br /></div>
<br />此方法与动态分辨率一起使用，当动态分辨率低于后置缓冲时，可以增加场景中观察到的像素数量，从而改善场景中的细节。当动态分辨率等于或高于后置缓冲时，结果就是一种抗锯齿处理形式。<br /><br />
<p ><img src="http://software.intel.com/file/37647" /></p>
<div ><b>图 6：</b> <i>动态分辨率低于后置缓冲时临时抗锯齿的结果</i><br /><br /></div>
<br />
<p ><img src="http://software.intel.com/file/37648" /></p>
<div ><b>图 7：</b> <i>动态分辨率等于或高于后置缓冲时临时抗锯齿的结果</i><br /><br /></div>
<br />为了提高纹理分辨率，需要将 MIP LOD 偏移应用于纹理。在 Microsoft Direct3D* 11 中，在 3D 场景传递过程中使用的 D3D11_SAMPLER_DESC MipLODBias 为 -0.5f。此外，在缩放过程中使用的采样器需要使用双线性缩小过滤，例如：D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT。<br /><br />为了减少拖影，我们使用针对运动模糊写出的速率缓冲。重要的是，这种缓冲包含屏幕空间中每个像素的速率，因此会影响镜头移动。缩放系数是根据当前帧及上一帧的速率计算出来的，应用于上一帧的颜色以确定其对最终图像的影响。这将根据采样位置在两个帧中的实际空间中的相似性来调整其影响比例。<br /><br />
<p ><img src="http://software.intel.com/file/37649" /></p>
<br />示例经过 K 优化，可以提供笔者所认为的实时应用最佳结果，在实际可播放的帧速率下没有观察到拖影。屏幕快照显示了高对比区的少量拖影（如下面的屏幕快照中所示），这可以根据需要通过优化消除。<br /><br />对于游戏来说，透明度呈现了无法始终渲染速度信息方面的一个特定问题。在这种情况下，在向前渲染透明度的过程中可使用阿尔法通道来存储用于缩放影响因素的值，所采用方式与当前使用速度的方式大致相同。<br /><br />这种拖影消除方法的一种替代方法是使用屏幕空间速度从当前像素所在位置的前一个帧中采样。这是在 CryENGINE* 3 中使用的技术，首次呈现是在游戏《孤岛危机* 2》 [Crytek 2010]。有趣的是，LucasArts 的 Dmitry Andreev 曾考虑使用临时抗锯齿处理，但由于在其引擎中使用了动态分辨率而没有采用 [Andreev 2011]。笔者认为它们是兼容的，如示例代码中所示。<br /><br />
<p ><img src="http://software.intel.com/file/37650" /></p>
<div ><b>图 8：</b> <i>用于速度缩放和运动物体的临时抗锯齿处理<br /></i></div>
<br />
<h2 class="sectionHeading">运动模糊的效果</h2>
运动模糊会让像素模糊，有效地减少观察到的锯齿，因此摄像头移动时可以使用较低的分辨率。但是，示例在其分辨率控制算法中并没有利用这种做法。以下屏幕快照展示了将分辨率降低到 0.71 倍时，后置缓冲如何在保持几乎相同图像的情况下获得更高性能。与各种运动模糊采样率结合，这可能是一种减少采样不足导致伪影的方法，在保持性能稳定的同时采用大镜头运动。<br /><br />
<p ><img src="http://software.intel.com/file/37651" /></p>
<div ><b>图 9：</b> <i>关闭动态分辨率时的运动模糊</i><br /><br /></div>
<br />
<p ><img src="http://software.intel.com/file/37652" /></p>
<div ><b>图 10：</b> <i>打开动态分辨率时 0.71 倍分辨率下的运动模糊。请注意帧速率降低但质量相似的最终结果</i><br /></div>
<br />
<h2 class="sectionHeading">超级采样</h2>
超级采样是一种简单的技术，其中用于渲染场景的渲染目标大于后置缓冲。这种技术在很大程度上已被当前的实时渲染群体所忽略，多次采样抗锯齿处理及其他技术已经取代了它的用途，因为它们有更好的内存开销和性能。<br /><br />使用动态分辨率可以显著降低增加超级采样的性能影响，因为使用的实际分辨率可以进行动态调整。这对启用超级采样的性能影响很小，主要是因为清除较大缓冲导致了额外开销。示例代码在启用超级采样时实现了 2 倍分辨率渲染目标，但相对于后置缓冲分辨率的较小分辨率增加获得了很好的质量，因此，如果内存紧张，可以使用较小的渲染目标。在处理器图形平台上，内存的问题不是那么严重，因为 GPU 可以访问相对较大的系统内存，并且可以充分利用所有系统内存。<br /><br />集成了动态分辨率渲染方法后，使用超级采样就不那么重要了。我们鼓励开发者考虑这种技术，因为它可能对较小的屏幕有益，对于可能有足够的性能以超最大质量运行的游戏的未来硬件也会有益。<br /><br /><br />
<h2 class="sectionHeading">渲染目标清除</h2>
由于动态分辨率渲染不会总是使用整个渲染目标表面，因此它可以用于仅清除所需的部分。示例实施了像素渲染器清除，在测试的英特尔® 核芯显卡 3000 系统上，如果 1280x720 后置缓存的动态分辨比率小于 0.71 倍，像素渲染器清除的性能高于标准清除。在许多情况下，可能不必清除渲染目标，因为每个帧会将其完全覆盖。<br /><br />深度缓冲仍可使用标准清除方法完全清除，因为它们可能实施分层深度。有些多次采样的目标还可能会使用压缩，因此应进行正常清除。<br /><br /><br />
<h2 class="sectionHeading">性能扩展</h2>
尽管由于大量无级别细节和只有简单剔选的高度细节化场景产生了大量高顶点处理负载，示例代码也很好地实现了随分辨率扩展。这使得选择的控制方法明显有利于所需级别的帧速率保持。<br /><br />大多数游戏使用细节级别机制来控制顶点负载。如果这些级别与对象的大致像素大小关联，则将能够得到更大的性能扩展。<br /><br />
<p ><img src="http://software.intel.com/file/37653" /></p>
<div ><b>图 11：</b> <i>1280x720 下的动态分辨率性能</i><br /></div>
<br />
<h2 class="sectionHeading">分辨率控制</h2>
示例实现了手动控制以外的分辨率控制方法。该代码保存在 DynamicResolutionRendering.cpp 文件中的 ControlResolution 函数中。所需的性能可在刷新率（通常为 60Hz 或 60FPS）和一半刷新率（通常为 30FPS）之间选择。<br /><br />控制方案是基本方案：分辨率缩放增量根据所需帧时间和当前帧时间中的无量纲差异按比例计算。<br /><br />
<p ><img src="http://software.intel.com/file/37654" /></p>
其中 <em>S' </em>是新的分辨率缩放率，<em>S</em> 是当前分辨率缩放率，<img src="http://software.intel.com/file/37641" />是缩放增量，<em>k</em> 是变化率常量，<em>T</em> 是所需的帧时间，<em>t</em> 是当前帧时间。<br /><br />当前帧时间使用 GPU 内部帧时间（不包括使用 Microsoft DirectX* 查询计算的当前帧时间）与以正常方式根据帧之间的间隔计算的帧时间的平均值。GPU 内部帧时间在启用了垂直同步时是必需的，在这种情况下，帧时间会受同步率限制，但我们需要知道实际渲染时间是否比该时间短。用实际帧速率进行平均可帮助同时考虑当前工作负载与部分 CPU 帧工作负载。如果实际帧时间显著大于 GPU 内部帧时间，则将被忽略，因为这一般是由 CPU 副峰值（如从窗口变为全屏）造成的。<br /><br /><br />
<h2 class="sectionHeading">潜在的改进</h2>
以下列表并不完整，只是列出了笔者认为是当前工作自然延伸的一些功能：<br /><br />
<ul>
<li>将动态分辨率场景渲染与类似的阴影贴图方法结合。 </li>
<li>将此技术与单独的控制机制一起用于粒子系统，仅在渲染少数小颗粒时允许提升质量，在填充率提高时提高性能。</li>
<li>该技术与也可与应用于临时抗锯齿处理的其他抗锯齿技术兼容。</li>
<li>临时抗锯齿处理可以使用改进的加权和，该加权和与到当前和上一个帧的像素中心的距离有关，而不仅是混合总和。也可使用与速率相关的偏移读取，如在 CryENGINE* 3 中所用的那样 [Crytek 2010]。</li>
<li>有些游戏可能会得益于对较小图像区域运行更高的抗锯齿处理技术，例如针对主要人物或用鼠标亮显的 RTS 单位。</li>
</ul>
<h2 class="sectionHeading">结论</h2>
动态分辨率渲染为开发者提供了以最少的用户干预改善整体质量所必需的工具，在与临时抗锯齿处理技术使用时更是如此。鉴于 PC GPU 市场上的性能范围很大，我们鼓励开发者使用此技术作为其获得所需游戏帧速率的方法。<br /><br /><br />
<h2 class="sectionHeading">参考资料</h2>
[Sigg 2005] Christian Sigg、Martin Hadwiger，“快速第三级过滤”，GPU Gems 2. Addison-Wesley, 2005.<br /><br />[Crytek 2010] HPG 2010“游戏中的未来图形”，Cevat Yerli 和 Anton Kaplanyan。<a target="_blank" href="http://www.crytek.com/cryengine/presentations">http://www.crytek.com/cryengine/presentations</a><br /><br />[GDC Vault 2011] <a target="_blank" href="http://www.gdcvault.com/play/1014646/-SPONSORED-Dynamic-Resolution-Rendering">http://www.gdcvault.com/play/1014646/-SPONSORED-Dynamic-Resolution-Rendering</a><br /><br />[Intel GDC 2011] <a href="http://software.intel.com/en-us/articles/intelgdc2011/">http://software.intel.com/en-us/articles/intelgdc2011/</a><br /><br />[Andreev 2011] <a target="_blank" href="http://www.gdcvault.com/play/1014550/Anti-aliasing-from-a-Different">http://www.gdcvault.com/play/1014550/Anti-aliasing-from-a-Different</a> [PPT 4.6MB] ]]></description>
      <link>http://software.intel.com/zh-cn/articles/dynamic-resolution-rendering-article/</link>
      <pubDate>Wed, 14 Sep 2011 09:00:00 -0700</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/dynamic-resolution-rendering-article/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/dynamic-resolution-rendering-article/</guid>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
    </item>
    <item>
      <title>英特尔® 软件学院系列课程技术书籍之视觉计算应用开发</title>
      <description><![CDATA[ <div >
<div align="center">
<p>
<h2>英特尔® 软件学院系列课程技术书籍<br />之<br />视觉计算应用开发</h2>
</p>
</div>
<div>
<table>
<tbody>
<tr>
<td width="120" valign="top"><img src="http://software.intel.com/file/38358" /></td>
<td>视觉计算（Visual Computng）技术的研究和应用对象并不是很清晰、严格，因此视觉计算技术在不同的上下文中可能会涉及多个领域，如数据可视化（Data Visualization）、计算机图形学（Computer Graphics）、数字图像处理（Image Processing）、多媒体技术（MultiMeida）、计算机视觉（Computer Vision）等，这些都可以称为视觉计算技术。图像和视频是视觉计算技术中重要的组成部分，信息时代大量的丰富信息都是通过数字图像和视频展示给每一个人。为了向程序员普及或推广数字图像和视频软件开发技术，降低视觉计算软件开发的门槛，我们这本书将介绍图像和视频处理的基础理论知识和英特尔公司提供的视觉计算软件开发库相结合，注重理论联系实际，强调实践。在每个章节，都配有相关实例来说明如果利用英特尔® 集成性能原件（Intel® IPP）开发相关应用关键代码。</td>
</tr>
</tbody>
</table>
<p><br />本书共分9 章，具体内容如下：<br />第一章、视觉计算软件开发基础。介绍软件开发相关技术，英特尔图像、视频高性能库开发包，以及编程环境介绍。<br />第二章、数字图像基础。详细介绍数字图像的基本概念，图像处理的常用技术，以及Intel®IPP 图像编程基础。<br />第三章、图像编码与文件格式。详细介绍常用编码技术，以及用Intel® IPP 实现JPEG 编码。<br />第四章、灰度、彩色图像增强。详细介绍亮度、对比度增强和彩色增强相关技术，以及用Intel® IPP 实现相关增强技术。<br />第五章、图像的平滑和锐化。详细介绍空间域和频域的图像平滑和锐化技术，以及用Intel® IPP 实现相关平滑和锐化技术。<br />第六章、图像几何变化。详细介绍图像的各种仿射变换，以及用Intel® IPP 实现相关图像几何变换技术。<br />第七章、数字视频基础。详细介绍视频编解码的基本原理和相关技术，以及用Intel® IPP和英特尔® 多媒体软件开发套件（Intel® Media SDK）实现相关编解码技术。<br />第八章、图像处理软件开发综合实例。综合前几章的内容，将通用的图像处理技术打包实现。同时添加了一个GUI 的图像几何变换的实例。<br />第九章、视频处理软件开发综合实例。详细分析音视频应用的一个架构及其实现。以及用DirectShow 开发视频播放程序。</p>
<p>本书可以作为软件程序工程师的参考书，也可作为大专院校相关专业的教学参考用书。</p>
<br /></div>
<div >
<h3 class="sectionHeading"><b>目录</b></h3>
<h4>序</h4>
<h4>前言</h4>
<h4>第 1 章 视觉计算软件开发基础</h4>
<span >1.1 视觉计算概述</span><br /><span >1.1.1 图像</span><br /><span >1.1.2 视频</span><br /><span >1.1.3 音频</span><br /><span >1.1.4 游戏</span><br /><span >1.2 软件开发与优化基础</span><br /><span >1.2.1 C 语言概述</span><br /><span >1.2.2 软件开发基本步骤</span><br /><span >1.2.3 软件测试与优化技术</span><br /><span >1.3 视觉计算软件开发平台</span><br /><span >1.3.1 可视化集成开发环境（IDE）</span><br /><span >1.3.2 控制台应用程序开发</span><br /><span >1.3.3 Intel® C++编译器</span><br /><span >1.3.4 Intel® Debugger 调试工具</span><br /><span >1.3.5 Intel® VTune 性能分析器</span><br /><span >1.3.6 Intel® Parallel Studio 并行工作室</span><br /><span >1.3.7 Intel® IPP</span><br /><span >1.3.8 Intel® MediaSDK</span><br /><span >1.4 上机实验</span><br /><span >1.4.1 实验一 编写简单的C/C++程序并进行优化</span><br /><span >1.4.2 实验二 用IPP 库编写简单的C/C++程序</span><br />
<h4>第 2 章 数字图像基础</h4>
<span >2.1 数字图像概述</span><br /><span >2.1.1 什么是数字图像</span><br /><span >2.1.2 数字图像的获取与表示</span><br /><span >2.1.3 数字图像的特点</span><br /><span >2.2 图像基本概念</span><br /><span >2.2.1 像素与灰度</span><br /><span >2.2.2 采样量化</span><br /><span >2.2.3 三基色原理</span><br /><span >2.2.4 彩色模型（RGB、YUV、YCbCr、HSV、HLS）</span><br /><span >2.2.5 IPP 库所支持的图像格式</span><br /><span >视觉计算应用开发</span><br /><span >2.2.6 图像增强基础</span><br /><span >2.3 图像变换</span><br /><span >2.3.1 图像变换的目的</span><br /><span >2.3.2 图像变换的种类（DFT/FFT、DCT）</span><br /><span >2.3.3 图像变换的应用</span><br /><span >2.3.4 IPP 库中的二维图像线性变换函数</span><br /><span >2.4 图像压缩编码</span><br /><span >2.4.1 信息编码</span><br /><span >2.4.2 无损压缩</span><br /><span >2.4.3 有损压缩</span><br /><span >2.5 IPP 图像处理编程基础</span><br /><span >2.5.1 内存中图像数据的定义</span><br /><span >2.5.2 图像数据的内存分配、赋值与拷贝</span><br /><span >2.5.3 IPP 图像处理中的算术、逻辑、阈值和比较运算</span><br /><span >2.5.4 一个简单的图像处理编程模板工程</span><br /><span >2.6 上机实验</span><br /><span >2.6.1 实验一 用IPP 函数实现图像内存的分配、赋值和拷贝</span><br /><span >2.6.2 实验二 用IPP 函数实现彩色图像到灰度图像的转换</span><br />
<h4>第 3 章 图像编码与文件格式</h4>
<span >3.1 无损压缩</span><br /><span >3.1.1 Huffman 编码</span><br /><span >3.1.2 行程（RLE）编码</span><br /><span >3.1.3 LZW 编码</span><br /><span >3.2 有损压缩</span><br /><span >3.2.1 量化编码</span><br /><span >3.2.2 预测编码</span><br /><span >3.2.3 变换编码</span><br /><span >3.3 图像文件格式</span><br /><span >3.3.1 BMP 格式</span><br /><span >3.3.2 GIF 格式</span><br /><span >3.3.3 JPEG 格式</span><br /><span >3.3.4 JPEG 2000 格式</span><br /><span >3.3.5 TIFF 格式</span><br /><span >3.3.6 PSD 格式</span><br /><span >3.3.7 PNG 格式</span><br /><span >3.4 用IPP 函数实现JPEG 图像编码算法</span><br /><span >3.4.1 算法总体流程</span><br /><span >3.4.2 预处理：图像颜色空间转换</span><br /><span >3.4.3 离散余弦变换</span><br /><span >3.4.4 变换域中数据量化</span><br /><span >视觉计算应用开发</span><br /><span >3.4.5 量化后编码</span><br /><span >3.4.6 压缩实例说明</span><br /><span >3.5 上机实验</span><br /><span >3.5.1 实验一 用IPP 函数实现图像的FFT 和DCT 变换</span><br /><span >3.5.2 实验二 用IPP 函数实现图像的Huffman 编码</span><br /><span >3.5.3 实验三 用IPP 函数实现图像的读取、保存和互相转换</span><br />
<h4>第 4 章 图像增强—灰度、彩色</h4>
<span >4.1 亮度、对比度增强</span><br /><span >4.1.1 灰度变换</span><br /><span >4.1.2 直方图</span><br /><span >4.1.3 直方图均衡</span><br /><span >4.1.4 直方图匹配</span><br /><span >4.1.5 IPP 函数对强度变换的支持</span><br /><span >4.2 彩色增强</span><br /><span >4.2.1 伪彩色增强</span><br /><span >4.2.2 真彩色增强</span><br /><span >4.3 上机实验</span><br /><span >4.3.1 实验一 用IPP 函数实现图像的亮度对比度增强和直方图均衡</span><br /><span >4.3.2 实验二 用IPP 函数实现图像伪彩色增强</span><br /><span >4.3.3 实验三 用IPP 函数实现图像真彩色增强</span><br />
<h4>第 5 章 图像增强—平滑、锐化</h4>
<span >5.1 图像平滑（去噪）</span><br /><span >5.1.1 邻域平均</span><br /><span >5.1.2 中值滤波</span><br /><span >5.1.3 图像间运算</span><br /><span >5.2 图像锐化</span><br /><span >5.2.1 一阶微分算子</span><br /><span >5.2.2 Roberts 算子</span><br /><span >5.2.3 Prewitt 算子</span><br /><span >5.2.4 Sobel 算子</span><br /><span >5.2.5 Laplace 算子</span><br /><span >5.3 频域处理</span><br /><span >5.3.1 频谱的意义</span><br /><span >5.3.2 低通滤波</span><br /><span >5.3.3 高通滤波</span><br /><span >5.3.4 同态滤波</span><br /><span >5.4 IPP 函数库中的滤波函数</span><br /><span >5.4.1 图像边界处理</span><br /><span >5.4.2 滤波器</span><br /><span >视觉计算应用开发</span><br /><span >5.5 上机实验</span><br /><span >5.5.1 实验一 用IPP 函数实现图像的平滑处理</span><br /><span >5.5.2 实验二 用IPP 函数实现图像的锐化处理</span><br />
<h4>第 6 章 图像几何变换</h4>
<span >6.1 图像缩放</span><br /><span >6.2 图像旋转</span><br /><span >6.3 图像变形</span><br /><span >6.4 图像几何变换中的插值算法</span><br /><span >6.5 上机实验</span><br /><span >6.5.1 实验一 掌握运用IPP 图像旋转的相关函数</span><br /><span >6.5.2 实验二 掌握运用IPP 库函数实现图像的缩放、旋转与变形</span><br />
<h4>第 7 章 数字视频基础</h4>
<span >7.1 数字视频概述</span><br /><span >7.1.1 什么是数字视频</span><br /><span >7.1.2 数字视频的获取与表示</span><br /><span >7.2 视频压缩编码</span><br /><span >7.2.1 帧内压缩</span><br /><span >7.2.2 帧间压缩</span><br /><span >7.3 视频编码标准</span><br /><span >7.3.1 层次式视频语法结构（Hierarchical Syntax）</span><br /><span >7.3.2 H.261</span><br /><span >7.3.3 H.263</span><br /><span >7.3.4 H.264</span><br /><span >7.3.5 MPEG-1</span><br /><span >7.3.6 MPEG-2</span><br /><span >7.3.7 MPEG-4</span><br /><span >7.4 视频文件格式</span><br /><span >7.4.1 YUV 格式</span><br /><span >7.4.2 AVI 格式</span><br /><span >7.4.3 MPG 格式</span><br /><span >7.4.4 WMV 格式</span><br /><span >7.4.5 RM 格式</span><br /><span >7.4.6 MP4 格式</span><br /><span >7.5 用IPP 开发数字视频应用</span><br /><span >7.5.1 IPP 对数字视频应用的支持</span><br /><span >7.5.2 IPP 对视频编解码提供的通用函数（General Functions）</span><br /><span >7.6 用Media SDK 开发数字视频应用</span><br /><span >视觉计算应用开发</span><br /><span >7.6.1 头文件和库文件引用</span><br /><span >7.6.2 Media SDK 会话（SDK Sessions）</span><br /><span >7.6.3 内存管理</span><br /><span >7.6.4 以视频编码为例来说明用Media SDK 开发的基本步骤</span><br /><span >7.7 上机实验</span><br /><span >7.7.1 实验一 用Media SDK 实现数字视频的MPEG2 编码</span><br />
<h4>第 8 章 图像处理软件开发综合实例</h4>
<span >8.1 实例一 通用图像处理程序</span><br /><span >8.2 实例二 用鼠标交互对图像进行几何变换</span><br />
<h4>第 9 章 视频处理软件开发综合实例</h4>
<span >9.1 实例一 通用音视频应用架构及实现</span><br /><span >9.1.1 音视频中的数据流（Data Flow Support）</span><br /><span >9.1.2 音视频中数据流的多路复用（multiplex）及分离（splitter）</span><br /><span >9.1.3 UMC 中逻辑架构</span><br /><span >9.1.4 UMC 中关键接口、类层次关系及关键代码实现</span><br /><span >9.2 实例二 用DirectShow 开发视频播放程序</span><br /><span >9.2.1 DirectShow 简介</span><br /><span >9.2.2 COM 基础</span><br /><span >9.2.3 DirectShow SDK 基本架构</span><br /><span >9.2.4 DirectShow SDK 简单应用程序案例</span><br /><span >9.2.5 用Intel® Media SDK 开发Filter 组件</span><br />
<h4>附录</h4>
<span >附录一：IPP 图像视频处理函数名的命名规则</span><br /><span >附录二：景深的概念</span><br /><span >附录三：位图文件结构定义</span><br /><span >附录四：JPEG 中Huffman 编解码说明</span><br /><span >附录五：伪彩色增强中的伪彩色编码表</span><br /><span >附录六：数字视频彩色格式</span><br /></div>
</div> ]]></description>
      <link>http://software.intel.com/zh-cn/articles/book-Visual-Computing/</link>
      <pubDate>Thu, 01 Sep 2011 09:00:00 -0700</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/book-Visual-Computing/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/book-Visual-Computing/</guid>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
    </item>
    <item>
      <title>英特尔® 软件学院系列课程技术书籍</title>
      <description><![CDATA[ <h4 class="sectionHeading"><b>英特尔® 软件学院系列课程技术书籍</b></h4>
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td width="120" valign="top"><img height="130" width="100" src="http://software.intel.com/file/38362" align="left" /></td>
<td valign="top"><b><a name="Embedded Application Development"></a>基于英特尔® 凌动<sup>TM</sup> 平台的嵌入式应用开发</b>，英特尔亚太研发有限公司 组编<br /><br />嵌入式领域具有硬件专用性强，技术更新较快等特点。在英特尔® 凌动™ 处理器开始全面进入嵌入式领域之际，对于有志进入或正在从事嵌入式方面工作的人士来说，更应该抓住机遇掌握好凌动系统开发的技术。对此，我们适时地推出这本基于英特尔® 凌动™ 处理器和开源操作系统 平台应用开发的指导教材。借助编者在嵌入式领域多年的教学经验和开发实践，整本书力求达到如下效果：介绍完整的嵌入式系统知识，又重点讲述具体架构的应用开发；理论联系实际，突出实践特色；知识结构全面、完整，又力求突出英特尔特色。<br /><br /></td>
</tr>
<tr>
<td colspan="2">
<div ></div>
</td>
</tr>
<tr>
<td width="120" valign="top"><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Multicore-Multithread-Technology/"><img height="130" width="100" src="http://software.intel.com/file/38361" align="left" /></a></td>
<td valign="top"><b><a name="Multicore Multithread Technology"></a><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Multicore-Multithread-Technology/">多核多线程技术</a></b>，英特尔亚太研发有限公司 组编<br /><br />本书第一章介绍了多核体系结构、芯片发展与系统软件；第二章综述了多线程并行程序的性能分析方法；第三章针对Intel 多核处理器介绍了多线程程序的性能调优方法；第四章是多线程编程方法综述；第五章针对多线程编程中的常见问题进行了详细的分析并探讨了一些可能的解决途径；第六章介绍了Unix/Linux 环境下利用POSIX 标准线程库/接口进行多线程程序设计的具体接口和方法；第七章结合Windows API 介绍了在Windows 环境下进行多线程编程的基础知识和多线程编程的一些常用技术；第八章进一步探讨了一种可以以渐进方式，利用编译指导以及运行时库，将单线程程序逐步改造为多线程程序的OpenMP 编程接口。纵观全书，处处体现出对多线程编程理念与综合应用能力的培养。<br /><br />本书主要为从事程序设计的工程师、大学生编写。使他们在面对多核体系结构，以及需要多线程编程时有一个好的参考手册。也为高等学校计算机专业的师生进行多核多线程程序教学时提供一本有价值的参考书。<br /><br /></td>
</tr>
<tr>
<td colspan="2">
<div ></div>
</td>
</tr>
<tr>
<td width="120" valign="top"><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Programming-on-Intel-Platform/"><img height="130" width="100" src="http://software.intel.com/file/38360" align="left" /></a></td>
<td valign="top"><b><a name="Programming on Intel Platform"></a><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Programming-on-Intel-Platform/">英特尔® 平台编程</a></b>，英特尔亚太研发有限公司 组编<br /><br />本书介绍的软件优化中采用的环境和示例主要以 Windows 操作系统下的C语言程序为参考，但是其基本思想也可以用在Linux 操作系统的C 语言以及C++语言编程中。第一章首先回顾了C 语言，以帮助读者复习一下C 语言编程的基本架构、数据类型和数据结构；第二章介绍了如何写出好的代码，如何保证代码的易读和可维护性，同时也介绍了一些在代码编写过程中可以采用的通用编程技巧；第三章介绍了为什么需要从软件设计开始就考虑性能并贯穿整个软件开发周期，同时介绍了一个自顶向下的软件优化策略、常用的性能调试工具以及如何选择和设计一个好的Benchmark；第四章介绍了高性能的Intel C++编译器的使用，包括常用的编译选项、支持的语言扩展等；第五章则介绍了如何使用Intel 性能分析器VTune 来寻找和分析应用的性能瓶颈以进行进一步的优化；最后一章介绍了一些特别针对Intel 处理器特性的优化，包括分支、缓存优化以及如何利用SIMD 来提高并行性等，最后介绍了Intel 公司的针对处理器作了特别优化的性能库MKL 和IPP 的使用。<br /><br />本书可以作为普通高校学生在学习 C 语言编程之后的软件优化进阶教材，也可供广大C 和C++程序员参考。<br /><br /></td>
</tr>
<tr>
<td colspan="2">
<div ></div>
</td>
</tr>
<tr>
<td width="120" valign="top"><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Processor-Architecture/"><img height="130" width="100" src="http://software.intel.com/file/38359" align="left" /></a></td>
<td valign="top"><b><a name="Processor Architecture"></a><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Processor-Architecture/">处理器架构</a></b>，英特尔亚太研发有限公司 组编<br /><br />本课程是现代计算机处理器技术领域的中级培训课程。本课程以介绍计算机处理器的基本概念、工作原理、设计方法为主要内容，重点介绍CPU的硬件组成与工作原理，同时介绍当前CPU的新技术与发展趋势。本课程的教学目的在于帮助学员建立计算机处理器的完整概念，学习系统分析和设计方法，了解计算机处理器的最新研究成果。<br /><br /></td>
</tr>
<tr>
<td colspan="2">
<div ></div>
</td>
</tr>
<tr>
<td width="120" valign="top"><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Visual-Computing/"><img height="130" width="100" src="http://software.intel.com/file/38358" align="left" /></a></td>
<td valign="top"><b><a name="Visual Computing"></a><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Visual-Computing/">视觉计算应用开发</a></b>，英特尔亚太研发有限公司 组编<br /><br />视觉计算（Visual Computng）技术的研究和应用对象并不是很清晰、严格，因此视觉计算技术在不同的上下文中可能会涉及多个领域，如数据可视化（Data Visualization）、计算机图形学（Computer Graphics）、数字图像处理（Image Processing）、多媒体技术（MultiMeida）、计算机视觉（Computer Vision）等，这些都可以称为视觉计算技术。图像和视频是视觉计算技术中重要的组成部分，信息时代大量的丰富信息都是通过数字图像和视频展示给每一个人。为了向程序员普及或推广数字图像和视频软件开发技术，降低视觉计算软件开发的门槛，我们这本书将介绍图像和视频处理的基础理论知识和英特尔公司提供的视觉计算软件开发库相结合，注重理论联系实际，强调实践。在每个章节，都配有相关实例来说明如果利用英特尔® 集成性能原件（Intel® IPP）开发相关应用关键代码。<br /><br /></td>
</tr>
<tr>
<td colspan="2">
<div ></div>
</td>
</tr>
<tr>
<td width="120" valign="top"><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Project-Management/"><img height="130" width="100" src="http://software.intel.com/file/38357" align="left" /></a></td>
<td valign="top"><b><a name="Project Management"></a><a target="_blank" href="http://software.intel.com/zh-cn/articles/book-Project-Management/">项目管理</a></b>，英特尔亚太研发有限公司 组编<br /><br />本教材的目的就是将项目管理方面通用的知识与技巧总结出来，并与Intel企业项目管理经验相结合，系统地阐述通用项目管理知识。<br /><br />通过本课程学习使学生掌握有关项目管理的基本理论和基本方法，培养学生具备基本的项目管理技能以及按照项目方法去管理某些工作的技能。具体目标有：使学生了解项目管理的基本概念、基本原理，掌握项目范围管理、项目工期管理、项目费用管理、项目质量管理、项目团队管理、项目风险管理、项目沟通管理等基本方法与技能，初步具备项目启动、项目实施等项目生命周期各阶段管理所需的技能。<br /><br /></td>
</tr>
<tr>
<td colspan="2">
<div ></div>
</td>
</tr>
</tbody>
</table> ]]></description>
      <link>http://software.intel.com/zh-cn/articles/Intel-Software-College-technical-books-series/</link>
      <pubDate>Tue, 30 Aug 2011 09:00:00 -0700</pubDate>
      <comments>http://software.intel.com/zh-cn/articles/Intel-Software-College-technical-books-series/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/zh-cn/articles/Intel-Software-College-technical-books-series/</guid>
      <category>移动软件开发社区</category>
      <category>多核软件开发</category>
      <category>可管理性软件开发社区</category>
      <category>英特尔® 凌动™ 软件开发社区</category>
      <category>视觉计算</category>
      <category>英特尔(R) 软件网络</category>
      <category>嵌入式软件开发社区</category>
      <category>英特尔AppUpSM开发人员计划</category>
    </item>
  </channel></rss>
