[PYTHON] Switch camera resolution from OpenCV

Introduction

The price of WEB cameras has skyrocketed since working from home began. I had a hard time changing the resolution and frame rate when capturing with openCV with the Henachoko camera I bought during this period, so I will summarize it.

What i did

When using openCV with Jetson, when I tried to change the codec of the WEB camera, it was said that it was unhandled property in the set of CAP_PROP_FOURCC, so input v4l2src, use gstreamer to output appsink, and use this as the argument string of videoCapture I changed the codec and resolution of the camera by specifying as.

Frame rate change in OpenCV

Normally As shown in [Python] Webcam frame size and FPS settings with OpenCV

Resolution change


cap=videoCapture(0)
video_input.set(cv2.CAP_PROP_FPS, 30) 
video_input.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
video_input.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) 

You can change the resolution by doing something like that. At this time, the resolution and FPS of the change destination must be supported by the camera, and this list can be obtained by using the v4l2-ctl command or the like. The following is the output of the target Henachoko camera this time.

XavierNX:~/docker/darknet/work$ v4l2-ctl -d /dev/video1 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'MJPG' (compressed)
	Name        : Motion-JPEG
		Size: Discrete 1920x1080
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 320x180
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.033s (30.000 fps)

	Index       : 1
	Type        : Video Capture
	Pixel Format: 'YUYV'
	Name        : YUYV 4:2:2
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)

XavierNX:~/docker/darknet/work$ 

If you don't have v4l2-ctl, you can install it with apt install v4l-utils.

problem

--Problem 1: OpenCV tries to open camera in YUYV In the example output above, OPENCV is trying to open at 640x360-30FPS, the first YUYV (I'm not sure if it's the first). Unless you change this behavior and switch the camera to MJPG format, you can only set resolutions other than 640x360 with this Henachoko camera. --Problem 2: In VideoCaptureProperties, you can change the format with CAP_PROP_FOURCC, but unhandled It cannot be changed on Jetson.

About problem 2

See Speed up OpenCV camera loading and reduce delay time

Resolution change


import cv2

cap=cv2.VideoCapture(1)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'));
video_input.set(cv2.CAP_PROP_FPS, 30) 
video_input.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
video_input.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) 

while True:
    ret, frame_read = cap.read()
    cv2.imshow('Read',frame_read )
    cv2.waitKey(30)
cap.release()

I feel like it works. But for some reason, when I try it, on JETSON

[ WARN:0] global /home/nvidia/host/build_opencv/nv_opencv/modules/videoio/src/cap_gstreamer.cpp (1184) setProperty OpenCV | GStreamer warning: GStreamer: unhandled property

I can't switch to MJPG. If you actually look at OpenCV 4.11 git CAP_gstreamer.cpp, CAP_PROP_FORCC is the set function. It's not defined and I feel like it's written to fall into an unhandled property. Since it works with MAC, it seems that the implementation when opening a VIDEO device with videoCapture uses different code, but the operation with Jetson seems to be As designed operation in the code.

solution

I gave up on this path and changed the codec resolution and FPS by specifying v4l2src and appsink with gstreamer.

Resolution change v4l2src


import cv2

src = 'v4l2src device=/dev/video1 ! image/jpeg,width=1280, height=720, framerate=(fraction)30/1 !jpegdec !videoconvert ! appsink'

cap=cv2.VideoCapture(src)
while(cap.isOpened()):
    ret, frame_read = cap.read()

    cv2.imshow('Read',frame_read )
    cv2.waitKey(30)
cap.release()

~             

Besides, if you rewrite the video input part of gstreamer, you can do various things and it seems to be fun. v4l2src documentation Or, if you search by the parameters put on gst-launch-1.0, you will find various things.

Recommended Posts

Switch camera resolution from OpenCV
Image acquisition from camera with Python + OpenCV
Python, OpenCV camera capture
Camera capture with Python + OpenCV
Switch from python2.7 to python3.6 (centos7)
Shoot time-lapse from a PC camera using Python and OpenCV
Face recognition with camera with opencv3 + python2.7
Python to switch from another language