mad的问题汇总

Q:我想将I帧的预测图像和原始图像的平均绝对误差给输出来,请问这个在JM86中需要在哪一点改动呢?谢谢 A: 差值保存在diffy中: diffy[j][i] = imgY_org[img->opix_y+j][img->opix_x+i] - pred[j][i]; 分析MAD不知道程序中在哪求可以直接搜索"MAD“ 结果中有一个函数: img->MADofMB[img->current_mb_nr] = calc_MAD(); 就是这个了,进去看一下: //calculate MAD for the current macroblock double calc_MAD() { int k,l; int s = 0; double MAD; for (k = 0; k < 16; k++) for (l = 0; l < 16; l++) s+= abs(diffy[k][l]); MAD=s*1.0/256; return MAD; } 刚好是根据diffy求MAD Q:看了很多的文献,不论是经典的二次R-Q模型,还是其它什么模型,其中总有一个用于表示编码复杂度的变量,如二次R-Q模型中是MAD,有的模型中是SATD等,根据二次R-Q模型的源出文献《Scalable Rate Control for MPEG-4 Video》,MAD的引入是为了使模型scalable with video content,但是为什么有这种效果却没有讲。请教各位,MAD的引入的原因是为了什么,有什么数据来证明或文献支持?谢谢高手赐教! A:就是为了根据前一帧的复杂度来预测当前帧的复杂度啊。 我说的是R-Q模型中,引入了MAD,不是使用MAD的线性预测模型 A:《Scalable Rate Control for MPEG-4 Video》中最初得到的二次模型是一个码率和QP之间的关系,但是实际中并不是QP越高,码率就越小,不同的图像复杂度不同,对得到的码率也会有影响,因此,需要对原先的二次模型做一个修正,加入图像复杂度这个因素。而对于为什么MAD可以近似代表图像复杂度,我想不用我解释了吧,自己好好想下就知道了。 Q:道理确实是如此,从二次模型的公式来看,对某个图像,给定QP时,BIts/MAD就是一个常数,这意味着Bits和MAD就是线性关系,但从《Scalable Rate Control for MPEG-4 Video》中,并没有看到相关的证明! A:率失真模型中,一方面关心的是比特率与QP值(或量化步长)的关系,另外一方面关心的是比特率与图像编码复杂度之间的关系。 假定QP值如果和编码复杂度相互独立的话,那么率失真模型应当相当优雅。但是实际的情况并非如此,特别是在H.264中。 在MPEG-4及以前版本中,计算MAD的方法是用运动估值后的残差信息。这样MAD值与比特之间确实存在一种线性关系(注意是线性,而不是正比),虽然在楼主提到的文献Scalable Rate Control for MPEG-4 Video 中并没有给出图。为了方便,或者为了避免一些无法解决的问题,该文献将MAD直接写入了二次率失真模型中,作为正比项存在,并一直主导着视频图像编码的码率控制算法。 在下通过大量的实验数据,绘制出了H.264中比特率与MAD的关系,甚至是预测MAD(JVT-G012线性预测方法)的关系图。从图中可以看到,在H.264中比特率与MAD的线性关系存在,但不明显,而且线性截距很大,不可忽略。比特率与预测MAD的关系可以用不相关三个字来形容。个中特点,各自揣摩。 谈一点我个人的看法: MAD如果统计的是运动估值后的残差信息,确实可以直接理解为图像的编码复杂度。因为这个时候的MAD已经带有双重特性:其一运动估值,其二残差。这个时候的MAD的表征对象就是马上用于变换编码和量化的基础。很多早期的文献对此都有评论,推导或改进。但是如果MAD不能直接取到的话,再用MAD的任何预测形式来做图像复杂度都是自欺欺人的做法。 “从二次模型的公式来看,对某个图像,给定QP时,BIts/MAD就是一个常数” 从在下的若干实验看来,BIts/MAD不会是个常数。原因很简单,BIts/(MAD+b)才是常数,b表示截距。我想 Scalable Rate Control for MPEG-4 Video 的作者是知道的,但是他不愿这样做,所以没有给出图。 另外特别注意,MAD和QP不独立,在H.264中。 十年放羊 写的“BIts/(MAD+b)才是常数”才是常数,这个很早就有文献,就是在二次模型中那个常数项是不能省掉的,我也做了这方面的实验,MAD确实与QP有关系,而且关系应该能用模型表示出来,应该可以进行理论推导 Q:JM86中关了RDO后 原始图像和运动预测补偿后的MAD怎么突然变的很大?是什么原因,我觉得应该变的小一点才是正确的 为什么差别那么大,RDO开着的时候是1点多 关掉的时候是 6点多, 不一定RDO最准确,RDO只是选择使代价最小的点作为匹配点,不一定是最匹配的位置,应该是开着RDO好一点,因为可以进行模式选择,对宏块进行细分 A:你说的对。RDO 最小并不是 MAD 最小。所以 RDO 跟 MAD 之间没有规律性。 Q:在编码中,P帧中也有使用帧内预测模式来进行预测编码的,那么在计算该P帧的MAD时,是否计算帧内预测模式下编码宏块的MAD值?在JM配置文件中有没有选项使编码P帧时只使用帧间编码模式,将帧内编码模式关掉,如果有是哪个参数呢?谢谢~~~~~ A:配置文件中没有,JM86 可以强制修改 encode_one_macroblock 函数中的 valid 变量 Q:JSVM9.17中,jsvmCalcMAD好像不是计算的MAD,是SAD啊,程序如下 unsigned int MbEncoder::jsvmCalcMAD( IntMbTempData*& rpcMbBestData, MbDataAccess& rcMbDataAccess ) { UInt uiDist = 0; UInt uiDelta = 1; Int n, m; IntMbTempData *rpcMbTempData = new IntMbTempData; rpcMbTempData->init( rcMbDataAccess ); rpcMbTempData->loadLuma ( *m_pcIntOrgMbPelData ); rpcMbTempData->loadChroma ( *m_pcIntOrgMbPelData ); XPel* pucDst = rpcMbBestData->getMbLumAddr(); XPel* pucSrc = rpcMbTempData->getMbLumAddr(); Int iStride = rpcMbTempData->getLStride(); Int iDeltaXStride = uiDelta * iStride; AOF( iStride == rpcMbBestData->getLStride() ); for( n = 0; n < 16; n += uiDelta ) { for( m = 0; m < 16; m += uiDelta ) { uiDist += abs( pucSrc[m] - pucDst[m] ); } pucSrc += iDeltaXStride; pucDst += iDeltaXStride; } delete rpcMbTempData; return uiDist; } 最后的uiDist应该再除以16*16才对吧 A:MAD,SAD都是衡量失真的准则,其作用就是用来做比较 如果每个块的sad都要除以16x16以后再互相比大小,不觉得这很多余么 SAD足矣,这里的确是计算的SAD而不是MAD Q:在264的码率控制中要用到MAD值,请问对于帧间和帧内编码的宏块其MAD值分别是怎么计算的?我在JM代码中看不太明白,有知道的朋友能给说说?谢谢了! A: I帧和第一个P帧用固定的Qp,不进行MAD值的预测,从第二个P帧开始,利用前一帧相同位置basic unit的MAD值线性预测当前basic unit的MAD值 Q: 我的意思是实际MAD值是怎样计算的? 对于帧间编码宏块 MAD=(原宏块像素值-运动补偿后的预测宏块像素值)/256; 对于帧内编码宏块 MAD=(原宏块像素值-帧内预测宏块像素值)/256; 我这样理解对吗? A: 对,在JM86代码的calc_MAD() 函数中 Q:都知道在二次模型中有MAD。但是为什么这里要用MAD。有没有文献或者数据的支持呢。为什么可以引入。无论是MAD还是SSD,有具体推导的过程吗 A:为某帧编码后大小也即Rate可以用MAD与QP的函数表达, 即 RATE=function(MAD,QP)q Q:在计算QP的时候,有RD的二次关系。但是RD二次模型的基础是图像复杂度相似的情况。D可以由QP表达。引入MAD是为了让图像scalable。 我想知道MAD引入有没有严格的理论证明。 A:是针对 R=X1*Q^(-1)+X2*Q^(-2)这个式子对吧. X1,X2表征和图像复杂度有关的变量, 实际操作中通过MAD计算, 我没有记错吧? 嗯....那个X1X2的部分我是有点记错了, 不过幸好不是错得很离谱, 式子应该是R/MAD_predicted=X1*Q^(-1)+X2*Q^(-2) MAD是用来近似描述图像复杂度的一个参数 (scalable这个词在这里怪怪的, 我不是很确定你用这个词在这里的意思), 实际编码不可能存在输入任何源固定一个Q的情况下编出来的比特数都一样嘛. 当然是和源的复杂度有关的. 至于描述复杂度也可以用其他参数, 如上面说的SSD. Q:Q:在JM的码率控制中,函数calc_mad()是用来计算一个宏块的MAD,而且这个函数encode_one_macroblock()中调用。我想使用前面已经计算过的相邻宏块的MAD,那怎么得到它的值呢?可有数组储存已经计算出来的MAD的值?还有,在JVT-G012中,MAD线性模型是用来预测基本单元的MAD的,那它能和一个宏块的MAD相加吗? A:当然有存储mad的数组了,自己跟踪代码,就能找到了。mad的和,本来就是为了计算每个bu的mad以及每帧的mad,当然要把每个mad加起来了。不过单纯的一个bu的mad加上一个不属于该bu的宏块的mad没有什么意义。 Q:请教各位大侠,在码率控制中有一部分要预测当前基本单元的MAD。一开始我以为是整个BasicUnit 总的MAD,但我看了代码后觉得好像是BasicUnit 中宏块的MAD。 请问到底怎么理解基本单元的MAD呢? A:是整个 BasicUnit 的平均 MAD。也就是 BasicUnit 中所有 MB 的 MAD 求和再平均。提案里就是这么提的,就这么做就可以了。 (第二人解释)最终得到的值,表示的是当前恢复图像的basic unit 与原始图像中对应的部分,平均每个像素值的差别. Q:在jvt-o12,jvt-h017提到的码率控制算法中,帧层码率控制和basic unit的码率控制时都要由前一帧的mad来预测 当前的mad,提案中采用的是线性预测,即: pred_mad = C0xprev_mad + C1 pred_mad:预测的当前帧mad; prev_mad:为前一帧的实际mad C0,C1为预测系数; 每次帧编码完成后,得到当前帧的实际mad,更新C0,C1; 我的问题是更新C0,C1具体是如何进行的. A:经过研究,还是不知道具体采用的了理论是什么,不过看明白了代码的做法.代码做法是对于每个线性预测关系 pred_mad = C0xprev_mad + C1; 两端乘以prev_mad ,得到 pred_madxpred_mad = C0xprev_madxpred_mad + C1xpred_mad; 以上两式连立,写成矩阵形式: B = AC; 其中 B为1x2,B0 = pred_mad,B1 = pred_madxpred_mad; A为2x2,A00 = 1,A01 = A10 = prev_mad,A11 = prev_madxprev_mad; C就是由待更新的C0,C1组成的1x2矩阵. 假设有n个A - B 的对应关系,则可以得到n个Bi = AiC(i = 1,2,,,n),将这些等式相加,得到总的SUM(B) = SUM(A)C; 再由克来母公式计算出C. Q&A说过无数次了,跟代码最接近的是 JVT-H017r3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值