简体   繁体   English

在Matlab中将视频拆分为图像

[英]splitting video into images in matlab

I am on a problem. 我有问题。 My problem is that I want to split all image frames from an avi video. 我的问题是我想从avi视频分割所有图像帧。 First of all I used aviread() function it gives me the out of memory error. 首先,我使用了aviread()函数,它给了我内存不足的错误。 Then from online help I were using mmreader() and read() function to split image frames, but the problem is read images from read() function could not be showed with imshow() function. 然后从在线帮助中,我使用mmreader()和read()函数来分割图像帧,但是问题是从read()函数读取的图像无法用imshow()函数显示。 I have the following code snippet, 我有以下代码片段,

function test()
   A='G:\ims\avi\nh.avi';
   B=mmreader(A);
   ims=read(B,[2000 2200]);
   figure(1),imshow(ims(1));
end

I hoped this code would show the first image frame but it does not. 我希望这段代码会显示第一个图像帧,但不会。 In this code I am free of out of memory error because I only read 200 frames. 在此代码中,我没有内存不足错误,因为我只读取200帧。 But the problem still remains when I try to read all the frames. 但是当我尝试读取所有帧时,问题仍然存在。 So mainly I have the following two problems, 所以主要我有以下两个问题,

  1. how can I get rid of out of memory problem using mmreader() and read() ? 如何使用mmreader()和read()摆脱内存不足的问题?
  2. why not imshow() above does not show the image frame? 为什么上面的imshow()不显示图像帧?

To get rid of the out of memory error consider reading in a single frame inside of a loop as shown in the mmreader documentation ( doc mmreader ): 要消除内存不足错误,请考虑在循环中读取单个帧,如mmreader文档( doc mmreader )中所示:

for k = 2000 : 2200
    ims = read(B, k);
end

The reason imshow is not working is that the value returned by read(...) is Height x Width x Colors x NumFrames Where Height is the height of the video, Width is the width of the video, Colors is the number of colors (usually 3) and NumFrames is the number of frames you read. imshow的原因是read(...)返回的值是Height x Width x Colors x NumFrames其中Height是视频的高度,Width是视频的宽度,Colors是颜色的数量(通常为3),而NumFrames是您读取的帧数。

To display the first frame use: 要显示第一帧,请使用:

imshow(ims(:,:,:,1));

If you want to implement a basic video player, here is an example: 如果您想实现基本的视频播放器,请参考以下示例:

mov = VideoReader('xylophone.mpg');   %# use mmreader on older versions
for i=1:mov.NumberOfFrames
    img = read(mov,i);
    imshow(img)
    drawnow
end

This reads one frame at a time, and displays it using IMSHOW. 每次读取一帧,并使用IMSHOW显示。 Note that it is required to call DRAWNOW (or pause with some small value) so that the GUI event queue gets flushed. 请注意,需要调用DRAWNOW(或以较小的值暂停),以便刷新GUI事件队列。

If you are interested, I showed in a previous answer an example of a GUI for browsing the frames of a video file. 如果您有兴趣,我在上一个答案中展示了一个用于浏览视频文件帧的GUI示例。

This splits a video into frames with no need for extra codecs: 这样可以将视频分割为多个帧,不需要额外的编解码器:

clc;
close all;

% Open an sample avi file

filename = '.\003.AVI';
mov = MMREADER(filename);

% Output folder

outputFolder = fullfile(cd, 'frames');
if ~exist(outputFolder, 'dir')
    mkdir(outputFolder);
end

%getting no of frames

numberOfFrames = mov.NumberOfFrames;
numberOfFramesWritten = 0;
for frame = 1 : numberOfFrames    
    thisFrame = read(mov, frame);
    outputBaseFileName = sprintf('%3.3d.png', frame);
    outputFullFileName = fullfile(outputFolder, outputBaseFileName);
    imwrite(thisFrame, outputFullFileName, 'png');
    progressIndication = sprintf('Wrote frame %4d of %d.', frame,numberOfFrames);
    disp(progressIndication);
    numberOfFramesWritten = numberOfFramesWritten + 1;
end
progressIndication = sprintf('Wrote %d frames to folder "%s"',numberOfFramesWritten, outputFolder);
disp(progressIndication);

Here is what I use to split up videos and recombine them into animated GIF's. 这是我用来分割视频并将其重新组合为GIF动画的方法。 I am sure you can adapt it into whatever you like. 我相信您可以将其调整为您喜欢的任何格式。 It is entirely based on code snippets from MATLAB help. 它完全基于MATLAB帮助中的代码片段。

function [ startframe, endframe ] = catgif( inputvideoname, outputfilename,...
startframe, endframe, preview)

InputVideo = VideoReader(inputvideoname);
filename = outputfilename;

if (endframe > InputVideo.NumberOfFrames)
    endframe = InputVideo.NumberOfFrames;    
end

figure(1)
for ii = 1:endframe
    if (ii >= startframe)
        img = read(InputVideo,ii);

        %Resize or rotate as appropriate. 
        %img = imresize(imrotate(img, -90),0.5, 'bicubic');
        img = imresize(img,0.5, 'bicubic');

        imshow(img,'Border','tight');
        drawnow
        frame = getframe(1);
        im = frame2im(frame);
        [imind,cm] = rgb2ind(im,256);
        if ~strcmp(preview, 'yes')
            if ii == startframe;
                imwrite(imind,cm,filename,'gif', 'DelayTime', 0, 'Loopcount',inf);
            else
                imwrite(imind,cm,filename,'gif','DelayTime', 0, 'WriteMode','append');
            end
        end
    end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM