音视频之H.265/HEVC环路后处理
H.265/HEVC系列文章:
1、音视频之H.265/HEVC编码框架及编码视频格式
2、音视频之H.265码流分析及解析
3、音视频之H.265/HEVC预测编码
4、音视频之H.265/HEVC变换编码
5、音视频之H.265/HEVC量化
6、音视频之H.265/HEVC环路后处理
类似于以往的视频编码标准,H.265/HEVC 仍采用基于块的混合编码框架,方块效应、振铃效应、颜色偏差以及图像模糊等失真效应仍存在于采用 H.265/HEVC 标准的压缩视频中。为了降低这类失真对视频质量的影响,H.265/HEVC中采用了环路滤波技术叫(In-loop Filtering),包括去方块滤波(Deblocking Filter)和像素自适应补偿(Sample Adaptive Offset)两个模块。去方块滤波用于降低方块效应,像素自适应补偿用于改善振铃效应,这两个模块在编码框架中的位置如图7.1所示。可以看到,去方块滤波模块和像素自适应补偿模块都处在编码环路中,即经过滤波的重构像素才能作为后续编码像素的参考使用。环路滤波处理后的重建像素更有利于参考,进一步减小后续编码像素的预测残差,有效地提高视频的主客观质量。
一、去方块滤波:
1、去方块效应的由来:
方块效应是指图像中编码块边界的不连续性,如图7.2(b)所示,压缩重建图像有明显的方块效应,严重影响图像的主观质量。
造成方块效应的主要原因是:
- 各个块的变换量化编码过程相互独立,相当于对各个块使用了不同参数的滤波器分别滤波,因此各块引入的量化误差大小及其分布特性相互独立,导致相邻块边界的不连续。
- 此外,运动补偿预测过程中,相邻块的预测值可能来自于不同图像的不同位置,这样就会导致预测残差信号在块边界产生数值不连续。
- 另外,时域预测技术使得参考图像中存在的边界不连续可能会传递到后续编码图像。
对块边界进行平滑滤波可以有效地降低、去除方块效应。
- 用于解码端的后处理滤波技术(环外滤波),可以有效改善图像的主客观质量。
- 一种环路滤波方法,它采用3抽头的低通滤波器来削弱边界的不连续,可以有效降低低比特率编码视频的方块效应。
- 通过设标志位可以有效降低环路滤波及后处理滤波的计算复杂度。
- 分区域滤波方法,对平坦区域利用9抽头滤波器对块边界及块内部的像素进行调整,对纹理区域通过解析像素特征对边界处像素进行相应的修正。
- H.264视频编码标准引入了环路去方块滤波,编码环路中的滤波模块不但可以改善滤波后重建图像的质量,而且滤波后重建图像作为时域预测参考还可以提升后续编码的质量。它自适应地根据不同的视频内容及不同的编码方式选择不同强度的滤波参数,然后对其进行平滑处理。该方法在相同的PSNR下可节省码流9%左右,同时明显地提高了图像视觉质量。
H.265/HEVC标准中的环路去方块滤波:
H.265/HEVC标准仍采用环路去方块滤波应对方块效应,其去方块滤波算法在提高视频主客观质量的同时,具有较低的计算复杂度,并允许并行处理等实现技术,主要体现在以下几方面。
- 无论亮度分量还是色度分量,去方块滤波均对8x8的块边界进行处理,并且对于色度分量仅当边界两侧至少有一个块采用帧内预测模式时,该边界才需要滤波,这使得滤波次数大大降低。
- 滤波时,每行像素边界两边最多各修正3个像素值,这使得各8x8的块边界空间独立,可以并行进行滤波操作。
- 可以先处理整幅图像中的垂直边界,再处理水平边界,而非H.264中的垂直边界和水平边界穿插进行,使得CTB的解码顺序更加灵活。
2、去方块滤波技术:
H.265/HEVC 中的去方块滤波模块需要针对所有PU和TU边界中的8x8的块边界进行处理,包括两个环节:滤波决策和滤波操作。首先进行滤波决策,以得到边界的滤波强度(不滤波、弱滤波或强滤波)及滤波参数。然后进行滤波操作,即根据所选择的滤波强度及滤波参数对像素进行相应的修正。
H.265/HEVC 中的去方块滤波算法对不同的视频内容及不同的编码参数具有自适应能力,即不同的块边界自适应选择是否滤波及滤波强度,如对平滑区域处的不连续边界做强滤波处理,对纹理较丰富的区域弱滤波乃至不滤波。另外,在片级上允许根据不同视频序列的个体特征调节全局滤波参数,即对滤波参数增加偏移值进行微调,如此就可增加或减少滤波强度,优化解码视频质量,获得比默认值更好的效果。例如,当偏移为负值时,滤波强度减弱,可以有助于小的空间细节的逼真度,特别是高分辨率的视频。当偏移为正值时,滤波强度增加,可以去除默认值所不能滤除的方块效应,尤其是针对低分辨率视频内容,去除可能由次优的运动估计、模式选择或残差编码引起的方块效应,提高图像主观质量。该全局滤波参数通过图像片头中的语法元素传输。
值得注意的是,虽然去方块滤波的最小单位是8x8块的边界,而实际是将8x8块分成两部分独立进行去方块滤波处理,垂直边界以8x4为基本单位,水平边界以4x8为基本单位。
滤波决策:
滤波决策的目的是对所有PU和TU边界中8x8的块边界,根据视频内容及编码参数,确定其滤波强度及滤波参数,是去方块滤波的关键环节。如图7.3所示,该环节包含3个步骤:获取边界强度是根据边界块的编码参数初步判断块边界是否需要滤波及滤波参数,因为相邻块采用不同的编码参数(如采用不同预测方式、不同的参考图像、不同的运动矢量等)易造成像素值在块边界的不连续。滤波开关决策进一步对视频内容进行分析,主要根据边界两侧块内像素值的变化及编码参数(量化参数)确定边界是否需要滤波,因为平坦区域的不连续块边界才是滤波对象。滤波强弱选择根据视频内容(块边界及块内部像素值的变化)及编码参数(量化参数)进一步判断边界是否需要滤波以及选择合适的滤波强度,因为边界的不连续也可能是视频自身内容所致。
符合滤波条件(PU和TU边界中8x8的块边界)的亮度分量块边界都需要通过以上3个环节确定滤波强度及滤波参数,而对于色度分量的块边界,滤波决策环节只需要为其获取边界强度,且其边界强度值直接取相应亮度分量的边界强度步骤得到的边界强度值。
获取边界强度:
获取边界强度是根据边界块的编码参数初步判断块边界是否需要滤波及滤波参数,经过获取边界强度模块后,所有允许滤波的边界获得边界强度(Boundary Strength,BS),其取值为0、1或2。对于亮度分量,边界强度值为0时,表示该边界不需要滤波,并不再进行后续处理(滤波开关决策、滤波强弱选择以及滤波操作)。亮度分量边界强度值为1或2时,会进行后续模块处理,并且其值会影响后续“滤波强弱选择”中的阌值。对于色度分量,边界强度值为0、1时,表示该边界不需要滤波,只有边界强度值为2时,才会对其进行滤波(也不需要进行后续滤波开关决策、滤波强弱选择)。
获取边界强度的流程如图7.4所示,其中P和Q为边界两旁4x4大小的块。块P和Q的位置如图7.5所示,对于垂直边界,P表示边界左边的块,Q表示边界右边的块;对于水平边界,P表示边界上边的块,Q表示边界下边的块。可以看到,边界强度值在一定程度上反映了两个相邻块编码参数的一致性,相邻块采用的编码参数越一致,其块边界误差的连续性越好。
滤波开关决策:
由于人眼的空间掩盖效应,图像平坦区域的不连续块边界更容易被观察到。如图7.6(a)所示,当边界两边的像素值相对平滑,但在边界处呈现出大的差异时,人眼视觉系统可以明显地识别出这种位于边界处的不连续。然而,当边界两侧的像素值呈现出高度变化的现象,如图7.6(b)所示,此时这种不连续难以察觉。另外,滤波操作也会减弱强纹理区域应有的纹理信息。滤波开关决策模块就是根据边界块内像素值的变化程度判断该边界区域的内容特性,然后根据边界区域的内容特性确定是否需要进行滤波操作。
一个垂直块边界区域如图 7.7所示,其中p(x,y)、q(x,y)分别为块边界两侧的像素值。定义4个变量:表示P块首行像素的变化率,
表示Q块首行像素的变化率,
表示P块末行像素的变化率,
表示Q块末行像素的变化率。
块边界区域的纹理度值越大,表明该区域越不平坦,当其大到一定程度时,该边界则不需要滤波。因此,H.265/HEVC标准规定当满足式(7-1)时,该边界的滤波开关打开,否则关闭。
滤波强弱选择:
在滤波开关打开的条件下,须对视频内容进行更加细致的判断,以进-步确定滤波强度。图7.8给出了3种边界情况。图7.8(a)与图7.8(b)相比较,图7.8(a)边界两侧像素值平坦,在视觉上会形成更强的块效应,因此,需要对边界周围的像素进行大范围、大幅度的修正,才能得到良好的视觉效果。而对于图7.8(c),边界处的像素差值特别大,由于像素失真总会处于一定的范围之内,当差值超出一定的范围后,这种块边界差别则是视频内容本身所致。
以图7.7为例,H.265/HEVC标准规定当式(7-2)~(7-7)均满足时,则该边界采用强滤波,否则采用弱滤波。式(7-2)和式(7-3)用于判断边界两边像素值的变化率。式(7-4)和式(7-5)用于判断边界两侧像素是否平坦。式(7-6)和式(7-7)用于判断在边界处像素的跨度是否控制在一定的范围内。
否则的值按照下列公式进行计算:
通过比较可以看出,在衡量边界两侧像素的变化率方面,无论是滤波开关还是滤波强弱,都利用与相关的值进行判断。并且,此值的大小关系如下:滤波开关阈值最大,弱滤波其次,最小的是强滤波的值。这个现象正说明了边界两侧像素值变化率越小,越需要更强的滤波。
滤波操作:
滤波操作的实现过程包括3种情况:亮度分量的强滤波、弱滤波以及色度分量的滤波。
亮度分量的强滤波:
强滤波会对边界两侧的像素进行大范围、大幅度的修正,如图7.7中的像素 p(m,n)和 q(m,n)都要进行修正,m 取值 0,1,2,且n取值 0,1,2。像素值的修正公式为式(7-8)~(7-13)。
亮度分量的弱滤波:
弱滤波操作中修正的像素范围及幅度较小,而且需要根据每一行像素的具体情况确定每行的滤波操作。以图7.7中第一行像素为例,下面给出具体的弱滤波操过程。
计算边界处像素的变化程度:
色度滤波:
当获取边界强度模块判定BS=2时,色度分量需要进行滤波操作,色度滤波的过程相对简单,以第一行像素为例具体滤波操作如下。
像素值 p(0,n)和q(0,)分别按式(7-21)和式(7-22)进行修正,n取值 0,1,2,3。
3、去方块滤波的实现:
去方块滤波的具体实现因滤波顺序的不同可有多种形式,可以以CTB为基本单位,按照raster扫描方式进行处理;或先将整幅图像划分成互不重叠的8x8的块,然后再进行滤波;或以CU为基本单位,按照Z扫描方式进行处理。但其整体上都遵循对整幅图像先水平滤波再垂直滤波,并且仅对 8x8大小的块边界进行处理的原则。
为了对去方块滤波的操作过程有系统的认识,下面详细描述该技术在 HM10.0中的实现过程:
滤波顺序:
首先,将图像划分为大小相同的CTB块,按照raster 扫描方式对每个CTB进行处理。其次,对于每个CTB,按照Z扫描方式以CU为基本单位进行处理,如图7.9所示,设CTB大小为64x64。
每个亮度CU块对应两个色度块,亮度块与色度块穿插着进行滤波。
对垂直边界按照从左到右的顺序进行处理,如图7.9中的第1个CU块,其亮度分量的滤波顺序为a→d,色度分量的滤波顺序为e→f,g-h,整体上滤波顺序为a→e→g→b→c→f→h→d,如图7.10所示。
确定滤波边界:
该部分的核心是确保被滤波的边界必是PU或TU的边界,并且图像边界不需要被滤波,具体步骤如下。
- 将图7.10中a,b,c,d的滤波标志均设置为 0。
- 对边界a进行判断。如果边界a不满足以下3种情况时,将其滤波标志重置为1。
a为图像的左边界。
loop_filter_across_tiles_enabled_flag的值为0,并且a的左边界为tile 的边界。
slice_loop_filter_across_slices_enabled_flag的值为0,并且a的左边界为 Slice 的边界。
- 标记TU的边界。如果变换单元的划分方式为图7.12(a),则将图7.10中边界c的滤波标志重置为1;如果变换单元的划分方式为图7.12(b),则边界b,c,d的滤波标志均重置为1。
- 标记PU的边界。如果预测单元的划分方式为图7.13(a)和(b)则将图7.10中边界c的滤波标志重置为1;如果预测单元的划分模式为图7.13(c),则将边界b的滤波标志重置为1;如果预测单元的划分模式为图7.13(d),则将边界d的滤波标志重置为1。
计算边界强度:
对于第1步中滤波标志为0的边界,其边界强度为0;滤波标志为1的边界,根据去方块滤波技术中的方法,以8x4为基本单元计算边界强度值。这样,对于图7.10中亮度分量,即a~d四条垂直边界,共得到32个BS值;对于色度分量,e()和g()的边界强度值由a(2i)的边界强度值复制而来; f(i)和 h(i)的边界强度值由 c(27)的边界强度值复制而来,i取值 0,1,2,3,如图 7.14所示。
对亮度分量进行滤波开关决策、滤波强弱选择:
对每个8x4的垂直边界,按照如图7.15所示的流程进行滤波开关及滤波强弱判断。
滤波:
该部分包括亮度分量的滤波以及色度分量的滤波。根据去方块滤波技术中滤波操作介绍的计算方法进行滤波。值得注意的是,第3步中滤波开关及强弱选择仅针对亮度分量,是否进行色度分量滤波仅与边界强度值有关系。
如图 7.14 所示,先对 a(0)进行滤波开关决策及滤波强弱选择,然后进行滤波操作。再依次对a(1)~a(7)进行处理。边界a处理完毕,再对色度分量的边界e进行滤波。整体上按照a→e→g→b→c→f→h→d的顺序。
至此,第一个CU块的垂直边界滤波完成。其余CU块处理方法相同。待整幅图像的所有垂直边界滤波完成后,再对其进行水平边界的滤波,该过程与垂直边界的滤波过程类似。
在不同的编码配置情况下,去方块滤波器可以在比特率上带来不同程度的减少,在主观感受上也有明显的改善。表7.3为去方块滤波性能的实验结果,采用HM10.0编码器,标准配置中去方块滤波器打开,对比组中关掉了去方块滤波,每个序列编码帧数为60帧。可以看出,关掉去方块滤波后,在同样的视频质量下带来了1.83%~4.19%的比特率增加。
图7.16为序列PartyScene,分辨率为832x480,帧率为50fps。编码配置条件为随机接入,QP=39。图7.16(a)为关掉去方块滤波处理的结果,图7.16(b)为打开去方块滤波的结果,可以明显地看出方块效应的减弱。
图7.17为序列FourPeople,分辨率为1280x720,帧率为60fps。编码配置条件为low-delayB,QP=39。图7.17(a)为关掉去方块滤波处理的结果,图7.17(b)为打开去方块滤波的结果。
4、语法语义:
SPS级语法语义:
pcm_loop_filter_disabled_flag:该语法元素用于说明对于一个编码单元CU,在pcm_enabled_fag为1的条件下是否采用环路滤波技术,包括去方块滤波以及像素自适应补偿。当该语法元素取值为1时,表示不使用;取值为0时,表示使用。
PPS 级语法语义:
loop_filter_across_tiles_enabled_flag:该语法元素用于说明在 tile的边界处是否执行环路滤波操作,包括去方块滤波和像素自适应补偿。当取值为1时,表示执行;取值为0时,表示不执行。
pps_loop_filter_across_slices_enabled_flag:该语法元素用于说明在Slice 的左边界以及上边界处是否执行环路滤波操作。当取值为1时,表示执行;取值为0时,表示不执行。
deblocking_filter_control_present_flag:该语法元素指出控制去方块滤波的语法元素是否出现在PPS中。当取值为1时,表示在PPS中有控制去方块滤波的语法元素;取值为0时,表示没有。
deblocking_filter_override_enabled_flag:该语法元素指出在 Slice 头部是否出现语法元素 deblocking_filter_override_flag。当取值为1时,表示在 Slice 头部存在语法元素deblocking_ filter_override_flag;取值为0时,表示在Slice头部不存在该语法元素。其默认值为0。
pps_deblocking_flter_disabled_flag:该语法元素表示在语法元素slice_deblocking_ filter_disabled_flag 未出现的条件下,是否对各个 Slice执行去方块滤波。当取值为1时不执行;取值为0时执行。默认值为0。
pps_beta_offset_div2&pp_tc_offset_div2:该语法元素表示去方块滤波参数/2和
/2的默认补偿值,该补偿值还可以在Slice的头部进行重载。其取值范围为[-6,6],当该语法元素未出现时,认为其值为0。
Slice 级语法语义:
deblocking_filter_override_flag:该语法元素表明在 Slice 的头部是否出现去方块滤波参数。当取值为1时,表明出现了去方块滤波参数;当取值为0时,表明未出现。其默认值为0。
slice_deblocking_filter_disabled_flag:该语法元素表明对于当前 Slice是否进行去方块滤波操作。当其取值为1时,表示不进行;取值为0时表示进行。当该语法元素未出现时,其值等于语法元素pps_deblocking_filter_disabled_flag 的值。
slice_beta_offset_div2&slice_tc_offset_div2:该语法元素表明当前Slice 的去方块滤波参数/2和
/2的补偿值,其取值范围为[-6,6]。当该语法元素未出现时,slice_beta_offset _div2 的值等于pps_beta_offset_div2的值,slice_tc_offset_div2 的值等于 pps_tc_offset_div2 的值。
slice_loop_filter_across_slices_enabled_flag:该语法元素表明对于当前 Slice 的左边界及上边界是否进行环路滤波操作,包括去方块滤波和像素自适应补偿。当取值为1时,表示可能进行(具体情况要根据后续条件判断);取值为0时,不进行环路滤波。当该语法元素未出现时,其值等于pps _loop_filter_across_slices_enabled_flag 的值。
二、样点自适应补偿:
H.265/HEVC 仍采用基于块的 DCT变换,并在频域对变换系数进行量化。对于图像里的强边缘,由于高频交流系数的量化失真,解码后会在边缘周围产生波纹现象,这种失真被称为振铃效应,严重影响视频的主客观质量。如图7.18所示,实线中的高频信息失真后变成了虚线(实线表示原始像素值,虚线表示重构像素值)。可以看到,重构像素值在边缘两侧上下波动。
如上所述,造成此现象的根本原因是高频信息的丢失。因此,要抑制振铃效应,就需要减小高频分量的失真,而直接精细量化高频分量势必会降低压缩效率。样点自适应补偿技术则从像素域入手降低振铃效应;对重构曲线中出现的波峰像素添加负值进行补偿,波谷添加正值进行补偿。由于在解码端只能得到重构图像信息,因此可以根据重构图像的特点,通过将其划分类别,然后在像素域进行补偿处理。
WMV9(Windows Media Video9)中,为了削弱振铃效应,在解码端采用一种去振铃滤波器,它将像素划分为两个种类:边缘性像素及非边缘性像素,再对其分别进行滤波处理,这可能导致图像之间切换时出现剧烈的闪动现象。
VCEG-AL27中提出了自适应环路滤波技术,它根据拉普拉斯能量和将重构像素值进行分类,再针对不同种类的像素进行相应的滤波及补偿。该方法可以获得较高的编码增益,然而其像素值的分类及滤波过程复杂度过高。
JCTVC-A124中提出了极值校正滤波器(EXC)以及边带修正滤波器(BDC)。EXC通过比较当前像素值与其4个相邻像素值的大小,识别到极值像素的位置,然后对其进行修正。BDC将像素值划分成多条边带,然后根据不同的边带进行相应的补偿此两种滤波方式均基于整幅图像,其整体复杂度也较高。
在JCTVC-A124的基础上,JCTVC-B077提出了基于图像的边带补偿法(PBO)、边界补偿法(PEO)以及自适应限幅(PAC)。比起BDC的均边带划分方式,PBO增加了一种非均匀划分方式。另外,该技术基于图像四叉树划分进行,整体上复杂度较高。JCTVC-C147和JCTVC-D122提出了针对不同的块,从多种分类方式中自适应选择一种进行补偿,计算复杂度仍很高。JCTVC-E049提出了像素自适应补偿法(SAO),在第5次JCT-VC 会议上SA0 被采纳至 H.265/HEVC 工作草案中。
1、SAO技术:
H.265/HEVC标准中的SAO以CTB为基本单位,通过选择一个合适的分类器将重建像素划分类别,然后对不同类别像素使用不同的补偿值,可以有效提高视频的主客观质量。它包括两大类补偿形式,分别是边界补偿(Edge Offset,EO)和边带补偿(Band Offset,BO),此外还引入了参数融合技术。
边界补偿:
边界补偿技术是通过比较当前像素值与相邻像素值的大小对当前像素进行归类,然后对同类像素补偿相同数值。为了均衡复杂度与编码效率,边界补偿选用了1维3像素分类模式。
根据选取像素的位置差异,边界补偿共分为4种模式:水平方向(EO_0)、垂直方向(E0_1)、135°方向(EO_2)以及45°方向(EO_3),如图7.19所示。其中,c表示当前像素,a和b表示相邻像素。
在任意一种模式下,根据以下条件将重构像素归为5个不同种类:
- 如果a<c且b<c,则将像素c划分为种类1。
- 如果c<a且c==b或者c==a目c<b,则将像素c划分为种类2。
- 如果c>a且c==b或者c==a日c>b,则将像素c划分为种类3。
- 如果c>a且c>b,则将像素c划分为种类4。
- 如果不属于以上4种情况,则将像素c划分为种类0。
种类1~4所表示的像素关系如图7.20所示,这4个种类的边缘形状依次为谷状、凹角、凸角、峰状。
边界补偿技术首先根据这一规则将CTB块中的所有像素分成5类然后对属于种类1、种类2、种类3、种类4的像素进行补偿,即增加或减少一定数值(补偿值),对于属于种类0的像素不进行补偿。不同种类的像素可以采用不同的补偿值,但同一种类的像素必须采用相同的补偿值。
JCTVC-G680的实验结果表明超过90%的补偿值,其符号与种类相匹配。基于这一规律,按照不同划分种类对补偿值的符号进行限制;种类1和种类2的补偿值大于等于0,种类3和种类4的补偿值小于等于0。因此,对于边界补偿来讲,只需要传送补偿值的绝对值,解码器根据像素补偿种类即可判断出它的符号。
边带补偿:
边带补偿(BO)技术根据像素强度值进行归类,它将像素范围等分成32条边带。例如,对于8比特像素值,其范围为0~255,每条边带包含8个像素值,即[8k,8k+7]这个范围属于第条边带,k的取值范围为[0,31]。然后每个边带会根据自身像素特点进行补偿,且同一边带使用相同的补偿值。
一般情况下,在一定的图像区域内,像素值的波动范围很小,一个CTB中的大多数像素属于少数几个边带。H.265/HEVC标准规定一个CTB只能选择4条连续的边带,并只对属于这4个边带的像素进行补偿。这样边带补偿值数量与边界补偿值数量进行了统一,可以减少对线性存储器的要求。选择哪4条边带可以通过率失真优化方法确定,然后将最小边带号以及4个补偿值传至解码端。
参数融合:
参数融合(Merge)是指对于一个CTB块,其SAO参数直接使用相邻块的 SAO 参数,这时只需要标识采用了哪个相邻块的 SAO 参数即可。
如图7.21所示,A、B、C均表示CTB块,当对C块进行SAO参数决策时,4块和 B块的 SAO 参数已经确定。此时,C的SAO参数有以下3种选择:
- 直接使用 A 块的参数。
- 直接使用B块的参数。
- 通过分析自身像素块的特点,选择不同于A块和B块的参数。
前两种选择属于参数融合算法。对于这两种情况,C块仅需要传送融合标志位即可。
值得注意的是,在使用参数融合时,一个CTU的亮度和色度分量必须同时使用自身左相邻块的补偿参数,或者同时使用自身上相邻块的补偿参数。否则,采用非参数融合,即亮度和色度分量独立根据自身像素值特点选择划分模式及补偿值,在这种情况下两个色度分量共用相同的划分模式。
2、SAO的实现:
快速 SAO 模式判别:
SAO最终的补偿类型可以从以下8种情况中进行选择:不补偿、EO_0模式、EO_1模式、EO_2模式、EO_3模式、BO模式、左相邻块参数融合模式和上相邻块参数融合模式。另外,对于非参数融合模式,像素被分成许多类,每类又可能有多个候选补偿值。SAO模式判别就是指为CTU选择一组SAO参数(模式、补偿值、边带信息等),通常是选择率失真性能最优的一组 SAO 参数。
其中,SAO"为最优的一组SAO参数,为允许最大编码比特数,D为失真,R为编码比特数,R包含编码该模式的各种标志信息以及补偿值信息等。
拉格朗日优化可以将其转化为非限制条件下的求极值问题:
其中,为拉格朗日因子。基于率失真优化的SAO模式判别过程需要得到每种候选SAO参数对应的D和R,通常需要尝试每一种可能的 SAO参数对CTU进行SAO处理。因此,基于率失真优化的SAO模式选择过程中,不可避免地多次计算原始像素与重构像素之间的失真,计算复杂度很高。为了降低复杂度,可以优化失真计算方法,进而降低基于率失真优化的SAO模式选择过程的计算复杂度。下面介绍快速的失真计算方法。
SAO在HM10.0中的实现过程:
为了对SAO有一个更加准确的认识,下面较详细地描述HM10.0中SAO的实现方法。SAO过程的重点是利用拉格朗日优化选择最优的SAO参数,为了降低计算复杂度,该过程采用了上述的快速模式判别方法。
一个CTU 的 SAO 流程如图 7.22所示:
信息统计:
为了利用上述的快速模式判别方法,首先对一个CTU(包括一个亮度分量的 CTB和两个色度分量的CTB)采用不同SAO模式时进行信息统计。具体的信息如表7.4所示。
亮度CTB的 SAO 模式:
首先为亮度分量分别尝试5种SAO模式:EO_0式、EO_1式、EO_2模式、EO_3模式、BO模式,得到每种模式的相对率失真代价。这需要针对每种模式尝试不同的补偿值,每种模式的相对率失真代价为最优补偿值时的相对率失真代价。考虑不补偿模式,根据式(7-25)选择最优的SAO模式(包含不补偿模式),并记录该模式的相对率失真代价。
分别尝试左相邻块参数融合模式(左侧块可用)和上相邻块参数融合模式(上侧块可用),得到相对率失真代价和
。
色度CTB的 SAO 模式:
同亮度CTB,可以为两个色差分量得到最优SAO模式(包含不补偿模式),并记录最优模式的相对率失真代价(两分量的和),值得注意的是两种色度分量共用相同的划分模式。并得到左相邻块参数融合模式(左侧块可用)和上相邻块参数融合模式(上侧块可用)的相对率失真代价
和
。
CTU 的最优 SAO 模式:
综合亮度CTB和色度CTB的SAO模式,为CTU组合成3种SAO模式。
通过比较、
和
,拥有最小值相对率失真代价的模式为该CTU 的最优 SAO模式,该模式的SAO参数包括亮度模式、色度模式补偿值和边带号等。
CTU的 SAO 滤波:
采用最优的 SAO 参数对该CTU 进行补偿。
EO 模式:
如前所述,亮度及色度CTB的SAO模式选择过程中需要确定每一种EO模式(EO_0模式、EO_1模式、EO_2模式、EO_3模式)的相对率失真代价,这就需要为每种EO模式尝试不同的补偿值。下面以EO_0模式为例,介绍其最优补偿值的确定过程。
EO0模式时,CTB中的像素被分为5类,对于属于种类1~4的像素需要进行补偿,每个种类又可以选择不同的补偿值,因此需要为每个种类选取最优补偿值(、
、
、
)。每个种类(种类1~4)最优补偿值的确定过程独立进行,下面以种类1的最优补偿值
为例介绍其获取过程,流程如图 7.23所示。
BO模式:
如前所述,亮度及色度CTB的SAO模式选择过程中需要确定BO模式的相对率失真代价,这就需要尝试不同的边带及补偿值。BO模式时,CTB内的像素被划分到32个边带,最终选择4条连续的边带,并只对属于这4个边带的像素进行补偿,不同的边带可以选择不同的补偿值。
BO模式的确定过程:首先依次为0~31个边带选取最优补偿值,然后确定最优的连续4个边带。下面以第0条边带为例介绍其最优补偿值的获取过程,流程图如图 7.24 所示。
在HM10.0中是以一个Slice 为基本单位进行SAO的。也就是说先对整个Slice的CTU进行信息统计,再计算其SAO参数,最后再进行补偿。表7.5给出了SAO性能的实验结果,标准配置中SAO打开,对比组中SAO关掉,每个序列编码帧数为60帧。可以看出,关掉SAO后,在同样的视频质量下带来了0.63%~6.64%的比特率的上升。
图 7.25为序列 Chinaspeed,分辨率为832x480,帧率为25fps。编码配置条件为 LP,QP-39。图7.25(a)为不使用 SAO 处理的结果,图7.25(b)为使用SAO后的结果,可以明显地看出图7.25(b)比较平滑。
图7.26为序列Cactus,分辨率为1920x1080,帧率为50fs。编码配置条件为 LP,QP-39。图7.26(a)为不使用 SAO 处理的结果,图7.26(b)为使用SAO的结果,可以明显地看出图7.26(b)比较平滑。
3、语法语义:
SAO 语法:
SAO的语法如表7.6所示,它定义了SAO的语法结构,指明了SAO部分在码流中依次出现的语法元素及它们出现的条件,并提出描述子的方法等。
对于当前位置为(rx,ry)的CTU块,首先根据条件判断其是否可以选择左块参数融合模式,如果可以,则根据相应描述子提取出对应的比特该比特即表示出了sao_merge_let_flag的值;同样可提取出sao_merge_up_flag的值。如果这两个语法元素有一个为真,说明该CTU块使用了参数融合模式,其 SAO参数信息根据融合块就可得到;否则,该CTU块使用了非参数融合模式,此时可根据相应描述子分别提取出亮度和色度分量的补偿类型、补偿值、边带序号等SAO参数信息用于后续补偿。
SAO语义:
1.sao_merge_left_flag:
该语法元素代表当前CTU块的SAO参数信息是否与左侧相邻块进行了融合,取值为0或1。
当等于1时,表示当前 CTU块的 SAO 信息,即语法元素 sao_type_idx_luma, sao_type_idx_chroma, sao_band_position, sao_eo_class_luma, sao_eo_class_chroma,sao_offset_abs 以及 sao_offset_sign 的值是根据左侧 CTU 块的相应语法元素得到的;当该值等于0时,表示以上构成SAO信息的语法元素的值不是从左侧 CTU 得到的。其默认值为 0。
2.sao_merge_up_flag:
该语法元素代表当前CTU块的SA参数信息是否与上侧相邻块进行了融合,取值为0或1。
当等于1时,表示当前 CTU的SAO 信息,即语法元素 sao_type_idx_luma, sao_type_idx_ chroma, sao_band_position,sao_eo_class_luma, sao_eo_class_chroma,sao_offset_abs 以及sao_ offset_sign的值是根据上侧 CTU相应语法元素得到的;当该值等于0时,表示以上构成SAO信息的语法元素的值不是从上侧CTU 得到的。其默认值为0。
3.sao_type_idx_luma:
该语法元素代表亮度分量的补偿类型。数组SaoTypeldx[cIdx][rx][ry]表示色彩分量为cldx且位置为(rx,ry)处的CTB块的补偿类型,该变量取值为0时,表示不补偿;该变量取值为1时,表示边带补偿;该变量取值为2时,表示边界补偿。亮度分量的补偿类型,即数组SaoTypeldx[0][rx][ry]的值由以下步骤得到。
如果 sao_type_idx_luma存在,则将其赋给 SaoTypeldx[0][rx][ry]。
否则,进行以下步骤。
若sao_merge_leffag=l,则将 SaoTypeldx[0][rx-1][ry]的值赋给SaoTypeldx[0][rx][ry]。
否则,若sao_merge_up_fag-1,则将 SaoTypeldx[0][rx][ry-1]的值赋给 SaoTypeldx[0][rx][ry]。
否则,将 SaoTypeldx[0][rx][ry]设置为 0。
4.sao_type_idx_chroma:
该语法元素代表色度分量的补偿类型。色度分量的补偿类型,即数组 SaoTypeldx[cIdx][rx][ry]的值(cIdx=1,2)由以下步骤得到。
如果 sao_type_idx_chroma 存在,则将其赋给 SaoTypeldx[cIdx][rx][ry]。
否则,进行以下步骤。
若sao_merge_leftflag=1,则将 SaoTypeldx[0][rx-1][ry]的值赋给SaoTypeldx[cIdx][rx][ry].
否则,若sao_merge_up_flag=1,将SaoTypeldx[0][rx][ry-1]的值赋给
SaoTypeldx[cIdx][rx][ry]。
否则,将 SaoTypeldx[cldx][rx][ry]设置为0。
5. sao_offset_abs[cIdx][rx][ry][i]:
该语法元素表示色彩分量为Idx,位置为(x,y)的CTB,它的第i个种类的补偿值。当其不存在时,通过以下步骤得到。
若sao_merge_left_flag=l,则将sao_ofset _abs[cIdx][rx-1][ry][i]的值赋给 sao offset abs[cldx][rx][ry][i]。
否则,若sao_merge_up_flag=l,则将sao offset abs[cldx][rx][ry-1][i]的值赋给 sao_offset_abs[cldx][rx][ry][i]。
否则,将其设为0。
6.sao_offset_sign[cldx][rx][ry][i]:
当 SaoTypeldx[cldx][rx][ry]=1,即边带补偿时,该值代表了色彩分量为Idx,位置为(rx,y)的CTB,它的第i个补偿值的符号。
当该值不存在,通过以下方式获得。
若sao_merge_left flag=l,则将sao_offset _sign[cldx][rx-1][ry][]的值赋给 sao offset sign[cldx][rx][ry][i]。
否则,若sao_merge_up_flag=1,则将 sao _ofset sign[cIdx][rx][ry-1][i]的值赋给它。
否则,将其置 0。
7. sao_band_position[cIdx][rx][ry]:
该语法元素代表了进行边带补偿的最小边带位置。当其不存在时,通过以下步骤获得。
若sao_merge_left_flag=1,
则将 sao_band_position[cIdx][rx-1][ry]赋给 sao_band_position[cIdx][rx][ry]。
否则,若sao_merge_up_flag=1,则将sao_band position[cIdx][rx][ry-1]赋给它。
否则,将其置 0。
8.sao_eo_class_luma:
该语法元素代表了亮度分量的边界补偿模式。数组SaoEoClass[cldx][rx][ry]表示了色彩分量为 cdx,在位置(rx,ry)处的CTB 的补偿类型。SaoEoClass[0][rx][ry]通过以下步骤得到。
如果 sao_eo_class_luma存在,则将其值赋给 SaoEoClass[0][rx][ry].
否则,进行以下步骤。
若sao_merge_left_flag=1,则将 SaoEoClass[0][rx-1][ry]的值赋给SaoEoClass[0][rx][ry]。
否则,若sao_merge_up_flag1,则将 SaoEoClass[0][rx][ry-1]的值赋给 SaoEoClass[0][rx][ry]。
否则,将其设置为 0。
9.sao_eo_class_chroma:
该语法元素代表了色度分量的边界补偿模式。SaoEoClass[cIdx][rx][ry]的值(cIdx=1,2)通过以下步骤得到。
如果 sao_eo_class_chroma存在,则将其值赋给 SaoEoClass[cIdx][rx][ry]。
否则,进行以下步骤。
若 sao_merge_left_flag-1,则将 SaoEoClass[cIdx][rx-1][ry]的值赋给SaoEoClass[cldx][rx][ry]。
否则,若sao_merge_up_flag=1,则将 SaoEoClass[cldx][rx][ry-1]的值赋给 SaoEoClass[cIdx][rx][ry]。
否则,将其设置为0。
SPS 级 SAO 语义:
sample_adaptive_offset_enabled flag:该语法元素标识是否采用 SAO补偿技术。当该值取1时,表示使用;该值取0时,表示不使用。
PPS 级 SAO 语义:
loop_filter_across_tiles_enabled_flag:该语法元素用于标识在 tile的边界处是否执行环路滤波操作,包括去方块滤波和像素自适应补偿。当取值为1时,表示执行;取值为0时,表示不执行。
pps_loop_filter_across_slices_enabled_flag:该语法元素用于标识在Slice 的左边界以及上边界处是否执行环路滤波操作。当取值为1时,表示执行;取值为0时,表示不执行。
Slice 级 SAO 语义:
slice_sao_luma_flag:该语法元素标识当前 Slice的亮度分量是否允许进行SAO操作。当取值为1时,表示允许进行SAO:取值为0时,表示不允许进行SAO。当该语法元素未出现时,默认其值为0。
slice_sao_chroma_flag:该语法元素标识当前Slice的色度分量是否允许进行 SAO操作。当取值为1时,表示允许进行SAO;取值为0时,表示不允许进行SAO。当该语法元素未出现时,默认其值为0。
slice_loop_filter_across_slices_enabled_flag:该语法元素标识当前Slice 的左边界及上边界是否进行环路滤波操作,包括去方块滤波和像素自适应补偿。当取值为1时,表示可能进行(具体情况要根据后续条件判断);取值为0时,不进行环路滤波。当该语法元素未出现时,其值等于pps_loop_ filter_across_slices_enabled_flag 的值。
参考资料:
《新一代高效视频编码 H.265/HEVC 原理、标准与实现》——万帅 杨付正 编著
相关文章:
音视频之H.265/HEVC环路后处理
H.265/HEVC系列文章: 1、音视频之H.265/HEVC编码框架及编码视频格式 2、音视频之H.265码流分析及解析 3、音视频之H.265/HEVC预测编码 4、音视频之H.265/HEVC变换编码 5、音视频之H.265/HEVC量化 6、音视频之H.265/HEVC环路后处理 类似于以往的视频编码标准,H…...
RSUniVLM论文精读
一些收获: 1. 发现这篇文章的table1中,有CDChat ChangeChat Change-Agent等模型,也许用得上。等会看看有没有源代码。 摘要:RSVLMs在遥感图像理解任务中取得了很大的进展。尽管在多模态推理和多轮对话中表现良好,现有模…...
redis特性及应用场景
文章目录 什么是redis?热库redis作为热库的特性redis适用场景 什么是redis? redis在系统架构中的位置就是冷热分离架构的热数据库位置, redis就是热库, 我们一般说缓存数据库。 其他的像MySQL、SQL Server这种关系数据库、MongoDB…...
Java中正则表达式使用方法
1. 正则表达式概述 正则表达式(Regular Expression,简称 Regex)是一种用于匹配字符串的模式工具。在 Java 中,正则表达式通过 java.util.regex 包实现,主要涉及以下两个类: Pattern:表示一个编…...
CSS基础
1. CSS入门 1.1. CSS是什么 CSS是Cascading Style Sheets的缩写,翻译为层叠样式表。CSS是一种样式表语言,用来描述HTML文档的表现方式,如字体、色彩、背景色等等。我们先从一段简单的CSS代码开始。 代码1 CSS示例 p {color: red; }这段代…...
【Linux系统篇】:什么是信号以及信号是如何产生的---从基础到应用的全面解析
✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨ ✨ 个人主页:余辉zmh–CSDN博客 ✨ 文章所属专栏:Linux篇–CSDN博客 文章目录 一.信号概念1.生活角度的信号2.技术应用角度的信号3.补充内容前…...
SpringSecurity源码解读AbstractAuthenticationProcessingFilter
一、介绍 AbstractAuthenticationProcessingFilter 是 Spring Security 框架里的一个抽象过滤器,它在处理基于表单的认证等认证流程时起着关键作用。它继承自 GenericFilterBean,并实现了 javax.servlet.Filter 接口。此过滤器的主要功能是拦截客户端发送的认证请求,对请求…...
Python torchvision.transforms 下常用图像处理方法
torchvision.transforms 是 PyTorch 用于处理图像数据的一个模块,提供了丰富的图像变换功能。 1. transforms.Compose 的使用方法 transforms.Compose 用于将多个 transforms 操作组合起来,形成一个变换序列,然后按顺序对图像进行处理。其输…...
Zynq7020 制作boot.bin及烧录到开发板全流程解析
Zynq7020作为Xilinx推出的经典SoC芯片,其PS(Processing System)与PL(Programmable Logic)协同工作的特性使其在嵌入式开发中广泛应用。然而,初次接触Zynq的开发者在制作启动文件boot.bin及烧录时࿰…...
【办公类-89-02】20250424会议记录模版WORD自动添加空格补全下划线
背景需求 4月23日听了一个MJB的征文培训,需要写会议记录 把资料黏贴到模版后,发现每行需要有画满下划线 原来做这套资料,就是手动按空格到一行末,有空格才会出现下划线,也就是要按很多的空格(凑满一行&…...
Python-36:饭馆菜品选择问题
问题描述 小C来到了一家饭馆,这里共有 nn 道菜,第 ii 道菜的价格为 a_i。其中一些菜中含有蘑菇,s_i 代表第 ii 道菜是否含有蘑菇。如果 s_i 1,那么第 ii 道菜含有蘑菇,否则没有。 小C希望点 kk 道菜,且希…...
某大型电解铝厂电解系统谐波治理装置改造沃伦森电气
电解铝行业谐波治理解决方案——无源滤波装置优化升级,保障稳定运行 在电解铝生产过程中,谐波污染问题严重影响电网电能质量,甚至可能导致滤波装置损坏,引发群爆事故。河南登封某大型电解铝厂通过无源滤波装置智能化改造ÿ…...
基于YOLO+DeepSeek的农作物病虫害检测系统
前言 本系统是一个基于YOLODeepSeek的农作物病虫害检测系统。 可使用YOLOV1-YOLOV12的任意模型进行目标检测。可以实现检测图片、批量检测图片、视频检测、摄像头检测四种方式。 能够检测出[“苹果-黑腐病”, “苹果-健康”, “苹果-结痂”, “甜椒-细菌性斑疹”, “甜椒-健康…...
Python实现技能记录系统
Python实现技能记录系统 来自网络,有改进。 技能记录系统界面如下: 具有保存图片和显示功能——允许用户选择图片保存,选择历史记录时若有图片可预览图片。 这个程序的数据保存在数据库skills2.db中,此数据库由用Python 自带的…...
【专题刷题】二分查找(一):深度解刨二分思想和二分模板
📝前言说明: 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,按专题划分每题主要记录:(1)本人解法 本人屎山代码;(2)优质解法 优质代码;ÿ…...
基于Python+Flask的MCP SDK响应式文档展示系统设计与实现
以下是使用Python Flask HTML实现的MCP文档展示系统: # app.py from flask import Flask, render_templateapp Flask(__name__)app.route(/) def index():return render_template(index.html)app.route(/installation) def installation():return render_templa…...
Flask + ajax上传文件(一)
一、概述 本教程将教你如何使用Flask后端和AJAX前端实现文件上传功能,包含完整的代码实现和详细解释。 二、环境准备 1. 所需工具和库 Python 3.xFlask框架jQuery库Bootstrap(可选,用于美化界面)2. 安装Flask pip install flask三、项目结构 upload_project/ ├── a…...
【每天一个知识点】熵(Entropy)
“熵(Entropy)”是信息论、热力学、机器学习等多个领域的核心概念。它可以用一句话概括为: 🔑 熵表示系统的不确定性或信息混乱程度。 📚 一、信息论中的熵(Information Entropy) 在 Claude Sh…...
GIT 使用小记
全局设置 PS C:\workspace> git config --global user.name "FreeMan" PS C:\workspace> git config --global user.email "12323772wawhyuser.noreply.gitee.com" PS C:\workspace> git remote add origin https://gitee.com/wawhy/mountain.git…...
如何保证高防服务器中的系统安全?
对于高防服务器中的系统安全,企业通常会采取一系列的防护措施和策略防止网络攻击、入侵、恶意软件和其他网络安全威胁,下面是几个较为主要的安全防护措施,能够帮助企业提升高防服务器的安全性。 定期更新服务器中操作系统以及所有安装的软件&…...
【go语言】window环境从源码编译go
背景 早就听过go语言已经实现自举, 也就是使用旧版本go,来编译新版源码,得到新版本go。 步骤 1. 下载源码 git clone https://github.com/golang/go.git 2. 开始make cd go\src make.bat 3. 等待编译 卡住就按下回车 验证新版本 ……...
医学图像(DICOM数据)读取及显示(横断面、冠状面、矢状面、3D显示)为什么用ITK+VTK,单独用ITK或者VTK能实一样功能吗?
在医学图像处理中,结合使用 ITK 和 VTK 是常见的做法,因为它们各自专注于不同的核心功能。以下是逐步解释为何代码中同时使用两者,以及单独使用是否可行的分析: 1. 为什么用ITK处理DICOM数据? 1.1 ITK的DICOM处理优势…...
TiDB 深度解析与 K8S 实战指南
一、TiDB 核心特性与架构原理 1. 核心特性 分布式架构: 采用计算(TiDB Server)、存储(TiKV)、调度(PD)分离设计,支持水平扩展至 PB 级数据量。通过 PD 动态调度 Region(…...
WPS右键菜单中“上传到云文档”消失,使用命令行注册解决
关于上传到wps云文档,右键菜单莫名消失的问题 尝试在WPS设置显示上传到wps云文档的右键菜单,以及使用设置和修复工具修复,均无法显示菜单。 最终解决方法: regsvr32 "D:\Program Files (x86)\WPS Office\12.1.0.20784\offic…...
计算机求职面经内容与技巧分享
计算机求职面经内容与技巧分享 一、求职前的充分准备 (一)简历优化 突出技术能力:在简历中,务必清晰呈现自己精通的编程语言,例如熟练掌握 Java、Python 等语言的核心语法、常用库及框架。详细列举熟悉的技术栈&#x…...
java Springboot使用扣子Coze实现实时音频对话智能客服
一、背景 因公司业务需求,需要使用智能客服实时接听顾客电话。 现在已经完成的操作是,智能体已接入系统进行对练,所以本文章不写对联相关的功能。只有coze对接~ 扣子提供了试用Realtime WebSocket,点击右上角setting配…...
焦化烧结行业无功补偿解决方案—精准分组补偿 稳定电能质量沃伦森
在焦化、烧结等冶金行业,负荷运行呈现长时阶梯状变化,功率波动相对平缓,但对无功补偿的分组精度要求较高。传统固定电容器组补偿方式无法动态跟随负荷变化,导致功率因数不稳定,甚至可能因谐波放大影响电网安全。 行业…...
机器人项目管理新风口:如何高效推动智能机器人研发?
在2025年政府工作报告中,“智能机器人”首次被正式纳入国家发展战略关键词。从蛇年春晚的秧歌舞机器人惊艳亮相,到全球首个人形机器人马拉松的热议,智能机器人不仅成为科技前沿的焦点,也为产业升级注入了新动能。而在热潮背后&…...
ZooKeeper配置优化秘籍:核心参数说明与性能优化
#作者:张桐瑞 文章目录 tickTime:Client-Server通信心跳时间initLimit:Leader-Follower初始通信时限syncLimit:Leader-Follower同步通信时限dataDir:数据文件目录clientPort:客户端连接端口服务器名称与地…...
uniapp -- 实现微信小程序、app、H5端视频上传
布局及实现代码: <template><view class"flex flex-column p-4 grid-gap-4"><view class"flex flex-column grid-gap-4 bg-white p-4 rounded-4"><view class"font-weight-600">视频名称</view><i…...
2025年Redis分片存储性能优化指南
一、分片规则与负载均衡 动态哈希分片 采用CRC16算法计算键哈希值,通过hash_slot CRC16(key) % 16384确定槽位分布,结合Redis Cluster自动管理槽位迁移。 总分片数按需动态调整,例如从16节点扩容至32节点时,触发槽位重分配以…...
前端跨端框架的开发以及IOS和安卓的开发流程和打包上架的详细流程
以下是关于 前端跨端框架开发 以及 iOS/Android 原生开发流程与上架 的详细指南,涵盖技术选型、开发工具、打包发布全流程: 一、前端跨端开发框架对比与流程 主流跨端框架 框架技术栈性能接近原生生态成熟度适用场景React NativeJS/React80%⭐⭐⭐⭐⭐…...
项目《基于Linux下的mybash命令解释器》(二)
一、使用系统命令的完整代码 #include<stdio.h> #include<wait.h> #include<stdlib.h> #include<unistd.h> #include<assert.h> #include<string.h> #include<pwd.h>#define ARG_MAX 10//防止参数不够,可以做到一改全改…...
arm64适配系列文章-第十章-arm64环境上jenkins的部署
ARM64适配系列文章 第一章 arm64环境上kubesphere和k8s的部署 第二章 arm64环境上nfs-subdir-external-provisioner的部署 第三章 arm64环境上mariadb的部署 第四章 arm64环境上nacos的部署 第五章 arm64环境上redis的部署 第六章 arm64环境上rabbitmq-management的部署 第七章…...
PyTorch生成式人工智能实战(2)——PyTorch基础
PyTorch生成式人工智能实战(2)——PyTorch基础 0. 前言1. 创建 PyTorch 张量2. PyTorch 张量索引和切片3. PyTorch 张量形状4. 在 PyTorch 张量数学运算小结系列链接 0. 前言 为了训练生成式人工智能模型,我们可以使用多种数据格式ÿ…...
解决高德地图AMapUtilCoreApi、NetProxy类冲突
问题: Duplicate class com.amap.apis.utils.core.api.AMapUtilCoreApi found in modules jetified-3dmap-10.0.600 (com.amap.api:3dmap:10.0.600) and jetified-search-9.7.1 (com.amap.api:search:9.7.1) Duplicate class com.amap.apis.utils.core.api.NetProx…...
java—14 ZooKeeper
一、ZooKeeper简介 ZooKeeper是一种分布式协调服务,用于管理大型主机。在分布式环境中协调和管理服务 是一种复杂的过程,ZooKeeper通过简单的架构和API解决了这个问题。ZooKeeper运行开 发人员专注于核心应用程序逻辑,而不必担心应用程序的分…...
特征存储的好处:特征存储在机器学习开发中的优势
随着企业寻求提升机器学习生产力和运营能力 (MLOps),特征存储 (Feature Store) 的普及度正在迅速提升。随着 MLOps 技术的进步,特征存储正成为机器学习基础设施的重要组成部分,帮助企业提升模型的性能和解释能力,并加速新模型与生产环境的集成。这些存储充当集中式存储库,…...
【Promethus(普罗米修斯)介绍安装及使用】
一、系统介绍 1、什么是Prometheus? Prometheus:不仅是一款时间序列数据库,在整个生态上还是一套完整的监控系统。同时,还涉及许多以“explore”命名的客户端数据采集工具以及pushgateway网关。 官网:https://prometheus.io/ 文献:https://prometheus.io/docs/introdu…...
力扣热题100题解(c++)—矩阵
73.矩阵置零 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 int m matrix.size(); // 行数int n matrix[0].size(); // 列数bool firstRowZero false; // 标记第一行是否包含 0bool f…...
Spring Boot Controller 单元测试撰写
文章目录 引言标准用法必需依赖项核心注解说明代码示例 当涉及静态方法时的测试策略必需依赖项核心注解说明代码示例 引言 之前在编写 Controller 层的单元测试时,我一直使用 SpringBootTest 注解,但它会加载整个 Spring 应用上下文,资源开销…...
MVCC详解
目录 undo日志版本链 read view一致性视图 MVCC过程分析 读事务&写事务 Multi-Version Concurrency Control,多版本并发控制在读已提交和可重复读隔离级别下都实现了MVCC机制 undo日志版本链 一行数据被修改后,MySQL会保留修改前的数据(u…...
【通关函数的递归】--递归思想的形成与应用
目录 一.递归的概念与思想 1.定义 2.递归的思想 3.递归的限制条件 二.递归举例 1.求n的阶乘 2.顺序打印一个整数的每一位 三.递归与迭代 前言:上篇博文分享了扫雷游戏的实现,这篇文章将会继续分享函数的递归相关知识点,让大家了解并掌握递归的思…...
Python爬虫实战:移动端逆向工具Fiddler经典案例
一、引言 在移动互联网迅猛发展的当下,移动端应用产生了海量的数据。对于开发者而言,获取这些数据对于市场调研、竞品分析、数据挖掘等工作具有重要意义。Fiddler 作为一款功能强大的 Web 调试代理工具,能够有效捕获、分析和修改移动端的网络请求,为开发者深入了解移动端网…...
从平台工程视角出发,重塑云原生后端的工程体系
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:从 DevOps 到平台工程,云原生后端的演进逻辑 云原生的广泛应用,使得后端系统的开发、部署与运维逐渐从“编写业务代码”演进为“构建工程平台”。过去,后端开发者通常将注意力集中于 API 编写…...
【Hive入门】Hive分区与分桶深度解析:优化查询性能的关键技术
引言 在大数据领域,Apache Hive作为构建在Hadoop之上的数据仓库工具,因其类SQL的查询语言(HiveQL)和良好的扩展性而广受欢迎。然而,随着数据量的增长,查询性能往往成为瓶颈。本文将深入探讨Hive中两种关键的数据组织技术——分区(…...
Pytorch中的Dataset和DataLoader
1. PyTorch数据处理的核心概念 在PyTorch中,数据处理主要依赖两个核心组件: torch.utils.data.Dataset:定义如何访问数据集(单个样本的数据和标签)。torch.utils.data.DataLoader:负责批量加载数据、打乱数据、并行加载等。1.1 为什么需要Dataset和DataLoader? 问题:深…...
中介者模式:解耦对象间复杂交互的设计模式
中介者模式:解耦对象间复杂交互的设计模式 一、模式核心:用中介者统一管理对象交互,避免两两直接依赖 当系统中多个对象之间存在复杂的网状交互时(如 GUI 界面中按钮、文本框、下拉框的联动),对象间直接调…...
IEEE综述 | 车道拓扑推理20年演进:从程序化建模到车载传感器
导读 车道拓扑推理对于高精建图和自动驾驶应用至关重要,从早期的程序化建模方法发展到基于车载传感器的方法,但是很少有工作对车道拓扑推理技术进行全面概述。为此,本文系统性地调研了车道拓扑推理技术,同时确定了未来研究的挑战和…...
手撕C++STL list:深入理解双向链表的实现
目录 1. 引言 3. list 类的实现 (1) 基本结构 (2) 初始化与清理 (3) 插入与删除 (4) 常用接口 (4) 常用接口 4. 测试代码 5. 总结 1. 引言 在C STL中,list是一个基于双向链表的容器,支持高效的头尾插入/删除操作(O(1)时间复杂度&…...