HEVC中SAO--自适应样点补偿 详细分析解读

原创 2012年12月05日 09:46:32

 HEVC中SAO--自适应样点补偿:

  本文分三个部分, 1.Sample Adaptive Offset原理, 2.SAO处理流程分析, 3.SAO意义何在!

a)  SAO原理:

    SAO是在DB之后进行, 输入是重建帧和原始帧数据, 输出是SAO数据和SAO后的重建帧. 自适应样点补偿是一个自适应选择过程,在去块滤波后进行。

下面是整个HEVC的编码框图, 可以看到SAO是在整个帧编码完成后得到重建帧后进行的,属于Slice级别(帧级).

 

     首先把Frame划分为若干LCU, 然后对每个LCU中每个像素进行SAO操作.将根据其LCU像素特征选择一种像素补偿方式,以减少源图像与重构图像之间的失真。自适应样点补偿方式分为带状补偿(Band Offset,BO)和边缘补偿(Edge Offset,EO)两大类。

带状补偿将像素值强度等级划分为若干个条带,每个条带内的像素拥有相同的补偿值。进行补偿时根据重构像素点所处的条带,选择相应的带状补偿值进行补偿。

    边缘补偿主要用于对图像的轮廓进行补偿。它将当前像素点值与相邻的2个像素值进行对比,用于比较的2个相邻像素可以在下图中所示的4种模板中选择,从而得到该像素点的类型。解码端根据码流中标示的像素点的类型信息进行相应的补偿校正。

对每个模板还要确定属于那种类型,类型确定有下面表格来决定.

b)  SAO处理流程分析:

 

    SAO主函数代码结构如下:主要有3个函数完成所有操作.

Void TEncSampleAdaptiveOffset::SAOProcess()

rdoSaoUnitAll(pcSaoParam, dLambdaLuma, dLambdaChroma, depth);

if (pcSaoParam->bSaoFlag[0])

 processSaoUnitAll(saoLcuParam[0], oneUnitFlag[0], 0);

if (pcSaoParam->bSaoFlag[1])

{

processSaoUnitAll(saoLcuParam[1], oneUnitFlag[1], 1);

processSaoUnitAll(saoLcuParam[2], oneUnitFlag[2], 2);

}

}

    其中TEncSampleAdaptiveOffset::rdoSaoUnitAll函数完成对整个Frame的所有LCU的YUV进行reset stats和calcSaoStatsCu,以及saoComponentParamDist得到最佳SAO_TYPE选择.最后encodeSaoOffset.

Void TEncSampleAdaptiveOffset::rdoSaoUnitAll()

{ …

 for (idxY = 0; idxY< frameHeightInCU; idxY++)

 {

   for (idxX = 0; idxX< frameWidthInCU; idxX++)

// reset stats Y, Cb, Cr

     calcSaoStatsCu(addr, compIdx,  compIdx);

     saoComponentParamDist();

     sao2ChromaParamDist();

     for ( compIdx=0;compIdx<3;compIdx++)

      encodeSaoOffset(&saoLcuParam[compIdx][addr], compIdx);

       // Cost of Merge

   }

 }

}

    下面是子函数的说明:

也就是TEncSampleAdaptiveOffset::calcSaoStatsCuOrg

主要是得到LCU中所有像素各种SAOType的所有信息和状态统计,

分析记录各种SAOType(SAO_EO_0,SAO_EO_1,SAO_EO_2,SAO_EO_3,SAO_BO)以及各种SAOTypeLen和YUV分量对应的m_iOffsetOrgm_iCount.

     iStats = m_iOffsetOrg[0.1.2][0.1.2.3.4]; //YUV and SA0_TYPE

     iCount = m_iCount[0.1.2][ 0.1.2.3.4];

如果是BO,通过iClassIdx =m_lumaTableBo[pRec[x]];来确定属于那个条带,并记录iStats[iClassIdx] += (pOrg[x] - pRec[x]);iCount[iClassIdx]++;这里iClassIdx大小为0~32.

如果是EO, 通过iClassIdx =m_auiEoTable[uiEdgeType]来确定模板类型,并记录iStats[iClassIdx] += (pOrg[x] -pRec[x]);iCount[iClassIdx]++;

这里iClassIdx大小为0~4.

其中映射关系如下:就是查表映射.

const UInt TComSampleAdaptiveOffset::m_auiEoTable[9] =

