Python版OpenCVでフレームレートを算出
2017年9月、Raspberry PiでPython版OpenCVを用いてフレームレート(FPS)を算出するPythonスクリプトを作成しました。
フレームレートの計測は、USBカメラ画像を画面表示するプログラムで実施しました。使用したUSBカメラは、ELECOM社のUCAM-DLF30EWHです。
【カメラ仕様】
画素数 | 30万画素 |
受像素子 | 1/6インチCMOSセンサ |
最大解像度 | 640×480 ピクセル |
フレームレート | 最大30fps |
色数 | 約1677万色(24bit) |
PythonとOpenCVのバージョンを確認します。
- Python : 2.7.13
- OpenCV : 3.3.0
$ python Python 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170124] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> print cv2.__version__ 3.3.0 >>> quit()
フレームレート算出スクリプト
OpenCVの計測モジュールは、OpenCV-Python チュートリアルのコードの性能評価と改善方法を参照しました。
フレームレートを算出するPythonスクリプトを下記に示します。
$ cat fps.py # -*- coding: utf-8 -*- import cv2 class FrameRate: def __init__(self): self._count = 0 self._fps = 0 self._freq = 1000 / cv2.getTickFrequency() self._tmStart = cv2.getTickCount() self._tmNow = cv2.getTickCount() def get(self): self._count += 1 self._tmNow = cv2.getTickCount() tmDiff = (self._tmNow - self._tmStart) * self._freq if tmDiff >= 1000 : self._tmStart = self._tmNow self._fps = self._count self._count = 0 return self._fps
- cv2.getTickFrequency()は、単位時間あたりのクロック周波数を取得します。
- cv2.getTickCount()は、ある時点からの内部的な経過時間のクロック数を取得します。
従って、ある関数を実行する前後でこの関数によりクロック数を取得すると、そのクロック数の差分によりその関数の処理時間(クロック数)を知ることができます。
クラス FrameRate の初期化で、メンバー変数を初期化します。
- _count : フレーム数 ← 0
- _fps : フレームレート ← 0
- _freq : クロックの周期(ms)
- _tmStart : 計測開始時のクロック数
- _tmNow : 計測開始時のクロック数
クラス FrameRate のget()で、フレームレートを計算して取得します。
- _count : フレーム数 をインクリメントします
- _tmNow : 現在のクロック数を取得します
- tmDiff : _tmStart から _tmNow の経過時間(ms)を算出します
- tmDiff が1秒を超えると、_count がフレームレート(1秒間のフレーム数)なります。フレーム数をリセットして、_tmStart←_tmNowとします。
フレームレート算出スクリプトの使い方
フレームレート算出スクリプトの使い方のサンプルとして、USBカメラ画像を画面表示するプログラムに組み込んだ例を示します。
カメラ画像の画面表示スクリプトのフレームワークは、ほぼ以前に作成したものと同様です。
$ cat caminput.py #!/usr/bin/python # -*- coding: utf-8 -*- import cv2 import fps gFrameRate = fps.FrameRate() # 初期化 fontcolor = (255,255,255) fontface = cv2.FONT_HERSHEY_SIMPLEX fontthick = 2 cap = cv2.VideoCapture(0) while( cv2.waitKey(1) < 0 ): ret, ImgFrame = cap.read() fps = gFrameRate.get() # フレームレート取得 fps_str = '%4d' % fps cv2.putText(ImgFrame, fps_str, (10,25), fontface, 1.0, fontcolor, fontthick , cv2.LINE_AA) cv2.imshow('Capture',ImgFrame) # When everything done, release the capture cap.release() cv2.destroyAllWindows()
「import fps」で、フレームレート算出クラス fps.py をインポートします。
「gFrameRate = fps.FrameRate()」で、クラスを初期化してgFrameRateインスタンスを生成します。
キー入力の無い間、繰り返します。
「ImgFrame = cap.read()」で、キャプチャーデバイスから次のフレームを取得・デコードして、ImgFrameに格納します。
「fps = gFrameRate.get()」で、フレームレートを算出して取得し、fpsを4桁の文字列に変換して「cv2.putText()」で画像に埋め込みます。
「cv2.imshow(‘Capture’,ImgFrame)」で、ウインドウCaptureにImgFrameの画像を表示します。
フレームレート計測
USBカメラ画像を画面表示するプログラムでは、20~30fpsで動作しました。使用したELECOM社のUCAM-DLF30EWHカメラの仕様は、最大30fpsのフレームレートなので妥当な結果です。