ros-drivers / video_stream_opencv

A package to open video streams and publish them in ROS using the opencv videocapture mechanism
224 stars 159 forks source link

Unable to force image width #99

Closed ghost closed 3 years ago

ghost commented 3 years ago

Camera displays properly but forced image width is not accepted. I'm concerned this might hurt the accuracy of a camera calibration that uses the topics published by this node if it's publishing the wrong image width?

I do not have a calibration file because I'm trying to create one from the rtsp stream using this node.

roslaunch video_stream_opencv camera.launch video_stream_provider:=rtsp://192.168.1.1:554/h264 width:=640 height:=480 PARAMETERS /camera/camera_stream/buffer_queue_size: 100 /camera/camera_stream/camera_info_url: /camera/camera_stream/camera_name: camera /camera/camera_stream/flip_horizontal: False /camera/camera_stream/flip_vertical: False /camera/camera_stream/fps: 30.0 /camera/camera_stream/frame_id: camera /camera/camera_stream/height: 480 /camera/camera_stream/loop_videofile: False /camera/camera_stream/set_camera_fps: 30.0 /camera/camera_stream/start_frame: 0 /camera/camera_stream/stop_frame: -1 /camera/camera_stream/video_stream_provider: rtsp://192.168.1.... /camera/camera_stream/width: 640 /rosdistro: melodic /rosversion: 1.14.10 process[camera/camera_stream-1]: started with pid [9386] [ INFO] [1619190027.680806948]: Initializing nodelet with 12 worker threads. [ INFO] [1619190027.780440745]: Camera name: camera [ INFO] [1619190027.780463526]: Provided camera_info_url: '' [ INFO] [1619190027.780472029]: Publishing with frame_id: camera [ INFO] [1619190027.780481436]: Setting camera FPS to: 30 [ INFO] [1619190027.780489365]: Throttling to fps: 30 [ INFO] [1619190027.780497527]: Setting buffer size for capturing frames to: 100 [ INFO] [1619190027.780505387]: Flip horizontal image is: false [ INFO] [1619190027.780512194]: Flip vertical image is: false [ INFO] [1619190027.780544536]: Video start frame is: 0 [ INFO] [1619190027.780556521]: Video stop frame is: -1 [ INFO] [1619190027.780569394]: Forced image width is: 640 [ INFO] [1619190027.780596154]: Forced image height is: 480 [ INFO] [1619190028.041820904]: using default calibration URL [ INFO] [1619190028.041950479]: camera calibration URL: file:///root/.ros/camera_info/camera.yaml [ INFO] [1619190028.042117590]: Unable to open camera calibration file [/root/.ros/camera_info/camera.yaml] [ WARN] [1619190028.042185972]: Camera calibration file /root/.ros/camera_info/camera.yaml not found. [ INFO] [1619190028.042328757]: Opening VideoCapture with provider: rtsp://192.168.1.1:554/h264 [ INFO] [1619190030.582899323]: Video stream provider type detected: rtsp_stream [ INFO] [1619190030.583051765]: Camera reports FPS: 15 [ WARN] [1619190030.617485528]: No calibration file given, publishing a reasonable default camera info. [ INFO] [1619190030.617566677]: The image width is: 640 [ INFO] [1619190030.617603730]: The image height is: 360

ghost commented 3 years ago

@awesomebytes to test, I reproduced what image_proc does in python, using the projection and distortion matrices given by calibration.

Sure enough, I am only able to correctly undistort images of size 640x360, which means this node is telling camera_calibration to use that same image size, not the 640x480 I am requesting/forcing.

So is there anyway to force the width? Or is this due to a known limitation? My camera says it supports 640x480, so I'm just confused where 360 width is even coming from?

awesomebytes commented 3 years ago

I doubt the OpenCV backend can change the resolution of a RTSP stream remotely. The image width and height comes from these lines of code: https://github.com/ros-drivers/video_stream_opencv/blob/master/src/video_stream.cpp#L78-L85

Which is called here: https://github.com/ros-drivers/video_stream_opencv/blob/master/src/video_stream.cpp#L214-L217

Which you'll see that is basically getting the size from an actual image received from the stream. video_stream_opencv just reports the size received. Maybe there is some way to force your camera to do 640x480 from the driver side?

ghost commented 3 years ago

@awesomebytes thanks for your assistance. It appears the latest manufacturer firmware must have a bug. I've independently verified with a trivial rospy node just printing the image shape that in fact it is oddly having a height of 360, but that was never the case before the firmware update.

jingyibo123 commented 7 months ago

Facing a similar issue here.

However, openCV by default seems to request only the lowest setting 640x480, and ignores the previous v4l2 configuration.

Turns out OpenCV can indeed change resolution of stream remotely. I do think we should add lines like this here

...
cap->set(CV_CAP_PROP_FRAME_WIDTH, latest_config.width);
cap->set(CV_CAP_PROP_FRAME_HEIGHT, latest_config.height);

I would gladly open a PR if that'll work @awesomebytes