5
votes

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.

1
Looking at the source code in modules\highgui\src\cap_libv4l.cpp (specifically at the icvSetControl 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 of V4L2_CID_EXPOSURE_ABSOLUTE (maybe 0x902?) and call the set function with that -- set(0x902, 20).Dan Mašek

1 Answers

4
votes

If you build opencv with GStreamer support (flag: -D WITH_GSTREAMER=ON) you can open a VideoCapture using a GStreamer pipeline where you can specify all kind of parameters for v4l2:

std::string cameraPipeline;
cameraPipeline ="v4l2src device=/dev/video0 extra-controls=\"c,exposure_auto=1,exposure_absolute=500\" ! ";
cameraPipeline+="video/x-raw, format=BGR, framerate=30/1, width=(int)1280,height=(int)720 ! ";
cameraPipeline+="appsink";

VideoCapture cap;
cap.open(cameraPipeline);

This is works in C++ and Python. You can get the full list of controls by typing this in a terminal : v4l2-ctl --list-ctrls-menus