自適應QP(Adaptive QP)

Adaptive QP

Adaptive QP是爲每個CU自適應的選擇QP以提升編碼質量。由配置參數AdaptiveQP指定是否開啓該功能。默認不開啓。

("AdaptiveQP,-aq", m_bUseAdaptiveQP,false, "QP adaptation based on a psycho-visual model")

其QP計算原則是:對於平坦塊選擇較小的QP,對於活動性較高的塊選擇較大的QP

CU的活動性由其亮度分量的方差計算得到。例如,對於一個2Nx2N的CU,首先計算其4個NxN的亮度子塊的方差,然後由方差計算該CU的活動性actcu:

 

爲了實現在活動性高的區域使用較大QP,平坦區域使用較小QP,需要對圖像中每個2Nx2N的CU的actcu進行歸一化。假設圖像f的所有2Nx2N的CU的平均活動性爲actf,則歸一化後的norm_actcu計算如下:

 

QPA由配置參數MaxQPAdaptationRange指定,默認值爲6。

  ("MaxQPAdaptationRange,-aqr",m_iQPAdaptationRange,6, "QP adaptation range")

最終CU的QP計算如下:

 

注意:配置文件中參數MaxCuDQPDepth指定了能使用Adaptive QP的最小CU尺寸,默認爲0。其值要小於最大CU深度。

以下代碼是HM中Adaptive QP計算過程:

/** Compute QP for each CU
 * \param pcCU Target CU
 * \param uiDepth CU depth
 * \returns quantization parameter
 */
Int TEncCu::xComputeQP( TComDataCU* pcCU, UInt uiDepth )
{
  Int iBaseQp = pcCU->getSlice()->getSliceQp();
  Int iQpOffset = 0;
  if ( m_pcEncCfg->getUseAdaptiveQP() )
  {
    TEncPic* pcEPic = dynamic_cast<TEncPic*>( pcCU->getPic() );
    UInt uiAQDepth = min( uiDepth, pcEPic->getMaxAQDepth()-1 );
    TEncPicQPAdaptationLayer* pcAQLayer = pcEPic->getAQLayer( uiAQDepth );
    UInt uiAQUPosX = pcCU->getCUPelX() / pcAQLayer->getAQPartWidth();
    UInt uiAQUPosY = pcCU->getCUPelY() / pcAQLayer->getAQPartHeight();
    UInt uiAQUStride = pcAQLayer->getAQPartStride();
    TEncQPAdaptationUnit* acAQU = pcAQLayer->getQPAdaptationUnit();
​
    Double dMaxQScale = pow(2.0, m_pcEncCfg->getQPAdaptationRange()/6.0); //!<縮放因子s
    Double dAvgAct = pcAQLayer->getAvgActivity();  //!<平均活動性
    Double dCUAct = acAQU[uiAQUPosY * uiAQUStride + uiAQUPosX].getActivity();
    Double dNormAct = (dMaxQScale*dCUAct + dAvgAct) / (dCUAct + dMaxQScale*dAvgAct); //!<歸一化
    Double dQpOffset = log(dNormAct) / log(2.0) * 6.0; //!<換底公式
    iQpOffset = Int(floor( dQpOffset + 0.49999 ));
  }
​
  return Clip3(-pcCU->getSlice()->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQp+iQpOffset );
}

感興趣的請關注微信公衆號Video Coding

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章