SVT-AV1中的global-MV/仿射运动实现分析

一 逻辑实现
函数作用

这是一个路由函数,router function,根据配置的 correspondence_method, 选择使用哪种方法来收集对应点,correspondences, 对应点是全局运动估计的基础数据。

在全局运动估计流程中的位置。

全局运动估计的完整流程

1 收集阶段,-本函数,根据配置选择方法收集对应点

方法A,角点检测方法,correspondence from corners

方法B, MV方法,correspondence from mvs

输出:对应点数组,当前帧位置,参考帧位置。

2 合并阶段,RANSAC算法,将收集到的对应点聚合成全局运动模型

在compute+global motion中调用determine gm parames()->svt_aom_ransac()

RANSAC算法从大量对应点中找出最能代表全局运动的模型参数

输出:全局运动模型参数,放射变换矩阵等

3 应用阶段,在模式决策中使用全局运动模型为每个块计算MV

两种方法的对比:

角点方法

原理:基于图像特征,角点进行匹配,不依赖运动估计结果

优点:更鲁棒,精度高,不依赖ME质量,适合复杂运动

缺点:计算复杂度中等

适用场景:复杂运动,ME质量差时,需要高精度时

MV方法,(MV_64x64, MV_32x32, MV_16x16/MV_8x8)

原理:从运动估计结果中提取MV,转换为对应点

优点:计算速度快,利用已有的ME结果

缺点:依赖ME质量,精度受ME影响

适用场景:ME质量好时,需要快速计算时。

函数参数说明:

