ビデオ ファイルの読み取り
特定の時間またはフレーム インデックスから開始してビデオのフレームを読み取り、指定の区間内のフレームを読み取り、あるいはビデオのすべてのフレームを読み取ります。
指定の時間またはフレーム インデックスで開始するフレームの読み取り
ファイルの先頭から 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
あるいは、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
あるいは、すべてのビデオ フレームを一度に読み取ることができます。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')
と入力することで再度有効にできます。
参考
VideoReader
| mmfileinfo
| movie
| read
| readFrame