Can cv2.VideoCapture(0) display live camera feed like picamera2?

Hi all, I’m working with an Arducam IMX519 camera on my Pi and I’m a bit stuck. Right now I’m able to grab and display the live feed using picamera2 in Python, and that works fine. But I’d like to do the same thing with cv2.VideoCapture(0) since the rest of my code is built around OpenCV. Does anyone know if cv2.VideoCapture(0) can be used to read the live feed the same way picamera2 does? I’ve been poking at it and I just can’t find a way to make it work. Any guidance would be appreciated.

Hey, welcome. Can you confirm a couple things so we’re on the same page?

  • Which camera model exactly (you mentioned Arducam IMX519, just confirming)
  • How are you currently opening the stream with picamera2 (roughly)
  • What happens when you call cv2.VideoCapture(0) - does the index open at all, do you get an empty frame, an error, etc.

Even a short snippet of your current picamera2 code and the cv2 attempt would help.

Thanks. Yes, it’s the Arducam IMX519. On the picamera2 side I basically do the usual thing - create a Picamera2 instance, configure a preview/video config, start it, then grab frames and show them. That works and I can see the live feed.

On the OpenCV side I’m just doing:

cap = cv2.VideoCapture(0)
ret, frame = cap.read()

and then trying to imshow the frame. It doesn’t give me anything usable - I never get a proper live feed out of it. No crash, no exception to speak of, it just doesn’t produce the camera feed. I couldn’t figure out what I’m doing wrong.

Ok, so that behavior lines up with what I’d expect for this camera. The IMX519 here isn’t exposed as a standard V4L2 device that OpenCV can open and read from directly, so cv2.VideoCapture(0) won’t grab the sensor output the way it would with a plain USB webcam. OpenCV can’t read the camera data directly in this setup.

picamera2 is the layer that actually talks to the sensor - it’s what you’re already using successfully. The intended pattern is to keep reading frames with picamera2 and only hand the frame data over to OpenCV for processing/display, not to open the camera with cv2.VideoCapture(0).

Ah ok, so it’s not something I’m configuring wrong, it’s just how the camera is accessed. That explains why I couldn’t find a way to make VideoCapture(0) work.

So how am I supposed to combine the two then? Do I take the frames from picamera2 and then pass them into OpenCV? Is there a reference for the right way to wire it up? I want to make sure I don’t hack something fragile together.

You’ve got it - data can’t be read directly by OpenCV here, it has to be read by picamera2 first. The cleanest reference is the official picamera2 example that does exactly this: it captures frames through picamera2 and feeds them into OpenCV.

Take a look here:
https://github.com/raspberrypi/picamera2/blob/main/examples/opencv_face_detect.py

Ignore the face-detect part if you don’t need it - the important bit is how it obtains the frame from picamera2 and hands it to cv2 for processing/display. You can drop your own logic in place of theirs.

That example makes sense, I can see the pattern now - picamera2 is grabbing the frame and OpenCV is just consuming it. I’ll refactor my code that way and stop trying to open it with cv2.VideoCapture(0).

Just to double check before I rewrite everything: there’s really no setting or backend flag that makes cv2.VideoCapture(0) work for this camera? I’d rather be sure than keep revisiting it later.

Correct - for the Arducam IMX519 with picamera2, OpenCV can’t capture frames directly. There isn’t a cv2 flag or index that will make VideoCapture(0) read this sensor the way picamera2 does. The camera stream must be obtained through picamera2 (exactly like the opencv_face_detect.py example shows) and then passed to OpenCV for whatever you need - display, detection, encoding, etc.

So the takeaway: keep reading frames with picamera2, hand them to OpenCV, and drop cv2.VideoCapture(0) from this path entirely. If you hit anything odd after refactoring, post your updated snippet and we’ll take a look.