20 likes | 87 Views
Simple implementation of block-based Optical Flow estimation. Test sequences: http://www.cs.cmu.edu/~cil/v-images.html. function mf=mfblkmod(I1,I2,n) %main % I1, I2: two successive frames if mod(n,2)==0 % n must be odd error('n must be odd'); end mf=zeros(size(I1)); c = 0;
E N D
Simple implementation of block-based Optical Flow estimation Test sequences: http://www.cs.cmu.edu/~cil/v-images.html function mf=mfblkmod(I1,I2,n) %main % I1, I2: two successive frames if mod(n,2)==0 % n must be odd error('n must be odd'); end mf=zeros(size(I1)); c = 0; for i=(1+(n-1)/2):(size(I1,1)-(n-1)/2), for j=(1+(n-1)/2):(size(I1,2)-(n-1)/2), c = c+1; [v1,v2]=VelBlk(I1,I2,i,j,n); mf(i,j)=v1+sqrt(-1)*v2; end end function [SDx1,SDx2,SDt]=grdblk(I1,I2,i,j,n) % [SDx1,SDx2,SDt] are the gradient estimations in an nxn block centered % at the position (i,j) of the frame I1 . % We consider that the motion vector is the same for all pixels of % the block. BlockA=BLKOF(I1,n,i,j); %create block centered at (i,j) BlockB=BLKOF(I2,n,i,j); SDx1=zeros((n-1)^2,1); SDx2=zeros((n-1)^2,1); SDt=zeros((n-1)^2,1); c=0; for row=1:n-1, for col=1:n-1, c=c+1; [res1,res2,res3]=grdEst(BlockA,BlockB,row,col); SDx1(c)=res1; SDx2(c)=res2; SDt(c)=res3; end end function [v1,v2]=VelBlk(I1,I2,i,j,n) % estimate the velocity inside a block % 'v1' and 'v2' are velocity's components of an nxn block: % [v1 v2]'= V; (i,j) is the center of the block . [SDx1,SDx2,SDt]=grdblk(I1,I2,i,j,n); x1x1=sum(SDx1.*SDx1); x2x2=sum(SDx2.*SDx2); tt=sum(SDt.*SDt); x1x2=sum(SDx1.*SDx2); x1t=sum(SDx1.*SDt); x2t=sum(SDx2.*SDt); A = [x1x1,x1x2 ; x1x2,x2x2]; A=inv(A); B= [-x1t ; -x2t]; V=A*B; v1=V(1); v2=V(2);
function [DscDx1,DscDx2,DscDt]=grdEst(I1,I2,n1,n2) % Gradient estimation using finite differences . % 'I1' and 'I2' are the k-th and (k+1)-th frames ,respectively . % (n1,n2) is the position of a pixel in the frames . DscDx1 = (1/4)*( I1(n1+1,n2) - I1(n1,n2) + I1(n1+1,n2+1) - I1(n1,n2+1) + ...; I2(n1+1,n2) - I2(n1,n2) + I2(n1+1,n2+1) - I2(n1,n2+1) ); DscDx2 = (1/4)*( I1(n1,n2+1) - I1(n1,n2) + I1(n1+1,n2+1) - I1(n1+1,n2) + ...; I2(n1,n2+1) - I2(n1,n2) + I2(n1+1,n2+1) - I2(n1+1,n2) ); DscDt = (1/4)*( I2(n1,n2) - I1(n1,n2) + I2(n1+1,n2) - I1(n1+1,n2) + ...; I2(n1,n2+1) - I1(n1,n2+1) + I2(n1+1,n2+1) - I1(n1+1,n2+1) ); function block=BLKOF(I,n,i,j) % Create a nxn block from frame I. % (i,j) is the central pixel of the block. % It must be : (n-1)/2 < i < size(I,1)-(n-1)/2 % (n-1)/2 < j < size(I,2)-(n-1)/2 % DIMENSIONS CHECK (n must be odd) if (mod(n,2)==0) error('n must be odd'); end i1 = i - (n-1)/2; i2 = i + (n-1)/2; j1 = j - (n-1)/2; j2 = j + (n-1)/2; if ( ((i1>0) & (i2<size(I,1)+1)) & ((j1>0) & (j2<size(I,2)+1)) ) block = I(i1:i2,j1:j2); else return end %Display the results [x,y] = meshgrid(1:size(I1,2)m1:size(I1,1)); figure,imshow(I1), hold on, quiver(x,y,imag(mf),real(mf)) % OR downsample the dense motion field (by a factor S, e.g. S=2) to display it: quiver(x(1:S:size(I1,1),1:S:size(I1,2)),y(1:S:size(I1,1),1:S:size(I1,2)),imag(mf(1:S:size(I1,1),1:S:size(I1,2))),real(mf(1:S:size(I1,1),1:S:size(I1,2))))