OpenCVでカメラのフレームレート(fps: frames per second)を設定するには、文法上は
import cv2
# カメラを開く
cap = cv2.VideoCapture(0)
# フレームレートを設定
ret = cap.set(cv2.CAP_PROP_FPS, 15)
のようにすると、フレームレートを15fpsに設定した事になります。
しかしながら、実際にカメラで画像を撮影してみると、フレームレートが変わったように感じません。
OSがLinuxではフレームレートを設定出来ているような情報を見かけるのですが、Windowsでは、あまり見かけません。
という事で、Windows環境でフレームレートが設定できるのか?評価してみました。
評価環境
カメラ:Anker PowerConf C200
OS:Windows11
Python 3.11
opencv-python 4.7.0.72
評価方法
以下のサンプルプログラムを実行し、300枚撮影するのに掛かった時間を計測し、fpsを計算しました。
import cv2
import time
# カメラを開く
cap = cv2.VideoCapture(0)
# フレームレートを設定
ret = cap.set(cv2.CAP_PROP_FPS, 15)
# 設定されているフレームレートを取得
print(cap.get(cv2.CAP_PROP_FPS))
# 撮影開始時間
start = time.perf_counter()
# 画像を300枚撮影する
for i in range(300):
# 画像をキャプチャする
ret, frame = cap.read()
# 画像300枚を撮影するのにかかった時間からfpsの計算
print(f"{300/(time.perf_counter() - start)}fps")
# カメラを閉じる
cap.release()
# すべてのウィンドウを閉じる
cv2.destroyAllWindows()
このプログラムを実行すると、
ret = cap.set(cv2.CAP_PROP_FPS, 15)
の部分でfpsを15に設定すると、戻り値(ret)は Trueとなり、一見、設定できているように見えるのですが、
print(cap.get(cv2.CAP_PROP_FPS))
として、フレームレートを取得すると30fpsとなり、実際にはフレームレートは設定できていませんでした。
そこで、
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
として、DirectShowを使ってカメラを開き、set()関数でfpsを15fpsに設定し、get()関数で設定したフレームレートを取得すると、ちゃんと変更されている事が確認できます。
しかしながら、実際にread()関数でカメラのフレーム画像を取得する時間を計算してみると、29.3fpsとなり、結局のところ、フレームレートは設定できていませんでした。
CAP_DSHOW(DirectShow)以外にCAP_MSMF(Microsoft Media Foundation)など、いろいろ試してみましたが、設定できず。
もちろん、fpsが設定できるかどうかは、カメラ依存の部分もあろうかと思いますが、3つのカメラで評価してみたところ、フレームレートを変更することはできませんでした。。
結局のところ、fpsを落とすには、フレームを間引くしか無いのかも?
参考
https://docs.opencv.org/4.7.0/d8/dfe/classcv_1_1VideoCapture.html
https://docs.opencv.org/4.7.0/d4/d15/group__videoio__flags__base.html#gga023786be1ee68a9105bf2e48c700294da77ab1fe260fd182f8ec7655fab27a31d