Matlab:为什么我不能使用 VideoWriter 创建 mp4 文件?
Matlab: Why can't I create an mp4 file using VideoWriter?
我想删除视频的背景。之后我想把它放到另一个视频中,然后将它另存为一个新的 mp4 文件。我正在使用 Windows 10 并且遇到以下问题,我无法在 运行 我的代码后创建新的 mp4 文件。
想法:
我有一辆后面有绿屏的车。我想把这辆车剪下来放在街拍前。
结果应该是一辆汽车在街上行驶(视频)。
来自 myScript 的代码:
clear
close all
v = VideoReader(fullfile('videos', 'carWithGreenscreen.mp4'));
s = VideoReader(fullfile('videos','street.mp4'));
video=zeros(v.Height,v.Width,3,floor(v.Duration/(1/v.FrameRate))-2,'uint8');
t=1;
car = 0.6 ;
values=[0;1;0];
while hasFrame(v)
Img = im2double(readFrame(v));
mask = sqrt((values(1)-Img(:, :, 1)).^2+(values(2)-Img(:, :, 2)).^2+(values(3)-Img(:, :, 3)).^2)<car;
video(:,:,:,t) = imoverlay(im2uint8(Img),mask,[0 0 0]);
imshow(video(:,:,:,t));
t=t+1;
end
videoOut = VideoWriter('result.mp4','MPEG-4'); %here I want to create a video%
videoOut.FrameRate=v.FrameRate;
open(videoOut);
moveX=0;
for t=1:1:size(video,4)
im = video(:,:,:,t);
mask = im(:,:,1)+im(:,:,2)+im(:,:,3)==0;
frame=imoverlay(readFrame(s),~mask,[0 0 0]);
frame=frame+im;
writeVideo(videoOut,frame);
imshow(frame);
end
close(videoOut);
在我 运行 之后出现以下代码错误:
Error using myScript (line 27)
No more frames available to read from file.
line 27: frame=imoverlay(readFrame(s),~mask,[0 0 0]);
但最后它没有创建 mp4 文件...我用 avi 尝试过但我只创建了一个 0KB 的空 .avi 文件...
我设法重现了这个问题,它看起来像是一个 codec 问题。
我下载了 FFmpeg 命令行工具,并生成了示例(合成)视频:
对于 carWithGreenscreen.mp4
,我 selected libxvid
编解码器:
ffmpeg -r 2.5 -f lavfi -i testsrc=rate=1:size=320x256 -t 10 -c:v libxvid videos/carWithGreenscreen.mp4
对于 street.mp4
,我 selected libx264
编解码器:
ffmpeg -r 2.5 -f lavfi -i mandelbrot=rate=1:size=320x256 -t 10 -c:v libx264 videos/street.mp4
在 Windows 10 中的 MATLAB R2019a 中执行脚本时,我收到相同的错误消息:
Error using myScript (line 27)
No more frames available to read from file.
当我 select libxvid
for street.mp4
时,脚本正在运行。
显然,MATLAB 对 h264 编解码器的支持是有限的。
根据文档,支持 h264 编解码器,但由于某种原因它无法正常工作,我找不到解决方案。
这是一个解决方法:
- 使用 FFmpeg 将
street.mp4
转换为未压缩的 AVI。
首选未压缩的 AVI 格式,因为没有转码(没有数据丢失)。
(下载静态链接的最后一个稳定版本的 FFmpeg)。
您可以在 MATLAB 中执行 FFmpeg 以执行转换(将 ffmpeg 可执行文件与您的脚本放在同一文件夹后):
% Convert street.mp4 to street.avi (create uncompressed AVI video file)
[status, cmdout] = system(['ffmpeg -y -i ', fullfile('videos','street.mp4'), ' -c:v rawvideo -pix_fmt bgr24 ', fullfile('videos','street.avi')]);
if (status ~= 0)
display(cmdout); % Displat cmdout in case of an error.
end
%Open street.avi instead of street.mp4
s = VideoReader(fullfile('videos','street.avi'));
这里是完整的修改代码:
clear
close all
v = VideoReader(fullfile('videos', 'carWithGreenscreen.mp4'));
%s = VideoReader(fullfile('videos','street.mp4'));
% Convert street.mp4 to street.avi (create uncompressed AVI video file)
[status, cmdout] = system(['ffmpeg -y -i ', fullfile('videos','street.mp4'), ' -c:v rawvideo -pix_fmt bgr24 ', fullfile('videos','street.avi')]);
if (status ~= 0)
display(cmdout); % Displat cmdout in case of an error.
end
%Open street.avi instead of street.mp4
s = VideoReader(fullfile('videos','street.avi'));
video=zeros(v.Height,v.Width,3,floor(v.Duration/(1/v.FrameRate))-2,'uint8');
t=1;
car = 0.6 ;
values=[0;1;0];
while hasFrame(v)
Img = im2double(readFrame(v));
mask = sqrt((values(1)-Img(:, :, 1)).^2+(values(2)-Img(:, :, 2)).^2+(values(3)-Img(:, :, 3)).^2)<car;
video(:,:,:,t) = imoverlay(im2uint8(Img),mask,[0 0 0]);
imshow(video(:,:,:,t));
t=t+1;
end
videoOut = VideoWriter('result.mp4','MPEG-4'); %here I want to create a video%
videoOut.FrameRate=v.FrameRate;
open(videoOut);
moveX=0;
for t=1:1:size(video,4)
im = video(:,:,:,t);
mask = im(:,:,1)+im(:,:,2)+im(:,:,3)==0;
frame=imoverlay(readFrame(s),~mask,[0 0 0]);
frame=frame+im;
writeVideo(videoOut,frame);
imshow(frame);
end
close(videoOut);
%Delete VideoReader objects (force closing the files).
v.delete();
s.delete();
最后一帧样本(两个合成模式的叠加):
我想删除视频的背景。之后我想把它放到另一个视频中,然后将它另存为一个新的 mp4 文件。我正在使用 Windows 10 并且遇到以下问题,我无法在 运行 我的代码后创建新的 mp4 文件。
想法: 我有一辆后面有绿屏的车。我想把这辆车剪下来放在街拍前。 结果应该是一辆汽车在街上行驶(视频)。
来自 myScript 的代码:
clear
close all
v = VideoReader(fullfile('videos', 'carWithGreenscreen.mp4'));
s = VideoReader(fullfile('videos','street.mp4'));
video=zeros(v.Height,v.Width,3,floor(v.Duration/(1/v.FrameRate))-2,'uint8');
t=1;
car = 0.6 ;
values=[0;1;0];
while hasFrame(v)
Img = im2double(readFrame(v));
mask = sqrt((values(1)-Img(:, :, 1)).^2+(values(2)-Img(:, :, 2)).^2+(values(3)-Img(:, :, 3)).^2)<car;
video(:,:,:,t) = imoverlay(im2uint8(Img),mask,[0 0 0]);
imshow(video(:,:,:,t));
t=t+1;
end
videoOut = VideoWriter('result.mp4','MPEG-4'); %here I want to create a video%
videoOut.FrameRate=v.FrameRate;
open(videoOut);
moveX=0;
for t=1:1:size(video,4)
im = video(:,:,:,t);
mask = im(:,:,1)+im(:,:,2)+im(:,:,3)==0;
frame=imoverlay(readFrame(s),~mask,[0 0 0]);
frame=frame+im;
writeVideo(videoOut,frame);
imshow(frame);
end
close(videoOut);
在我 运行 之后出现以下代码错误:
Error using myScript (line 27)
No more frames available to read from file.
line 27: frame=imoverlay(readFrame(s),~mask,[0 0 0]);
但最后它没有创建 mp4 文件...我用 avi 尝试过但我只创建了一个 0KB 的空 .avi 文件...
我设法重现了这个问题,它看起来像是一个 codec 问题。
我下载了 FFmpeg 命令行工具,并生成了示例(合成)视频:
对于 carWithGreenscreen.mp4
,我 selected libxvid
编解码器:
ffmpeg -r 2.5 -f lavfi -i testsrc=rate=1:size=320x256 -t 10 -c:v libxvid videos/carWithGreenscreen.mp4
对于 street.mp4
,我 selected libx264
编解码器:
ffmpeg -r 2.5 -f lavfi -i mandelbrot=rate=1:size=320x256 -t 10 -c:v libx264 videos/street.mp4
在 Windows 10 中的 MATLAB R2019a 中执行脚本时,我收到相同的错误消息:
Error using myScript (line 27)
No more frames available to read from file.
当我 select libxvid
for street.mp4
时,脚本正在运行。
显然,MATLAB 对 h264 编解码器的支持是有限的。
根据文档,支持 h264 编解码器,但由于某种原因它无法正常工作,我找不到解决方案。
这是一个解决方法:
- 使用 FFmpeg 将
street.mp4
转换为未压缩的 AVI。
首选未压缩的 AVI 格式,因为没有转码(没有数据丢失)。
(下载静态链接的最后一个稳定版本的 FFmpeg)。
您可以在 MATLAB 中执行 FFmpeg 以执行转换(将 ffmpeg 可执行文件与您的脚本放在同一文件夹后):
% Convert street.mp4 to street.avi (create uncompressed AVI video file)
[status, cmdout] = system(['ffmpeg -y -i ', fullfile('videos','street.mp4'), ' -c:v rawvideo -pix_fmt bgr24 ', fullfile('videos','street.avi')]);
if (status ~= 0)
display(cmdout); % Displat cmdout in case of an error.
end
%Open street.avi instead of street.mp4
s = VideoReader(fullfile('videos','street.avi'));
这里是完整的修改代码:
clear
close all
v = VideoReader(fullfile('videos', 'carWithGreenscreen.mp4'));
%s = VideoReader(fullfile('videos','street.mp4'));
% Convert street.mp4 to street.avi (create uncompressed AVI video file)
[status, cmdout] = system(['ffmpeg -y -i ', fullfile('videos','street.mp4'), ' -c:v rawvideo -pix_fmt bgr24 ', fullfile('videos','street.avi')]);
if (status ~= 0)
display(cmdout); % Displat cmdout in case of an error.
end
%Open street.avi instead of street.mp4
s = VideoReader(fullfile('videos','street.avi'));
video=zeros(v.Height,v.Width,3,floor(v.Duration/(1/v.FrameRate))-2,'uint8');
t=1;
car = 0.6 ;
values=[0;1;0];
while hasFrame(v)
Img = im2double(readFrame(v));
mask = sqrt((values(1)-Img(:, :, 1)).^2+(values(2)-Img(:, :, 2)).^2+(values(3)-Img(:, :, 3)).^2)<car;
video(:,:,:,t) = imoverlay(im2uint8(Img),mask,[0 0 0]);
imshow(video(:,:,:,t));
t=t+1;
end
videoOut = VideoWriter('result.mp4','MPEG-4'); %here I want to create a video%
videoOut.FrameRate=v.FrameRate;
open(videoOut);
moveX=0;
for t=1:1:size(video,4)
im = video(:,:,:,t);
mask = im(:,:,1)+im(:,:,2)+im(:,:,3)==0;
frame=imoverlay(readFrame(s),~mask,[0 0 0]);
frame=frame+im;
writeVideo(videoOut,frame);
imshow(frame);
end
close(videoOut);
%Delete VideoReader objects (force closing the files).
v.delete();
s.delete();
最后一帧样本(两个合成模式的叠加):