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
よしっ!変わった!!
以上。