I'm using OpenCV 3.1 and Python 2.7 to capture video frames from my webcam, Logitech C270. I'm also using video4linux2(v4l2) to set the properties of my camera but this led to a few problems. My OS is Ubuntu 15.04.
The specific property I'm trying to change is absolute_exposure.
I'm able to change it manually using v4l2 API via terminal, with the command v4l2-ctl --set-ctrl exposure_absolute=40
, and it works nice but I need to write a script for this task.
Using OpenCV's set(cv2.CAP_PROP_EXPOSURE, 20)
leads to "VIDEOIO ERROR: V4L: Property Exposure(15) not supported by device". I'm sure the webcam supports the change of this property since it's possible to do so using v4l2, then I assume the problem is with OpenCV's wrapper.
I also tried to use subprocess lib to send a terminal command and change the property using v4l2. The command is subprocess.call('v4l2-ctl --device=/dev/video0 --set-ctrl exposure_absolute=20', shell=True)
.
The result is that exposure_absolute changes but it isn't applied to my current video capture. Image 1 shows the result after setting the property via script. Image 2 shows the result after setting the same property via terminal, with the same video capture active.
Setting exposure_absolute via script (image 1)
Setting exposure_absolute via terminal (image 2)
Image 2 was taken right after image 1, the highlighted line is the same of image 1.
Am I doing something wrong on the subprocess call? Or how can I make the change of this property using a script?
Also, why cv2.VideoCapture(id)
resets the camera properties, it's no use changing them before running the script, and is it possible to stop that?
__________________________________________________
Edit: I maybe found a workaround for this problem. The subprocess call is indeed right, I just had to use cv2.read()
once before changing the properties, apparently the first cv2.read()
is where the camera properties are reset. I still don't know how to stop it from automatically resetting webcam's properties though.
modules\highgui\src\cap_libv4l.cpp
(specifically at theicvSetControl
function), it would appear that you should be able to pass in a V4L control code instead of the CV2 codes. So, find the numerical value ofV4L2_CID_EXPOSURE_ABSOLUTE
(maybe 0x902?) and call theset
function with that --set(0x902, 20)
. – Dan Mašek