【问题标题】:splitting video into images in matlab在matlab中将视频分割成图像
【发布时间】:2013-01-26 19:12:04
【问题描述】:

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

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() 不显示图片帧?

【问题讨论】:

  • 您使用的是哪个版本的 MATLAB?

标签: matlab video image-processing video-processing


【解决方案1】:

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

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

imshow不起作用的原因是read(...)返回的值是Height x Width x Colors x NumFrames 其中Height是视频的高度,Width是视频的宽度,Colors是个数颜色(通常为 3),NumFrames 是您阅读的帧数。

显示第一帧使用:

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

【讨论】:

    【解决方案2】:

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

    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 示例。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 请解释答案。有时最好用一些代码来解释答案,因为这些链接将来可能会失效
      【解决方案4】:

      这是我用来分割视频并将它们重新组合成动画 GIF 的方法。我相信你可以把它改编成你喜欢的任何东西。它完全基于 MATLAB 帮助中的代码 sn-ps。

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-16
        • 1970-01-01
        • 2011-05-20
        • 2014-04-11
        • 2012-11-13
        • 2023-03-06
        • 2017-04-20
        相关资源
        最近更新 更多