复制代码
pcs 图像父控制集,包含`
` gm_ctrls.correspondence_method 对应点收集方法配置`
 `pa_me_data: 运动估计数据MV方法需要`
 `其他全局运动相关配置`
`frm_buffer 当前帧图像缓冲区,亮度分量`
`frm_width 当前帧宽度,像素`
`frm_height 当前帧高度`
`frm_stride 当前帧行跨度,字节数,用于访问图像数据`
`frm_corners 输入,当前帧已经检测的角点数组,仅角点方法使用`
    `格式[x0, y0, x1, y1, x2, y2, ...]`
    `在调用本函数前已经通过svt_av1_fast_corner_detect() 检测完成`
    `MV方法不使用此参数`
`num_frm_corners 输入,当前帧角点数量,仅角点方法使用`
`ref 参考帧图像缓冲区,亮度分量`
`ref_stride 参考帧行跨度`
`correspondences 输出:收集到的对应点数组,每个对应点表示,当前帧位置(x,y) 参考帧位置(rx, ry)`
`这些对应点将被传递给RANSAC算法进行聚合`

`num_correspondences 输出 实际手机到的对应点数量`
`list_idx 参考帧列表索引,MV方法使用`
`0 list0 前向参考帧`
`1 list1 后向参考帧`
`ref_idx 参考帧索引,仅MV方法使用`
`在指定列表中的位置 (0,1,2,....)`

`void gm_compute_correspondence(PictureParentControlSet* pcs, uint8_t *frm_buffer, int frm_width, int frm_height, int frm_stride, int *frm_corners, int num_frm_corners, uint8_t *ref, `
`int ref_stride, `
`COrrespondence* correspondences, int* num_correspondences, uint8_t list_idx, uint8_t ref_idx)`
`{`
`//根据配置选择对应点收集方法`
`//检查 correspondence method配置,决定使用哪种方法收集对应点`
    `if (pcs->gm_ctrls.correspondence_method == CORNERS) `
    `{`
        `//方法A,角点检测方法`
        `//使用角点检测和匹配来收集对应点`
        `//这是更常用和更鲁棒的方法,不依赖运动估计的质量`
        `corresppondence_from_corners(`
        `&pcs->gm_ctrls, //全局运动控制参数,包含角点数量配置等`
        `frm_buffer, //当前帧图像缓冲区`
`        frm_height,             // 当前帧高度`
`            frm_stride,             // 当前帧行跨度`
`            frm_corners,            // 当前帧已检测的角点数组(输入)`
`            num_frm_corners,        // 当前帧角点数量(输入)`
`            ref,                    // 参考帧图像缓冲区`
`            ref_stride,             // 参考帧行跨度`
`            correspondences,        // 输出:匹配得到的对应点数组`
`            num_correspondences);   // 输出:匹配成功的对应点数量`
        
        `//角点方法的工作流程`
        `//1 在参考帧中检测角点,correspondence from corners 内部完成`
        `//2 匹配当前帧和参考帧的角点,通过NCC归一化互相关`
        `//精炼匹配结果,提高亚像素精度`
        `//4 输出高质量的对应点数组`
    `} else {`
    `//方法B MV方法`
    `//从运动估计结果中提取MV,转换为对应点`
    `//这种方法利用已有ME结果,计算速度快`
    `//断言检查,确保correspondence method 最有效的MV方法`
    `//MV方法包括,MV_64x64(0), MV_32x32(1), MV_16x16(2), MV_8x8(3)`
    `    orrespondence_from_mvs(`
`            pcs,                    // 图像父控制集(包含ME结果数据)`
`            correspondences,        // 输出:从MV转换得到的对应点数组`
`            num_correspondences,    // 输出:收集到的对应点数量`
`            list_idx,               // 参考帧列表索引(0=List0, 1=List1)`
`            ref_idx);               // 参考帧索引(在列表中的位置)`
    `}`
`//MV方法的工作流程`
`//1 遍历所有SB super block  64x64块`
`//2 从每个SB内部的子块,根据correspondence method选择块大小,提取MV`
`//3 将MV转换为对应点,当前帧位置 x,y 参考帧位置, rx = x + mv.x , ry = y + mv.y`
`//4输出对应点数组`    
`}`

`/*`
`通过角点检测和匹配来收集对应点,这是角点聚合MV模式的核心函数`

`角点检测方法 vs MV方法`
`角点方法,基于图像特征,角点进行匹配,不依赖运动结果`
`MV方法,基于运动估计的MV结果,依赖ME的质量`
`角点方法通常更准确,因为角点事图像中的稳定特征点。`

`完整流程,三步`
`第一步:角点检测,在调用本函数前已完成`
    `当前帧的角点已经通过svt_av1_fast_corner_detect() 检测完成`
    `角点存储在frm_corners 中,数量为num_frm_corners`
    `角点检测使用FAST算法,找到图像中的特征点,边缘,角落等`
`第二步:参考帧角点检测,本函数内部`
    `在参考帧中检测角点,找到对应的特征点`
    `使用相同的FAST角点检测算法`
`第三部:角点匹配,本函数内部`
    `将当前帧的角点与参考帧的角点进行匹配`
    `通过计算归一化互相关NCC找到最佳匹配`
`     - 只有匹配质量超过阈值的角点对才会被保留`
` * - 匹配结果会被进一步精炼以提高精度`
 `匹配过程详解 在svt_av1_determine_correspondence中`
` * 1. 对当前帧的每个角点:`
` *    - 在参考帧的所有角点中搜索最佳匹配`
` *    - 计算两个角点周围区域的归一化互相关(NCC)`
` *    - 只考虑距离合理的候选(避免匹配到太远的点)`
` *    - 选择NCC值最高的匹配`
` * 2. 匹配质量检查:`
` *    - 只有当 NCC > THRESHOLD_NCC * variance 时才保留匹配`
` *    - 这确保了匹配的可靠性`
`  * 3. 匹配精炼(improve_correspondence):`
` *    - 在匹配点周围的小窗口(SEARCH_SZ x SEARCH_SZ)内进行精细搜索`
` *    - 双向精炼:先精炼参考帧位置,再精炼当前帧位置`
` *    - 找到亚像素精度的最佳匹配位置`
` * 输出:`
` * - 对应点数组:每个对应点表示当前帧角点(x,y)和参考帧角点(rx,ry)的匹配`
` * - 这些对应点将被传递给RANSAC算法,聚合成全局运动模型`
` * `
` * 为什么角点方法更常用?`
` * - 角点是图像中的稳定特征,对光照变化、噪声等更鲁棒`
` * - 不依赖运动估计的质量,即使ME失败也能工作`
` * - 匹配精度高,能提供高质量的对应点`
` * - 适合处理复杂运动(旋转、缩放等)`
` * @param gm_ctrls 全局运动控制参数`
` * @param frm_buffer 当前帧图像缓冲区`
` * @param frm_width 当前帧宽度`
` * @param frm_height 当前帧高度`
` * @param frm_stride 当前帧行跨度`
` * @param frm_corners 输入:当前帧已检测的角点数组(格式:[x0,y0, x1,y1, ...])`
` * @param num_frm_corners 输入:当前帧角点数量`
` * @param ref 参考帧图像缓冲区`
` * @param ref_stride 参考帧行跨度`
` * @param correspondences 输出:匹配得到的对应点数组`
` * @param num_correspondences 输出:匹配成功的对应点数量`
`*/`
`static void correspondence_from_corners(GmControls* gm_ctrls, uint8_t* frm_buffer, int frm_width, int frm_height,`
`                                        int frm_stride, int* frm_corners, int num_frm_corners, uint8_t* ref,`
`                                        int ref_stride, Correspondence* correspondences, int* num_correspondences)`
`{`
`//第一步,在参考帧中检测角点,`
`/使用FAST 角点检测算法在参考帧中找到特征点`
`//角点存储格式:[x0, y0, x1, y1, x2, y2, ...],所以数组大小是 2 * MAX_CORNERS`
    `int ref_corners[2 * MAX_CORNERS]; //最大4096 个角点`
    `//在参考帧中检测角点,最多检测 MAX_CORNERS个`
    `//角点存储格式 [x0, y0, x1, y1, x2, y2, ...] 所以数组大小事2 * MAX_CORNERS`
    `//在参考帧中检测角点,最多检测MAX_CORNERS个`
    `//返回实际检测到的角点数量`
    `int num_ref_corners = svt_av1_fast_corner_detect(`
    `(unsigned char*)ref, frm_width, frm_height, ref_stride, ref_corners, MAX_CORNERS);`
    `//第二步,根据配置调整使用的角点数量`
    `//gm_ctrls->corners 控制使用多少比例的角点`
    `//1 使用1/4 的角点,`
    `//2 使用1/2的角点`
    `//使用3/4的角点`
    `//使用全部的角点,`
    `//这样可以平衡计算复杂度和匹配精度`
`    num_ref_corners = num_ref_corners * gm_ctrls->corners / 4;`
`    num_frm_corners = num_frm_corners * gm_ctrls->corners / 4;`
    `//第三步,匹配当前帧和参考帧的角点,生成对应点`
    `//这是核心步骤,通过归一化互相关NCC匹配角点`
    
    `//匹配过程 在svt_av1_determine_correspondence 中实现,`
    `//1 对当前帧的每个角点,在参考帧的所有角点中找到最佳匹配`
    `//2计算两个角点周围match_sz x match_sz 区域的归一化互相关`
    `//3保留NCC > THREASHOLD_NCC * variance 的高质量匹配`
    `//4 对匹配结果进行精炼,提高亚像素精度`
    `//输出:对应点数组,每个对应点表示`
    `//x,y 当前帧中的角点位置`
    `//rx, ry 参考帧中匹配的角点位置`
    `//这些对应点奖杯传递给RANSAC算法,聚合成全局运动模型参数`
    `*num_correspondences = svt_av1_determine_correspondence(frm_buffer, (int*)frm_corners`
    `,`  `num_frm_corners,`
    `ref, `
    `(int*)ref_corners,`
    `num_ref_corners,`
    `frm_width,`
    `frm_height,`
    `frm_stride,`
    `ref_stride,`
    `correspondences,`
    `gm_ctrls->match_sz);`
`}`

`/*`
`FAST-9` `角点检测,带非极大值抑制,全局运动估计中角点检测的核心函数`
`函数作用`
    `这是FAST` `Features` `from Accelerated` `Segment` `Test` `角点检测算法的完整实现,包含三个步骤,检测,评分,非极大值抑制,函数用于在全局运动估计中检测图像特征点。`
`FAST算法原理`
`FAST算法通过检查像素周围16个点的亮度差异来快速判断是否为角点,`
    `如果中心像素周围有连续9个,或者更多点的亮度明显高于或者低于中心的像素,则认为是角点9` `表示需要连续9个点满足条件。FAST-9` `变体。`
    
`算法流程:`
`步骤1:角点检测,svt_aom_fast9_detect`
    `遍历图像中的每个像素,边界除外`
    `检查像素周围16个采样点的亮度`
    `如果满足FAST9条件,标记为候选角点`
    `输出:所有候选角点的坐标数组`
`步骤2:角点评分svt_aom_fast9_score`
    `为每个候选角点计算一个分数`
    `分数表示该角点的强度或显著性`
    `分数越高,角点越明显,越稳定`
    `输出:每个角点对于的分数数组`
`步骤3:非极大值抑制` `svt_aom_nonmax_suppression`
    `在焦点密集区域,只保留分数最高的角点`
    `抑制周围分数较低的角点,避免重复检测`
    `输出,经过筛选的高质量角点数组`
    
`在全局运动估计中的作用`
    `1` `在当前帧和参考帧中匹配对应点`
    `2` `通过RANSAC算法拟合生成全局运动模型`
    `3实现从局部特征到全局运动的聚合`
`im 输入图像缓冲区,亮度分量,8位灰度图`
    `图像数据按行存储,每一行stride字节`
`xsize 图像宽度,像素数`
`ysize 图像高度,像素数`
`stride` `图像行跨度,字节数`
    `通常等于图像宽度,但是可能包含对齐填充`
    `用于计算像素在缓冲区中的位置im[y * stride + x]`
`b` `角点检测阈值,brightness` `threshold`
    `控制角点检测的敏感度`
    `值越大,检测到的角点越少,只检测非常明显的角点`
    `值越小,检测到的角点越多,包括较弱的角点`
    `典型值范围` `10-30`
    `ret_num_corners 输出参数,返回检测到的角点数量`
        `经过非极大值抑制后的最终角点数量`
    `xy*` `返回角点坐标数组的指针`
        `每个元素是一个xy结构体,包含角点(x,y)坐标`
        `数组大小为ret_num_corners` 
        `调用者需要负责释放内存,使用free`
`内存管理`
    `函数内部会分配内存存储角点数组`
    `调用者需要在使用完成后调用free 释放返回的指针`
    `函数内部会释放中间结果,corners和scores数组`
`*/`
`xy*` `svt_aom_fast9_detect_nonmax(const byte* im, `
`int xsiez, int ysize, int stride, int b, int *ret_num_corners)`
`{`
    `//变量声明`
    `//corners 存储第一步检测到的所有候选角点坐标`
    `//类型xy是结构体,包含x和y两个整数成员`
    `xy*` `corners;`
    `//num_corners` `候选角点的数量,检测过程中会被更新,`
    `//scores 存储每个候选角点的分数数组`
    `//分数表示角点的显著性` `强度,用于后续的非极大值抑制`
    `int *scores;`
    `//nonmax 存储经过非极大值抑制后的最终角点坐标`
    `//这是函数的返回值,包含高质量的,非重复的角点`
    
    `xy*` `nonmax;`
    `//步骤1,角点检测`
    `//调用FAST-9` `检测算法,在图像中找出所有候选角点。`
    `//参数说明`
    `//im 输入图像缓冲区`
    `//xsize,` `ysize 图像尺寸`
    `//stride` `行跨度`
    `//b 检测阈值`
    `//&num_corners` `输出参数,返回检测的角点数量`
    `//返回值,候选角点坐标数组,需要后续释放内存`
    `/检测原理`
    `//遍历图像中每个像素,边界3像素除外需要16个采样蒂娜`
    `//检查像素周围16个采样点的亮度`
    `//如果连续9个点都明显亮于,或者暗于中心像素,标记为角点。`
    `corners = svt_aom_fast9_detect(im, xsize, ysize, stride, b, &num_corners);`
    `//步骤2,角点评分,`
    `//为每一个候选点计算一个分数,表示角点的显著性`
    `//参数说明`
    `//im 输入图像,用于计算分数`
    `//` `stride` `行跨度`
    `//corners 候选角点数组,步骤1的输出`
    `//num_corners` `角点数量`
    `//b` `检查阈值` `用于评分计算`
    
    `//返回值,分数数组,每个角点对应一个分数`
    `//评分原理`
    `//通过二分搜索找到使该点仍然能被检测为角点的最大阈值`
    `//这个阈值就是该角点的分数,`
    `//分数越高,说明角点越明显,越稳定`
    `scores` `= svt_aom_fast9_score(im, stride, corners, num_corners, b);`
    `//步骤3,非极大值抑制`
    `//在角点密集区域,只保留分数最高的角点,抑制周围的低分角点`
    
    `//参数说明`
    `//corners` `候选角点数组`
    `//scores` `角点分数数组`
    `//num_corners` `角点数量`
    `//ret_num_corners 输出参数,返回抑制后的角点数量`
    
    `//返回值,经过筛选的最终角点数组,需要调用者释放内存`
    `//抑制原理`
    `//对于每个角点,检查其3x3邻域内的其他角点`
    `//如果领域内有分数更高的角点,则抑制当前角点`
    `//只保留局部最大值,非极大值抑制`
    `//这也可以避免在同一个特征区域监测到多个重要的角点`
    `nonmax = svt_aom_nonmax_suppresion(corners, scores, num_corners, ret_num_corners);`
    `//内存清理`
    `//释放中间结果的内存,只保留最终的非极大值抑制结果`
    
    `//释放候选角点数组,步骤1的输出,已被nonmax替代`
    `free(corners);`
    `//释放角点分数数组,(步骤2的输出,不再需要)`
    `free(scores);`
    `//返回值最终结果`
    `//返回经过非极大值抑制后的高质量角点数组`
    `//调用者需要在使用完后调用free(nonmax)释放内存`
    `return nonmax;`
`}`

`最小二乘法计算线性回归。通过找到的参考帧中的角点和编码帧中的角点,`
`计算映射关系。`
`x' = a1*x + a2*y + a3`
`y' = b1*x + b2*y + b3`







`
相关推荐
搬砖者(视觉算法工程师)2 小时前
【无标题】
人工智能·计算机视觉·机器人
RFID舜识物联网2 小时前
高校实验室智能化升级:RFID技术革新化学试剂管理
大数据·人工智能·科技·物联网·安全
子夜江寒2 小时前
OpenCV部分操作介绍
图像处理·python·opencv·计算机视觉
深蓝学院2 小时前
为何机器学习常提反事实推断?——从起源、价值到数学建模
人工智能·机器学习
轻竹办公PPT2 小时前
2026 年 AI PPT 工具深度复盘:工具间的效率鸿沟与职场应用场景分析
人工智能·python·powerpoint
企业老板ai培训2 小时前
从九尾狐AI案例拆解智能矩阵架构:如何用AI获客引擎重构传统企业流量体系
人工智能·矩阵·重构
零售ERP菜鸟2 小时前
IT年度商业计划书框架(精简版)
大数据·人工智能·职场和发展·创业创新·学习方法·业界资讯
张祥6422889042 小时前
线性代数本质笔记十二
人工智能·算法·机器学习
乌恩大侠2 小时前
【AI-RAN 调研】软银株式会社的 “AITRAS” 基于 Arm 架构的 NVIDIA 平台 实现 集中式与分布式 AI-RAN 架构
人工智能·分布式·fpga开发·架构·usrp·mimo