H.264压缩技术之帧内预测(I Frame)——Matlab源码解析

前言

这篇博客开始就将介绍H.264视频编码中的,帧内编码,也就是I帧编码。章节展开将严格按照Matlab源码的逻辑进行书写。如果你手头有代码,建议配合代码一起食用。(开源代码overview部分有介绍)

另外注意:这里的子目录,代表进入了函数中。例如:3.main(),那么3.1就是main{ code }.

前文回顾:强烈建议回顾一下Overview部分。
H.264压缩技术之总览(Overview)——Matlab源码解析.
H.264压缩技术之视频基础(foundation of learning video)——Matlab源码解析.

1.设置参考帧+I帧编码

由于进行编码的帧格式为 IPPP格式,也就是说第一个帧是I帧,后续的都是P帧。
所以设置第一帧参考帧X为自身:

X(:,:,1)=Seq(:,:,1) %解释一下Seq为啥是3维数组,前两位代表每个帧的像素值,最后一位代表是第几帧

进行I帧编码

[Seq_r(:,:,1),bits] = encode_i_frame(Seq(:,:,1),QP);    % Encoding
%encode_i_frame函数是编码I帧的函数,
%函数内主要操作为:熵编码,残差块,预测等
%QP为质量因子
%返回的结果Seq_r为重构帧,bits为进行编码后的比特流

2.Seq序列分块

这里的Seq可以理解为最左边的建筑工。现在将建筑工进行16-16分块。对每个16-16的大块,再进行4-4的小分块。这里用不同的颜色标记出不同的小分块。
在这里插入图片描述

3.开始对每块进行预测

这里的预测分为3种情况。分别是:

  1. 无需预测:针对左上角的块
  2. 仅仅需要水平或垂直预测
  3. 9个方向都得预测

如下图:右上角那一块蓝色块,就是属于不需要进行预测操作的块。对于右下角的橙色部分的块(4*4,不包含蓝色部分)仅仅需要进行水平预测。对于其他的普通情况,那么就需要进行9大方向的预测。

这里笔者仅仅介绍一种水平预测模式。其他的8种模式十分的类似,读者可以自行进行实验或查阅相关资料。
在这里插入图片描述

4.水平预测(pred_horz_4)

先看水平预测的主函数。pred_horz_4。

pred_horz_4(Seq,Seq_r,i,j)
%Seq:目前操作的序列块
%Seq_r前一个重构的序列块
%块的i,g位序

我们需要三个玩意,如上文注释部分解释。
你可以会问,如果这是第一块,那么,这个Seq_r哪来的?
其实在前面对第一块属于比较特殊的块,认为第一块为非预测块,不需要进行预测。只需要进行后续的编码即可。

4.1进行水平预测

其实水平预测没什么大不了,只是将参考块Seq_r的特定采样点(像素)照抄了一篇,赋值给预测矩阵pred而已。
在这里插入图片描述

4.2计算残差块 icp

如下图所示。我们按照步骤2.2 ——> 2.4操作结束后。得到残差块icp,和sae,并且记录当前块的预测模式mode。
在这里插入图片描述最后通过比较每种预测模式mode的sae,取sae最小的模式作为当前块的预测模式。
多说一句:sae越小代表什么?
sae越小代表你进行预测时用对应模式所需要记录的变化信息越少(其实也相当于预测的最为准确)。
举例:如果sae=0,那么就说明预测块=参考块,说明完全没有运动变化,那么不改变是最好的“预测”。

最后返回4个值:icp,pred,sae,mode

[icp,pred,sae,mode]=pred_horz_4(Seq,Seq_r,i,j)

5.块编码(code_block)

针对第一块,非预测块,仅仅需要进行块编码。
块编码需要注意几点问题(非预测块):

  1. 进行编码的是残差块-icp
  2. 最后生成新的Seq_r作为下一块的参考
  3. 注意非预测块Seq_r的生成方式。Seq_r=icp_r+pred
  4. 最后生成了两样东西,一个是比特流,一个是重构块
    在这里插入图片描述补充一点:一般代码中带_r的都代表重构的意思。也就是经过反量化反熵编码所得的信息。

