Main Content

ビデオ ファイルの読み取り

特定の時間またはフレーム インデックスから開始してビデオのフレームを読み取り、指定の区間内のフレームを読み取り、あるいはビデオのすべてのフレームを読み取ります。

指定の時間またはフレーム インデックスで開始するフレームの読み取り

ファイルの先頭から 0.5 秒後にビデオ ファイルの一部の読み取りを開始します。次に、ビデオ ファイルのフレーム インデックス 100 から末尾までビデオを読み取ります。

サンプル ファイル 'xylophone.mp4' に関連付けられる VideoReader オブジェクトを作成します。

vidObj = VideoReader('xylophone.mp4');

ファイルの先頭から 0.5 秒後に読み取りを開始するよう指定するには、CurrentTime プロパティを設定します。

vidObj.CurrentTime = 0.5;

readFrame メソッドを使用して、ファイルの末尾に到達するまでビデオ フレームを読み取ります。

while hasFrame(vidObj)
    vidFrame = readFrame(vidObj);
    imshow(vidFrame)
    pause(1/vidObj.FrameRate);
end

Figure contains an axes object. The axes object contains an object of type image.

あるいは、read メソッドを使用して、指定のフレーム インデックスからビデオの末尾まで、ビデオからフレームを読み取ることもできます。読み取るインデックスを [100 Inf] と指定します。read メソッドによって、ビデオ ファイルの 100 から末尾までのフレームがすべて返されます。

vidframes = read(vidObj,[100 Inf]);

指定した区間内のフレームの読み取り

時間またはフレームの区間を指定して、ビデオ ファイルの一部を読み取ります。

0.6 秒から 0.9 秒の間のビデオ フレームを読み取ります。最初に、ビデオ リーダー オブジェクトと、フレームを保持する構造体配列を作成します。

vidObj = VideoReader('xylophone.mp4');
s = struct('cdata',zeros(vidObj.Height,vidObj.Width,3,'uint8'),'colormap',[]);

次に、CurrentTime プロパティを設定することで、ファイルの先頭から 0.6 秒後に読み取りを開始するよう指定します。

vidObj.CurrentTime = 0.6;

CurrentTime が 0.9 秒に達するまで 1 フレームずつ読み取ります。各ビデオ フレームからのデータを構造体配列に追加します。構造体配列内のフレーム数を表示します。s は 1 行 10 列の構造体であり、10 フレームが読み取られたことを示しています。構造体 s 内のフレームをムービーとして表示する詳細については、関数 movie のリファレンス ページを参照してください。

k = 1;
while vidObj.CurrentTime <= 0.9
    s(k).cdata = readFrame(vidObj);
    k = k+1;
end
whos s
  Name      Size              Bytes  Class     Attributes

  s         1x10            2305344  struct              

あるいは、フレーム インデックスを使用して、指定した区間内のすべてのフレームを読み取ることができます。たとえば、read の 2 番目の引数を [18 27] に指定します。read メソッドは FrameSize 行 10 列の配列を返し、10 フレームが読み取られたことを示します。

frames = read(vidObj,[18 27]);
whos frames
  Name          Size                    Bytes  Class    Attributes

  frames      240x320x3x10            2304000  uint8              

すべてのフレームの読み取り

ビデオのすべてのフレームを 1 フレームごとに、またはすべてのフレームを一度に読み取ります。

ビデオ リーダー オブジェクトを作成して、ビデオ内のフレームの合計数を表示します。

vidObj = VideoReader('xylophone.mp4');
vidObj.NumFrames
ans = 141

readFrame メソッドを使用して、すべてのフレームを 1 フレームごとに読み取り、そのフレームを表示します。

while hasFrame(vidObj)
   frame = readFrame(vidObj);
   imshow(frame)
   pause(1/vidObj.FrameRate);
end

Figure contains an axes object. The axes object contains an object of type image.

あるいは、すべてのビデオ フレームを一度に読み取ることができます。read メソッドはビデオ フレームの FrameSize 行 141 列の配列を返します。

allFrames = read(vidObj);
whos allFrames
  Name             Size                      Bytes  Class    Attributes

  allFrames      240x320x3x141            32486400  uint8              

ビデオ読み取りのトラブルシューティングとヒント

  • hasFrame メソッドは、CurrentTime プロパティの値が Duration プロパティと等しい場合に、論理 1 (真) を返すことがあります。これは基盤となる API 使用の制限によるものです。

  • CurrentTime プロパティを Duration 値に近い値に設定して、ビデオ ファイルの最後のフレームまで検索することは推奨されません。一部のファイルでは、この操作により、CurrentTime 値が Duration 値未満であっても、ファイルの終端に到達したことを示すエラーが返されます。これは通常、ファイルの期間がビデオ ストリームの期間より長く、ファイルの終端付近に読み取れるビデオがない場合に発生します。

  • ビデオ ファイルからのデータの読み取りを制限するために、Duration プロパティを使用することは推奨されません。hasFrame メソッドを使用して、読み取れるフレームがあるかどうかをチェックしてください。読み取れるフレームがなくなったことをファイルがレポートするまでデータを読み取るのが最善です。

  • Windows® システムでのビデオ読み取りパフォーマンス: Windows で MP4 および MOV ファイルに対するビデオ リーダーのパフォーマンスを高めるために、MATLAB® ではシステムのグラフィックス ハードウェアをデコードに使用します。ただし、システムの特定のグラフィックス ハードウェアによっては、デコードにグラフィックス カードを使用した場合、パフォーマンスが低下することがあります。システムでのビデオ リーダーのパフォーマンス低下に気づいた場合は、matlab.video.read.UseHardwareAcceleration('off') と入力してハードウェア アクセラレーションをオフにしてください。ハードウェア アクセラレーションは、matlab.video.read.UseHardwareAcceleration('on') と入力することで再度有効にできます。

参考

| | | |

関連するトピック