Arducam IMX519 low FPS

  1. Where did you get the camera module(s)?
    Robu.in

  2. Model number of the product(s)?
    IMX519 16MP AutoFocus

  3. What hardware/platform were you working on?
    Raspberry Pi 2, headless raspbian-lite

  4. Instructions you have followed. (link/manual/etc.)
    16MP IMX519 - Arducam Wiki

  5. Problems you were having?
    Getting very low FPS(5fps) using PiCamera2 library

  6. The dmesg log from your hardware?

  7. Troubleshooting attempts you’ve made?
    Running capture_array() method in separate thread but 5FPS seems to be the fastest it can go. Currently I set the resolution at 1920x1080 with RGB format.

  8. What help do you need?
    Specifications from camera make it clear that FPS of the cam can go as fast as 80fps. I am probably using a slower method to fetch the frames. I want help in figuring out how to increase FPS as my application needs to be real-time. I timed Picamera2.capture_buffer() method and it takes 0.17-0.19 seconds consistently to return a frame. I hope its my way of capturing the frame which is slowing the FPS, there must be some better way to take continuous images. Also, I need to have access to each frame and hence, directly recording video is not beneficial.

Code Snippets:

    def __init__(self, camID):
        """
        Connects to a given arducam at camID and loads default
        configuration
        """
        self.picam = Picamera2(camera_num=camID) # connects to camID indexed cam
        self.ID = camID
        self.config = None

        # Initialize camera
        self.configure()
        self.start()
        self.setFocus()

        # Start reading frames from camera in a new thread
        self.bufferQ = deque()
        self.bufferSize = 15
        self.captureThread = threading.Thread(target=self.buffering)
        self.captureThread.start()

    def configure(self):
        """
        TODO: Loads given configuration for the camera:
        """
        self.picam.still_configuration.main.size=(1920,1080)
        self.picam.still_configuration.main.format="RGB888"
        self.picam.still_configuration.align()
        self.picam.configure("still")

    def buffering(self, checkFPS=False):
        """
        This function will continuously read frames and put it into a buffer queue.
        """
        imageCounter = 0
        startTime = time.time()
        while True:
            if len(self.bufferQ) < self.bufferSize:
                self.bufferQ.append(self.imread())
            else:
                self.bufferQ.popleft()
                self.bufferQ.append(self.imread())

            imageCounter += 1
            
            if checkFPS and imageCounter % 100 == 0:
                endTime = time.time()
                self.realFPS = imageCounter/(endTime-startTime)
                # print(f"[ArduCAM]:[buffering]: Real FPS: {self.realFPS}: {imageCounter}/{endTime-startTime}")
                # Reset
                startTime = time.time()
                imageCounter = 0

    def imread(self):
        """
        Similar to OpenCV's imread. Returns frame. TODO: Overload
        with meta-data yeild
        """
        s = time.time()
        frame = self.picam.capture_array() # Returns a np-array type frame. 
        # print(f"[ArduCAM]:[Capturing Time]: {time.time()-s} seconds")
        return frame

I made the following changes to my config settings method:

    def configure(self, configLocation=None):
        """
        Available Modes: 'SRGGB10_CSI2P' : 1280x720 [80.01 fps - (1048, 1042)/2560x1440 crop]
                        1920x1080 [60.05 fps - (408, 674)/3840x2160 crop]
                        2328x1748 [30.00 fps - (0, 0)/4656x3496 crop]
                        3840x2160 [18.00 fps - (408, 672)/3840x2160 crop]
                        4656x3496 [9.00 fps - (0, 0)/4656x3496 crop]
        """
        self.picam.video_configuration.main.size=(1280,720)#(1920,1080)
        self.picam.video_configuration.main.format="RGB888"
        self.picam.video_configuration.align()
        self.picam.configure("video")
  • I changed the still configuration to video configuration.
  • But only changing that gave me memory errors.
    RuntimeError: Failed to start camera: Cannot allocate memory
  • I then lowered the configuration to 1280x720 and it ran without errors, giving ~32 FPS.

So, now I have two more doubts:

  1. How to use higher resolution with video mode.
  2. How to get the expected FPS(80fps). Is there still any better way to fetch the frames?

My board is Raspberry Pi 2(around 8 years back and mostly unused since then), probably having 512MB ram with a 32gb sd card. Can hardware be the problem as well?

Cross-posted on Raspberry Pi Troubleshoot forum and got the solution:

https://forums.raspberrypi.com/viewtopic.php?p=2140594#p2140594

import time
from picamera2 import Picamera2
picam2 = Picamera2()
main = {'size': (1280, 720)}
raw = {'size': (1280, 720)}
controls = {'FrameRate': 80, 'NoiseReductionMode': 3}
config = picam2.create_video_configuration(main, raw=raw, controls=controls)
picam2.configure(config)
picam2.start()

start = time.monotonic()
count = 0
while time.monotonic() - start < 10:
	picam2.capture_metadata()
	count += 1

print("Received", count, "frames)
1 Like