H.266/VVC代码学习18:特殊的角度模式:planar模式(xPredIntraPlanar)

1 简介

planar是模式标号为0的模式,当块内像素是渐变情况时,通常采用planar模式。
对应情况:在像素值缓慢变化的区域,
线性:它使用水平和垂直两个线性滤波器,将两者平均值作为当前像素的预测值。

2 计算

官方的计算方法如下,看起来较为繁琐:
planar计算
实际上这就是个线性缓变的计算。
首先已知的是左边和上边参考像素值,左下角和右上角参考像素值,进行如下操作即可算得对应位置的值:
1.将右上角的值填充整个右边作为块右侧参考像素。由左侧参考像素值,构建线性函数,渐变到右侧参考像素。得到像素数据1
2.将左下角的值填充整个下边作为块下侧参考像素。由上侧参考像素值,构建线性函数,渐变到下侧参考像素。得到像素数据2
3.将对应位置的像素数据1和像素数据2进行加权平均。

3 代码

void IntraPrediction::xPredIntraPlanar( const CPelBuf &pSrc, PelBuf &pDst, const SPS& sps )
{/********** 获取边缘像素值 **********/const uint32_t width  = pDst.width;	//此CU宽度const uint32_t height = pDst.height;	//此CU高度
#if JVET_M0102_INTRA_SUBPARTITIONSconst uint32_t log2W  = g_aucLog2[width  < 2 ? 2 : width];//宽度的logconst uint32_t log2H  = g_aucLog2[height < 2 ? 2 : height];//高度的log
#elseconst uint32_t log2W  = g_aucLog2[ width ];	const uint32_t log2H  = g_aucLog2[ height ];	
#endifint leftColumn[MAX_CU_SIZE + 1], topRow[MAX_CU_SIZE + 1], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
#if JVET_M0102_INTRA_SUBPARTITIONSconst uint32_t offset = 1 << (log2W + log2H);//后面用于四舍五入
#elseconst uint32_t offset = width * height;	
#endif// Get left and above reference column and rowfor( int k = 0; k < width + 1; k++ )	//获取宽度的像素值(上一行){topRow[k] = pSrc.at( k + 1, 0 );}for( int k = 0; k < height + 1; k++ )	//获取高度的像素值(左一列){leftColumn[k] = pSrc.at( 0, k + 1 );}// Prepare intermediate variables used in interpolationint bottomLeft = leftColumn[height];	//左下角像素值int topRight = topRow[width];			//右上角像素值/******* 填充四个边缘的值 *******/for( int k = 0; k < width; k++ ){	  bottomRow[k] = bottomLeft - topRow[k];topRow[k] = topRow[k] << log2H;  }for( int k = 0; k < height; k++ ){rightColumn[k] = topRight - leftColumn[k];leftColumn[k] = leftColumn[k] << log2W;      }/******* 填充PLANAR模式CU内部的像素值 *******/const uint32_t finalShift = 1 + log2W + log2H;const uint32_t stride = pDst.stride;	//一行的像素数,为了指向下一行的这个位置Pel*       pred = pDst.buf;for (int y = 0; y < height; y++, pred += stride){int horPred = leftColumn[y];		//水平预测值 = 左边这行的边缘值 + 右边这行边缘值for (int x = 0; x < width; x++){			 horPred += rightColumn[y];		//再次加上差值。topRow[x] += bottomRow[x];		//再次加上差值。int vertPred = topRow[x];		//垂直预测值 = 上边这行的边缘值 + 下边这行边缘值pred[x] = ((horPred << log2H) + (vertPred << log2W) + offset) >> finalShift;//计算,得到像素最终预测值}}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部