Python OpenCVでWebカメラで設定できる解像度、FPS、フォーマットを調べる


PythonのOpenCVを使ってWebカメラで設定できる解像度、PFS、FourCCを一覧表示するものを作りました。

経緯としては、
OpenCVでWebカメラを使う際に設定できる解像度、FPS、FOURCCを確認したかけど
OpenCVのAPIにはそれらしいインタフェースは見つからず。  

見つからないなら作ってしまおうと…
ただ、各設定値を設定してみて、反映されたかを総当たりしている形になるので、とても遅いですが…

## 動作確認環境

+ PC環境
    + Windows10
    + Python 3.8.10
    + opencv-python 4.5.2.54
+ Webカメラ
    + BUFFALO BSW300M


## ソースコード

```python
import itertools
import cv2

app_ids = [
    # (cv2.CAP_ANY, 'CAP_ANY'),
    (cv2.CAP_DSHOW, 'CAP_DSHOW'),
    (cv2.CAP_MSMF, 'CAP_MSMF'),
    (cv2.CAP_V4L2, 'CAP_V4L2'),
]
fourcc_list = [
    (cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), 'MJPG'),
    (cv2.VideoWriter_fourcc('Y', 'U', 'Y', 'V'), 'YUYV'),
    (cv2.VideoWriter_fourcc('Y', 'U', 'Y', '2'), 'YUY2'),
    (cv2.VideoWriter_fourcc('H', '2', '6', '4'), 'H264'),
    (cv2.VideoWriter_fourcc('B', 'G', 'R', '3'), 'BGR3'),
]
frame_list = [(1920, 1080), (1280, 1024), (1280, 720), (800, 600), (640, 480)]
fps_list = [60, 30, 24, 20, 15, 10, 5, 2, 1]

# DeviceID(0～9)と、API設定の組み合わせで繰り返し
for dev_id, api_id in itertools.product(range(10), app_ids):
    # VideoCaptureオブジェクトの取得
    cap = cv2.VideoCapture(dev_id, api_id[0])
    # 無効な場合はskip
    ret = cap.isOpened()
    if ret is False:
        continue

    # VideoCaptureの情報出力
    backend = cap.getBackendName()
    print("Camera #%d (%s : %s) :" % (dev_id, api_id[1], backend))

    # 対応FOURCCの確認
    for fourcc in fourcc_list:
        cap.set(cv2.CAP_PROP_FOURCC, fourcc[0])
        ret_fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
        if fourcc[0] != ret_fourcc:
            continue    # 設定失敗のためSkip

        # 対応解像度の確認
        for frame in frame_list:
            cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame[0])
            cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame[1])
            ret_w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            ret_h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            if frame[0] != ret_w or frame[1] != ret_h:
                continue

            # 対応FPSの確認
            for fps in fps_list:
                cap.set(cv2.CAP_PROP_FPS, fps)
                ret_fps = int(cap.get(cv2.CAP_PROP_FPS) + 0.5)
                if fps != ret_fps:
                    continue

                # プロパティの出力
                print('  Frame: %4d x %4d , FPS: %3d , FourCC: %s' % 
                        (ret_w, ret_h, ret_fps, fourcc[1]))
```
+ 確認したいFOURCCがあれば、`fourcc_list`に追加
+ 確認したい解像度があれば、`frame_list`に追加

## 出力例

長く出るので、かなり抜粋して記載

```
Camera #0 (CAP_DSHOW : DSHOW) :
  Frame: 1920 x 1080 , FPS:  60 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  30 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  24 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  20 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  15 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  10 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:   5 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:   2 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:   1 , FourCC: MJPG
  Frame: 1280 x  720 , FPS:  60 , FourCC: MJPG
  Frame: 1280 x  720 , FPS:  30 , FourCC: MJPG
  Frame: 1280 x  720 , FPS:  24 , FourCC: MJPG
～～～～省略～～～～
Camera #1 (CAP_DSHOW : DSHOW) :
  Frame: 1920 x 1080 , FPS:  60 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  30 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  24 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  20 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  15 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:  10 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:   5 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:   2 , FourCC: MJPG
  Frame: 1920 x 1080 , FPS:   1 , FourCC: MJPG
  Frame: 1280 x  720 , FPS:  60 , FourCC: MJPG
  Frame: 1280 x  720 , FPS:  30 , FourCC: MJPG
  Frame: 1280 x  720 , FPS:  24 , FourCC: MJPG
～～～～省略～～～～
  Frame: 1920 x 1080 , FPS:  60 , FourCC: YUY2
  Frame: 1920 x 1080 , FPS:  30 , FourCC: YUY2
  Frame: 1920 x 1080 , FPS:  24 , FourCC: YUY2
  Frame: 1920 x 1080 , FPS:  20 , FourCC: YUY2
～～～～省略～～～～
```