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