Hey everyone, I’m working on an agriculture weed detection project (HerbiControl) and I’m trying to get better FPS out of my camera setup. I’ve got an Arducam 8MP Camera v2.2 connected via CSI to a Raspberry Pi 4B 8GB. I’m using Python with OpenCV for color detection on the live frames, but I’m only getting around 15 FPS.
I also picked up an Arducam Ezbox-Swift USB camera (the one advertised up to 360fps at 1080P) hoping it would help, but when I tried switching from CSI to USB the FPS actually got worse. So I’ve been sticking with the CSI connection for now but I’m stuck at 15fps.
My target is at least 30 FPS, ideally 60 FPS, for the weed detection to work properly in the field. What kind of computer would I even need to process 360fps at VGA resolution? Is the Pi 4B just not up to the task?
The Arducam 8MP Camera v2.2 over CSI should actually support 30–60 FPS on the Raspberry Pi 4B without issues. The bottleneck is almost certainly in your Python/cv2 processing pipeline, not the camera hardware itself.
Before we dig into the code, can you run a quick test to verify the camera is capable of hitting 60fps? Just run this on your Pi:
rpicam-still -t 0 --framerate 60
This gives you a live preview at 60fps with no Python/OpenCV overhead. Let me know if that looks smooth — it’ll help us narrow down where the bottleneck is.
Thanks for the quick reply. Here’s my current setup:
Raspberry Pi 4B 8GB
Arducam 8MP Camera v2.2 (CSI connector)
Python + cv2 for color detection
Target camera I’m evaluating: Arducam Ezbox-Swift (High Framerate Autofocus USB2.0 UVC, up to 360fps, 1080P)
I tried USB cameras already and the frame rate dropped compared to CSI. That’s why I’ve stayed with the CSI connector. But even on CSI I’m only seeing 15fps. I haven’t run that rpicam-still test yet — I’ll try it. But honestly I think it’s my processing loop that’s the issue. Happy to share my code if that helps.
Yeah, please share your code — that’s going to be key here. The fact that you’re seeing a drop when going from CSI to USB and still only getting 15fps on CSI suggests there’s something in the Python pipeline that’s dragging everything down. Let me see the actual script you’re running so I can spot where the time is being lost.
Here’s the demo code I’m working with. It uses the Picamera2 library (CSI-native), not OpenCV VideoCapture. In the real version of the software, reading from file gets replaced with capture_array():
So I went ahead and tested the Ezbox Swift on a Raspberry Pi on my end to verify what the camera itself is capable of. Good news: the camera definitely outputs 360fps as advertised. I can confirm it with this v4l2 command at VGA (640x480) using MJPG format:
That runs fine and hits 360fps. So the camera and the USB interface are not the problem.
Now here’s where I’m a little confused — it looks like you’re working with two different codebases. One uses Picamera2 (for the CSI camera) and the other uses OpenCV VideoCapture (for USB cameras). These are totally different pipelines. Can you clarify which setup is your actual target? Are you trying to get the Ezbox Swift working with OpenCV, or are you sticking with the CSI camera and Picamera2? I need to understand which path we’re debugging.
Good question. I’m running into a configuration problem — I can’t seem to support both USB and CSI at the same time in one configuration. I haven’t found a way to have both options active simultaneously.
My thinking is — if the CSI setup isn’t going to work out, I could switch the configuration over to USB. But Picamera2 is CSI-only, right? So I’d need a completely different approach for USB. I think I need some guidance on what the right path is here.
You’ve hit on the core issue. Picamera2 is specifically for the CSI-connected camera through the Raspberry Pi’s camera subsystem — it won’t work with USB UVC cameras like the Ezbox Swift.
So these are really two separate paths:
CSI + Picamera2: Uses picam2.capture_array() to grab frames. You’re getting 15fps here, and we need to figure out why — the camera hardware supports much more.
USB + OpenCV: Uses cv2.VideoCapture() for UVC devices like the Ezbox Swift. The camera itself can do 360fps at VGA, but OpenCV’s capture loop on a Pi 4B will likely bottleneck well before that.
A few things I noticed in your Picamera2 code that might be contributing to the 15fps:
You’re calling create_still_configuration but configuring and starting a "preview" stream — these are different modes. The still config may be setting up a higher-resolution sensor mode that slows things down.
You’re requesting 800x600 in RGB888. That’s not an insignificant amount of data to push through the pipeline.
You have cv2.rotate happening in the loop on every frame — that’s a CPU hit.
Which direction do you want to go first? Optimize the CSI pipeline, or get the Ezbox Swift running properly over USB with OpenCV?