bjontegaard.m 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. % rd1, rd2: tables of rate/distortion pairs, in units of dB and bits per pixel
  2. % type: 1 = piecewise-linear, 2 = cubic-polyfit
  3. % min_bpp, max_bpp: constraints on the bitrates to compare.
  4. % Set to 0 for automatic selection.
  5. function [rate,psnr] = bjontegaard(rd1,rd2,type,min_bpp,max_bpp)
  6. function [p] = pwl_fit(x,y)
  7. n=size(x,1)-1;
  8. p=[diff(y),y(1:n,:)];
  9. end
  10. function [p] = cubic_fit(x,y)
  11. s=min(x);
  12. e=max(x);
  13. p=polyfit((x.-s)./(e-s),y,3);
  14. end
  15. function [p] = interp_helper(x,y,k)
  16. n=size(x,1)-1;
  17. p=zeros(n,4);
  18. for i=1:n
  19. dx=x(i+1)-x(i);
  20. dy=y(i+1)-y(i);
  21. a=k(i)*dx-dy;
  22. b=-k(i+1)*dx+dy;
  23. p(i,4)=y(i);
  24. p(i,3)=a+dy;
  25. p(i,2)=b-2*a;
  26. p(i,1)=a-b;
  27. end
  28. end
  29. % Three-point first-order approximation
  30. function [k] = average_fit(x,y)
  31. n=size(x,1);
  32. dx=diff(x);
  33. dy=diff(y);
  34. d=dy./(2*dx);
  35. % one-sided average
  36. k=[d;0]+[0;d];
  37. % set end derivatives to zero
  38. %k(1)=0;
  39. %k(n)=0;
  40. end
  41. % Three-point second-order approximation
  42. function [k] = threepoint_fit(x,y)
  43. n=size(x,1);
  44. dx=diff(x);
  45. dy=diff(y);
  46. d=dy./dx;
  47. k=zeros(n,1);
  48. for i=2:n-1
  49. k(i)=(dx(i-1)*d(i)+dx(i)*d(i-1))/(dx(i)+dx(i-1));
  50. end
  51. % set end derivatives to zero
  52. k(1)=0;
  53. k(n)=0;
  54. end
  55. % Cubic Spline Interpolation
  56. function [k] = spline_fit(x,y)
  57. n=size(x,1);
  58. dx=diff(x);
  59. dy=diff(y);
  60. m=zeros(n,n);
  61. d=zeros(n,1);
  62. for i=1:n-1
  63. m(i,i+1)=1/dx(i);
  64. m(i+1,i)=1/dx(i);
  65. m(i+1,i+1)=2*m(i,i+1);
  66. m(i,i)=m(i,i)+2*m(i,i+1);
  67. d(i+1)=3*dy(i)/(dx(i)^2);
  68. d(i)=d(i)+3*dy(i)/(dx(i)^2);
  69. end
  70. k=m\d;
  71. end
  72. % Shape-preserving Cubic Hermite Interpolation
  73. function [k] = spchi_fit(x,y)
  74. n=size(x,1);
  75. dx=diff(x);
  76. dy=diff(y);
  77. d=dy./dx;
  78. % Assume all interior points have slope 0
  79. k=zeros(n,1);
  80. % Find index of non-local extrema interior points
  81. i=find(sign(d(1:n-2)).*sign(d(2:n-1))>0);
  82. % Compute the shape-preserving, non-centered three point average
  83. % using Brodlie modification of Butland formula
  84. ds=dx(i)+dx(i+1);
  85. w1=(dx(i)+ds)./(3*ds);
  86. w2=(ds+dx(i+1))./(3*ds);
  87. dmax=max(abs(d(i)),abs(d(i+1)));
  88. dmin=min(abs(d(i)),abs(d(i+1)));
  89. k(i+1)=dmin./conj(w1.*(d(i)./dmax)+w2.*(d(i+1)./dmax));
  90. % Set the end points
  91. k(1)=((2*dx(1)+dx(2))*d(1)-dx(1)*d(2))/(dx(1)+dx(2));
  92. if sign(k(1))~=sign(d(1))
  93. k(1)=0;
  94. elseif (sign(d(1))~=sign(d(2)))&&(abs(k(1))>abs(3*d(1)))
  95. k(1)=3*d(1);
  96. end
  97. k(n)=((2*dx(n-1)+dx(n-2))*d(n-1)-dx(n-1)*d(n-2))/(dx(n-1)+dx(n-2));
  98. if sign(k(n))~=sign(d(n-1))
  99. k(n)=0;
  100. elseif (sign(d(n-1))~=sign(d(n-2)))&&(abs(k(n))>abs(3*d(n-1)))
  101. k(n)=3*d(n-1);
  102. end
  103. end
  104. function k = monotonize(x,y,k)
  105. n=size(x,1);
  106. dx=diff(x);
  107. dy=diff(y);
  108. d=dy./dx;
  109. a=k(1:n-1)./d;
  110. b=k(2:n)./d;
  111. t=[a<0;0]+[0;b<0];
  112. for i=1:n-1
  113. if (dy(i)==0)
  114. k(i)=0;
  115. k(i+1)=0;
  116. a(i+1)=0;
  117. b(i)=0;
  118. t=[a<0;0]+[0;b<0];
  119. elseif (t(i)>0)
  120. k(i)=0;
  121. elseif (a(i)*a(i)+b(i)*b(i)>9)
  122. tau=3/sqrt(a(i)*a(i)+b(i)*b(i));
  123. k(i)=tau*a(i)*d(i);
  124. k(i+1)=tau*b(i)*d(i);
  125. end
  126. end
  127. end
  128. function h = plot_poly(x,p)
  129. n=100;
  130. u=zeros(1,size(p,1)*n+1);
  131. v=zeros(1,size(p,1)*n+1);
  132. t=0:1/n:1;
  133. s=1;
  134. for i=1:size(p,1),
  135. u(s:(s+n))=t*(x(i+1,1)-x(i,1))+x(i,1);
  136. v(s:s+n)=polyval(p(i,:),t);
  137. s=s+n;
  138. end
  139. h = plot(u,v);
  140. hold all;
  141. end
  142. function val = int_poly(x,p,min_x,max_x)
  143. n=size(x,1);
  144. val=0;
  145. for i=1:n-1
  146. if abs(x(i+1,1)-x(i,1))>eps
  147. if x(i,1)>x(i+1,1)
  148. x0=x(i+1,1);
  149. x1=x(i,1);
  150. t0=1;
  151. t1=0;
  152. else
  153. x0=x(i,1);
  154. x1=x(i+1,1);
  155. t0=0;
  156. t1=1;
  157. end
  158. if x1>=min_x&&x0<=max_x
  159. dx=x1-x0;
  160. dt=t1-t0;
  161. if min_x>x0
  162. t0=t0+dt*(min_x-x0)/dx;
  163. end
  164. if max_x<x1
  165. t1=t1+dt*(max_x-x1)/dx;
  166. end
  167. pi=polyint(p(i,:));
  168. val=val+(polyval(pi,t1)-polyval(pi,t0))*(x1-x0);
  169. end
  170. end
  171. end
  172. end
  173. function val = avg_diff(x1,y1,x2,y2,type,min_x,max_x)
  174. min_x=max(max(min(x1),min(x2)),min_x);
  175. max_x=min(min(max(x1),max(x2)),max_x);
  176. switch type
  177. case 1
  178. p1=pwl_fit(x1,y1);
  179. p2=pwl_fit(x2,y2);
  180. case 2
  181. p1=cubic_fit(x1,y1);
  182. p2=cubic_fit(x2,y2);
  183. x1=[min(x1);max(x1)];
  184. x2=[min(x2);max(x2)];
  185. case 3
  186. p1=interp_helper(x1,y1,monotonize(x1,y1,average_fit(x1,y1)));
  187. p2=interp_helper(x2,y2,monotonize(x2,y2,average_fit(x2,y2)));
  188. case 4
  189. p1=interp_helper(x1,y1,monotonize(x1,y1,threepoint_fit(x1,y1)));
  190. p2=interp_helper(x2,y2,monotonize(x2,y2,threepoint_fit(x2,y2)));
  191. case 5
  192. p1=interp_helper(x1,y1,spline_fit(x1,y1));
  193. p2=interp_helper(x2,y2,spline_fit(x2,y2));
  194. case 6
  195. p1=interp_helper(x1,y1,spchi_fit(x1,y1));
  196. p2=interp_helper(x2,y2,spchi_fit(x2,y2));
  197. end
  198. int1=int_poly(x1,p1,min_x,max_x);
  199. int2=int_poly(x2,p2,min_x,max_x);
  200. val = (int2-int1)/(max_x-min_x);
  201. end
  202. rate1=log(rd1(:,1));
  203. psnr1=rd1(:,2);
  204. rate2=log(rd2(:,1));
  205. psnr2=rd2(:,2);
  206. min_bpp=log(min_bpp);
  207. max_bpp=log(max_bpp);
  208. psnr=avg_diff(rate1,psnr1,rate2,psnr2,type,min_bpp,max_bpp);
  209. rate=(exp(avg_diff(psnr1,rate1,psnr2,rate2,type,0,Inf))-1)*100;
  210. %p_pwl=pwl_fit(x1,y1);
  211. %p_cubic=cubic_fit(x1,y1);
  212. %p_average=interp_helper(x1,y1,monotonize(x1,y1,average_fit(x1,y1)));
  213. %p_threepoint=interp_helper(x1,y1,monotonize(x1,y1,threepoint_fit(x1,y1)));
  214. %p_spline=interp_helper(x1,y1,spline_fit(x1,y1));
  215. %p_spchi=interp_helper(x1,y1,spchi_fit(x1,y1));
  216. %plot_poly(x1,p_pwl);
  217. %plot_poly([min(x1);max(x1)],p_cubic);
  218. %plot_poly(x1,p_average);
  219. %plot_poly(x1,p_threepoint);
  220. %plot_poly(x1,p_spline);
  221. %plot_poly(x1,p_spchi);
  222. %int_poly(x1,p_pwl,min(x1),max(x1))
  223. %int_poly([min(x1);max(x1)],p_cubic,min(x1),max(x1))
  224. %int_poly(x1,p_average,min(x1),max(x1))
  225. %int_poly(x1,p_threepoint,min(x1),max(x1))
  226. %int_poly(x1,p_spline,min(x1),max(x1))
  227. %int_poly(x1,p_spchi,min(x1),max(x1))
  228. %plot(x1,y1,'o');
  229. end