视频中的I、P、B帧

1.I、P、B帧概念简述

视频解码之后,每帧都代表一幅静态的图像。而在实际压缩时,为了节省存储空间,往往会采取各种压缩算法减少数据的容量,其中I、P、B帧就是最常见的。简单地说,I帧是关键帧就是一副RGB图像,属于帧内压缩,解码时只需要利用到I帧其本身的信息即可;P帧为前向预测编码帧,即P帧解码时需要参考前面相关帧的信息才能解码;B帧为双向预测编码帧,解码时既需要参考前面已有的帧又需要参考后面待解码的帧;他们都是基于I帧来压缩数据。一般平均来说,I的压缩率是7(跟JPG图片差不多),P是20,B可以达到50,可见使用B帧能节省大量空间,节省出来的空间可以用来保存多一些I帧,这样在相同码率下,可以提供更好的画质。

I帧 帧内编码帧 又称intra picture,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象。I帧可以看成是一个图像经过压缩后的产物。I帧画面完整保留,解码时只需要本帧数据就可以完成(因为包含完整画面)。

P帧 前向预测编码帧 又称predictive-frame,通过充分将图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,也叫预测帧;表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)

B帧 是双向差别帧,也就是B帧记录的是本帧与前后帧的差别,换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累。

因此,I帧和P帧的解码算法比较简单,资源占用也比较少,I帧只要自己完成就行了,至于P帧,也只需要解码器把前一个画面缓存一下,遇到P帧时就使用之前缓存的画面就行。如果视频流只有I和P,解码器可以不管后面的数据,边读边解码,线性前进。如果视频流还有B帧,则需要缓存前面和当前的视频帧,待后面视频帧获得后,再解码。
压缩算法的说明


2.I、P、B帧特点分析

I帧特点:

1.它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输;

2.解码时仅用I帧的数据就可重构完整图像;

3.I帧描述了图像背景和运动主体的详情;

4.I帧不需要参考其他画面而生成;

5.I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);

6.I帧是帧组GOP的基础帧(第一帧),在一组中只有一个I帧;

7.I帧不需要考虑运动矢量;

8.I帧所占数据的信息量比较大。

9.训练视频分类任务的时候往往在处理I-frame的时候要采用更加复杂的网络。

P帧特点:

1.P帧是I帧后面的编码帧(在MPEG-4的压缩视频中,一般是一个GOP里面拥有12个frame,第1个为I-frame其后面跟随着11个P-frame);

2.P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差);

3.解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像;

4.P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧;

5.P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧;

6.由于P帧是参考帧,它可能造成解码错误的扩散;

7.由于是差值传送,P帧的压缩比较高。

Some Quetion to solve:

1.如何从P帧中提取出motion vector和residual两部分信息?

2.如何确定P-frame的解码是只取决于该GOP的I-frame还是取决之前的P-frame?

B帧特点

1.B帧是由前面的I或P帧和后面的P帧来进行预测的;

2.B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量;

3.B帧是双向预测编码帧;

4.B帧压缩比最高,因为它只反映丙参考帧间运动主体的变化情况,预测比较准确;

5.B帧不是参考帧,不会造成解码错误的扩散。


3.I、P、B帧编码的流程

I、p、B 帧编码的基本流程
I 帧编码的基本流程为:

(1) 进行帧内预测,决定所采用的帧内预测模式。
(2) 像素值减去预测值,得到残差。
(3) 对残差进行变换和量化。
(4) 变长编码和算术编码。
(5) 重构图像并滤波,得到的图像作为其它帧的参考帧。

P 帧和 B 帧编码的基本流程为:

(1) 进行运动估计,计算采用帧间编码模式的率失真函数(节)值。P 帧
只参考前面的帧,B 帧可参考后面的帧。
*(2) 进行帧内预测,选取率失真函数值最小的帧内模式与帧间模式比较,确定
采用哪种编码模式。
(3) 计算实际值和预测值的差值。
(4) 对残差进行变换和量化。
(5) 熵编码,如果是帧间编码模式,编码运动矢量
注:I、B、P各帧是根据压缩算法的需要,是人为定义的,它们都是实实在在的物理帧,至于图像中的哪一帧是I帧,是随机的,一但确定了I帧,以后的各帧就严格按规定顺序排列


4.I、P、B帧编码的流程

P 帧的预测与重构的基本流程为:

P 帧是以I帧为参考帧,在I帧中找出P帧“某点”的预测值和运动矢量,取预测差值和运动矢量一起传送。在接收端根据运动矢量从I帧中找出P帧“某点”的预测值并与差值相加以得到P帧“某点”样值,从而可得到完整的P帧。


5.h264的压缩方法:

1.分组:把几帧图像分为一组(GOP,也就是一个序列),为防止运动变化,帧数不宜取多。
2.定义帧:将每组内各帧图像定义为三种类型,即I帧、B帧和P帧;
3.预测帧:以I帧做为基础帧,以I帧预测P帧,再由I帧和P帧预测B帧;
4.数据传输:最后将I帧数据与预测的差值信息进行存储和传输。

帧内(Intraframe)压缩也称为空间压缩(Spatial compression)。当压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧之间的冗余信息,这实际上与静态图像压缩类似。帧内一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示。帧内压缩一般达不到很高的压缩,跟编码jpeg差不多。
  
