Cannot disable auto exposure on IMX462 camera with Raspberry Pi 4B, OpenCV, v4l2loopback

Hi, hoping someone can help. I’m using an IMX462 camera (Arducam Raspberry Pi camera, SKU B0333) on a Raspberry Pi 4B. The problem is I can’t control the exposure — I need to disable auto exposure completely. I’m developing a device that measures relative changes in light intensity, and it has to be able to detect very low light intensity. The IMX462 is described as very good for exactly this, but if the exposure keeps adjusting automatically it changes the intensity value of my data, which ruins the measurement. How can I set the exposure manually / turn off auto exposure? I’m capturing with OpenCV through v4l2loopback.

Hi! For manual exposure on the Pi camera stack you need to pin both the shutter and the gain. With the libcamera apps you’d do something like:

libcamera-still -t 0 --shutter 1000 --gain 2.0

Just a note: the unit of the shutter value is microseconds. Setting both explicitly effectively gives you a fixed exposure/gain so auto exposure won’t kick in and skew your readings.

Can you tell me exactly how you’re grabbing the frames right now (libcamera tools, gstreamer, or OpenCV), and whether you get any error output? Logs would help me point you in the right direction.

Thanks. The libcamera-still command works for a one-off still capture, that’s how I’ve been testing it. But that’s not really how my application runs. I’m using OpenCV with v4l2loopback — I create a v4l2 loopback device and read from it in OpenCV. So the command you gave doesn’t fit into that pipeline. Can I set the exposure on v4l2loopback? And no, I don’t have any logs to share, there’s no error, it just doesn’t let me lock the exposure.

Ah OK, that changes things. When you go through OpenCV + v4l2loopback on the Pi, the actual capture is handled by the gstreamer libcamera plugin under the hood. Unfortunately, currently the libcamera plugin of gstreamer does not support setting controls. So there’s no way to set the exposure/gain through that path right now — the manual --shutter / --gain approach only works with the libcamera apps (libcamera-still and friends), not through the gstreamer plugin. Just to be sure I’m reading your setup right: is the loopback device being fed by a libcamerasrc/gstreamer pipeline, or are you feeding it directly from the libcamera apps?

It’s fed through the gstreamer libcamera plugin, yes — that’s the path OpenCV ends up using with v4l2loopback. So if I understand you: the plugin doesn’t expose the exposure control at all, so there’s nothing for me to set on the loopback device either? I was hoping v4l2loopback itself would accept an exposure control that I could just set and forget.

Right — since the control isn’t exposed by the gstreamer libcamera plugin, querying or setting an exposure control on the loopback side won’t do anything useful. The loopback isn’t where the control lives; it just passes frames through. So to summarize where this stands: for fixed manual exposure you’d need a capture path driven by the libcamera apps, where --shutter (microseconds) and --gain work as expected. If your pipeline has to stay on gstreamer libcamera via OpenCV + v4l2loopback, setting controls like exposure is not supported at this time, so there’s no way to lock auto exposure through that route. If you can share your exact gstreamer pipeline string, I can take a look, but as it stands the control-setting limitation on that plugin is the blocker.