Using Arducam OV7251 with C++ and two cameras on Raspberry Pi 5

Hi all, I’m trying to get the Arducam OV7251 working on a Raspberry Pi running kernel 5.10.92-v7l+. I followed the Arducam Pivariety V4L2 Driver release (Arducam_pivariety_v4l2_v1.0) but /dev/video0 still doesn’t show up at all. Has anyone run into this?

Quick question before we go deeper - is this the B0161 module? That one is a bit special and can’t be accessed through libcamera like the standard Pivariety flow.

Yes, it’s the B0161 (OV7251). I didn’t realize that. So what’s the correct way to get it working then?

Right, that’s the issue. The B0161 can’t be accessed using libcamera, so it won’t expose /dev/video0 through the normal libcamera/V4L2 flow. Instead it needs a device tree overlay plus the OpenCV-based preview scripts. Here’s what to do:

  1. Install OpenCV for Python:
    sudo apt install python3-opencv

  2. Edit the boot config:
    sudo nano /boot/config.txt

  3. Add this under the [all] section at the bottom:
    dtoverlay=ov7251,media-controller=0

  4. Reboot.

After that the camera should be accessible via the preview scripts. I’ve sent you the two scripts (play.py and play2.py) through a private message - please check your messages and try running them.

That did it! After adding the overlay and rebooting, the camera lights up and play.py gives me a preview. Thanks.

Couple of follow-up questions: can I use this Arducam OV7251 (I keep typoing it as ov7521) with C++? And is it possible to run two of these OV7251 cameras on a Raspberry Pi 5?

Glad it’s working. For C++: yes, you can use it. The overlay still provides the access path, and you’d use the OpenCV C++ API (VideoCapture) to grab frames, similar to what play.py does in Python. The key point is that it’s the ov7251 overlay with media-controller=0 doing the work, not libcamera.

For two OV7251 cameras on a Pi 5: that depends on the available CSI ports and whether the overlay can be instantiated twice without I2C address conflicts. I’d need to check the specifics of the Pi 5 setup and the overlay parameters, but it’s not as straightforward as just plugging both in. Can you tell me how you’re connecting them?

One more thing on performance. The camera is running but I’m only getting 30 fps at 640x480 (VGA). The datasheet says it can capture VGA at 100 fps. I’m checking the fps with play.py. Is there a way to push it to 100 fps at 640x480?

Good question. First thing to check: how is play.py measuring the fps? If it’s timing the loop that includes OpenCV’s imshow/waitKey or any display step, the 30 fps could be a preview/display bottleneck rather than the sensor itself. The OV7251 can hit 100 fps at VGA in the right mode, but the actual throughput depends on the mode the driver/overlay sets up and what the script does with each frame.

Can you try measuring capture-only fps - grab frames in a loop without displaying them and time it? Also worth checking whether the overlay/driver is selecting a lower-fps mode. I’ve been looking at the datasheet you shared (OV7251_MIPI_Camera_Module_DS_v1.pdf), and the 100 fps figure assumes the sensor is running in its high-fps mode, so the mode selection needs to be confirmed.

To summarize where we are: the B0161/OV7251 is working now via dtoverlay=ov7251,media-controller=0 and the OpenCV preview scripts (not libcamera/V4L2, which is why /dev/video0 never appeared). C++ access should work through OpenCV’s VideoCapture. The remaining open issue is the 30 fps at 640x480 vs the 100 fps in the datasheet - the current suspicion is that play.py’s display loop or the sensor mode selection is limiting it, but that still needs confirmation from a capture-only fps test.