Python+OpenCVで動画を範囲時間だけカットする方法コード例

OpenCVには動画カットするメソッドはありません。

▼ でも次のことを実現したかった

  • 例えば1分30秒の動画あって、
  • 開始地点25秒からとして、
  • 終了地点50秒までカットしたい

結論から書くとOpenCVでもできます。

どうしても他ライブラリを使いたくない人のために、
Python+OpenCVで範囲時間で動画カットする方法を解説

0.OpenCVで動画カットするまでの大まかな流れ

ここでは次のような手順を踏んでいきます。

▼ このような流れになる

  • 動画のカット開始地点をミリ秒で指定
  • 動画のカット終了地点もミリ秒で指定
  • カット動画をmp4として保存する

▼ さらに詳細な流れはこうなる

  1. 動画の始点と終点のフレーム番号を取得
    OpenCVではダイレクトに「̻○○ミリ秒~○○ミリ秒まで」のような操作はできない。フレーム単位なので開始・終了地点のミリ秒をフレーム番号(インデックス)に直しておく
  2. その範囲内のフレームを画像に分割
    例えば100フレーム目から350フレーム目までのように、カットしたい部分のフレームを全て画像として取得する。ただし音声は考えないことにする
  3. フレーム画像を1つのmp4動画に再構成する
    あとは分割したそれぞれの画像を1つのmp4動画として再構成するだけ。やってることはパラパラ漫画を作るのと全く同じ

こういう風な流れ

今回は音声無しで動画カットしてみます。

1.FPS・フレーム数・始点/終点フレーム番号を取得

初めは下準備から

FPS、総フレーム数、始点・終点のフレーム番号…

これらをまとめて取得・算出しておきます。

▼ つまりはこのようなコード

ここまでが動画カットの下準備コード

恐らく「こんな断片的なコードを見せられても…」と思ってるでしょうが、最後にコード全体をまとめて載せるので安心してください。

動画カット用のフレームインデックスを計算してます。

2.カット開始~終了地点までのフレームを画像分割

そしたら開始~終了までのフレームを画像分割します。

▼ 開始~終了までのフレーム分割のコード例

ここは短いですね。

OpenCVではフレーム画像を videoCapture.read() で取得できるのですが、フレームインデックス等が渡せないのが曲者でした。だから遠回りな方法を取ってます。

ちなみにフレーム分割は次でも詳しく触れました。

▼ Python+opencvで動画のnフレーム目を画像保存

この記事ではフレームを画像保存までしてます。

でも今回の動画カットではメモリ上に展開しています。

それ以外では特別に説明する箇所なし

3.フレーム画像配列を1つのmp4動画に再構成する

最後に切り出したフレーム達をmp4に再構成します。

▼ こういったコードで再構成する

何をしてるかはコメント参照

本当にやってることはパラパラ漫画と同じです。先ほど開始~終了地点までのフレーム画像配列を作ったので、それをひたすら動画に追加していってるだけです。

▼ ちなみに cv2.VideoWriter について

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Parameters
filename Name of the output video file.
fourcc 4-character code of codec used to compress the frames. For example, VideoWriter::fourcc('P','I','M','1') is a MPEG-1 codec, VideoWriter::fourcc('M','J','P','G') is a motion-jpeg codec etc. List of codes can be obtained at Video Codecs by FOURCC page. FFMPEG backend with MP4 container natively uses other values as fourcc code: see ObjectType, so you may receive a warning message from OpenCV about fourcc code conversion.
fps Framerate of the created video stream.
frameSize Size of the video frames.
isColor If it is not zero, the encoder will expect and encode color frames, otherwise it will work with grayscale frames (the flag is currently supported on Windows only).

引用元 : https://docs.opencv.org/3.4/dd/d9e/classcv_1_1VideoWriter.html#ac3478f6257454209fa99249cc03a5c59

こんな便利なものがOpenCVでは用意されてます。

4.最後に全体のコードをまとめて載せておく

分かりやすく関数化しました。

▼ 関数化した結果コード

ミリ秒単位で指定できるから直観的

以上、Python+OpenCVで動画カットでした。

もしコードに誤りがあればご指摘ください。

Shareこの記事をシェアしよう!

Commentsこの記事についたコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください