0

私は問題を抱えています。私の問題は、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 フレームしか読み取れないため、メモリ不足エラーは発生しません。しかし、すべてのフレームを読み取ろうとすると、まだ問題が残ります。主に次の2つの問題があります。

  1. mmreader() と read() を使用してメモリ不足の問題を解決するにはどうすればよいですか?
  2. 上記の imshow() が画像フレームを表示しないのはなぜですか?
4

4 に答える 4

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));
于 2012-07-29T19:17:24.757 に答える
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);
于 2013-01-26T09:03:14.407 に答える
0

基本的なビデオ プレーヤーを実装する場合の例を次に示します。

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

これは、一度に 1 フレームを読み取り、IMSHOW を使用して表示します。GUI イベント キューがフラッシュされるように、DRAWNOW を呼び出す (または小さな値で一時停止する) 必要があることに注意してください。

興味のある方は、以前の回答で、ビデオ ファイルのフレームを参照するための GUI の例を示しました。

于 2012-07-29T19:17:33.847 に答える
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
于 2013-01-26T11:06:42.053 に答える