6.比特流拼接,残差积累,准备编码P帧

这里其实做了好几件事,但是由于非常的简单,所以放在一块说了。

  1. 对生成的比特流进行拼接:如Step4所示
  2. 保存原始帧,并且设置重构帧作为新的参考帧
  3. 准备P帧预测
    在这里插入图片描述

7.小结

本章主要介绍了Matlab源码的帧内编码流程。总体来说就是做了三件事:

  1. 预测
  2. 块编码
  3. 比特流拼接

其中预测部分是帧内编码的精髓所在。通过9大方向的预测,找到最适合当前块的运动方法匹配的模式。大大减少了需要编码的比特数。

后续将介绍比较复杂的帧间预测(P Frame),敬请期待!

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
H.264是一种视频编码标准,其中的预测是其中一种压缩技术。在MATLAB中实现H.264编码可以使用一些开源库和工具,例如JM、x264等。以下是一个示例代码,实现了H.264预测编码: ```matlab % Read input video vidObj = VideoReader('input_video.mp4'); % Create output video object outputVideo = VideoWriter('output_video.mp4','MPEG-4'); outputVideo.FrameRate = vidObj.FrameRate; open(outputVideo); % Set H.264 encoder parameters params = struct('Profile','High','Level','4.0','BitRate',5000000,'FrameRate',vidObj.FrameRate); % Loop through each video frame while hasFrame(vidObj) % Read current frame frame = readFrame(vidObj); % Convert to YCbCr color space YCbCr = rgb2ycbcr(frame); % Split YCbCr into separate components Y = YCbCr(:,:,1); Cb = YCbCr(:,:,2); Cr = YCbCr(:,:,3); % Perform frame intra prediction on Y component Y_pred = intra_prediction(Y); % Combine YCbCr components YCbCr_pred = cat(3,Y_pred,Cb,Cr); % Convert back to RGB color space frame_pred = ycbcr2rgb(YCbCr_pred); % Write encoded frame to output video writeVideo(outputVideo,frame_pred); end % Close output video object close(outputVideo); function Y_pred = intra_prediction(Y) % Block size (8x8) block_size = 8; % Pad input image [rows,cols] = size(Y); Y_pad = padarray(Y,[block_size-1 block_size-1],'replicate','post'); % Perform intra prediction on each block for r = 1:block_size:rows for c = 1:block_size:cols % Get current block block = Y_pad(r:r+block_size-1,c:c+block_size-1); % Calculate prediction mode mode = calculate_mode(block); % Perform prediction switch mode case 0 % DC mode pred = mean(block(:)); case 1 % Horizontal mode pred = repmat(block(1,:),[block_size 1]); case 2 % Vertical mode pred = repmat(block(:,1),[1 block_size]); case 3 % Diagonal mode pred = diag(block); pred = repmat(pred(:),[1 block_size]) + repmat(pred(:)',[block_size 1]); pred = pred/(block_size+1); otherwise error('Invalid prediction mode'); end % Subtract prediction from current block Y_pred(r:r+block_size-1,c:c+block_size-1) = block - pred; end end end function mode = calculate_mode(block) % Calculate sum of absolute differences (SAD) for each mode SAD = zeros(4,1); SAD(1) = sum(abs(block(:)-mean(block(:)))); SAD(2) = sum(abs(block(1,:)-mean(block(:)))); SAD(3) = sum(abs(block(:,1)-mean(block(:)))); SAD(4) = sum(abs(diag(block)-mean(block(:)))); % Find mode with minimum SAD [~,mode] = min(SAD); mode = mode-1; end ``` 这段代码实现了一个简单的预测编码器,基于直接模式选择方法(mode selection),并且使用直流、水平、垂直和对角线预测模式进行预测。在实际应用中,需要使用更复杂的编码器和预测算法,以达到更好的压缩效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值