OpenCVからWebカメラの「解像度」「FPS」及び、「フォーマット(コーディック)」を設定する方法
1 はじめに
CX事業本部の平内(SIN)です。
OpenCVでは、USBで接続されたWebカメラを動画入力として扱うことができます。そして、提供されるメソッドで、「解像度」「FPS」及び「フォーマット(コーディック)」の設定及び、取得が可能です。
非常に簡単に利用できますが、想定外な設定となってしまっている例もあり、個人的には、よくやらかすので、自戒を込めてのメモです。
2 環境
動作確認に使用した機材はは、Model 4B と ロジクール HD Pro Webcam C920です。
OSは、今年2月の最新版(Raspbian Buster with desktop and recommended software) 2020-02-13-raspbian-buster-full.img です
$ cat /proc/cpuinfo | grep Revision Revision : c03112 $ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 10 (buster) Release: 10 Codename: buster $ uname -a Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux
OpenCVは、python3用に4.1.1がインストールされています。
pi@raspberrypi:~ $ python3 Python 3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '4.1.1'
3 Webカメラの対応諸元
最初に、Webカメラが対応している諸元を確認します。残念ながらOpenCVのメソッドでこれを取得する方法が無いので、v4l2-ctlを使用しています。
pi@raspberrypi:~ $ v4l2-ctl --list-formats-ext ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: 'YUYV' (YUYV 4:2:2) ・・・(略)・・・ Size: Discrete 800x448 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.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.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x600 Interval: Discrete 0.042s (24.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.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) ・・・(略)・・・ [1]: 'MJPG' (Motion-JPEG, compressed) ・・・(略)・・・ Size: Discrete 800x448 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.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.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) Size: Discrete 800x600 Interval: Discrete 0.033s (30.000 fps) Interval: Discrete 0.042s (24.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.133s (7.500 fps) Interval: Discrete 0.200s (5.000 fps) ・・・(略)・・・
出力を見ると、C920では、下記の2種類のフォーマット(コーディック)に対応している事が分かります。
- YUYV 4:2:2
- Motion-JPEG
注:最近のC920は、H.264には対応していないようです。
参考 : SAY GOODBYE TO IN-CAMERA HARDWARE ENCODING
確認しやすいように、上記の出力を一覧しておきます。
フォーマット(CODEC) | 解像度 | fps |
---|---|---|
MJPG | 1920 x 1080 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 1600 x 896 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 1280 x 720 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 1024 x 576 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 960 x 720 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 864 x 480 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 800 x 600 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 800 x 448 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 640 x 480 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 640 x 360 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 432 x 240 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 320 x 240 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 320 x 180 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 352 x 288 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 176 x 144 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 160 x 120 | 5, 7.5, 10, 15, 20, 24, 30 |
MJPG | 160 x 90 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 2304 x 1536 | 2 |
YUYV | 2304 x 1296 | 2 |
YUYV | 1920 x 1080 | 5 |
YUYV | 1600 x 896 | 5, 7.5 |
YUYV | 1280 x 720 | 5, 7.5, 10 |
YUYV | 1024 x 576 | 5, 7.5, 10, 15 |
YUYV | 960 x 720 | 5, 7.5, 10, 15 |
YUYV | 800 x 600 | 5, 7.5, 10, 15, 20, 24 |
YUYV | 864 x 480 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 800 x 448 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 640 x 480 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 640 x 360 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 432 x 240 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 352 x 288 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 320 x 240 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 320 x 180 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 176 x 144 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 160 x 120 | 5, 7.5, 10, 15, 20, 24, 30 |
YUYV | 160 x 90 | 5, 7.5, 10, 15, 20, 24, 30 |
4 OpenCV
続いてOpenCVでWebカメラを利用する場合の一般的なコードです。cap.set()で解像度やFPSを指定し、cap.get()で設定された内容を確認しています。
CAP_PROP_FOURCCでフォーマットを明示的に設定した例は少ないのですが、カメラが予期しないモードで動作していて、解像度等の設定に失敗する事があるので注意が必要です。
なお、CAP_PROP_FOURCCの戻り値は、文字列として取得するためにデコードする必要があります
参考:https://github.com/opencv/opencv/blob/master/samples/python/video_v4l2.py
デバイスの変更などで、想定していないモードで動作している可能性もありますので、プログラムの中で、解像度やFPSに依存したコードを書く場合は、cap.get()で取得した値を使用する方が安全だと思います。
# -*- coding: utf-8 -*- import cv2 # Webカメラ DEVICE_ID = 0 WIDTH = 800 HEIGHT = 600 FPS = 24 def decode_fourcc(v): v = int(v) return "".join([chr((v >> 8 * i) & 0xFF) for i in range(4)]) def main(): cap = cv2.VideoCapture (DEVICE_ID) # フォーマット・解像度・FPSの設定 #cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M','J','P','G')) cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('Y','U','Y','V')) cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT) cap.set(cv2.CAP_PROP_FPS, FPS) # フォーマット・解像度・FPSの取得 fourcc = decode_fourcc(cap.get(cv2.CAP_PROP_FOURCC)) width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) fps = cap.get(cv2.CAP_PROP_FPS) print("fourcc:{} fps:{} width:{} height:{}".format(fourcc, fps, width, height)) while True: # カメラ画像取得 _, frame = cap.read() if(frame is None): continue # 画像表示 cv2.imshow('frame', frame) # キュー入力判定(1msの待機) # waitKeyがないと、imshow()は表示できない # 'q'をタイプされたらループから抜ける if cv2.waitKey(1) & 0xFF == ord('q'): break # VideoCaptureオブジェクト破棄 cap.release() cv2.destroyAllWindows() if __name__ == '__main__': main()
5 失敗例
よくやってしまう失敗例を紹介させて下さい。
(1) フォーマット間違い
MJPGのつもりで、800 ✕ 600 30FPSを設定したつもりが、動作モードがYUYVになっていて失敗している状況です。 YUYVの場合、800 ✕ 600 の最高FPSは、24ですので、30を設定すると24で初期化されます。
WIDTH = 800 HEIGHT = 600 FPS = 30 fourcc:YUYV fps:24.0 width:800.0 height:600.0
(2) フォーマット間違い
YUYVの最高解像度である 2304 ✕ 1536 2FPSを設定したつもりが、動作モードがMJPGになっていて想定外の解像度・FPSになっている状況です。(この場合、MJPGの最高解像度になっている)
WIDTH = 2304 HEIGHT = 1536 FPS = 2 fourcc:MJPG fps:5.0 width:1920.0 height:1080.0
(3) 指定間違い
1920 ✕ 1080 30FPSを設定したつもりが、HIGHTとWIDTHを間違えて、想定外の解像度・FPSになっている状況です。完全な凡ミスですが、結構やってしまいます。
HEIGHT = 1920 WIDTH = 1080 FPS = 30 fourcc:MJPG fps:30.0 width:960.0 height:720.0
6 最後に
今回は、OpenCVで「解像度」「FPS」及び「フォーマット(コーディック)」を設定する要領について確認してみました。 想定外の動作をしないように、設定されている状態を常に確認しながら作業することが重要だと思います。(すいません、自分自身への戒めです)