Increase Frames Per Second (FPS) of live stream using Allied Vision Camera that uses Vimba SDK for Python

725 views Asked by At

To begin with, I am given Allied Vision Camera and with the help of Vimba SDK Python, I am streaming. FPS for streaming is around 12-14, whereas the maximum FPS offered by Manta G-201C is 30. How to reach to maximum FPS?

First of all, with the help of Vimba Viewer App, I am setting the necessary parameters like exposure time, white balance, gain etc. and the save the xml file. Now, with the help of xml file, I feed the necessary values to Vimba-Python as base settings. The following snippet of the code is shown below:

import cv2
import time
from vimba import *
import os
from datetime import datetime

is_running = True
i = 1
count = 0
path = 'C:\\Vimba\\dataset\\'

def do_something(img):
    lst = []
    global count
    count += 1
    filename = 'IMG_' + str(count) + '.jpg'
    cv2.putText(img, str(datetime.now()), (20, 40), cv2.FONT_HERSHEY_PLAIN, 2, (255, 255, 255), 2, cv2.LINE_AA)
    cv2.imwrite(filename, img)
    lst.append(img)
    return len(lst)


with Vimba.get_instance() as vimba:
    with vimba.get_all_cameras()[0] as cam:
        os.chdir(path)
        cam.set_pixel_format(PixelFormat.BayerRG8)
        cam.ExposureTimeAbs.set(30000.000000)
        cam.BalanceWhiteAuto.set('Off')
        cam.Gain.set(0)
        cam.AcquisitionMode.set('Continuous')
        cam.GainAuto.set('Off')
        cam.Height.set(720)
        cam.Width.set(1280)
        while is_running:
            start = time.time()
            frame = cam.get_frame()
            frame = frame.as_numpy_ndarray()
            frame = cv2.cvtColor(frame, cv2.COLOR_BAYER_RG2RGB)
            cv2.imshow('Live feed', frame)
            result = do_something(frame)
            end = time.time()
            seconds = end - start
            fps = int(result/seconds)
            print('FPS:', fps)
            # print(cam.AcquisitionFrameRateAbs.get())
            key = cv2.waitKey(1)
            if key == ord('q'):
                break
        cv2.destroyAllWindows()

As seen from the above code, I am reading all the values for camera settings (from xml file) and then created a function 'do_something(img)' that will save the images at the desired path and returns a value for total number of images stored in a list. That value is used to check for FPS. The following FPS I am getting after running the whole code:

FPS: 8
FPS: 13
FPS: 13
FPS: 14
FPS: 13
FPS: 13
FPS: 13
FPS: 12
FPS: 13
FPS: 13
FPS: 12
FPS: 14
FPS: 14
FPS: 13
FPS: 14
FPS: 14
FPS: 14
FPS: 14
FPS: 14

Whereas with the help of cam.AcquisitionFrameRateAbs.get(), it is showing me FPS of 30.00030000300003. I have tried couple of things from the internet, but nothing worked for me. I want to reach to 30 FPS from 14 and don't know how to do it. Any help is appreciated!

By the way, I am using ASUS F570Z laptop that has a graphic card NVIDIA GeForce GTX 1050 (4 GB), processor - AMD Ryzen 5 Quad Core 2500U, RAM - 8 GB DDR4 and Windows 10 64-bit.

1

There are 1 answers

2
T F On

As stated in the comments you need asynchronous acquisition: If you want to use multithreading and the frame handling mechanism of numpy array to opencv format for the frame, then you can modify line 62 in multithreading_opencv.py cv_frame = frame.as_opencv_image() and replace it with your frame handling. You can of course do the same with the other python scripts as well and disable the check for pixel format. In asynchronous_grab_opencv.py for example by replacing the whole code block 117-132 with just setting the pixel format.

You can also first get the frame, use Vimba image transform to change to BGR8 pixel format and then use as opencv frame:

frame.convert_pixel_format(PixelFormat.Bgr8)

opencv_frame = frame.as_opencv_image()

Both pixel format solutions are essentially doing the same. I'm not sure which would be faster, but just using asynchronous acquisition will already lead to higher FPS.