帧间(Interframe)压缩的原理是:相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小的特点。也即连续的视频其相邻帧之间具有冗余信 息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。帧间压缩也称为时间压缩(Temporal compression),它通过比较时间轴上不同帧之间的数据进行压缩。帧间压缩一般是无损的。帧差值(Frame differencing)算法是一种典型的时间压缩法,它通过比较本帧与相邻帧之间的差异,仅记录本帧与其相邻帧的差值,这样可以大大减少数据量。

顺便说下有损(Lossy )压缩和无损(Lossy less)压缩。无损压缩也即压缩前和解压缩后的数据完全一致。多数的无损压缩都采用RLE行程编码算法。有损压缩意味着解压缩后的数据与压缩前的数据不 一致。在压缩的过程中要丢失一些人眼和人耳所不敏感的图像或音频信息,而且丢失的信息不可恢复。几乎所有高压缩的算法都采用有损压缩,这样才能达到低数据 率的目标。丢失的数据率与压缩比有关,压缩比越小,丢失的数据越多,解压缩后的效果一般越差。此外,某些有损压缩算法采用多次重复压缩的方式,这样还会引 起额外的数据丢失


6.MPEG-4中I、P、B帧的判断

不同视频编码格式有不同的帧类型判断方法。MPEG4视频中,I帧、P帧、B帧的判定:MPEG4的每一帧开头是固定的00 00 01 b6格式,接下来的2bit分别代表着不同类型的视频帧。00代表I Frame,01代表 P Frame,10代表 B Frame。
在这里插入图片描述
通过代码判断的方法如下:



//寻找00 00 01 b6的下一个bit所在的索引值

static char*Find_VOP_Start(unsigned char *addrp, unsigned int FindSizes)

{

    int i = 0;

    while(i < FindSizes)

    {

        if(addrp[i] == 0x00)

            if(addrp[i + 1] == 0x00)

                if(addrp[i + 2] == 0x01)

                    if(addrp[i + 3] == 0xB6)

                        break;

        i++;

    }

    if(i < FindSizes - 4)

        return addrp + i + 4;

    else

        return 0;

}

//打印该帧的类型


    unsigned int *p;
    
    p=(int*)Find_VOP_Start(inbuf,recv_size);
    
     switch((*p) & 0xC0)
    
            {
    
                case 0x00:
    
                    fprintf(stdout,"The typeof frame is:I\n");// I Frame
    
                    break;
    
                case 0x40:
    
                    fprintf(stdout,"The typeof frame is:P\n");// P Frame
    
                    break;
    
                case 0x80:
    
                   fprintf(stdout,"The type of frame is:B\n");// B Frame
    
                    break;
    
                default:
    
                    fprintf(stdout,"No properframe !\n");
    
                    exit(1);
    
            }

如果是MPEG2视频,则先找到00 00 01 00,然后根据其后的3bit来判断,001是I帧,011是B帧,010是P帧,判断方法和MPEG4的判断方法完全相同,不同的是在于相关的类型标识比特位。

如果是H.264视频,要先把H264的ES流数据解析出来,然后分析出每一个NAL(Network Abstract Layer,网络抽象层),再解析出哪些NAL为一个Frame,最后解析Slice类型,根据Slice类型就可以判断这个Frame的IPB类型。判断方法较MPEG2与MPEG4复杂。

参考连接:
[1]http://www.voidcn.com/article/p-sfpbzqbp-dc.html
[2]http://www.voidcn.com/article/p-vhewanbu-bz.html
[3]http://www.voidcn.com/article/p-xccouyix-bhz.html

  • 2
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
视频编码分为三种类型:I(Intra-coded picture,内编码图像)、P(Predictive-coded picture,间预测编码图像)和B(Bidirectional-predictive-coded picture,双向预测编码图像)。 I是完全独立的,不依赖于其他进行解码。通常情况下,每个GOP(Group of Pictures,一组连续的)的第一都是I。 P和B都是依赖于其他进行解码的。P(前向预测)是由前面的I或P进行预测得到的,而B(双向预测)是由前后两个I或P进行预测得到的。 要提取视频的I、P和B,可以使用视频编解码器库,如FFmpeg。具体的操作步骤如下: 1. 安装FFmpeg库,并将其加入系统环境变量。 2. 打开命令行窗口(Windows)或终端(Linux/Mac),进入存放视频文件的目录。 3. 输入以下命令,提取I: ``` ffmpeg -i input.mp4 -vf "select=eq(pict_type\,I)" -vsync vfr output_%04d.jpg ``` 其,input.mp4为输入视频文件,output_%04d.jpg为输出的I图片文件名,%04d表示输出的文件名数字部分的位数为4位。可以根据需要修改输出文件的格式和存放路径。 4. 输入以下命令,提取P: ``` ffmpeg -i input.mp4 -vf "select=eq(pict_type\,P)" -vsync vfr output_%04d.jpg ``` 5. 输入以下命令,提取B: ``` ffmpeg -i input.mp4 -vf "select=eq(pict_type\,B)" -vsync vfr output_%04d.jpg ``` 执行以上命令后,FFmpeg会将视频的I、P和B提取出来,并保存为图片文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值