creating a video - zoom in effect of still image
조회 수: 5 (최근 30일)
이전 댓글 표시
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.
댓글 수: 0
채택된 답변
Image Analyst
2022년 6월 26일
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
Image Analyst
2022년 6월 27일
@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.)
추가 답변 (1개)
DGM
2022년 6월 26일
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);
댓글 수: 0
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!