如何更改 OpenCV 不支持但 v4l2 API 支持的网络摄像头属性?



我正在使用OpenCV 3.1Python 2.7从我的网络摄像头Logitech C270捕获视频帧。我还使用video4linux2(v4l2)来设置相机的属性,但这导致了一些问题。我的操作系统是Ubuntu 15.04.

我试图更改的特定属性是absolute_exposure

我可以通过终端使用v4l2neneneba API手动更改它,使用命令v4l2-ctl --set-ctrl exposure_absolute=40,效果很好,但我需要为此任务编写一个脚本。

使用OpenCV的set(cv2.CAP_PROP_EXPOSURE, 20)会导致"视频错误:V4L:设备不支持属性曝光(15)"。我确信网络摄像头支持更改此属性,因为使用v4l2可以做到这一点,那么我认为问题出在OpenCV的包装器上。

我还尝试使用subprocesslib发送一个终端命令,并使用v4l2更改属性。命令为subprocess.call('v4l2-ctl --device=/dev/video0 --set-ctrl exposure_absolute=20', shell=True)

结果是exposure_absolute发生了变化,但它没有应用于我当前的视频捕获。图1显示了通过脚本设置属性后的结果。图2显示了在激活相同视频捕获的情况下,通过终端设置相同属性后的结果。

通过脚本(图像1)设置曝光_绝对

通过终端设置曝光_绝对值(图2)

图像2是在图像1之后拍摄的,高亮显示的线与图像1相同。

我是否在子流程调用中做错了什么?或者如何使用脚本更改此属性?

此外,为什么cv2.VideoCapture(id)重置相机属性,在运行脚本之前更改它们没有用,有可能停止吗?

_________________________________________________

编辑:我可能找到了解决此问题的方法。子流程调用确实是正确的,在更改属性之前,我只需要使用cv2.read()一次,显然第一个cv2.read()是重置相机属性的地方。我仍然不知道如何阻止它自动重置网络摄像头的属性。

如果您使用GStreamer支持构建opencv(标志:-D with_GStreamer=ON),您可以使用GStreammer管道打开VideoCapture,在那里您可以指定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);

这适用于C++和Python。您可以通过在终端中键入以下内容来获得控件的完整列表:v4l2 ctl--列出ctrls菜单

最新更新