在matlab中将视频分割成图像

时间:2012-07-29 18:10:35

标签: matlab video image-processing video-processing

我遇到了问题。我的问题是我想从avi视频中分割出所有图像帧。首先我使用了aviread()函数,它给了我内存不足的错误。然后从在线帮助我使用mmreader()和read()函数来分割图像帧,但问题是从read()函数读取的图像无法用imshow()函数显示。我有以下代码段,

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

我希望这段代码会显示第一个图像帧,但事实并非如此。在这段代码中,我没有内存不足错误,因为我只读了200帧。但是当我尝试读取所有帧时问题仍然存在。所以主要是我有以下两个问题,

  1. 如何使用mmreader()和read()来消除内存不足问题?
  2. 为什么上面的imshow()不显示图像框架?

4 个答案:

答案 0 :(得分:1)

要消除内存不足错误,请考虑在循环内部的单个帧中读取,如mmreader文档(doc mmreader)中所示:

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

imshow无效的原因是read(...)返回的值是高度x宽度x颜色x NumFrames其中高度是视频的高度,宽度是视频的宽度,颜色是颜色数(通常为3),NumFrames是您读取的帧数。

要显示第一帧使用:

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

答案 1 :(得分:0)

如果你想实现一个基本的视频播放器,这是一个例子:

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

一次读取一帧,并使用IMSHOW显示它。请注意,需要调用DRAWNOW(或暂停一些小值),以便刷新GUI事件队列。

如果您有兴趣,我在previous answer中展示了一个用于浏览视频文件帧的GUI示例。

答案 2 :(得分:0)

这将视频分成帧,无需额外的编解码器:

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);

答案 3 :(得分:0)

以下是我用来分割视频并将它们组合成动画GIF的方法。我相信你可以适应任何你喜欢的东西。它完全基于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