福州大学《嵌入式系统综合设计》 实验九:ROI视频编码

一、实验目的

ROI视频编码即感兴趣区域视频编码,即针对感兴趣区域进行重点编码,提高编码质量,而对非感兴趣区域采用低质量编码。通过这种方法可以降低码率。本实验即让同学们能够在算能的FFMPEG接口下实现基于ROI的视频编码。

二、实验内容

在实验8的基础上,进一步实现ROI编码。即对图像不同区域设置不同的QP进行视频编码。

三、开发环境

开发主机:Ubuntu 20.04.6 LTS

硬件:算能SE5

四、实验器材

开发主机 + 云平台(或SE5硬件)

五、实验过程与结论

ROI视频编码原理

整帧视频图像的视觉质量很大程度上取决于感兴趣区域ROI部分的视觉质量,而非ROI的图像质量下降不易被察觉,对整帧图像的视觉质量影响较小, 感兴趣区域并不局限于人眼的感兴趣区域,在某些具体的工程应用中,可以将某些具体的场景或者事物定义为感兴趣区域。

感兴趣区域ROI的视频编码的基本方法如图所示,对于输入视频帧序列,通过特定的算法和视频帧本身的特性,提取出感兴趣区域和不感兴趣区域掩膜,并将其作为控制信息输入到视频编码器中,用其控制编码器编码当前帧相应的编码参数,包括量化参数,运动估计时的搜索区域大小和参考帧数目,以及预测模式范围等。感兴趣区域ROI提取模块起到预处理和控制器的作用,感兴趣区域提取涉及视觉显著性等,显著性是指视频帧序列中的能够引起 HVS 注意的物体所具有的特性,一般感兴趣区域的显著性可以表现为纹理、亮度、色度、对比度、形态、对比度等特征。

码率控制的目的是在给定的码率条件下,保证良好稳定的输出码流。按照粒度大小码率控制可分为 GOP 层、帧层以及宏块层(或者CTU层)。编码器通过对不同层级中编码单元分配不同的码率比计算相应的QP值。QP 越大,编码单元丢失的细节越多,图像的失真度增加,质量下降,同时码率也降低,随着 QP 的减小,编码单元的细节保留的增多,在提高质量的同时增大了码率。

在固定目标比特率的 CBR 编码模式中,编码器通过编码结果对每帧、每个宏块或者CTU分配不同的码率,动态计算调整 QP 大小,让最终编码的整体码率与给定码率接近。在基于ROI的编码方法中,在ROI 分析与提取的基础上,基于CBR 的码率控制模型,对宏块级的 QP 进行调整,即对 ROI 降低 QP 提高编码质量,对非 ROI 相应提高 QP。通过这种方式,视觉关注区域得到了更多的码率,而非视觉关注区域节省了非必要的码率分配,进而达到在整体码率不变的条件下,提升视频的主观视觉质量的目的。

关键核心代码讲解

设置ROI有效

ROI的设置是在编码过程中通过设置不同区域的QP来设置ROI,在设置之前需要在初始化编码器时设置ROI有效,因此,我们需要在实验8的openEnc函数中设置ROI有效,具体如下:

//av_dict_set_int(&dict, "qp", 25, 0);
av_dict_set_int(&dict, "roi_enable", 1, 0);

注意,上式中的av_dict_set_int(&dict, "qp", 25, 0)是实验8的代码,更换为ROI后需要删除。

设置QP

我们在实验8的基础上,在编码前设置图像不同区域的编码QP。本次实验对编码图像分成四个区域,如图所示,其中不同区域设置成不同的量化参数。在视频编码中,量化参数QP是非常重要的参数,它直接影响着视频的编码比特率。对于某些应用场合,尤其是当传输速率受限时,灵活地控制量化 参数使得编码速率尽量接近给定速率尤为重要。图中右下角区域每个编码单元(宏块或者CTB)QP设为较小的值,QP=10,该区域经过编码后,保留较多的细节信息。而其他三个区域QP=40,这几个区域可以获得较小的码率和较少的计算资源。

H264中ROI代码:

对于H.264编码器,首先计算每个宏块的索引位置(i,j),当判断当前宏块位于右下角区域时,QP设置为40,其他则设置为10。

#define BM_ALIGN16(_x)             (((_x)+0x0f)&~0x0f)
#define BM_ALIGN32(_x)             (((_x)+0x1f)&~0x1f)
#define BM_ALIGN64(_x)             (((_x)+0x3f)&~0x3f)  
AVFrameSideData *fside = av_frame_get_side_data(picture, AV_FRAME_DATA_BM_ROI_INFO);if (fside) {AVBMRoiInfo *roiinfo = (AVBMRoiInfo*)fside->data;memset(roiinfo, 0, sizeof(AVBMRoiInfo));if (enc_ctx->codec_id  == AV_CODEC_ID_H264) {roiinfo->customRoiMapEnable = 1;roiinfo->customModeMapEnable = 0;for (int i = 0;i <(BM_ALIGN16(height) >> 4);i++) {for (int j=0;j < (BM_ALIGN16(width) >> 4);j++) {int pos = i*(BM_ALIGN16(width) >> 4) + j;// test_1if ( (j >= (BM_ALIGN16(width) >> 4)/2) && (i >= (BM_ALIGN16(height) >> 4)/2) ) {roiinfo->field[pos].H264.mb_qp = 10;}else{roiinfo->field[pos].H264.mb_qp = 40;}}}} else if (enc_ctx->codec_id  == AV_CODEC_ID_H265) {roiinfo->customRoiMapEnable    = 1;roiinfo->customModeMapEnable   = 0;roiinfo->customLambdaMapEnable = 0;roiinfo->customCoefDropEnable  = 0;for (int i = 0;i <(BM_ALIGN64(height) >> 6);i++) {for (int j=0;j < (BM_ALIGN64(width) >> 6);j++) {int pos = i*(BM_ALIGN64(width) >> 6) + j;// test_1if ( (j > (BM_ALIGN64(width) >> 6)/2) && (i > (BM_ALIGN64(height) >> 6)/2) ) {roiinfo->field[pos].HEVC.sub_ctu_qp_0 = 10;roiinfo->field[pos].HEVC.sub_ctu_qp_1 = 10;roiinfo->field[pos].HEVC.sub_ctu_qp_2 = 10;roiinfo->field[pos].HEVC.sub_ctu_qp_3 = 10;} else {roiinfo->field[pos].HEVC.sub_ctu_qp_0 = 40;roiinfo->field[pos].HEVC.sub_ctu_qp_1 = 40;roiinfo->field[pos].HEVC.sub_ctu_qp_2 = 40;roiinfo->field[pos].HEVC.sub_ctu_qp_3 = 40;}roiinfo->field[pos].HEVC.ctu_force_mode = 0;roiinfo->field[pos].HEVC.ctu_coeff_drop = 0;roiinfo->field[pos].HEVC.lambda_sad_0 = 0;roiinfo->field[pos].HEVC.lambda_sad_1 = 0;roiinfo->field[pos].HEVC.lambda_sad_2 = 0;roiinfo->field[pos].HEVC.lambda_sad_3 = 0;}

H265中ROI代码:

对于H.265/HEVC编码器,编码标准制定了一种非常灵活的QP控制机制,它引入了量化组(Quantization Group, QG)的概念,规定一个CTB可以包含一个或多个固定大小的QG,同一个QG内的所有含有非零系数的CU共享一个QP,不同的QG可以使用不同的QP。这样一来,编码器能够更灵活地进行速率控制。

QG是指将一幅图像分成的固定大小(NxN)的正方形像素块。其大小N由图像参数集(PPS)指定,且必须处于最大CU与最小CU之间(包含最大与最小CU)。图中给出了一个32x32 QG的示意图,其中粗实线为CTB边界,粗虚线表示CU划分方式,细线为QG分界线。CU与QG没有固定的大小关系。由于在一幅图像中,QG为固定大小,而CU是根据视频内容自适应划分出来的,因此可能出现一个QG包含一个或多个CU的情形,也可能存在一个CU包含多个QG的情形。

实验过程

生成可执行文件:

makefile的写法与前面的例程基本相同,按照前面实验1、实验2步骤,生成可执行文件并上传到算能盒子或者云平台中。如果是在云平台上测试,则可将编译好的执行文件通过云空间文件系统上传。

root@d11ae417e206:/tmp/test# ls

ffmpeg_encode_withRoi  1080p.yuv

给可执行文件赋权限并执行。

root@d11ae417e206:/tmp/test# chmod 777 ffmpeg_encode_withRoi

运行指令:

生成并上传编译文件后,根据如下指令在目标开发机终端运行。

./ffmpeg_encode_withRoi 1080.yuv output.h264

运行结果如下:

[h264_bm @ 0x429a90] width =1920

[h264_bm @ 0x429a90] height=1080 src/allocator.c:136 (ion_dmabufalloc_map)  

DEBUG: retrieved virtual address for physical memory

src/allocator.c:144 (ion_dmabufalloc_map)  

DEBUG: Invalidated physical memory

src/allocator.c:155 (ion_dmabufalloc_map)  

DEBUG: virtual address:  0x7f820c8000  aligned: 0x7f820c8000

src/allocator.c:176 (ion_dmabufalloc_unmap)  

DEBUG: shut down virtual address for 3133440 bytes of physical memory

[h264_bm @ 0x429a90] input frame: context=(nil), pts=100, dts=-9223372036854775808

[85fb6010] src/enc.c:2264 (Wave5BitIssueCommand)  

instanceIndex=0: cmd=0x100

[85fb6010] src/enc.c:1647 (enc_start_one_frame)  

instance Index: 0. instance Queue Count: 1, total Queue Count: 1

[85fb6010] src/enc.c:733 (VpuHandlingInterruptFlag)  

INTR Done: enc pic. reason=0x100

[85fb6010] src/enc.c:2264 (Wave5BitIssueCommand)  

instanceIndex=0: cmd=0x4000

[h264_bm @ 0x429a90] output frame: context=(nil), pts=91, dts=87

enc_pkt.pts=91, enc_pkt.dts=87

rescaled enc_pkt.pts=46592, enc_pkt.dts=44544

Muxing frame

The end of file!

Flushing video encoder

[85fb6010] src/enc.c:2264 (Wave5BitIssueCommand)  

instanceIndex=0: cmd=0x100

[85fb6010] src/enc.c:1647 (enc_start_one_frame)  

instance Index: 0. instance Queue Count: 1, total Queue Count: 1

[85fb6010] src/enc.c:733 (VpuHandlingInterruptFlag)  

INTR Done: enc pic. reason=0x100

[85fb6010] src/enc.c:2264 (Wave5BitIssueCommand)  

instanceIndex=0: cmd=0x4000 [h264_bm @ 0x429a90] encoding end!

src/encoder.c:804 (bmvpu_enc_close)  

DEBUG: closing encoder src/allocator.c:112 (ion_dmabufalloc_deallocate)  

DEBUG: deallocated 262144 bytes of physical memory

src/allocator.c:112 (ion_dmabufalloc_deallocate)  

DEBUG: deallocated 262144 bytes of physical memory

src/allocator.c:112 (ion_dmabufalloc_deallocate)  

DEBUG: deallocated 262144 bytes of physical memory

src/allocator.c:112 (ion_dmabufalloc_deallocate)  

DEBUG: deallocated 262144 bytes of physical memory

src/encoder.c:295 (bmvpu_enc_unload)  

DEBUG: unloaded VPU [AVIOContext @ 0x499190] Statistics: 2 seeks, 7 writeouts

encode finish!

#######VideoEnc_FFMPEG exit

注:上图展示为部分关键运行结果,详细运行结果请见运行界面。

Elecard StreamEye分析

对视频文件进行ROI编码后,用Elecard StreamEye分析码流。通过播放编码后的视频可以看出,右下角区域比其他区域的清晰度更高,细节保留的更多。左下角使用较大的QP,使得图像细节丢失,木板的间隙模糊,人工效应明显。而右下角区域使用较小的QP编码,则相对清晰。

同时可以调出MB信息查看每一个编码单元的QP值,可以看出,右下角的QP值更低,其他区域的QP值更高。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/183053.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

离散化笔记

文章目录 离散化的适用条件离散化的意思AcWing 802. 区间和CODECODE2 离散化的适用条件 离散化用于区间求和问题对于数域极大&#xff0c;而数的量很少的情况下 离散化的意思 背景&#xff1a;对于一个极大数域上的零星几个数进行操作后&#xff0c;求某段区间内的和 其实意思…

JSch线上出现com.jcraft.jsch.JSchException: channel is not opened.问题分析

JSch线上出现com.jcraft.jsch.JSchException: channel is not opened.问题分析 文章目录 JSch线上出现com.jcraft.jsch.JSchException: channel is not opened.问题分析1. 背景1.系统使用jsch这个框架做文件发送以及远程命令执行的操作,系统一直运行正常,直到某一个环境发现 2.…

关于我司在上海物联网行业协会展厅展示项目案例

1 项目背景 上海市物联网行业协会&#xff08;SIOT&#xff09;是由本市物联网行业同业企业及其他相关经济组织自愿组成、实行行业服务和自律管理的非营利性社会团体法人&#xff0c;于2012年&#xff0c;经上海市经济和信息化委同意&#xff0c;在上海市社团局登记成立。 本…

【精选】Spring整合MyBatis,Junit 及Spring 事务Spring AOP面向切面详解

Spring整合MyBatis 搭建环境 我们知道使用MyBatis时需要写大量创建SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession等对象的代码&#xff0c;而Spring的作用是帮助我们创建和管理对象&#xff0c;所以我们可以使用Spring整合MyBatis&#xff0c;简化MyBatis开发。 …

SDK emulator directory is missing

要进行uniapp真机测试&#xff0c;不得不安装配置一下安卓开发环境 &#xff0c;搞一个模拟器。。。然后又是各种坑。。对比来对比去还是IOS的环境使用着舒服&#xff0c;XCODE下载好&#xff0c;一切重点就是在编码了。。 安卓这个脑残货呀&#xff0c;哎&#xff0c;各种安装…

数据挖掘之时间序列分析

一、 概念 时间序列&#xff08;Time Series&#xff09; 时间序列是指同一统计指标的数值按其发生的时间先后顺序排列而成的数列&#xff08;是均匀时间间隔上的观测值序列&#xff09;。 时间序列分析的主要目的是根据已有的历史数据对未来进行预测。 时间序列分析主要包…

whatsapp信息群发脚本开发!

WhatsApp 作为全球广受欢迎的通讯应用&#xff0c;在我们的日常生活中扮演着重要角色&#xff0c;有时候&#xff0c;我们需要向大量联系人发送消息&#xff0c;比如营销推广、活动通知等。 一个个手动发送消息?那简直太落后了!今天&#xff0c;我们将探讨如何利用脚本开发实…

centos nginx安装及常用命令

nginx配置文件位置 nginx 安装有两种方式一种是联网一键下载&#xff0c;Nginx 配置文件在 /etc/nginx 目录下&#xff0c;一种是源码包可以无网下载&#xff0c;有两个配置文件启动地方一个是安装包存放位置&#xff0c;一是/usr/local/nginx/conf下&#xff0c;启动要看你…

MxL3706-AQ-R 2.0通道绑定同轴网络集成电路特性

MxL3706-AQ-R是Max线性公司的第三代MoCA2.0同轴网络控Z器SoC&#xff0c;可用于在现有的家庭同轴电缆上创建具有千兆位吞吐量性能的家庭网络。 该MxL3706-AQ-R工作在400MHz至1675MHz之间的无线电频率&#xff0c;并与satellite共存&#xff0c;电X和有线电视运营商的频率计划。…

金属款超声波风速风向传感器的创新与科技力量

在当今的科技世界中&#xff0c;WX-WQX2S 金属款超声波风速风向传感器以其独特的功能和可靠的性能&#xff0c;引领着气象科技领域的新潮流。这款传感器利用超声波技术&#xff0c;对风速和风向进行高精度测量&#xff0c;为气象学家和环境监测机构提供了强大的工具。 一、金属…

基于STM32单片机的智能家居系统设计(论文+源码)

1.系统设计 基于STM32单片机的智能家居系统设计与实现的具体任务&#xff1a; &#xff08;1&#xff09;可以实现风扇、窗帘、空调、灯光的开关控制&#xff1b; &#xff08;2&#xff09;具有语音识别功能&#xff0c;可以通过语音控制家电&#xff1b; &#xff08;3&a…

图面试专题

一、概念 和二叉树的区别&#xff1a;图可能有环 常见概念 顶点&#xff08;Vertex&#xff09;&#xff1a; 图中的节点或点。边&#xff08;Edge&#xff09;&#xff1a; 顶点之间的连接线&#xff0c;描述节点之间的关系。有向图&#xff08;Directed Graph&#xff09;&…

精密制造ERP系统包含哪些模块?精密制造ERP软件是做什么的

不同种类的精密制造成品有区别化的制造工序、工艺流转、品质标准、生产成本、营销策略等&#xff0c;而多工厂、多仓库、多车间、多部门协同问题却是不少精密制造企业遇到的管理难题。 有些产品结构较为复杂&#xff0c;制造工序繁多&#xff0c;关联业务多&#xff0c;传统的…

深度学习实现语义分割算法系统 - 机器视觉 计算机竞赛

文章目录 1 前言2 概念介绍2.1 什么是图像语义分割 3 条件随机场的深度学习模型3\. 1 多尺度特征融合 4 语义分割开发过程4.1 建立4.2 下载CamVid数据集4.3 加载CamVid图像4.4 加载CamVid像素标签图像 5 PyTorch 实现语义分割5.1 数据集准备5.2 训练基准模型5.3 损失函数5.4 归…

Python+requests+unittest+excel搭建接口自动化测试框架

一、框架结构&#xff1a; 工程目录 代码&#xff1a;基于python2编写 二、Case文件设计 三、基础包 base 3.1 封装get/post请求&#xff08;runmethon.py&#xff09; import requests import json class RunMethod:def post_main(self,url,data,headerNone):res Noneif h…

电子学会C/C++编程等级考试2022年12月(三级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:鸡兔同笼 一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物。 时间限制:1000 内存限制:65536输入 一行,一个正整数a (a < 327…

小航助学题库蓝桥杯题库c++选拔赛(23年8月)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09; 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;

商业5.0:数字化时代的商业变革

随着数字化技术的迅速发展和应用&#xff0c;商业领域正在经历前所未有的变革。商业5.0&#xff0c;作为数字化时代的新概念&#xff0c;旨在探讨商业模式的创新和演变&#xff0c;从1.0到5.0&#xff0c;商业领域经历了从传统到数字化的转变。 一、商业1.0&#xff1a;传统商…

小航助学题库蓝桥杯题库c++选拔赛(22年1月)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09; 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;

PHP:js中怎么使用PHP变量,php变量为数组时的处理

方法一&#xff1a;使用内嵌 PHP 脚本标记 1、简单的拼接 使用内嵌的 PHP 脚本标记 <?php ?> 将 PHP 变量 $phpVariable 的值嵌入到 JavaScript 代码中。 <?php $phpVariable "Hello, World!"; ?><script> // 将 PHP 变量的值传递给 JavaS…