コンテンツにスキップ

Top

USBカメラのMotion-JPEG を Python + OpenCV + VideoCapture でキャプチャーする方法

普通にOpenCVでVideoCaptureをすると、イメージフォーマットがYUYV形式になる。
YUYVだとFPSが低い場合が多いので、多少画質が落ちても Motion-JPEG 形式にしたい。
ので、その方法を記す。

USBカメラのFPS値が低い(5fpsしか出ない)!!

1080p(30fps) の仕様のWebカメラを接続してVideoCaptureしたところ、どうもカクカクしている。

おかしいなと思いFPSを見てみると5fpsしか出ていない。

V4L2で確認したところ、確かに1920x1080では5fpsだ。

詐欺!?

と思ったが、Image Formatが YUYV(YUYV 4:2:2) のせいだった。

Motion-JPEGにすれば30fpsがちゃんとでた!

でも、OpenCVでどう設定するんだろう?

調べてやってみた!

VideoCaptureのデータフォーマット設定をYUYVからMJPGに変更する

現在のデータフォーマットとFPS値を確認

まず、FullHD(1080p)でのFOURCCとFPSの値を以下のコードで確認する。

$ vi fourcc_check.py

import cv2

cap = cv2.VideoCapture(1)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,1080)

fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
fourcc = fourcc.to_bytes(4, 'little').decode('utf-8')
print("FOURCC=" + str(fourcc))

fps    = int(cap.get(cv2.CAP_PROP_FPS))
print("FPS=" + str(fps))

cap.release()

$ python fourcc_check.py
FOURCC=YUYV
FPS=5

YUYVで5fpsだ。

YUYVフォーマットで30fps出せるか確認

フォーマットがYUYVのままで、FPSの設定を変えて、30fpsにできるか見てみる。

$ vi fourcc_check.py

import cv2

cap = cv2.VideoCapture(1)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,1080)
cap.set(cv2.CAP_PROP_FPS, 30)

fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
fourcc = fourcc.to_bytes(4, 'little').decode('utf-8')
print("FOURCC=" + str(fourcc))

fps    = int(cap.get(cv2.CAP_PROP_FPS))
print("FPS=" + str(fps))

cap.release()

$ python fourcc_check.py
FOURCC=YUYV
FPS=5

変わらない。
やはり、自分のWebカメラでは、YUYVでは5fpsが限度のようだ。

YUYV を Motion-JPEGに変更

YUYVをMotion-JPEGに変更する。

$ vi fourcc_check.py

import cv2

cap = cv2.VideoCapture(1)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,1080)
cap.set(cv2.CAP_PROP_FPS, 30)

cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"MJPG"))

fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
fourcc = fourcc.to_bytes(4, 'little').decode('utf-8')
print("FOURCC=" + str(fourcc))

fps    = int(cap.get(cv2.CAP_PROP_FPS))
print("FPS=" + str(fps))

cap.release()

$ python fourcc_check.py
FOURCC=MJPG
FPS=5

あれれ~おかしいぞ~
FOURCCはMJPGに変わったのに、FPSが5のままだ。
どういうことだろう? もしかして、CAP_PROP_FPSはMJPGに変更したあとでセットしないとダメなのかな?

$ vi fourcc_check.py

import cv2

cap = cv2.VideoCapture(1)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,1080)

cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"MJPG"))
cap.set(cv2.CAP_PROP_FPS, 30)

fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
fourcc = fourcc.to_bytes(4, 'little').decode('utf-8')
print("FOURCC=" + str(fourcc))

fps    = int(cap.get(cv2.CAP_PROP_FPS))
print("FPS=" + str(fps))

cap.release()

$ python fourcc_check.py
FOURCC=MJPG
FPS=30

よしっ!変わった!!

以上。