LoginSignup
11
14

More than 3 years have passed since last update.

動画ファイルからサイズ情報やサムネイルをPythonのOpenCVで取得

Posted at

OpenCVというライブラリがあり、これで動画ファイルを扱えるようです。OpenCVを使って、動画ファイルからサイズ情報やサムネイルを取得してみました。

OpenCVをインストール

この記事の内容を試すには以下のコマンドのみで十分でした。Python環境整備済みのLinuxの前提です。

$ pip install opencv-python

私の環境でpipenvでインストールしたら、バージョンは以下のようになりました。

$ pipenv install opencv-python

$ pipenv run pip list
Package       Version
------------- --------
numpy         1.19.5
opencv-python 4.5.1.48
pip           20.3.3
setuptools    51.0.0
wheel         0.36.2

動画サイズや長さなどの情報を取得

動画ファイルから縦横サイズ、再生時間、コーデックの情報を取得します。

# OpenCVをインポート
import cv2

# サンプル動画ファイル
videoPath = "./sample.mp4"

cap = cv2.VideoCapture(videoPath)

# 横幅
print(f"width: {cap.get(cv2.CAP_PROP_FRAME_WIDTH)}")
# width: 600.0

# 高さ
print(f"height: {cap.get(cv2.CAP_PROP_FRAME_HEIGHT)}")
# height: 360.0

# フレームレート
print(f"fps: {cap.get(cv2.CAP_PROP_FPS)}")
# fps: 30.0

# フレーム数
print(f"frame_count: {cap.get(cv2.CAP_PROP_FRAME_COUNT)}")
# frame_count: 639.0

# 再生時間
print(f"length: {cap.get(cv2.CAP_PROP_FRAME_COUNT) / cap.get(cv2.CAP_PROP_FPS)} s")
# length: 21.3 s

print("fourcc: " + int(cap.get(cv2.CAP_PROP_FOURCC)).to_bytes(4, "little").decode("utf-8"))
# fourcc: avc1
# コーデックの種類を4文字で表すコード

コーデックの種類を表すコードはfourccという4文字のコードです。

最初のフレームから画像ファイルを作成

動画ファイルの最初のフレームをNumpy配列で取得し、それを画像ファイルで書き出します。

import cv2

def buildVideoCaptures(videoPath, outputPath):
    cap = cv2.VideoCapture(videoPath)
    if not cap.isOpened(): return

    # 最初のフレームを読み込む
    _, img = cap.read()
    # imgは読み込んだフレームのNumpy配列でのピクセル情報(BGR)
    # imgのshapeは (高さ, 横幅, 3)

    # 画像ファイルで書き出す
    # 書き出すときの画像フォーマットはファイル名から自動で決定
    cv2.imwrite(outputPath, img)

buildVideoCaptures("./sample.mp4", "./thumbnail.jpg")

# PNG出力もOK
#buildVideoCaptures("./sample.mp4", "./thumbnail.png")

最初のフレームからサムネイルを作成

次は画像をリサイズして、サムネイルとして画像ファイルを作成します。cv2.resizeというメソッドでリサイズできます。

import cv2

def buildVideoCaptures(videoPath, outputPath):
    cap = cv2.VideoCapture(videoPath)
    if not cap.isOpened(): return

    _, img = cap.read()
    # imgは読み込んだフレームのNumpy配列でのピクセル情報(BGR)
    # imgのshapeは (高さ, 横幅, 3)

    # 画像サイズを取得
    width = img.shape[1]
    height = img.shape[0]

    # 縮小後のサイズを決定
    newWidth = 100
    newHeight = int(height * newWidth / width)

    # リサイズ
    img = cv2.resize(img, (newWidth, newHeight))

    # 画像ファイルで書き出す
    cv2.imwrite(outputPath, img)


buildVideoCaptures("./sample.mp4", "./thumbnail.jpg")

動画の途中からもサムネイルを作成

最初のフレームだけではなく、途中のフレームからも画像を取得します。再生時間を10分割して、10個のサムネイルを作成します。

import cv2

def buildVideoCaptures(videoPath, outputPath):
    cap = cv2.VideoCapture(videoPath)
    if not cap.isOpened(): return

    # フレーム数を取得
    frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

    for i in range(10):
        # フレーム位置を設定
        cap.set(cv2.CAP_PROP_POS_FRAMES, i * frame_count / 10)

        _, img = cap.read()
        # imgは読み込んだフレームのNumpy配列でのピクセル情報(BGR)
        # imgのshapeは (高さ, 横幅, 3)

        # 画像サイズを取得
        width = img.shape[1]
        height = img.shape[0]

        # 縮小後のサイズを決定
        newWidth = 100
        newHeight = int(height * newWidth / width)

        # リサイズ
        img = cv2.resize(img, (newWidth, newHeight))

        # 画像ファイルで書き出す
        # ファイル名には連番を付ける
        cv2.imwrite(outputPath % i, img)

buildVideoCaptures("./sample.mp4", "./thumbnail%d.jpg") # 出力ファイル名には連番を付ける
11
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
14