bjontegaard.m 6.8 KB

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