(图像来源:Reverse软件自带示例)
当你看到上面这张动图的时候,有没有觉得像变魔术一样不可思议呢?一地杂乱无章的瓜子通过摄影师的妙手点拨变成了“MAGIC”,“魔术”给人的是视觉冲击,点破个中缘由就没有那么“神奇”了。采用就是基于“时光倒流”思想对已摄制完成的视频影音倒序处理,归根结底是对视频帧的处理。
除了令人惊奇的“时光倒流”,下面请大家欣赏几幅美轮美奂的延时摄影作品:(图像来源:https://www.sohu.com/a/190975095_173711)
(四季变幻)
(蘑菇成长)
(草莓熟了)
延时摄影同样美的令人窒息,这里就不介绍如何拍摄了,毕竟这是摄影师的事,咱们能做的是对现成的视频进行延时处理。
下面就来说说如何用matlab实现对视频的“时光倒流”和“延时放映”处理。正如上面提到的,这些处理归根结底是对视频图像帧的处理,我们知道视频是由一幅幅图像序列连续放映形成的。因此我们只需要将视频中的图像序列倒着播放就能实现“时光倒流”,将长时视频中的近似帧删除掉就能实现“延时放映”。
在新版本matlab中,VideoReader已作为对视频的文件读取处理的推荐函数,今天的程序也将使用该函数来编写。使用read函数来读取视频中图像帧,采用imrotate函数来调整图像,运用image函数来显示图像。
由于存在视频解码的问题,读取和处理效果可能有差异,但并不影响显示效果。本示例使用MP4格式视频文件,为了方便上传,视频文件全部被做成GIF图像文件。
(原始视频)
1、“时光倒流”处理源代码
clc;close all;clear;
% 读取测试视频,谨防程序出错,请事先准备好视频文件
% 文末有本文测试视频的获取方式
v = VideoReader('test.mp4');
% 获取视频总帧数
numF = v.NumberOfFrames;
% 获取坐标轴句柄
currAxes = axes;
% 隐藏坐标轴
currAxes.Visible = 'off';
% 设置图像在坐标轴中的显示状态
set(gca,'position',[0.25 0 0.5 1]);
% 设置figure属性
set(gcf,'toolbar','none','menubar','none','name','感谢关注matlab爱好者','NumberTitle','off');
% 通过循环倒序读取图像帧
for k = numF-50:-1:5
% 因为是图像显示,因此没必要每帧都显示
if mod(k,23) == 0
% 读取视频帧
img = read(v,k);
% 顺时针旋转90度
img = imrotate(img,-90);
% 显示图像
image(img,'Parent',currAxes);
currAxes.Visible = 'off';
end
end
时光倒流处理效果图
2、延时放映处理源代码
clc;close all;clear;
% 读取测试视频,谨防程序出错,请事先准备好视频文件
% 文末有本文测试视频的获取方式
v = VideoReader('test.mp4');
% 获取视频总帧数
numF = v.NumberOfFrames;
% 获取坐标轴句柄
currAxes = axes;
% 隐藏坐标轴
currAxes.Visible = 'off';
% 设置图像在坐标轴中的显示状态
set(gca,'position',[0.25 0 0.5 1]);
% 设置figure属性
set(gcf,'toolbar','none','menubar','none','name','感谢关注matlab爱好者','NumberTitle','off');
% 由于拍摄视频时间过短,因此间隔取帧来演示延时放映
% 对于长时视频,建议通过对比图像帧的相似性来确定是否显示
for k = 1:numF
if mod(k,60) == 0
img = read(v,k);
img = imrotate(img,-90);
image(img, 'Parent',currAxes);
currAxes.Visible = 'off';
end
end
延时放映处理效果图
温馨提示:本文中的测试视频(test.mp4)通过网盘形式进行分享,请在公众中号中回复“测试”、“test”获取。关于如何生成保存GIF图像,请阅读历史相关推荐获取。
本文作者:艾木樨