Deinterlace a movie in Matlab

Here’s a simple function to deinterlace a movie that was interlaced to go from 24fps to 30fps:

Woody deinterlaced

function [As] = deinterlace(As)
    %function [As] = deinterlace(As)
    %Deinterlaces a video input by inverse 3:2 pulldown
    %As a 3D matrix of size (vsize x hsize x nframes)
    %The function assumes that for every 5 frames, 2 of these are
    %interlaced (transfer from a 24fps source to a 30fps output)
    %When it detects two consecutive frames are interlaced:
    %    im1 = As(:,:,jj);
    %    im2 = As(:,:,jj+1);
    %It tries to reassemble them in two ways:
    %    im0 = im1;
    %    im0(2:2:end,:) = im2(2:2:end,:);
    %
    %    im3 = im1;
    %    im3(1:2:end,:) = im2(1:2:end,:);
    %Looks at which looks best via computing the sum of the squares of the 
    %vertical second order derivatives, and replaces each frame with a copy
    %of whichever assembly looked best:
    %
    %if s0 < s3
    %    As(:,:,jj) = im0;
    %    As(:,:,jj+1) = im0;
    %else
    %    As(:,:,jj) = im3;
    %    As(:,:,jj+1) = im3;
    %end
    %
    %Author: Patrick Mineault
    %http://xcorr.net

    
    %Detect which frames are interlaced
    %assumes every 5th + offset and 5th + offset + 1'th frames are
    %interlaced
    interidx = sum(sum(convn(As,[-1,2,-1]','same').^2,1),2);
    interidx = interidx(1:floor(length(interidx)/5)*5);
    n = median(reshape(interidx,5,length(interidx)/5),2);
    [~,idx] = sort(median(n,2));
    thewhich = idx(end-1:end);
    
    if(min(thewhich) == max(thewhich) -1 )
        offset = min(thewhich);
    elseif(max(thewhich) == 5 && min(thewhich)==1)
        offset = max(thewhich);
    else
        error('WTF???');
    end
    
    %And deinterlace
    for jj = offset:5:size(As,3)-1
        im1 = As(:,:,jj);
        im2 = As(:,:,jj+1);
        
        %try both ways
        im0 = im1;
        im0(2:2:end,:) = im2(2:2:end,:);

        im3 = im1;
        im3(1:2:end,:) = im2(1:2:end,:);
        
        s0 = sum(sum(conv2(im0,[-1,2,-1]','same').^2));
        s3 = sum(sum(conv2(im3,[-1,2,-1]','same').^2));

        %replace
        if s0 < s3
            As(:,:,jj) = im0;
            As(:,:,jj+1) = im0;
        else
            As(:,:,jj) = im3;
            As(:,:,jj+1) = im3;
        end
    end
end

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s