毕业设计(论文)-YUV视频显示系统.doc_第1页
毕业设计(论文)-YUV视频显示系统.doc_第2页
毕业设计(论文)-YUV视频显示系统.doc_第3页
毕业设计(论文)-YUV视频显示系统.doc_第4页
毕业设计(论文)-YUV视频显示系统.doc_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

xx大学本科生毕业设计(论文)YUV视频显示系统xx大学 xx学院 05电子信息工程 xx2009年5月目录前言第一章 YUV简介第二章 YUV到 RGB 的转化第2.1节 YUV采样格式2.1.1各种YUV格式第2.2节 RGB图像格式2.2.1概述2.2.2各种RGB格式第2.3节 RGB与YUV相互转换2.3.1 RGB转YUV2.3.2 YUV转RGB2.3.3 查表法第三章 视频的显示第3.1节 视频图像的更新控制第3.2节 视频连续显示的实现方式第3.3节 图像缩放3.3.1 概述3.3.2 双线性内插值第3.4节 实现过程3.4.1 打开文件,获取文件信息3.4.2 读取并转换视频帧3.4.3 缩放图像并绘制第3.5节 消息驱动机制3.5.1 消息驱动3.5.2 消息传送3.5.3 消息处理3.5.4 Windows对消息驱动机制的支持第四章 主要程序流程及测试结果.2 2第4.1节 绘图线程主函数流程图2 2第4.2节 测试结果2 3参考文献. 2 4致谢 .2 5附录 2 6附录1 运行界面截图2 6打开后的界面2 6播放界面(根据播放状态,“播放”按钮会变为“暂停”按钮)2 6暂停播放2 6播放结束2 72倍大小播放(播放画面的大小会随窗口大小的改变自动调整)2 7附录22 8缩放2 8画面重绘2 9打开文件3 0【摘要】:视频信息处理中常需要用YUV格式的图像序列,为满足实时播放的需求,设计并实现了一种YUV格式图像的播放软件。采用查表法可实现YUV到RGB的快速转换;利用windows提供的多媒体定时器可控制视频播放速度,从而实现YUV格式视频的显示。【关键字】:YUV格式;查表法;视频播放器;视频处理。Abstract: Video information processing is often necessary to use YUV format image sequences, in order to meet the demand for real-time player, design and implementation of YUV format images of the player software. Using look-up table method can realize rapid YUV to RGB conversion; provided by the use of windows multimedia timer can control the video playback speed, and thus achieve YUV format video display. Keyword: YUV format; look-up table method; video player; deal Videos. 前言数字视频处理技术正在高速发展,利用先进的数字技术实时处理视频信号是必然的发展方向。在数字视频处理中,通常利用人眼对色度信号不敏感的特性,将RGB基色信号表示为YUV色差信号,这样可以适当去掉一些色度信号分量,而对图像质量不会产生较大影响,从而减少图像数据量。现有的显示设备大都采用RGB驱动,因此,在显示数字视频时需要将YUV格式转化为RGB格式,这涉及YUV与RGB色彩空间,YUV到RGB格式的转化算法,RGB格式的视频显示及控制等。设计并实现一种YUV格式图像的播放软件,该软件中采用查表法实现YUV到RGB 的快速转换,能满足实时播放的要求;利用多媒体定时器控制视频播放速度,可实现YUV格式视频的正确显示。第一章 YUV简介YUV(亦称YCrCb)是被欧洲电视系统所采用的一种颜色编码方法(属于PAL),是PAL和SECAM模拟彩色电视制式采用的颜色空间。其中的Y,U,V几个字母不是英文单词的组合词,Y代表亮度,UV代表色差,U和V是构成彩色的两个分量。在现代彩色电视系统中,通常采用三管彩色摄影机或彩色CCD摄影机进行取像,然后把取得的彩色图像信号经分色、分别放大校正后得到RGB,再经过矩阵变换电路得到亮度信号Y和两个色差信号RY(即U)、BY(即V),最后发送端将亮度和色差三个信号分别进行编码,用同一信道发送出去。这种色彩的表示方法就是所谓的YUV色彩空间表示。YUV主要用于优化彩色视频信号的传输,使其向后相容老式黑白电视。与RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽(RGB要求三个独立的视频信号同时传输)。其中“Y”表示明亮度(Luminance),也就是灰阶值;而“U”和“V” 表示的则是色度(Chrominance),作用是描述影像色彩及饱和度,用于指定像素的颜色。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面色调与饱和度,分别用Cr和CB来表示。其中,Cr反映了GB输入信号红色部分与RGB信号亮度值之间的差异。而CB反映的是RGB输入信号蓝色部分与RGB信号亮度值之同的差异。 YUV的优点是它的亮度信号和色度信号相互独立 , 由它们构成的单色图可以单独编码, 处理,由于在实现压缩,传输和处理上方便,YUV被广泛应用于广播和电视系统; 又因YUV为部分取样 , 采用YUV色彩空间还可以降低带宽。采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有Y信号分量而没有U、V分量,那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的相容问题,使黑白电视机也能接收彩色电视信号。第二章 YUV到 RGB 的转化在DirectShow中,常见的RGB格式有RGB1、RGB4、RGB8、RGB565、RGB555、RGB24、RGB32、ARGB32等;常见的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、 Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等。由于YUV 格式的复杂性,不可能像对RGB 那样,仅用简单像素格式,掩码来描述详尽的YUV格式。为此,Microsoft 引入了FOURCC( Four Character Code) 序列来表示视频数据流格式,这样各种YUV格式就可以用 4个字符的FOURCC 序列来唯一标识,新的YUV 格式只要在Microsoft 注册,就可以为软件和硬件提供者所接受。第2.1节 YUV采样格式主要的采样格式有YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1和 YCbCr 4:4:4。其中YCbCr 4:1:1 比较常用,其含义为:每个点保存一个 8bit 的亮度值(也就是Y值),每 2x2 点保存一个 Cr 和Cb 值, 图像在肉眼中的感觉不会起太大的变化。所以,原来用 RGB(R,G,B 都是 8bit unsigned) 模型,1个点需要 8x3=24 bits(如下图第一个图),(全采样后,YUV仍各占8bit)。按4:1:1采样后,而现在平均仅需要 8+(8/4)+(8/4)=12bits(4个点,8*4(Y)+8(U)+8(V)=48bits), 平均每个点占12bits。(1) YUV 4:4:4 YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节。 (2) YUV 4:2:2每个色差信道的抽样率是亮度信道的一半,所以水平方向的色度抽样率只是4:4:4的一半。对非压缩的8比特量化的图像来说,每个由两个水平方向相邻的像素组成的宏像素需要占用4字节内存。(3) YUV 4:1:14:1:1的色度抽样,是在水平方向上对色度进行4:1抽样。对于低端用户和消费类产品这仍然是可以接受的。对非压缩的8比特量化的视频来说,每个由4个水平方向相邻的像素组成的宏像素需要占用6字节内存。(4)YUV4:2:04:2:0并不意味着只有Y,Cb而没有Cr分量。它指得是对每行扫描线来说,只有一种色度分量以2:1的抽样率存储。相邻的扫描行存储不同的色度分量,也就是说,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0以此类推。对每个色度分量来说,水平方向和竖直方向的抽样率都是2:1,所以可以说色度的抽样率是4:1。对非压缩的8比特量化的视频来说,每个由2x2个2行2列相邻的像素组成的宏像素需要占用6字节内存。2.1.1各种YUV格式YUV格式通常有两大类:打包(packed)格式和平面(planar)格式。前者将YUV分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像素(macro-pixel);而后者使用三个数组分开存放YUV三个分量,就像是一个三维平面一样。表2.3中的YUY2到Y211都是打包格式,而IF09到YVU9都是平面格式。(注意:在介绍各种具体格式时,YUV各分量都会带有下标,如Y0、U0、V0表示第一个像素的YUV分量,Y1、U1、V1表示第二个像素的YUV分量,以此类推。)YUY2(和YUYV)格式为每个像素保留Y分量,而UV分量在水平方向上每两个像素采样一次。一个宏像素为4个字节,实际表示2个像素。(4:2:2的意思为一个宏像素中有4个Y分量、2个U分量和2个V分量。)图像数据中YUV分量排列顺序如下: Y0 U0 Y1 V0 Y2 U2 Y3 V2 YVYU格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:Y0 V0 Y1 U0 Y2 V2 Y3 U2 UYVY格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:U0 Y0 V0 Y1 U2 Y2 V2 Y3 AYUV格式带有一个Alpha通道,并且为每个像素都提取YUV分量,图像数据格式如下:A0 Y0 U0 V0 A1 Y1 U1 V1 Y41P(和Y411)格式为每个像素保留Y分量,而UV分量在水平方向上每4个像素采样一次。一个宏像素为12个字节,实际表示8个像素。图像数据中YUV分量排列顺序如下: U0 Y0 V0 Y1 U4 Y2 V4 Y3 Y4 Y5 Y6 Y8 Y211格式在水平方向上Y分量每2个像素采样一次,而UV分量每4个像素采样一次。一个宏像素为4个字节,实际表示4个像素。图像数据中YUV分量排列顺序如下: Y0 U0 Y2 V0 Y4 U4 Y6 V4 YVU9格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个4 x 4的宏块,然后每个宏块提取一个U分量和一个V分量。图像数据存储时,首先是整幅图像的Y分量数组,然后就跟着U分量数组,以及V分量数组。IF09格式与YVU9类似。IYUV格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个2 x 2的宏块,然后每个宏块提取一个U分量和一个V分量。YV12格式与IYUV类似。YUV411、YUV420格式多见于DV数据中,前者用于NTSC制,后者用于PAL制。YUV411为每个像素都提取Y分量,而UV分量在水平方向上每4个像素采样一次。YUV420并非V分量采样为0,而是跟YUV411相比,在水平方向上提高一倍色差采样频率,在垂直方向上以U/V间隔的方式减小一半色差采样。第2.2节 RGB图像格式2.2.1概述RGB色彩模式(也翻译为“红绿蓝”,比较少用)是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。RGB色彩模式使用RGB模型为图像中每一个像素的RGB分量分配一个0255范围内的强度值。例如:纯红色R值为255,G值为0,B值为0;灰色的R、G、 B三个值相等(除了0和255);白色的R、G、B都为255;黑色的R、G、B都为0。RGB图像只使用三种颜色,就可以使它们按照不同的比例混合,在屏幕上重现16777216种颜色。在 RGB 模式下,每种 RGB 成分都可使用从 0(黑色)到 255(白色)的值。例如,亮红色使用 R 值 246、G 值 20 和 B 值 50。 当所有三种成分值相等时,产生灰色阴影。 当所有成分的值均为 255 时,结果是纯白色;当该值为 0 时,结果是纯黑色。2.2.2各种RGB格式RGB1、RGB4、RGB8都是调色板类型的RGB格式,在描述这些媒体类型的格式细节时, 通常会在BITMAPINFOHEADER数据结构后面跟着一个调色板(定义一系列颜色)。它们的图像数据并不是真正的颜色值,而是当前像素颜色值在调色 板中的索引。以RGB1(2色位图)为例,比如它的调色板中定义的两种颜色值依次为0x000000(黑色)和0xFFFFFF(白色),那么图像数据 001101010111(每个像素用1位表示)表示对应各像素的颜色为:黑黑白白黑白黑白黑白白白。RGB565使用16位表示一个像素,这16位中的5位用于R,6位用于G,5位用于B。程序中通常使用一个字(WORD,一个字等于两个字节)来操作一个像素。当读出一个像素后,这个字的各个位的意义如下:高字节 低字节R R R R R G G G G G G B B B B B可以组合使用屏蔽字和移位操作来得到RGB各分量的值:#define RGB565_MASK_RED 0xF800#define RGB565_MASK_GREEN 0x07E0#define RGB565_MASK_BLUE 0x001FR = (wPixel & RGB565_MASK_RED) 11; / 取值范围0-31G = (wPixel & RGB565_MASK_GREEN) 5; / 取值范围0-63B = wPixel & RGB565_MASK_BLUE; / 取值范围0-31RGB555是另一种16位的RGB格式,RGB分量都用5位表示(剩下的1位不用)。使用一个字读出一个像素后,这个字的各个位意义如下:高字节 低字节X R R R R G G G G G B B B B B (X表示不用,可以忽略)可以组合使用屏蔽字和移位操作来得到RGB各分量的值:#define RGB555_MASK_RED 0x7C00#define RGB555_MASK_GREEN 0x03E0#define RGB555_MASK_BLUE 0x001FR = (wPixel & RGB555_MASK_RED) 10; / 取值范围0-31G = (wPixel & RGB555_MASK_GREEN) 5; / 取值范围0-31B = wPixel & RGB555_MASK_BLUE; / 取值范围0-31RGB24使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。注意在内存中RGB各分量的排列顺序为:BGR BGR BGR通常可以使用RGBTRIPLE数据结构来操作一个像素,它的定义为:typedef struct tagRGBTRIPLE BYTE rgbtBlue; / 蓝色分量BYTE rgbtGreen; / 绿色分量BYTE rgbtRed; / 红色分量 RGBTRIPLE;RGB32使用32位来表示一个像素,RGB分量各用去8位,剩下的8位用作Alpha通道或者不用。(ARGB32就是带Alpha通道的 RGB32。)注意在内存中RGB各分量的排列顺序为:BGRA BGRA BGRA通常可以使用RGBQUAD数据结构来操作一个像素,它的定义为:typedef struct tagRGBQUAD BYTE rgbBlue; / 蓝色分量BYTE rgbGreen; / 绿色分量BYTE rgbRed; / 红色分量BYTE rgbReserved; / 保留字节(用作Alpha通道或忽略) RGBQUAD。要得到较好的色彩效果,一般采用RGB24,即每个像素使用三个字节,分别描述R, G, B的值。本程序即采用RGB24作为输出格式。第2.3节 RGB与YUV相互转换2.3.1 RGB转YUV对于视频捕获和编解码等应用来讲,使用RGB的表示方式数据量太大了。需要想办法在不太影响感觉的情况下,对原始数据的表示方法进行更改,减少数据量。无论中间处理过程怎样,最终都是为了展示给人观看,这样的更改,也是从人眼睛的特性出发,和发明RGB三原色表示方法的出发点是一样的。于是使用Y, Cb , Cr模型来表示颜色。Iain的书中写道:The human visual system (HVS) is less sensitive to color than to luminance (brightness).人类视觉系统(其实就是人的眼睛)对亮度的感觉比对颜色更加敏感。在RGB色彩空间中,三个颜色的重要程度相同,所以需要使用相同的分辨率进行存储,最多使用RGB565这样的形式减少量化的精度,但是3个颜色需要按照相同的分辨率进行存储,数据量还是很大的。所以,利用人眼睛对亮度比对颜色更加敏感,将图像的亮度信息和颜色信息分离,并使用不同的分辨率进行存储,这样可以在对主观感觉影响很小的前提下,更加有效的存储图像数据。Y Cb Cr色彩空间和它的变形(有时被称为YUV)是最常用的有效的表示彩色图像的方法。Y是图像的亮度(luminance)分量,使用以下公式计算,为R,G,B分量的加权平均值:Y = kr R + kg G + kb B (1-1)其中k是权重因数。公式计算出了亮度信息,还有颜色信息,使用色差(color difference/chrominance)来表示,其中每个色差分量为R,G,B值和亮度Y的差值:Cb = BY (1-2)Cr = RY (1-3)Cg = GY (1-4)其中,Cb + Cr + Cg是一个常数(其实是一个关于Y的表达式),所以,只需要其中两个数值结合Y值就能够计算出原来的RGB值。所以,仅保存亮度和蓝色、红色的色差值,这就是(Y, Cb , Cr)。在不同的情况下,可以选取不同的权重因数,计算RGB对应的YUV值。2.3.2 YUV转RGB根据前面的式子,以及人的视觉系统与阴极射线管(CRT)的非线性关系,RGB与YUV的对应关系可以近似地表示为 R 1 0 1.140 Y G = 1 -0.394 -0.581 U (1-5) B 1 2.032 0 V实际上人眼能够分辨的颜色数量远小于2,因此计算机中一般使用RGB空间的一个子集:RGB 8:8:8(真彩色)来描述颜色,其中R, G, B为0255的整数,同理,Y, U, V也为0255的整数。为最大程度减少变换钟的舍入误差,由Y,U,V转化为R,G,B的公式为 R = 1.164 (Y-16) + 1.596 (V-128) G = 1.164 (Y-16) 0.391(U-128) 0.813(V-128)(1-6) B = 1.164 (Y-16) + 2.018 (U-128)然而上式中每转化一个像素需要7次乘法和7次加法,这需要消耗大量的计算时间。在计算机应用中RGB与YUV 空间都是有限集合,可以采用查表的方法,用空间换取时间,从而减少计算的复杂性。2.3.3查表法采用查表法可实现YUV到RGB的快速转换;利用windows提供的多媒体定时器可控制视频播放速度,从而实现YUV格式视频的显示。现有的显示设备大多采用RG驱动,在应用中需要YUV与RGB 彩色空间的转换,由于传统的转化方法需要消耗大量的计算时间,因此需要一种快速的转化方法。这就是查表法。因为RGB与YUV 空间中的元素太多,可采用查表法实现转化中的乘法计算,方法如下:初始化k为0。执行(原帧宽 / 2)(内循环) * (原帧高(外循环)次循环,在每次循环内,完成对目标RGB数据流从头开始依次6个字节(即2个像素)的转换。(此处之所以内循环的原帧宽要除以2,并在一个循环周期内完成两个像素的转换,是因为本程序读取的是YUV4:2:2编码,由前文所述,此编码方式对水平方向上的相邻两个像素关联计算以得到YUV编码值。)具体转换方法是:(1) 根据前文所述RGB编码数据流的存储方式(由左到右,由下往上),求出当前目标 正在写入的位置k所对应的源数据流位置,记为p(程序代码中对应为x * (y - i) + j). 则当前像素的G值为srcp - (srcp + 1 + srcp + 3) 2).(2) 计算出G值后,可以计算B值为G值 + srcp + 3.(3) 亦可计算R值为G值 + srcp + 1.(4) 当前像素的下一个像素的G值为srcp + 2 - (srcp + 1 + srcp + 3) 2).(5) 该像素B值为该像素G值 + srcp + 3.(6) 该像素R值为该像素G值 + srcp + 1.此法即前述数学方法的编码查表法体现。可避免浮点运算与数值乘法,大大提高转换速率。第三章 视频的显示第3.1节 视频图像的更新控制视频是由连续的帧形成的图像序列,利用人眼的视觉暂留特性可使静止的图像产生连续的效果。由于人眼的视觉暂留时间一般为1/121/16s ,要达到连续观看效果,必须保证图像更新时间小于视觉暂留时间,在YUV 模型的数字视频中,由于格式不同,每行采样数目,每帧有效行数和采样格式不同,图像更新的时间要求也不同,例如PAL制式中分辨率为720*576 ,播放25帧/s ; 而NTSC制式的分辨率为720*486 ,则要求播放 30帧/s. 所以对于不同的需要 ,应设计不同的视频图像更新时间控制 ,才能实现视频的正确显示 ,达到满意的效果。本程序为了测试及演示方便,暂时将帧速固定为20帧/s。在投入实际使用时,可以方便地将其改为可变的(只需要在文件中记录帧速,或者视频制式,然后在读取文件头时一并读取,计算出每画一帧的周期,让绘图线程按此周期绘图即可)。第3.2节 视频连续显示的实现方式由上所述,要连续显示视频,必须做到定时更新图像。这在计算机中有两种实现方式。(一) 使用Windows窗体的TIMER消息(二) 使用Windows多媒体计时由于基于器 WM_TIMER 消息的定时器精度低,它最多可以精确到 54.915 ms,约18.2次/s,并且 WM_TIMER 消息的优先级比较低,它可能造成 WM_TIMER 消息的“丢失”。从精度有优先级考虑,在实现视频中不能使用该定时器完成对视频的更新控制,因此,采用 Windows 多媒体服务中提供的多媒体定时器。(三) 使用线程的Sleep方法采用多线程编程,窗体的消息循环与绘图各一个线程,两个线程同时执行。绘图线程每次绘制一帧,然后Sleep一段时间,再继续绘制下一帧。如此往复,达到定时器的效果。此方法还有一个好处,可以使后台线程在绘制图像的时候,前台不至于停止对用户的响应。但是,使用此方法,由于引入了多线程编程,不可避免地要面对多线程间的同步问题。线程之间必须要制定一套严格的同步机制,稍有问题,就会导致程序崩溃。而且多线程编程非常不易调试。本程序采用的即是第三种方法。使用CEvent对象来进行线程同步。CEvent对象代表了一个“事件”,可以用来让一个线程通知另一个线程某“事件”已经发生:class CEvent : public CSyncObject要让事件“发生”,只要使用CEvent:SetEvent()将CEvent的状态设为“标记的”:BOOL CEvent:SetEvent( );比如,要在UI线程使后台线程停止播放,定义了一个CEvent对象g _ ThreadStop。在用户按下“停止”按钮后,执行以下代码以“标记”一个事件:g_ThreadStop.SetEvent();在后台线程中,可以使用WaitForSingleObject()方法查询时间CEvent的状态:DWORD WINAPI WaitForSingleObject( _in HANDLE hHandle, _in DWORD dwMilliseconds);只要将第二个参数设为0,函数就会立即返回由hHandle指定的CEvent的状态。返回值若为WAIT_OBJECT_0,则表示该CEvent已经处于“标记”状态。即事件已经发生了。如:int istop = :WaitForSingleObject (g_ThreadStop.m_hObject,0);if (istop = WAIT_OBJECT_0) 在本程序中使用这种方式,解决了线程同步的问题。第3.3节 图像缩放3.3.1 概述目前,实践已经证明,插值算法对于缩放比例较小的情况是完全可以接受的,令人信服的。一般的,缩小0.5倍以上或放大3.0倍以下,对任何图像都是可以接受的。比较常用的插值算法有以下三种:(1)最邻近插值(近邻取样法):最临近插值的思想很简单。对于通过反向变换得到的一个浮点坐标,对其进行简单的取整,得到一个整数型坐标,这个整数型坐标对应的像素值就是目的像素的像素值,也就是说,取浮点坐标最邻近的左上角点(对于DIB是右上角,因为它的扫描行是逆序存储的)对应的像素值。可见,最邻近插值简单且直观,但得到的图像质量不高,会出现大量“马赛克”。(2)双线性内插值:对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(I + u , j + v),其中i、j均为非负整数,u、v为0,1)区间的浮点数,则这个像素得值 f(I + u , j + v) 可由原图像中坐标为 (I ,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即f(I + u ,j + v) = (1-u)(1-v)f(I ,j) + v(1-u)f(i,j+1) + u(1-v)f(i+1,j) + uv f(i+1,j+1)其中f(I ,j)表示源图像(I , j)处的的像素值,以此类推。这就是双线性内插值法。双线性内插值法计算量大,但缩放后图像质量高,不会出现像素值不连续的情况。由于双线性插值具有低通滤波器的性质,使高频分量受损,所以可能会使图像轮廓在一定程度上变得模糊。(3)三次卷积法三次卷积法能够克服以上两种算法的不足,该算法考虑一个浮点坐标(I + u ,j + v)周围的16个邻点,计算精度高,但计算亮过大。3.3.2 双线性内插值图像的双线性插值放大算法中,目标图像中新创造的象素值,是由源图像位置在它附近的2*2区域4个邻近象素的值通过加权平均计算得出的。双线性内插值算法放大后的图像质量较高,不会出现像素值不连续的情况。然而次算法具有低通滤波器的性质,使高频分量受损,所以可能会使图像轮廓在一定程度上变得模糊。对于标准的双线性差值算法,X方向的线性插值(如下图3-1): 图3-1双线性内插值法具体到所实现的算法中,使Q11、Q12、Q21、Q22为光栅上相邻的四点(如图3-1所示),即P只能落于这四点其中一点上。col是当前像素离像素所属区域原点的水平距离,比如图2,各种不同的颜色代表一个区域,区域原点为区域左上角的像素。 R2 = Color Q22 Color Q12 col + Color Q12 256 (3-1) R1 = Color Q21 Color Q11 col + Color Q11 256 . (3-2) 其中:col = ( DestColNumber(SrcWidth 16 (3-4)其中:row = (DestRowNumber(SrcHeight 16; 将 P 输出到目标位图中。 for (目标图像第二行到最末行) for (行上的像素+) / 源图像上Q12, Q22, Q11, Q21的选取见下一节 获取源图像Q12, Q22, Q11, Q21的颜色; / X 方向的插值 (R2) = tempi+; / 下一行的(R2)等于上一行的(R1) (R1) = (Color(Q21) - Color(Q11) *col+ Color(Q11) * 256; / 保存 (R1)到一个临时数组,因为下一行的(R2)等于这一行的(R1) tempi+ = (R1); / Y 方向的插值 Color(P) = (R2) * 256 + (R2) - (R1) * row) 16; 将 P 输出到目标位图中。 算法中Q12, Q22, Q11, Q21的选取以放大两倍为例,说明选取Q12, Q22, Q11, Q21的过程。源图像3*3区域放大为目标区域6*6区域。设以下为目标图像(如图3-2):AABBAABBCCCCDDDD图3-2目标图像A像素区域对应的Q21,Q22,Q11,Q12,以红色区域为原点向右下方扩展的2*2区域(如图3-3)。Q12Q22Q11Q21 图3-3目标图像B像素区域对应的Q21,Q22,Q11,Q12,以蓝色区域为原点向右下方扩展的2*2区域(如图3-4)。Q12Q22Q11Q21图3-4目标图像C像素区域对应的Q21,Q22,Q11,Q12,以绿色区域为原点向右下方扩展的2*2区域(如图3-5)。Q12Q22Q11Q21图3-5目标图像D像素区域对应的Q21,Q22,Q11,Q12,目标图像处于最后两行的边界情况,将Q21,Q22,Q11,Q12这四个点的值设为一样(如图3-6)。Q11=Q12=Q22=Q21图3-6第3.4节 实现过程整个过程实现分为3个步骤:(1) 打开并读取文件头,获取视频信息; (2) 循环读取每一帧YUV视频,转换为RGB图像阵列;(3) 根据实际输出窗口的大小,对图像进行缩放,使用GDI+绘制到窗口上。3.4.1 打开文件,获取视频信息程序启动后,首先对各变量及参数进行初始化,读取视频帧宽、帧高、总帧数等信息,经判断合法后加以保存。创建后台绘图线程,但不设置“播放”事件。3.4.2 读取并转换视频帧根据文件头部中的帧宽高信息,可以计算出文件中一帧数据的大小。读取一帧数据,调用YUV2RGB()函数使用前文介绍的查表法完成YUV到RGB格式的转换,将转换得到的RGB数据流存入一个字节数组中。int Yuv2RGB(int originalWdith, int originalHeight, int targetWidth, int targetHeight, byte src, byte dest)3.4.3 缩放图像并绘制调用RGBFrameZoomer:Zoom()方法进行图像的缩放。缩放采用双线性差值算法。将缩放得到的数据流存入一个字节数组中。void RGBFrameZoomer:Zoom(const byte* src, const int srcWidth, const int srcHeight, byte* dest, const int destWidth, const int destHeight)调用DrawDibDraw()函数绘制图像。BOOL DrawDibDraw( HDRAWDIB hdd, HDC hdc, int xDst, int yDst, int dxDst, int dyDst, LPBITMAPINFOHEADER lpbi, LPVOID lpBits, int xSrc, int ySrc, int dxSrc, int dySrc, UINT wFlags );第3.5节 消息驱动机制3.5.1 消息驱动消息是windows运行机制中一个基本而又重要的概念。消息是一个报告事件发生的通知,消息驱动是围绕消息的产生与处理展开的,并依靠消息循环机制来实现。从程序设计的观点看,某条消息可被视为某个事件的发生,比如点击鼠标。事件即可以由用户引发,也可以由应用程序产生,当然Windows本身也能发出消息。Windows应用程序的消息来源有4种:输入消息,控制消息,系统消息,用户消息。Windows是一个多任务操作系统,所以没有哪一个程序能够独占系统的资源,资源都是由Windows统一管理的。那么某个程序是如何获得用户的信息呢?事实上,Windows在时刻监视着用户的每个举动,并分析用户的动作与哪一个程序相关,然后将动作以消息的形式发送给当前的应用程序。相反,应用程序也在时时等着消息的到来,一旦发现它的消息队列中有未处理的信息,就获取并分析该消息,并根据消息所包含的内容采取适当的动作来响应。这里引出另一个概念“消息驱动”。比如当你单击file菜单的时候,首先这个动作被windows所捕获,而不是应用程序。经分析windows知道该动作该由哪个应用程序处理,然后windows就发送WM_COMMAND消息给该应用程序,它告诉应用程序,你单击了file菜单。应用程序得知这一消息后,便采取相应的动作来响应它,进行“消息处理”。Windows为每个线程维护了相应的消息队列,应用程序的任务就是不停地从特定的消息队列中获取消息、分析消息并处理消息,直到消息(WM_QUIT)为止。这个过程的程序结构称为“消息循环”。3.5.2 消息传送发送一个消息时,系统直接调用窗口进程。通信是即时的。直到窗口进程为调用函数返回一个结果后,应用程序才能继续。寄送一个消息时,系统把消息发送到拥有该窗口的应用程序消息队列中。消息队列是系统定义的一个内存块,用于临时存储消息,或是把消息直接直接发给窗口过程。每个窗口维护自己的消息队列,从中取出消息,利用窗口函数进行处理。一有空闲,应用程序就搜索消息队列,并在消息队列中处理消息,即从队列中删除他们。调用函数发送消息后就立即返回,但结果只是表示消息寄送成功与否,而不表示被调用窗口进程的结果。通常鼠标和键盘消息是寄送的。3.5.3 消息处理Windows程序在处理消息时使用了“回掉函数”的特殊函数。这个函数由应用程序定义,但并不由应用程序来调用,而是共操作系统或者其子系统来调用的。这种调用通常在某一事件发生,或者在窗口或字体被枚举时发生。Windows向程序员所能发送的消息多达百种,但是,对于一般的应用程序来说,只是其中的一部分有意义。3.5.4 Windows对消息驱动机制的支持Windows操作系统包括3个内核基本模块:(1)GDI:负责在屏幕上绘制象素、打印考贝输出,绘制用户界面(2)KERNEL:支持与操作系统密切相关的功能。如,进程加载,系统调用(3)USER:为所有的用户界面对象提供支持,它用于接收和管理所有输入消息、系统消息,并把他们发给相应的窗口的消息队列。上述GDI、KERNEL和USESR模块中的库函数可被应用程序调用,也可被其他程序模块调用。Windows把包含库函数的模块称为EXPORT,在WINDOWS提供的一种新的EXE文件中有一个入口表用于指明模块内每个输出函数的地址。从应用程序方面,用到的库函数被认为是IMPORT函数。应用程序对一个入口函数发出的远程调用可用不同的重定位表来确定。几乎所有的应用程序都至少包含一个入口库函数或者称为被外部调用的函数。该windows库函数一般来自某个程序模块,用于从WINDOWS接收消息,该函数的使用标志必须是 EXPORT,这才能使WINDOWS允许它被一个外部模块正常调用。第四章 主要程序流程及测试结果第4.1节 绘图线程主函数流程图 图4-1 主函数流程图这个系统用基于微软的MFC实现由于MFC封装了有关消息驱动的底层实现,如消息循环、消息处理.所以使实现变得很简单,类似于“事件”的触发模式,但是研究其底层实现,仍然可以看到这是一个基于Windows消息驱动机制的系统 在Windows系统中,程序的设计围绕事件驱动来进行。当对象有相关的事件发生时(如按下鼠标键),对象产生一条特定的标识事件发生的消息,消息被送入消息队列,或不进入队列而直接发送给处理对象,主程序负责组织消息队列,将消息发送给相应的处理程序,使相应的处理程序执行相应的动作,做完相应的处理后将控制权交还给主程序。 第4.2节 测试结果 本系统的实际测试环境为:Intel Celeron CPU 2.00 GHz,256 MB内存,Speed 5400 r/s硬盘,TP6001A摄像头, METEORII/STD图像采集卡,Windows 2000 Advanced Server.在该环境下,以Coastguard图像序列为例测试从QCIF(YUV,176144

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论