{ 1, //0     2, //1     0, //2  3, //3  4, //4

 0, //5    0, //6    0, //7   0};

随后函数TEncSampleAdaptiveOffset::saoComponentParamDist完成最佳SAOTYPE的选择. 得到最佳dCostPartBest和typeIdx等信息.

下面两个语句得到每个BO带或者EO种类的offset.

m_iOffset[compIdx][typeIdx][classIdx] = m_iOffsetOrg[compIdx][typeIdx][classIdx]/(m_iCount[compIdx][typeIdx][classIdx];

m_iOffset[compIdx][typeIdx][classIdx] = Clip3(-m_iOffsetTh+1, m_iOffsetTh-1, (Int)m_iOffset[compIdx][typeIdx][classIdx]);

m_iOffset[compIdx][typeIdx][classIdx] = estIterOffset();

最后通过比较得到最佳dCostPartBest和typeIdx.

   if(m_dCost[yCbCr][typeIdx] < dCostPartBest)

   {

     dCostPartBest = m_dCost[yCbCr][typeIdx];

// saoLcuParam保存目前最好的.

     copySaoUnit(saoLcuParam, &saoLcuParamRdo );     

bestDist = estDist;      

}

同样TEncSampleAdaptiveOffset::sao2ChromaParamDist完成色度的选择.

TEncSampleAdaptiveOffset::SAOProcess()中的函数processSaoUnitAll主要完成SAO解码的操作,也就是对重建帧进行SAOoffset叠加.

另外一个同名函数SAOProcess属于COM库,主要是解码使用,也就调用processSaoUnitAll为主,负责恢复SAO偏移量.

Void TComSampleAdaptiveOffset::SAOProcess(TComPic* pcPic, SAOParam* pcSaoParam)

if (pcSaoParam->bSaoFlag[0] || pcSaoParam->bSaoFlag[1])

 { if (pcSaoParam->bSaoFlag[0])

   {

     processSaoUnitAll(saoLcuParam[iY], oneUnitFlag[iY], iY);

   }

   if(pcSaoParam->bSaoFlag[1])

   {

      processSaoUnitAll(saoLcuParam[1], oneUnitFlag[1], 1);//Cb

      processSaoUnitAll(saoLcuParam[2], oneUnitFlag[2], 2);//Cr

   }

 }

}

 

a)   SAO--自适应样点补偿意义何在:

     SAO意义:大量模拟测试和资料显示, SAO平均可以节约2%到6%的码率, 而编解码的复杂度只增加2%左右!SAO主要目的和操作原理减少源图像与重构图像之间的失真。如果只看这点,实际上每帧编码后的码率反而会增加,因为多了SAO的相关语法和语义以及补偿值的编码!其实不然,虽然当前帧的码率增加了几个字节或者几个bit, 但是这点增加码字使得源图像与重构图像的失真减少,使接下来的预测残差更小了,从而大大的降低码率了!

     我在想是否可以增加一个无损编码的HEVC版本呢? 增加另外一些语法和语义,把源图像与重构图像之间的失真单独拿出来再次采用其它无损编码技术编码,如果在需要超清晰的图像时,就可以和这个无损编码的码流组合解码,重建无损图像.个人随想!大家也可以发表下观点啊!

 

(如需转载请注明出处!谢谢!)

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数。 1.   最基本的算法是,从小到大遍历: for (i = 2 to A -1)          if (i * B > A)...

利用K-means聚类算法根据经纬度坐标对中国省市进行聚类

K-means聚类算法是一种非层次聚类算法,在最小误差的基础上将数据划分了特定的类,类间利用距离作为相似度指标,两个向量之间的距离越小,其相似度就越高。程序读取全国省市经纬度坐标,然后根据经纬度坐标进...

Radon变换理论介绍与matlab实现--经验交流

本人最近在研究Radon变换,在查阅了各种资料之后在此写下个人的理解,希望与各位牛牛进行交流共同进步,也使得理解更加深刻些。 Radon变换的本质是将原来的函数做了一个空间转换,即,将原来的XY平...

Matlab绘图-很详细,很全面

Matlab绘图强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数。此外,Ma...

CT图像重建技术

由于csdn贴图不方便,并且不能上传附件,我把原文上传到了资源空间CT图像重建技术 1.引言 计算机层析成像(Computed Tomography,CT)是通过对物体进行不同角度的射线投影测量而...

linux查找目录下的所有文件中是否含有某个字符串

查找目录下的所有文件中是否含有某个字符串  find .|xargs grep -ri "IBM"  查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名  find .|xargs g...

Radon变换入门matlab CT原理

http://hi.baidu.com/hi9394/blog/item/0d492b8bfd714700c8fc7aa9.html 简介 图像投影,就是说将图像在某一方向上做线性积分(或理解为累...

Intel系列处理器的三种工作模式

Intel系列处理器的三种工作模式 微机中常用的Intel系列微处理器的主要发展过程是:8080,8086/8088,80186, 80286,80386,80486,Pentium,Pen...

js弹出框、对话框、提示框、弹窗总结

js弹出框、对话框、提示框、弹窗总结 一、JS的三种最常见的对话框 [javascript] view plaincopy //=...

form表单的两种提交方式,submit和button的用法

1.当输入用户名和密码为空的时候,需要判断。这时候就用到了校验用户名和密码,这个需要在jsp的前端页面写;有两种方法,一种是用submit提交。一种是用button提交。 方法一: 在jsp的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HEVC中SAO--自适应样点补偿 详细分析解读
举报原因:
原因补充:

(最多只允许输入30个字)