Here’s a simple function to deinterlace a movie that was interlaced to go from 24fps to 30fps:
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
