改进《VVC/VTM中CU的划分结果打印》

之前CU划分结果的打印https://blog.csdn.net/pengyouyou/article/details/83152297

改进结果如下:四叉树(蓝色)、水平二叉树(绿色)、垂直二叉树(黄色)、水平三叉树(红色)和垂直三叉树(紫色)。

此结果在编码端实现,编码器下载地址https://download.csdn.net/download/pengyouyou/11050299

由于VVC中CU(CodingUnit)由CS(CodingStructure)来管理,而原始平台的CU是没有划分类型的信息的,因此在解码端无法获得CU的划分类型。

因此本文考虑在编码端实现。

实现思路:

在划分开始的时候(递归开始),划分出子节点,此时将划分类型保存到CS之中;然后由CS告知其中的每个CU;最后,每个CU被编码后,将CU的划分信息回传给父节点(递归结束)。

具体实现:(VTM4.0.1)

1)在CS中增加成员变量:

uint8_t partype;//增加划分模式管理

2)在CU中增加成员变量:

uint8_t finaltype; //增加划分模式信息

3)保存subcs的划分

EncCU.cpp1350行左右

      tempSubCS->partype=encTestMode.type; //保存当前subCu划分

      bestSubCS->partype = encTestMode.type;

4)将划分类型告知CU(在subcs初始化时进行,subcs从cs中获取cu)

CodingStructure.cpp749行函数void CodingStructure::initSubStructure()中subcs调用CodingStructure.cpp362行函数 CodingStructure::addCU()。即从cs中取出cu给subcs进行管理,此时告知CU自己的划分类型。cu->finaltype = partype;//cu存入cs采用的划分类型

注意:cu一定是被cs管理的

5)将subcs中cu的划分类型传递到cs中(cs接收subcs时):

CodingStructure.cpp817行函数void CodingStructure::useSubStructure()

将subcs中cu的信息拷贝到cs的cu中cu.finaltype = pcu->finaltype;//cu是this指针(父cs)

6)重建yuv中显示划分结果

在EnGOP.cpp2750行左右,compressGOP中重建完成(pcPic->reconstructed = true;)之后。

#if SPLIT_SHOW
    PelUnitBuf recpic = pcPic->getRecoBuf();//重建结束后得到重建缓存
    AreaBuf<Pel>& recYpoint = recpic.Y();//得到Y分量
    AreaBuf<Pel>& recCbpoint = recpic.Cb();//得到Cb
    AreaBuf<Pel>& recCrpoint = recpic.Cr();//得到Cr
    uint64_t culength = pcPic->cs->cus.size();//总的cu数量
    for (uint64_t n = 0; n<culength; n++) {
      CodingUnit* finalCU = pcPic->cs->cus.at(n);//得到每一个CU
      Area curArea(finalCU->lumaPos(), finalCU->lumaSize());//CU大小和位置
      if (finalCU->chType == CHANNEL_TYPE_LUMA) {//cu是否亮度cu
        splitshow(recYpoint, recCbpoint, recCrpoint, curArea, finalCU->finaltype);
      }      
    }
#endif // SPLIT_SHOW
#if SPLIT_SHOW
void splitshow(AreaBuf<Pel>& recYpoint, AreaBuf<Pel>& recCbpoint, AreaBuf<Pel>& recCrpoint, Area curArea,int type) {
  int x = curArea.x ;//偏置1个像素
  int y = curArea.y ;//
  int h = curArea.height;//
  int w = curArea.width;//
  int16_t Y_value=0,Cb_value=0,Cr_value=0;//
  switch (type) {
  case 10:Y_value = 327; Cb_value = 361; Cr_value = 960; break;//红色
  case 8:Y_value = 640; Cb_value = 215; Cr_value = 136; break;//绿色
  case 7:Y_value=164; Cb_value = 960; Cr_value = 440; break;//蓝色
  case 11:Y_value=426; Cb_value = 810; Cr_value = 888; break;//紫色
  case 9:Y_value = 901; Cb_value = 64; Cr_value = 584; break;//黄色
  case 12:Y_value = 739; Cb_value = 663; Cr_value = 64; break;//青色
  case 13:Y_value = 192; Cb_value = 656; Cr_value = 607; break;//靛青
  default:break;
  }
  //y,cb,cr纯红(327,361,960)纯绿(640,215,136)纯蓝(164,960,440)
  //淡紫色(426,810,888)黄色(901,64,584)青色(739,663,64)
  //靛青(192,656,607)
  for (int j = 0; j < h; j++) {
    //left
    //recYpoint.at(x, y + j) = Y_value; ///左边1
    //recYpoint.at(x + 1, y + j) = Y_value;//左边2
   // recCbpoint.at(x / 2, (y + j) / 2) = Cb_value; //cb分量
    //recCrpoint.at(x / 2, (y + j) / 2) = Cr_value;//cr分量
    //right
    recYpoint.at(x+w-2, y + j) = Y_value; ///1
    recYpoint.at(x+w-1, y + j) = Y_value;//2
    recCbpoint.at((x+w-2) / 2, (y + j) / 2) = Cb_value; //cb分量
    recCrpoint.at((x+w-2) / 2, (y + j) / 2) = Cr_value;//cr分量
  }
  for (int i = 0; i < w; i++) {
    //top
    //recYpoint.at(x + i, y) = Y_value; //上1
    //recYpoint.at(x + i, y + 1) = Y_value;//上2
    //recCbpoint.at((x + i) / 2, y / 2) = Cb_value; //cb分量
    //recCrpoint.at((x + i) / 2, y / 2) = Cr_value;//cr分量
    //down
    recYpoint.at(x + i, y+h-2) = Y_value; //1
    recYpoint.at(x + i, y+h-1) = Y_value;//2
    recCbpoint.at((x + i) / 2, (y+h-2) / 2) = Cb_value; //cb分量
    recCrpoint.at((x + i) / 2, (y+h-2) / 2) = Cr_value;//cr分量
  }
}
#endif

 

 

  • 11
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值