在使用ZED
Camera时,我希望获得原始的照片(未经过校正,对齐处理)。但由于系统是Ubuntu
14.04,只有ZED SDK 1.1.0版本支持,而对应的zed-ros-wrapper
v1.0.0只能订阅已经经过校正对齐的照片/camera/left/image_rect_color
和/camera/rgb/image_rect_color
(不过zed-ros-wrapper
v1.2.0版本开始就开始提供原始照片的订阅,Topic为/camera/left/image_raw_color
和/camera/right/image_raw_color
)。
如果直接使用ZED SDK所提供的图片获取接口'grab();
retrieveImage()',按照说明也是已经经过了对齐操作了,并非是原始照片。
还好由于ZED
Camera是标准的网络摄像头,使用v4l2-ctl --all
指令,有以下显示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 Driver Info (not using libv4l2): Driver name : uvcvideo Card type : ZED Bus info : usb-0000:00:14.0-3 Driver version: 4.4.59 Capabilities : 0x84200001 Video Capture Streaming Device Capabilities Device Caps : 0x04200001 Video Capture Streaming Priority: 2 Video input : 0 (Camera 1: ok) Format Video Capture: Width/Height : 2560/720 Pixel Format : 'YUYV' Field : None Bytes per Line: 5120 Size Image : 3686400 Colorspace : SRGB Custom Info : feedcafe Crop Capability Video Capture: Bounds : Left 0, Top 0, Width 2560, Height 720 Default : Left 0, Top 0, Width 2560, Height 720 Pixel Aspect: 1/1 Selection: crop_default, Left 0, Top 0, Width 2560, Height 720 Selection: crop_bounds, Left 0, Top 0, Width 2560, Height 720 Streaming Parameters Video Capture: Capabilities : timeperframe Frames per second: 30.000 (30/1) Read buffers : 0 brightness (int) : min=0 max=8 step=1 default=4 value=4 contrast (int) : min=0 max=8 step=1 default=4 value=4 saturation (int) : min=0 max=8 step=1 default=4 value=4 hue (int) : min=0 max=11 step=1 default=0 value=0 white_balance_temperature_auto (bool) : default=1 value=1 gain (int) : min=0 max=8 step=1 default=4 value=4 power_line_frequency (menu) : min=0 max=2 default=1 value=1 white_balance_temperature (int) : min=2800 max=6500 step=100 default=4600 value=4600 flags=inactive sharpness (int) : min=0 max=8 step=1 default=4 value=4 exposure_auto (menu) : min=0 max=3 default=0 value=2 exposure_absolute (int) : min=5000 max=80000 step=5000 default=60000 value=45000 flags=inactive exposure_auto_priority (bool) : default=0 value=0
所以可以使用OpenCV(opencv-2.4.13.2版本)自带的VideoCapture
函数获取原始照片:
1 2 3 4 5 6 7 8 9 10 11 cv::VideoCapture* camera_ = new cv::VideoCapture(0); cv::Mat raw, left_image, right_image; if (camera_->grab()) { camera_->retrieve(raw); cv::Rect left_rect(0, 0, width_ / 2, height_); cv::Rect right_rect(width_ / 2, 0, width_ / 2, height_); left_image = raw(left_rect); right_image = raw(right_rect); cv::waitKey(10); return true; }
但在读取,设置摄像头快门速度(EXPOSURE)时,
1 2 camera_->set(CV_CAP_PROP_EXPOSURE, exposure_); exposure_ = camera_->get(CV_CAP_PROP_EXPOSURE);
出现了以下错误:
1 2 HIGHGUI ERROR: V4L2: Unable to get property Exposure(9963793) - Invalid argument HIGHGUI ERROR: V4L: Exposure control in V4L is not supported
发现是OpenCV的bug,并且在最新的3.*版本已经修复,对于opencv-2.4.13.2版本需要手动修复。
解决方法
>在opencv-2.4.13.2/modules/highgui/src/cap_v4l.cpp
文件中,将V4L2_CID_EXPOSURE
替换为V4L2_CID_EXPOSURE_ABSOLUTE
,重新build一次。
重新运行程序,发现读取问题解决了,但是设置参数时依然出现问题:
1 2 3 HIGHGUI ERROR: V4L2: Failed to set control "10094850": Input/output error (value 12500) HIGHGUI WARNING: Setting property 10094850 through v4l2 failed. Trying with v4l1. HIGHGUI ERROR: V4L: Exposure control in V4L is not supported
后来终于找到解决方法,需要先通过设置'exposure_auto',关闭自动模式,才能进行快门设置。终端中运行:
1 v4l2-ctl --set-ctrl=exposure_auto=2
很奇怪,exposure_auto貌似只能设置为0/2。
为了让exposure_absolute
生效,还需设置:
1 v4l2-ctl --set-ctrl=exposure_auto_priority=1
现在可以在C++中通过OpenCV设置摄像头的快门了。
以上方法经过测试发现都是无效的,V4L2无法对快门速度进行设置。
后来,发现可以通过对zed-ros-wrapper进行修改,进行快门设置。
在zed_wrapper_nodelet.cpp
中添加控制exposure的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 int main(int argc, char **argv) { // Defines the exposure control. A -1 value enable the AutoExposure/AutoGain control. // Affected value should be between 0 and 100 for manual control. // A 0 value only disable automode without modifing the last auto values, // while a 1 to 100 value disable auto mode and set exposure to chosen value int exposure = 50; nh_ns.getParam("exposure", exposure); // before zed->grab() zed->setCameraSettingsValue(sl::zed::ZED_EXPOSURE, exposure); }
然后就可以在launch文件中添加控制快门语句:
1 <param name="exposure" value="50"/>