123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- % rd1, rd2: tables of rate/distortion pairs, in units of dB and bits per pixel
- % type: 1 = piecewise-linear, 2 = cubic-polyfit
- % min_bpp, max_bpp: constraints on the bitrates to compare.
- % Set to 0 for automatic selection.
- function [rate,psnr] = bjontegaard(rd1,rd2,type,min_bpp,max_bpp)
- function [p] = pwl_fit(x,y)
- n=size(x,1)-1;
- p=[diff(y),y(1:n,:)];
- end
- function [p] = cubic_fit(x,y)
- s=min(x);
- e=max(x);
- p=polyfit((x.-s)./(e-s),y,3);
- end
- function [p] = interp_helper(x,y,k)
- n=size(x,1)-1;
- p=zeros(n,4);
- for i=1:n
- dx=x(i+1)-x(i);
- dy=y(i+1)-y(i);
- a=k(i)*dx-dy;
- b=-k(i+1)*dx+dy;
- p(i,4)=y(i);
- p(i,3)=a+dy;
- p(i,2)=b-2*a;
- p(i,1)=a-b;
- end
- end
- % Three-point first-order approximation
- function [k] = average_fit(x,y)
- n=size(x,1);
- dx=diff(x);
- dy=diff(y);
- d=dy./(2*dx);
- % one-sided average
- k=[d;0]+[0;d];
- % set end derivatives to zero
- %k(1)=0;
- %k(n)=0;
- end
- % Three-point second-order approximation
- function [k] = threepoint_fit(x,y)
- n=size(x,1);
- dx=diff(x);
- dy=diff(y);
- d=dy./dx;
- k=zeros(n,1);
- for i=2:n-1
- k(i)=(dx(i-1)*d(i)+dx(i)*d(i-1))/(dx(i)+dx(i-1));
- end
- % set end derivatives to zero
- k(1)=0;
- k(n)=0;
- end
- % Cubic Spline Interpolation
- function [k] = spline_fit(x,y)
- n=size(x,1);
- dx=diff(x);
- dy=diff(y);
- m=zeros(n,n);
- d=zeros(n,1);
- for i=1:n-1
- m(i,i+1)=1/dx(i);
- m(i+1,i)=1/dx(i);
- m(i+1,i+1)=2*m(i,i+1);
- m(i,i)=m(i,i)+2*m(i,i+1);
- d(i+1)=3*dy(i)/(dx(i)^2);
- d(i)=d(i)+3*dy(i)/(dx(i)^2);
- end
- k=m\d;
- end
- % Shape-preserving Cubic Hermite Interpolation
- function [k] = spchi_fit(x,y)
- n=size(x,1);
- dx=diff(x);
- dy=diff(y);
- d=dy./dx;
- % Assume all interior points have slope 0
- k=zeros(n,1);
- % Find index of non-local extrema interior points
- i=find(sign(d(1:n-2)).*sign(d(2:n-1))>0);
- % Compute the shape-preserving, non-centered three point average
- % using Brodlie modification of Butland formula
- ds=dx(i)+dx(i+1);
- w1=(dx(i)+ds)./(3*ds);
- w2=(ds+dx(i+1))./(3*ds);
- dmax=max(abs(d(i)),abs(d(i+1)));
- dmin=min(abs(d(i)),abs(d(i+1)));
- k(i+1)=dmin./conj(w1.*(d(i)./dmax)+w2.*(d(i+1)./dmax));
- % Set the end points
- k(1)=((2*dx(1)+dx(2))*d(1)-dx(1)*d(2))/(dx(1)+dx(2));
- if sign(k(1))~=sign(d(1))
- k(1)=0;
- elseif (sign(d(1))~=sign(d(2)))&&(abs(k(1))>abs(3*d(1)))
- k(1)=3*d(1);
- end
- k(n)=((2*dx(n-1)+dx(n-2))*d(n-1)-dx(n-1)*d(n-2))/(dx(n-1)+dx(n-2));
- if sign(k(n))~=sign(d(n-1))
- k(n)=0;
- elseif (sign(d(n-1))~=sign(d(n-2)))&&(abs(k(n))>abs(3*d(n-1)))
- k(n)=3*d(n-1);
- end
- end
- function k = monotonize(x,y,k)
- n=size(x,1);
- dx=diff(x);
- dy=diff(y);
- d=dy./dx;
- a=k(1:n-1)./d;
- b=k(2:n)./d;
- t=[a<0;0]+[0;b<0];
- for i=1:n-1
- if (dy(i)==0)
- k(i)=0;
- k(i+1)=0;
- a(i+1)=0;
- b(i)=0;
- t=[a<0;0]+[0;b<0];
- elseif (t(i)>0)
- k(i)=0;
- elseif (a(i)*a(i)+b(i)*b(i)>9)
- tau=3/sqrt(a(i)*a(i)+b(i)*b(i));
- k(i)=tau*a(i)*d(i);
- k(i+1)=tau*b(i)*d(i);
- end
- end
- end
- function h = plot_poly(x,p)
- n=100;
- u=zeros(1,size(p,1)*n+1);
- v=zeros(1,size(p,1)*n+1);
- t=0:1/n:1;
- s=1;
- for i=1:size(p,1),
- u(s:(s+n))=t*(x(i+1,1)-x(i,1))+x(i,1);
- v(s:s+n)=polyval(p(i,:),t);
- s=s+n;
- end
- h = plot(u,v);
- hold all;
- end
- function val = int_poly(x,p,min_x,max_x)
- n=size(x,1);
- val=0;
- for i=1:n-1
- if abs(x(i+1,1)-x(i,1))>eps
- if x(i,1)>x(i+1,1)
- x0=x(i+1,1);
- x1=x(i,1);
- t0=1;
- t1=0;
- else
- x0=x(i,1);
- x1=x(i+1,1);
- t0=0;
- t1=1;
- end
- if x1>=min_x&&x0<=max_x
- dx=x1-x0;
- dt=t1-t0;
- if min_x>x0
- t0=t0+dt*(min_x-x0)/dx;
- end
- if max_x<x1
- t1=t1+dt*(max_x-x1)/dx;
- end
- pi=polyint(p(i,:));
- val=val+(polyval(pi,t1)-polyval(pi,t0))*(x1-x0);
- end
- end
- end
- end
- function val = avg_diff(x1,y1,x2,y2,type,min_x,max_x)
- min_x=max(max(min(x1),min(x2)),min_x);
- max_x=min(min(max(x1),max(x2)),max_x);
- switch type
- case 1
- p1=pwl_fit(x1,y1);
- p2=pwl_fit(x2,y2);
- case 2
- p1=cubic_fit(x1,y1);
- p2=cubic_fit(x2,y2);
- x1=[min(x1);max(x1)];
- x2=[min(x2);max(x2)];
- case 3
- p1=interp_helper(x1,y1,monotonize(x1,y1,average_fit(x1,y1)));
- p2=interp_helper(x2,y2,monotonize(x2,y2,average_fit(x2,y2)));
- case 4
- p1=interp_helper(x1,y1,monotonize(x1,y1,threepoint_fit(x1,y1)));
- p2=interp_helper(x2,y2,monotonize(x2,y2,threepoint_fit(x2,y2)));
- case 5
- p1=interp_helper(x1,y1,spline_fit(x1,y1));
- p2=interp_helper(x2,y2,spline_fit(x2,y2));
- case 6
- p1=interp_helper(x1,y1,spchi_fit(x1,y1));
- p2=interp_helper(x2,y2,spchi_fit(x2,y2));
- end
- int1=int_poly(x1,p1,min_x,max_x);
- int2=int_poly(x2,p2,min_x,max_x);
- val = (int2-int1)/(max_x-min_x);
- end
- rate1=log(rd1(:,1));
- psnr1=rd1(:,2);
- rate2=log(rd2(:,1));
- psnr2=rd2(:,2);
- min_bpp=log(min_bpp);
- max_bpp=log(max_bpp);
- psnr=avg_diff(rate1,psnr1,rate2,psnr2,type,min_bpp,max_bpp);
- rate=(exp(avg_diff(psnr1,rate1,psnr2,rate2,type,0,Inf))-1)*100;
- %p_pwl=pwl_fit(x1,y1);
- %p_cubic=cubic_fit(x1,y1);
- %p_average=interp_helper(x1,y1,monotonize(x1,y1,average_fit(x1,y1)));
- %p_threepoint=interp_helper(x1,y1,monotonize(x1,y1,threepoint_fit(x1,y1)));
- %p_spline=interp_helper(x1,y1,spline_fit(x1,y1));
- %p_spchi=interp_helper(x1,y1,spchi_fit(x1,y1));
- %plot_poly(x1,p_pwl);
- %plot_poly([min(x1);max(x1)],p_cubic);
- %plot_poly(x1,p_average);
- %plot_poly(x1,p_threepoint);
- %plot_poly(x1,p_spline);
- %plot_poly(x1,p_spchi);
- %int_poly(x1,p_pwl,min(x1),max(x1))
- %int_poly([min(x1);max(x1)],p_cubic,min(x1),max(x1))
- %int_poly(x1,p_average,min(x1),max(x1))
- %int_poly(x1,p_threepoint,min(x1),max(x1))
- %int_poly(x1,p_spline,min(x1),max(x1))
- %int_poly(x1,p_spchi,min(x1),max(x1))
- %plot(x1,y1,'o');
- end
|