2012-07-29 73 views
0

我遇到了問題。我的問題是,我想分割一個AVI視頻的所有圖像幀。首先我使用了aviread()函數,它給了我內存不足的錯誤。然後從聯機幫助我使用mmreader()和read()函數來分割圖像幀,但問題是read()函數讀取的圖像無法用imshow()函數顯示。我有以下代碼片段,將視頻分割成matlab中的圖像

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()上面不顯示圖像幀?
+0

您正在使用什麼版本的MATLAB? – Amro 2012-07-29 19:11:29

+0

它是Matlab 7 – 2013-08-14 05:27:33

回答

1

爲了擺脫內存不足錯誤的考慮讀一個循環內的單個幀,如圖所示mmreader文檔(doc mmreader)中:

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

原因imshow不工作是read(...)返回的值是高x寬x顏色x NumFrames其中Height是視頻的高度,Width是視頻的寬度,Colors是顏色的數量(通常爲3),NumFrames是您讀取的幀的數量。

要顯示第一幀使用:

imshow(ims(:,:,:,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示例。

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

請解釋答案。有時只用一些代碼解釋答案是很好的,因爲鏈接可能在將來變得無效 – VendettaDroid 2013-01-26 09:27:14

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