質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.64%

動画のFPS計測の実装方法

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,246

gjmwtaptm

score 12

 前提・実現したいこと

Python, OpenCVを用いてキャプチャした動画に対して、リアルタイムで物体認識して、認識結果を画像に表示しながら動画として再生した時のFPSを計測したいのですがどのように実装すればいいでしょうか?

認識結果を表示しながら再生した動画を保存し、その保存した動画をまたキャプチャーしてframe_rate = int(cap.get(5))すれば取れそうな気もしますが、できれば1ファイル1実行で計測したいです。
もし、他に方法がない場合は、認識結果を重畳した動画を保存する書き方を知りたいです。

 該当のソースコード

import cv2
import time

cap = cv2.VideoCapture("sample.mp4")

frame_count = int(cap.get(7))
frame_rate = int(cap.get(5))

# 1フレーム毎に物体認識をする
for i in range(frame_count):
    is_read, frame = cap.read()
    image_np = frame  
    # 処理に時間がかかる処理(物体認識)
    hogehoge()
    cv2.imshow("player", image_np)
    if cv2.waitKey(1) == 27:
        break
cap.release()
cv2.destroyAllWindows()

 試したこと

frame_rate = int(cap.get(5)) でキャプチャした動画そのもののFPSは取得出来ます。

 補足情報(FW/ツールのバージョンなど)

Python 3.5.5
Opencv 3.4.1

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

補足回答として、リアルタイムでキャプチャ~画像処理するケースでのfps算出例を示します。
以下では直近Nフレーム分の時刻をキューで保持しておくことで、処理時間(fps)の揺れを平滑化しています。

import time
import cv2
from collections import deque


# 直近N_SAMPLE分の時刻をキューで保持
N_SAMPLE = 5
q = deque([time.time() for i in range(N_SAMPLE)])

wait = 0.1 # 処理負荷[sec]

cap = cv2.VideoCapture(0)
#cap = cv2.VideoCapture("sample.mp4")
while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 何らかの処理
    #frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    time.sleep(wait)

    # 直近N_SAMPLEフレームからfps算出
    now = time.time()
    fps = N_SAMPLE / (now - q.popleft())
    q.append(now)

    cv2.putText(frame,'{:6.3f}fps'.format(fps),(10,20),cv2.FONT_HERSHEY_PLAIN, 1,(255,255,0))
    cv2.imshow('test',frame)

    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break

    # テスト : 負荷のコントロール
    if key == ord('u'):
        wait += 0.05
    elif key == ord('d'):
        wait -= 0.05
    if wait < 0:
        wait = 0

cap.release()
cv2.destroyAllWindows()

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

FPS は1秒あたりのフレーム数 (frame per second) なので、以下のようにすればよいです。

import time
import cv2

filepath = 'vtest.avi'
cap = cv2.VideoCapture(filepath)
num_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))  # フレーム数

start = time.time()
while True:
    # 1フレームずつ取得する。
    ret, frame = cap.read()
    if not ret:
        break  # 映像取得に失敗

    frame_no = int(cap.get(cv2.CAP_PROP_POS_FRAMES))  # 現在のフレーム番号
    fps  = frame_no / (time.time() - start)  # fps = フレーム数 / 経過時間 (s)
    print('fps: {:.2f}, frame no: {}/{}'.format(fps, frame_no, num_frames), end='\r')

    cv2.imshow('Frame', frame)
    cv2.waitKey(1)

cap.release()
cv2.destroyAllWindows()

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る