raspberrypi / picamera2

New libcamera based python library
BSD 2-Clause "Simplified" License
824 stars 176 forks source link

[HOW-TO] Improve streaming quality of Raspberry Pi Camera v3 during drone flight #1075

Open buscainod opened 1 month ago

buscainod commented 1 month ago

I am using the Raspberry Pi Camera v3 for live streaming during a drone flight. During a comparison test between the v2 and v3 cameras, I noticed that the v2 camera produced higher quality video. Since the v3 camera has autofocus, I need to disable it as the drone's vibrations may interfere with it. Here is how I configure the camera:

camera.set_controls({"FrameDurationLimits": (33000, 45000), "AfMode": controls.AfModeEnum.Manual, "LensPosition": 0})

Is there anything else I should adjust to improve the streaming quality?

I attached two screenshots taken from the live streams of both cameras for comparison.

Camera v2: Camera-v2

Camera v3: Camera-v3

davidplowman commented 1 month ago

I don't know if you're able to share the rest of the camera configuration? Important things will include not only the output resolution, but also the camera mode that's being selected (make sure you get a 2304x1296 mode). I assume you've set a reasonably high bitrate for the encoder.

Setting the lens to "infinity" sounds right, but of course it's still on the end of a spring so some degree of wobble is still likely. I assume the camera is in a glass housing of some sort as wind vibrations can cause trouble. We also know some folks who have actually glued the lenses in place at "infinity" - but be warned that this is clearly a warranty voiding procedure, and when we tried it, we destroyed several camera modules before being successful!

buscainod commented 1 month ago

I don't know if you're able to share the rest of the camera configuration? Important things will include not only the output resolution, but also the camera mode that's being selected (make sure you get a 2304x1296 mode). I assume you've set a reasonably high bitrate for the encoder.

Setting the lens to "infinity" sounds right, but of course it's still on the end of a spring so some degree of wobble is still likely. I assume the camera is in a glass housing of some sort as wind vibrations can cause trouble. We also know some folks who have actually glued the lenses in place at "infinity" - but be warned that this is clearly a warranty voiding procedure, and when we tried it, we destroyed several camera modules before being successful!

Yes of course! Here all my camera configuration:

camera.create_video_configuration(main={"size": (1280, 720),
                                                             "format": 'YUV420'},
                                                       raw={"size": (2304, 1296)}

I create the encoder this way:

encoder = H264Encoder(1500000)
output = FfmpegOutput("-an -preset ultrafast -tune zerolatency -rtsp_transport tcp -f rtsp " + rtsp_specific_link)
self.camera.start_recording(encoder, output)
davidplowman commented 1 month ago

I think your H264 bitrate seems a bit low - 1.5Mbps isn't huge - though looking at your images I'm not sure it's a big problem. But it might be worth increasing it just as an experiment. I think probably the -preset ultrafast isn't doing much, because it's the H264Encoder, not ffmpeg, that is doing the encoding. Presumably you can test all these options out with your drone on the ground?!?

Also, can you say what kind of a Pi this is? Thanks.

buscainod commented 1 month ago

I think your H264 bitrate seems a bit low - 1.5Mbps isn't huge - though looking at your images I'm not sure it's a big problem. But it might be worth increasing it just as an experiment. I think probably the -preset ultrafast isn't doing much, because it's the H264Encoder, not ffmpeg, that is doing the encoding. Presumably you can test all these options out with your drone on the ground?!?

Also, can you say what kind of a Pi this is? Thanks.

Oh ok! I'll try with an higher bitrate value and removing -preset ultrafast! I can definitely try it with the drone on the ground so i can share some results in a few days.

Right now I'm using the industrial Raspberry cm4

EDIT: Finally i tried what you suggested and it worked! Thanks so much for your help!