creating a video - zoom in effect of still image

5 views (last 30 days)
Hi!
I am trying to create a simple script in matlab that creates a video of - zoom in effect.
The original image is called : "start.jpeg" : it will be the first frame in the video.
The user need to draw a rectangular roi over the image, with the same AspectRatio of the original image dimentions.
The area in that roi will be the last frame in the video.
My idea was to create vectors: x ,y ,width ,height which represent the bounding box properties of each frame.
Using a for loop, every iteration we create a new frame by cropping the original image with the suitable bounding box.
after joining all the frames to one video , I see that the result is vert clumsy , and the zoom in effect is not "stable".
is there any way to create the zoom in effect stable?
here is the script I designed:
clc;
clear;
close all;
%% settings
time = 15; %15 sec
rate = 30; %30 frames per sec
nFrames = time * rate;
startFrame = imread('start.jpeg');
[row,col,~] = size(startFrame);
startPose = [0 0 col row];
figure; imshow(startFrame);
rect = drawrectangle("FixedAspectRatio",true,"AspectRatio",row/col);
endPose = rect.Position;
%%
x = floor(linspace(startPose(1),endPose(1),nFrames));
y = floor(linspace(startPose(2),endPose(2),nFrames));
w = floor(linspace(startPose(3),endPose(3),nFrames));
h = floor(linspace(startPose(4),endPose(4),nFrames));
v = VideoWriter('ZoomIn.avi');
open(v);
for i = 1:nFrames
crop = [x(i) ,y(i), w(i), h(i)];
f= imcrop(startFrame,crop);
[row,col,~] = size(startFrame);
f = imresize(f,[row col]);
writeVideo(v,f);
end
close(v);
The original script and image are attached.

Accepted Answer

Image Analyst
Image Analyst on 26 Jun 2022
It's somewhat smoother if you use round instead of floor. But I think some of the jitter is due to using integer coordinates for the cropping. If you want it perfectly smooth you'll have to crop out with subpixel resolution and that means using interp2. Can you do it? I think you can.
  6 Comments
Image Analyst
Image Analyst on 27 Jun 2022
@David Levi David, please vote for @DGM answer below since he gave you the code for the floating point interpolation (I did not have time to, at that point in time). This will award him 2 "Reputation Points" for his efforts to help you. (Both Accepted answers and votes both give the person 2 points.)

Sign in to comment.

More Answers (1)

DGM
DGM on 26 Jun 2022
You can get a bit better results by
  • not rounding the rect parameter
  • scaling prior to cropping
It's not perfect, but it's a bit better.
time = 15; %15 sec
rate = 30; %30 frames per sec
nFrames = time * rate;
startFrame = imread('peppers.png');
[row,col,~] = size(startFrame);
startPose = [0 0 col row];
figure; imshow(startFrame);
thisrect = drawrectangle("FixedAspectRatio",true,"AspectRatio",row/col);
endPose = thisrect.Position;
% just directly interpolate to get all rect vectors
% don't round; imcrop() accepts fractional inputs
pos = interp1(0:1,[startPose; endPose],linspace(0,1,nFrames));
v = VideoWriter('ZoomIn.avi');
open(v);
for i = 1:nFrames
thisrect = pos(i,:);
scale = mean([col row]./thisrect(3:4));
f = imresize(startFrame,scale);
f = imcrop(f,thisrect.*scale);
f = f(1:row,1:col,:); % crop any remaining excess
writeVideo(v,f);
end
close(v);

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!