opencv上设置摄像头曝光参数的经验

实际应用中我们需要调整摄像头的参数比如曝光,由于opencv的后端是一般编译是支撑多种插件,详细信息请参考OpenCV: Video I/O with OpenCV Overview,这里引用里面的图:

opencv上设置摄像头曝光参数的经验_第1张图片

 

对于VideoCaputure,后端有ffmpge,V4L,DShow等,opencv并没有完全用统一参数来屏蔽后端的差异性,也就是部分参数需要依据选择的后端来确定是否实现或者参数范围。

你可以通过下面命令查看当前opencv编译支撑了哪些后端:

C++ :   cout<

Python:  cv2.getBuildInformation()

以opencv修改曝光参数为例,常见的python代码形式如下:

vs.stream.set(cv2.CAP_PROP_AUTO_EXPOSURE,0.25)   #选择手动曝光

vs.stream.set(cv2.CAP_PROP_EXPOSURE,-4)   #设置曝光参数

这个代码在windows上可以正常修改曝光,但是linux可能报错(依据缺省的后端),出现类似下面的错误:

GStreamer warning: unhandled property: 15

这是因为linux下缺省用有时候是gstreamer做后端,而该接口没有实现曝光调整,如需让曝光有效,在linux平台需要强制使用V4L的后端,即在创建caputure时候通过参数指定:

cv::VideoCapture cap(0, cv::CAP_V4L);

指定V4L作为后端,则对应的参数范围也要做调整,在我的系统下测试切换曝光方式和设置曝光值都需要改变,常见的曝光参数都是负值,而V4L则需要传入标准正的值(见文档后面的曝光参数说明),你可以用v4l2-ctl 查看值的范围和当前值,下面方式是我实测有效的方法,其中os为nt表示是windows下的设置,缺省认为是linux系统

if os.name =='nt':

vs = VideoStream(src=1).start()

vs.stream.set(cv2.CAP_PROP_AUTO_EXPOSURE,0.25)

vs.stream.set(cv2.CAP_PROP_EXPOSURE,-4)

else:

v=VideoStream(src=0).stream

time.sleep(0.5)

v.stream.set(cv2.CAP_PROP_FRAME_WIDTH,640) #

v.stream.set(cv2.CAP_PROP_FRAME_HEIGHT,480)#

v.stream.set(cv2.CAP_PROP_AUTO_EXPOSURE,1.0)

v.stream.set(cv2.CAP_PROP_EXPOSURE,500)

vs=v.start()

Python系统中如果使用imutils.video其并没有提供切换到v4l的对外接口,可采用强制修改的方式实现,见下面红色部分(需根据自己python实际情况调整):

sudo vi  /usr/local/lib/python3.9/dist-packages/imutils/video/webcamvideostream.py   强制改变后端模式:

# from the stream

                #self.stream = cv2.VideoCapture(src)

                self.stream = cv2.VideoCapture(src,cv2.CAP_V4L)

                (self.grabbed, self.frame) = self.stream.read()

此外在打开摄像头和开始操作需要延时一下,否则出现下面错误:

requestBuffers VIDEOIO(V4L2:/dev/video0): failed VIDIOC_REQBUFS: errno=16 (Device or resource busy),出现这个错误后面就无法获取图像数据了。

曝光参数说明:

负值对应关系表

(计算公式 EXP_TIME = 2^(-EXP_VAL) UVC camera exposure timing in OpenCV | KUROKESU

opencv上设置摄像头曝光参数的经验_第2张图片

注意:V4L方式设置的曝光值就不是上面的负数,而是v4l2-ctl里面显示的值。

以曝光参数为例,网络提到的曝光参数都是负值,而v4l2的整数值除以100000 为秒(根据1.11. Camera Control Reference — The Linux Kernel documentation),假如值为200,那么就是20ms。

所以两者换算关系为:

Ev=2^(Ep)*10000  Ev为v4l2的曝光值而Ep为python下面的负数值。

如果希望通用保存的参数,因为Ep取值范围稀疏,可以以Ep的负值进行存储曝光值,如果是linux则利用上面公式转为正确值。

 

你可能感兴趣的:(opencv,摄像头)