如何从VVC VTM参考软件提取带索引的motion vector并导出为txt或xml文件
VVC VTM运动矢量导出索引添加方案
索引字段设计
你需要给每个运动矢量(MV)添加以下维度的索引,即可精确定位MV的所属位置:
- 帧POC(图像顺序计数,区分不同编码帧)
- 帧类型(I/P/B帧,I帧无运动矢量可跳过输出)
- CTU列号、CTU行号(定位到最大编码块级别)
- CU绝对X坐标、CU绝对Y坐标(定位到预测单元的左上角位置)
- CU宽度、CU高度(标记当前预测单元的尺寸)
- 参考帧POC(标记当前MV指向的参考帧序号,双向预测需要分别输出两个参考方向的对应字段)
VTM代码修改逻辑
找到你当前写入MV到文件的代码位置,通常位于EncCu.cpp的EncCu::xCompressCU函数中,CU模式决策完成后的位置,在原有导出逻辑前添加索引字段采集代码,参考实现如下:
// 原有MV获取逻辑 Mv curMv = pcCU->getMv(uiPartAddr, REF_PIC_LIST_0, 0); // 新增索引字段采集 int framePoc = pcCU->getSlice()->getPOC(); int ctuRsAddr = pcCU->getCtuRsAddr(); int ctuX = ctuRsAddr % pcCU->getPic()->getNumCtusInWidth(); int ctuY = ctuRsAddr / pcCU->getPic()->getNumCtusInWidth(); int cuAbsX = pcCU->getCUAbsX(); int cuAbsY = pcCU->getCUAbsY(); int cuW = pcCU->getWidth(uiPartAddr); int cuH = pcCU->getHeight(uiPartAddr); int refPoc = pcCU->getSlice()->getRefPOC(REF_PIC_LIST_0, pcCU->getRefIdx(uiPartAddr, REF_PIC_LIST_0, 0)); // TXT导出示例,制表符分隔,可在文件首行写入表头方便后续解析 outFile << framePoc << "\t" << ctuX << "\t" << ctuY << "\t" << cuAbsX << "\t" << cuAbsY << "\t" << cuW << "\t" << cuH << "\t" << refPoc << "\t" << curMv.getHor() << "\t" << curMv.getVer() << "\n";
注意:VTM默认输出的MV为1/4像素精度,如需整像素精度可将MV的水平、垂直分量除以4。
导出格式参考
TXT格式
首行表头示例:帧POC\tCTU列号\tCTU行号\tCU左上角X\tCU左上角Y\tCU宽度\tCU高度\t参考帧POC\tMV水平分量\tMV垂直分量
每行对应一个MV的全部信息,分隔符可根据你的解析需求替换为逗号、空格等。
XML格式
单个MV的XML节点结构示例:
<MotionVector id="1"> <FramePOC>15</FramePOC> <CTUPosX>2</CTUPosX> <CTUPosY>1</CTUPosY> <CUPosX>128</CUPosX> <CUPosY>64</CUPosY> <CUWidth>32</CUWidth> <CUHeight>32</CUHeight> <RefFramePOC>12</RefFramePOC> <MVHorizontal>24</MVHorizontal> <MVVertical>-4</MVVertical> </MotionVector>
准确性验证
导出完成后可随机选取3-5条记录,根据索引的坐标信息在原始YUV序列对应位置取块,在参考帧对应MV指向的位置取匹配块,确认两者的差值符合编码逻辑,即可验证索引与MV的对应关系正确。
内容的提问来源于stack exchange,提问作者YS2021
相关产品推荐
相关产品推荐

