VVC学习之二:VTM中CU划分结构QTMTT(3):打印QTMTT最终划分

介绍完QTMTT在VTM中的实现,相信很多人包括我也对QTMTT的最终划分结果很感兴趣,于是我尝试将最终的划分结果进行可视化显示。

xCompressCU中,将对CTU进行递归划分,用RDcost选择出最优的划分方式,因此在xCompressCU中很难提取到QTMTT的最优划分方式。因此,要得到最终划分结果,必须在xCompressCU之后。VTM提供了遍历每个CodingStructure中所有CU的函数traverseCUs(),因此只需要在xCompressCU之后,遍历CTU中每个CU就可以得到其位置和尺寸信息。

为了可视化显示CU,需要修改CU边界像素值,但是重建像素将会用作参考,直接修改重建值将会影响帧间预测的运动估计和运动补偿,因此不能直接修改CU的重建值。我用了最笨的方法,copy重建帧,在copy上进行可视化,并保存下来。

下面给出实现过程

// 遍历每帧图像中所有CTU,对每个CTU遍历所有CU
for (int y = 0; y < pcv.heightInCtus; y++)
	{
		for (int x = 0; x < pcv.widthInCtus; x++)
		{
			const UnitArea ctuArea(pcv.chrFormat, Area(x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth));
			//  CU-based painting
			if (CS::isDualITree(cs))
			{
				for (auto &currCU : cs.traverseCUs(CS::getArea(cs, ctuArea, CH_L), CH_L))
				{
					xDrawCUIntraColor(currCU, Height, Width, pbufY, pbufU, pbufV);
				}
			}
			else
			{
				for (auto &currCU : cs.traverseCUs(CS::getArea(cs, ctuArea, CH_L), CH_L))
				{
					xDrawCUColor(currCU, Height, Width, pbufY, pbufU, pbufV);
				}
			}

		}
	}
// 这里根据每个CU的编码模式,选择了不同的显示颜色
void xDrawCUIntraColor(CodingUnit& cu, int orgHeight, int orgWidth, unsigned char* tempY, unsigned char* tempU, unsigned char* tempV)
{
	const CompArea&  lumaArea = cu.block(COMPONENT_Y);

	int cuX = lumaArea.x;
	int cuY = lumaArea.y;
	int cuH = lumaArea.height;
	int cuW = lumaArea.width;

	int chromaX = cuX >> 1;
	int chromaY = cuY >> 1;
	int chromaH = cuH >> 1;
	int chromaW = cuW >> 1;

	unsigned char y = 0, u = 0, v = 0;
	if (cu.firstPU->intraDir[CHANNEL_TYPE_LUMA] < 2)
	{
		rgb2yuv(0, 0, 255, y, u, v);      // blue
	}
	else
	{
		rgb2yuv(255, 0, 0, y, u, v);      // red
	}

	int tempLumaIdx;
	for (int i = 0; i < cuH; i++)
	{
		for (int j = 0; j < cuW; j++)
		{
			tempLumaIdx = (i + cuY) * orgWidth + cuX + j;
			if (i == cuH - 1 || j == cuW - 1) //i == 0 || i == cuH - 1 || j == 0 || j == cuW - 1
			{
				tempY[tempLumaIdx] = y;
			}
		}
	}

	int tempChromaIdx;
	for (int i = 0; i < chromaH; i++)
	{
		for (int j = 0; j < chromaW; j++)
		{
			tempChromaIdx = (i + chromaY) * orgWidth / 2 + (chromaX + j);
			if (i == chromaH - 1|| j == chromaW - 1)  //i == 0 || i == chromaH - 1 || j == 0 || j == chromaW - 1
			{
				tempU[tempChromaIdx] = u;
				tempV[tempChromaIdx] = v;
			}
		}
	}
}

最终的效果如下:
帧内划分
帧内划分结果
帧间划分
帧间划分结果

  • 7
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值