AV1视频编码位于图像边界的超级块划分

一 位于图像边界的超级块划分
在实际的视频编码过程中给你,图像的宽度和高度可能不是128或64的整数倍,这会导致图像的右侧和底部的超级块可能会超出图像的实际边界。为了解决这个问题,当超级块的任何部分超出图像的底部或右侧边界时,这些超级块被强制进行划分,直到所有的编码像素块完全包含在图像的边界之内。在图3-2的示例中,该图片的分辨率是832x480,因此,当超级块大小是128x128时,右侧和底部的超级块都超出了图像边界,而当超级块大小是64x64时,仅仅底部超级块超出了图像边界。

这些超出图像边界的超级块,AV1标准会使用四叉树划分模式PARTITION_SPLIT 或者长宽比为1:2的水平划分模式PARTITION_HORZ,或者长宽比时2:1的垂直划分模式PARTITION_VERT,强制对这些超级块进行划分。在超级块强制划分过程中,如果生成的四叉树节点仍存在一部分区域位于图像边界之外,那么该四叉树节点将继续被强制划分,直到每个编码块的所有像素都位于图像边界内部。AV1使用语法元素split_or_horz和split_or_vert表示每个四叉树节点的划分模式。

1 如果当前四叉树节点的左上角四叉树子节点超出了图像的底部边界,那么AV1使用语法元素split_or_horz 表示其划分模式,此时,split_or_horz 等于0表示使用划分模式 PARTITION_HORZ划分当前节点,否则,表示使用划分模式PARTITION_SPLIT划分当前节点。

2 如果当前四叉树节点的左上角四叉树子节点超出了图像的右侧边界,那么AV1使用于法元素split_or_vert 表示其划分模式。split_or_vert等于0表示使用PARTITION_VERT划分当前节点,否则,使用PARTITION_SPLIT划分当前节点。

3 如果当前四叉树节点的左上角四叉树子节点既超出了图像的右侧边界,又超出了图像的底部边界,那么AV1使用划分模式PARTITION_SPLIT对该四叉树节点进行划分,此时,不需要编码任何语法元素。

假设变量r和c分别表示当前四叉树节点的行坐标和列坐标,r和c均以4亮度像素为基本单位,变量bSize表示四叉树节点的大小,函数parse symbol 是解析语法元素symbol的函数,那么AV1标准文档定义的编码块划分流程decode_partition如下所示:

复制代码
decode_partition(r, c, bSize)` `{`
`//如果当前四叉树节点的起始行坐标r或列坐标c超过图片边界,则退出。`
    `if` `(r >= MiRows || c >= MiCols)`
        `return` `0;`
    `AvailU` `= is_inside(r - 1, c)`
    `AvailL` `= is_inside(r, c - 1)`
    
    `//根据当前四叉树节点的尺寸bSize获取节点的宽度`
    `num4x4` `= Num_4x4_Blocks_Wide[bSize]`
    `//halfBlock4x4是当前四叉树节点宽度的一半,quarterBlock4x4` `是宽度的1/4`
    `halfBlock4x4` `= num4x4` `>>` `1`
    `quarterBLock4x4` `= halBlock4x4>>1`
    `//hasRows和hasCols分别表示四叉树节点的左上角四叉树子节点是否超过底部边界`
    `//和右侧边界,hasRows和hasCols取值false表示超过了图像边界`
    `hasRows` `=` `(r + halfBlock4x4)` `<` `MiRows`
    `hasCols` `=` `(c + halfBlock4x4)` `<` `MiCols`
    `if (bSize < BLOCK_8x8)` `{`
    `//尺寸bSize,小于8x8时,不需要继续分割`
            `partition` `= PARTITION_NONE`
    `}` `else if` `(hasRows && hasCols)` `{`
    `//左上角四叉树子节点位于图像内部,则解析语法元素parition`
        `parse(partition)`
    `}` `else if` `(hasCols)` `{`
    `//左上角四叉树子节点超过图像底部边界,则解析语法元素split_or_horz`
    `//并据此对partition进行赋值`
        `parse(split_or_horz)`
        `partition` `=` `split_or_horz` `?` `PARTITION_SPLIT:` `PARTITION_HORZ`
    `}` `else if` `(hasRows)` `{`
    `//左上角四叉树子节点超过图像右侧边界,则解析语法元素split_or_horz`
    `//并据此对partition进行赋值`
        `parse(split_or_vert)`
        `partition =` `split_or_vert ?` `PARTITION_SPLIT:` `PARTITION_VERT`
    `}` `else {`
    `//左上角四叉树子节点同时超过图像底部和右侧边界,则把partition,`
    `//赋值为PARTITION_SPLIT`
        `partition` `= PARTITION_SPLIT`
    `}`
    `subSize =` `Partition_SUbSize[partition][bSize]`
    `splitSize` `= Partition_Subsize[PARTITION_SPLIT][bSize]`
    
    `if (partition == PARTITION_NONE)` `{`
    `//当节点不再继续划分,则解码重构当前节点`
        `decode_block(r, c, subSize)`
    `}` `else` `if` `(partition == PARTITION_HORZ)` `{`
    `//解码重构上方的编码块`
        `decode_block(r, c, subSize)`
        `//当下侧的编码块位于图像内部时,则解码重构下方编码块`
        `if` `(hasRows)` `{`
            `decode_block(r + halfBlock4x4, c, subSize)`
        `}`
    `}` `else if` `(partition == PARTITION_VERT)` `{`
    `//解码重构左侧编码块`
        `decode_block(r, c, subSize)`
        `//当右侧编码块位于图像内部时,则解码重构右侧编码块`
        `if (hasCols)`
            `decode_block(r, c + halfBlock4x4, subSize)`
    `}` `else if (partition == PARTITION_SPLIT)` `{`
    `//按照四叉树划分模式,递归解码子节点`
        `decode_partition(r, c, subSize)`
        `decode_partition(r, c + halfBlock4x4, subSize)`
        `decode_partition(r + halfBlock4x4, c, subSize)`
        `decode_partition(r + halfBLock4x4, c + halfBlock4x4, subSize)`
    `}` `else if (partition == PARTITION_HORZ_A)` `{`
    `//解码重构上方两个方形编码块`
        `decode_block(r, c, splitSize)`
        `decode_block(r, c + halfBlock4x4, splitSize)`
        `//解码重构下方一个矩形编码块`
        `decode_block(r + halfBlock4x4, c, subSize)`
    `}` `else if (partition == PARTITION_HORZ_B)` `{`
    `//解码重构上方一个矩形编码块`
        `decode_block(r, c, subSize)`
        `//解码下方两个方向编码块`
        `decode_block(r + halfBLock4x4, c, splitSize)`
        `decode_block(r + halfBLock4x4, c + halfBlock4x4, splitSize)`
    `}` `else if (partition == PARTITION_VERT_A)` `{`
    `//解码左侧两个方形编码块`
        `decode_block(r, c, splitSize)`
        `decode_block(r + halfBLock4x4, c, splitSize)`
        `//解码右侧一个矩形编码块`
        `decode_block(r, c + halfBlock4x4, subSize)`
    `}` `else if (partition == PARTITION_VERT_B)` `{`
    `//解码左侧一个方形编码块`
        `decode_block(r, c, subSize)`
        `//解码右侧两个方形编码块`
        `decode_block(r, c + halfBlock4x4, splitSize)`
        `decode_block(r + halfBlock4x4, c + halfBlock4x4, splitSIze)`
    `}` `else if (partition == PARTITION_HORZ_4)` `{`
        `decode_block(r + quarterBlock4x4 * 0, c, subSize)`
        `decode_block(r + quarterBlock4x4 * 1, c, subSize)`
        `decode_block(r + quarterBlock4x4 * 2, c, subSize)`
        `//当最后一个编码块位于图像内部时,则解码重构最后一个编码块`
        `if (r + quarterBlock4x4 * 3 < MiRows)`
            `decode_block(r + quarterBlock4x4 * 3, c, subSize)`
    `}` `else {`
        `decode_block(r + quarterBlock4x4 * 0, c, subSize)`
`        decode_block(r + quarterBlock4x4 * 1, c, subSize)`
`        decode_block(r + quarterBlock4x4 * 2, c, subSize)`
        `//当最后一个编码块位于内部时,则解码重构最后一个编码块`
        `if` `(c + quarterBlock4x4 * 3 < MiCols)`
            `decode_block(r, c + quarterBlock4x4 * 3, subSize)`
    `}`
`}`
`

二 根据AV1标准文档定义的编码块划分流程decode_partition, 如果当前四叉树节点仅仅超出了图像的底部边界但是没有超出图像的右侧边界,那么当前节点的split_or_vert似乎在任何条件下都能被赋值为PARTITION_VERT,而与当前所有节点在图像内部区域的大小无关。只有当四叉树节点所在图片内部正好可以通过划分模式

PARTITION_VERT产生时,该节点的split_or_vert才能被赋值为PARTITION_VERT;否则,该节点不能被正确解码,对于超出图像的右侧边界但是没有超出图像底部边界的超级块,只有当四叉树节点所在图片内部区域正好可以通过划分模式PARTITION_HORZ产生时,其split_or_horz才能被赋值为PARTITION_HORZ 图3-7位图像边界处的超级块划分示意图。

相关推荐
薛定猫AI1 小时前
【深度解析】Gemini Omni 多模态生成与 Agent 化创作工作流:从视频编辑到 UI 生成的技术演进
人工智能·ui·音视频
Terrence Shen4 小时前
大模型部署工具对比
人工智能·深度学习·计算机视觉
AI算法沐枫6 小时前
大模型 | 大模型之机器学习基本理论
人工智能·python·神经网络·学习·算法·机器学习·计算机视觉
埃菲尔铁塔_CV算法6 小时前
YOLO11 与传统纹理特征融合目标检测 完整实现教程
人工智能·神经网络·yolo·计算机视觉
松☆7 小时前
ops-transformer:FlashAttention算子深度实践
人工智能·计算机视觉·目标跟踪
普密斯科技8 小时前
在线图像测量仪实战案例:医疗西林瓶尺寸检测的精准解决方案
大数据·人工智能·计算机视觉·健康医疗·测量
AI人工智能+8 小时前
不动产权证书识别技术:融合了计算机视觉、自然语言处理(NLP)和人工智能的深度技术栈
人工智能·计算机视觉·语言模型·ocr·不动产权证书识别
音视频牛哥9 小时前
大牛直播SDK(SmartMediaKit)Windows平台RTSP/RTMP直播播放SDK集成说明(C++版)
windows·音视频·实时音视频·windows rtsp播放器·windows rtmp播放器·超低延迟rtsp播放器·超低延迟rtmp播放器
Hua-Jay10 小时前
OpenCV联合C++/Qt 学习笔记(二十二)----相机模型与投影及单目相机标定
c++·笔记·qt·opencv·学习·计算机视觉
凌峰的博客11 小时前
T2SMark:在扩散模型噪声水印中寻找鲁棒性与多样性的平衡
人工智能·深度学习·计算机视觉