【Python×OpenCV】
フレームレート(FPS)を変更・確認する方法 (実測方法も)
本記事では、産業用UVCカメラのフレームレートに関して、コマンドでの設定・確認の方法、実測が設定と同じにならない原因などについて紹介します。
フレームレート(FPS)とは
フレームレート(FPS)は、動画において「1秒間に取得/表示する画像の枚数」を表す値です。
この、「1秒間に取得/表示する画像の枚数」というのは、動画が映画のフィルムやパラパラ漫画のように静止画の集まりでできているというイメージを持っていただくとわかりやすいかと思います。
映画は映写器のスピード、パラパラ漫画は手の動かし具合で1秒間に表示する枚数が変わり、1秒間に表示する枚数が少ないと映像はカクカク動き、1秒間に表示する枚数が多いと映像は滑らかに動きます。
サンプル:2fpsと10fpsでこんなに違う
→カクカク
10fps
→滑らか
身近なフレームレート(FPS)
身近なフレームレートの例を以下に示します。
表示 | テレビの地上放送・DVD | 30fps |
---|---|---|
4K放送 | 60fps | |
ゲーム (ESports) | 120fps | |
撮影 | 防犯カメラ | 5fps |
産業用カメラ | 15〜60fps | |
ハイスピードカメラ | 100〜20,000fps |
このように、フレームレートは、用途によって大きく異なります。
フレームレートが高い方がいいように思われがちですが、高くすることによるデメリットもあるため、FPSを決める際には、注意が必要です。
以下にフレームレートを高くしたときのメリット・デメリットを紹介します。
カメラのフレームレート(FPS) を高くした場合のメリット・デメリット
メリット
- 再生した際の動画の動きが滑らかになる
- 高速で移動する物体を捉えられる
デメリット
- PCに高い処理能力が必要になる
- ファイルの容量が大きくなる
- 露光時間がフレームレートの逆数で律速される(画像が暗くなる可能性がある)
関連記事
- ビデオカメラのフレームレートに関して(準備中)
PCの性能やファイル容量を変えずにフレームレートを高くするには
解像度も、フレームレートと同じように高くすればするほど、高い処理能力やファイル容量が増えるという特性があります。
よって、フレームレートをあげた際に、解像度を下げることを検討すると、処理能力やファイル容量にかかる過剰な負荷を低減することが可能です。
産業用UVCカメラの対応フレームレートの確認方法
変更可能なフレームレートは使用するカメラの画像処理チップで決まっています。
設定可能なフレームレートは、ピクセルフォーマット(データ形式)や解像度によっても変化するので、まずは、その点も含めて詳細を確認してください。
フレームレートはv4l2のコマンドで確認することができるので、以下のコマンドを実行してください。
注意:あらかじめv4l2をインストールする必要があります。
関連記事
- Linix用ビデオデバイスドライバ v4l2とは(準備中)
v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: 'YUYV' (YUYV 4:2:2) Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.040s (25.000 fps) Interval: Discrete 0.050s (20.000 fps) Interval: Discrete 0.067s (15.000 fps) Interval: Discrete 0.100s (10.000 fps) Interval: Discrete 0.200s (5.000 fps)
実行結果から、今回確認したカメラでは、YUYVフォーマットの640×480画素の画像を30、25、20、15、10、5fpsのフレームレートで取得できることがわかります。
カメラのフレームレートの設定・確認方法
設定できるフレームレートが確認できたら、その中から使用するフレームレートを決めてカメラの設定を変更します。
設定の変更には (1)プログラム内で設定を変更する方法 と (2)ドライバーで設定を変更する方法 があります。
設定方法1プログラム内でフレームレートを設定する方法 (Python-OpenCV編)
以降の内容は、PythonとOpenCVがインストールされていることが前提となっています。
・カメラのフレームレート変更 (Python-OpenCV編)
フレームレートを設定するためのOpenCVの設定パラメータは、CAP_PROP_FPSです。
Pythonのプログラム内でこの設定パラメータを指定すると、そのコマンドが読み込まれた時点で、カメラのフレームレートが変更されます。
USBカメラは電源OFF時にリセットされることがあるため、毎回同じFPS設定でプログラムを実行したいという場合には、この方法がおすすめです。
以下のようにset()コマンドを実行してください。
cap.set(cv2.CAP_PROP_FPS, 30)
この時、”cap”は、VideoCaptureコマンドで指定したカメラのオブジェクト名で、”30”は、変更したいフレームレートの値です。
・カメラのフレームレート確認 (Python-OpenCV編)
設定の確認は、get()コマンドで取得した値をprint文で出力することで可能です。
コマンドprint(cap.get(cv2.CAP_PROP_FPS))
30.0
仕様にないフレームレートを設定したらどうなるのか
カメラによって設定できるフレームレートが決まっているため、設定にない値を指定した場合にはその値に近く可能な設定値になります。例えば25FPSと30FPSの設定が可能な場合、27.49を設定すると25FPSになり27.50を設定すると30FPSになります。
エラーなどが出るわけではないので、自身が期待した値になっているか、必ず値を確認してください。
設定方法2ドライバーで設定を変更する方法 (v4l2編) 【Linux系OSのみ】
v4l2はVideo for Linux 2の略称で、Linux系OSでカメラなどの映像デバイスを扱うためのデバイスドライバです。
こちらのデバイスドライバのコマンドを用いてもカメラの設定を変更することが可能です。
・カメラのフレームレート変更(v4l2編)
v4l2でのフレームレートの設定は、Linuxのターミナル上でのコマンド実行により可能で、コマンド実行後からカメラの設定が変更されます。 フレームレートの設定は、-pオプションで可能なので、以下のようにコマンドを実行するとフレームレートが変わります。
コマンドv4l2-ctl -p 10
”10”は、変更したいフレームレートの値です。
実行結果Frame rate set to 10.000 fps
設定変更タイミングの注意点
ゲインや露光量など-cコマンドで変更できる項目は、画像取得プログラム実行中でも実行できますが、-pオプションは、「Device or resource busy」というエラーでコマンドがFailedになります。
v4l2でのフレームレート変更は、プログラムの実行前に行ってください。
・カメラのフレームレート確認(v4l2編)
v4l2でのフレームレートの確認は、フレームレート変更と同様にターミナル上で行います。確認は-P(大文字)オプションなので、以下のコマンドをターミナル上で実行してください。
コマンドv4l2-ctl -P
Streaming Parameters Video Capture: Capabilities : timeperframe Frames per second: 10.000 (10/1) Read buffers : 0
Frame per secondの右の値がカメラのフレームレートです。
実際のフレームレート(FPS) の測定方法
カメラのFPSを30fpsに設定したからといって、実際にプログラムで1秒間に30枚の画像が取得できるかというと、そうではありません。
カメラの設定は、あくまでカメラから送付されてくる画像の枚数(データ量)であり、実際にプログラム上で行われる画像取得の間隔がカメラからの送付間隔よりも長くなる可能性があるからです。
ここからは、実際のフレームレートの測定方法、そして、実際のフレームレートが設定値よりも遅くなる場合の要因(カメラの露光時間、プログラムの処理時間など)についてお話させていただきます。
実際のフレームレート(FPS)の測定方法
実際のフレームレートの測定方法にはいろいろありますが、今回は、プログラムで、一定枚数の画像を取得する時間を計測し、1秒間あたりに取り込んだ画像の枚数をフレームレートとして計算する方法を紹介します。
サンプルプログラム
import cv2 import sys #カメラの設定 デバイスIDは0 cap = cv2.VideoCapture(0) #フレームレートの設定 cap.set(cv2.CAP_PROP_FPS, 30) #フレームレートの確認 fps_setting = cap.get(cv2.CAP_PROP_FPS) print("FPS(Setting):",'{:11.02f}'.format(fps_setting)) #OpenCVのタイマーの準備 timer = cv2.TickMeter() timer.start() #各変数の初期値設定 count = 0 max_count =30 fps = 0 #繰り返しのためのwhile文 while True: #カメラからの画像取得 ret, img = cap.read() #Max_Countの回数になったら、その枚数を取得するのにかかった時間を求めてFPSを算出 if count == max_count: timer.stop() fps = max_count / timer.getTimeSec() print("FPS(Actual):" , '{:11.02f}'.format(fps)) #リセットと再スタート timer.reset() count = 0 timer.start() #カメラの画像の出力(なくてもOK) cv2.imshow('video image', img) #取得枚数をカウント count += 1 #繰り返し分から抜けるためのif文 key = cv2.waitKey(1) if key == 27: break #メモリを解放して終了するためのコマンド cap.release() cv2.destroyAllWindows()
FPS(Setting): 30.00 FPS(Actual) : 23.32 FPS(Actual) : 29.96 FPS(Actual) : 29.96 FPS(Actual) : 29.89 FPS(Actual) : 29.97 FPS(Actual) : 29.88 FPS(Actual) : 29.98 ・・・
結果のように、計算したフレームレートが連続して実行ターミナルに出力されます。
例では、設定したフレームレートに近いフレームレートが実現できていますが、そうはならない場合もあります。
最後に、フレームレートの実測値が設定値にならない場合の原因をいくつか紹介します。
フレームレートの実測値が設定値と違う。原因は?
・接続されているカメラの設定値が認識と違う
当然ですが、カメラの設定が正しく実行されていないと期待したフレームレートにはなりません。まずは、設定の部分でもふれましましたが、設定を確認するコマンドを用いての確認が有効です。
また、意図しない箇所で、カメラの設定が上書きされてしまっているという可能性もあるので、注意してください。
例えば、v4l2でプログラム実行前に設定をしているが、その後、プログラム内でOpen CVのコマンドにより意図しない再設定がされているなどが考えられます。
・カメラの露光時間がフレームレートを律速している
例えば、露光時間の設定が50ms(1枚の撮影に50msかかる)だった場合、1秒間で20枚しか撮像できないので、フレームレートの設定を30fpsにしていても、実測では20fpsとなります。
現在の産業カメラはAuto Exposure機能を搭載している機種が多いので、明るいところでは、十分なフレームレートが出ている場合でも、暗いところでは十分なフレームレートがでないということが起こる可能性があります。
・プログラムの画像取得の繰り返しタイミングがフレームレートより遅くなっている
(プログラムの処理の増大、パソコンの性能不足)
プログラムのフレームレートである画像取得の間隔は、read()コマンドの実行間隔です。
例えば、read()コマンドで画像を取得した後に、画像を加工して、DBと照合して、結果を判定をするという処理が存在し、その処理に0.1msかかる場合には、次のread()コマンド実行が0.1ms後になります。
これでは、カメラが30fpsのフレームレートで画像を取得していてもプログラムが実際に使用する画像は1秒間に10枚となり、実測では10fpsしか出ません。
「プログラム内で繰り返し実行する画像取得コマンドのループ内に含まれる処理の量(プログラムの量)」と「その処理を行うパソコンの性能」によって、処理時間が律速するため、"複雑な処理を行う場合"、"複数のカメラを使う場合"、"処理速度の遅いPCを使用する場合"などは注意が必要になります。
最後に
本記事では、フレームレートに関して、設定の方法、確認の方法、実測が設定と同じにならない原因 などについて解説しました。
フレームレートは映像の滑らかさの観点からは高くできる方が望ましいですが、他の項目とのトレードオフが出てきた場合には、慎重に決めて設定をしてください。
このカテゴリのコンテンツ
関連コンテンツ
用語集
マシンビジョンコース
カメラ基礎知識
特殊カメラ基礎知識
画像処理プログラミング
USBカメラ設定パラメータ
カメラの選び方
マシンビジョンアプリケーション
- ばら積みピッキングとロボットビジョン