Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fps low #123

Open
skywo1f opened this issue Mar 27, 2020 · 11 comments
Open

fps low #123

skywo1f opened this issue Mar 27, 2020 · 11 comments

Comments

@skywo1f
Copy link

skywo1f commented Mar 27, 2020

When I am testing the camera (1800U500c) using the vimba viewer, I get 100+ fps for full resolution. When I test the same camera using pymba, I only get ~10 fps. I know it is not an exposure time issue as I have varied that from 40 to 40k with minimal effect on the fps. What does help with the fps is asking the camera for less pixels (e.g. 1200x1200 is returned at 30fps). Any idea how to speed up the fps?

@skywo1f
Copy link
Author

skywo1f commented Mar 27, 2020

`from time import sleep
from pymba import Vimba
from _display_frame import display_frame
import time
import cv2

import threading

def camCapture(camera):
try:
camera.arm('SingleFrame')
while (True):
start_time = time.time() # start time of the loop
frame = camera.acquire_frame()
image = frame.buffer_data_numpy()

        cv2.imshow('ImageWindow', image)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        print("FPS: ", 1.0 / (time.time() - start_time))

except: 
    camera.disarm()
    camera.close()

if name == 'main':

with Vimba() as vimba:
    camera = vimba.camera(0)
    camera.open()
    featureAM = camera.feature('DeviceLinkThroughputLimitMode')
    value = featureAM.value
    featureAM.value = 'Off'

    feature = camera.feature('PixelFormat')
    value = feature.value
    feature.value = 'BGR8'

    featureH = camera.feature('Height')
    value = featureH.value
    featureH.value = 1944                           #default 1944   small 1146

    featureW = camera.feature('Width')
    value = featureW.value
    featureW.value = 2592                           #default 2592   small 2200


    featureGA = camera.feature('GainAuto')
    value = featureGA.value
    featureGA.value = 'Continuous'

    featureBWA = camera.feature('BalanceWhiteAuto')
    value = featureBWA.value
    featureBWA.value = 'Once'

    featureET = camera.feature('ExposureTime')
    value = featureET.value
    featureET.value = 4000                                           #default 4000

    capture_thread = threading.Thread(target=camCapture,args=(camera,))
    capture_thread.daemon = True
    capture_thread.start()


    try:
        while(True):
            time.sleep(4)
    except:
        camera.disarm()
        camera.close()`

@jakove
Copy link

jakove commented Mar 30, 2020

I think the problem is in camCapture.
The camera is armed in "SingleFrame"-mode. SingleFrame is only for shooting one frame.
If you want to reach high fps-rates you have to use "Continous" with a proper callback function.
In the examples is shown how to use the callback function.
I achieve in full resolution 395 fps with my usb camera, which is the frame-rate limit of the camera. For me it is possible to achive round about 1100 fps.

@skywo1f
Copy link
Author

skywo1f commented Apr 1, 2020

would you mind posting your code?
I tried using continuous frames, but 1, it was hard getting them into an object which opencv could interact with, and 2, even the continuous frames example was working a little janky(20 fps, only showing the top fifth of the image) for me on my xavier.

@jakove
Copy link

jakove commented Apr 1, 2020

Im am working with a nvidia jetson xavier too. So the hardware should be no problem.
At first you should follow the instructions from allied vision. There ist a document for jetson:
https://cdn.alliedvision.com/fileadmin/content/documents/products/software/software/embedded/Optimizing-Performance-Jetson_appnote.pdf

Forfirst steps try to use the examples:
callback function: https://github.com/morefigs/pymba/blob/master/examples/camera/_display_frame.py

streaming images: https://github.com/morefigs/pymba/blob/master/examples/camera/opencv_acquire_streaming_images.py

The callback function should be fast enough for 100+ fps. At first you should try to implement it by yourself.

To fix the highest framerate:

camera.feature("ExposureTime").value = 200
#is needed for editing framerate
camera.feature("AcquisitionFrameRateMode").value = 'Basic'
#get the max fps with settings (depends on image size and on exposure time)
max_fps = camera.feature("AcquisitionFrameRate").range[-1]
camera.feature("AcquisitionFrameRate").value = max_fps

My code ist to complex for posting it here. Cause i copy the images to gpu and run a cnn.
But i try to help if there are further questions.

@skywo1f
Copy link
Author

skywo1f commented Apr 9, 2020

I tried your suggestion but I am getting
`Traceback (most recent call last):
File "fast_color_video.py", line 55, in
featureAFR.value = max_fps
File "/usr/local/lib/python3.6/dist-packages/pymba/feature.py", line 40, in value
self._access_func('set', self.info.featureDataType)(value)
File "/usr/local/lib/python3.6/dist-packages/pymba/feature.py", line 142, in _set_float
raise VimbaException(error)
pymba.vimba_exception.VimbaException: Operation is invalid with the current access mode.

`
when I try to change those camera values

But even if I did have access, it wouldn't matter as those values are already at "basic" and max_fps by default (I printed them out).

Increasing the exposure time makes the fps go down, but lowering the exposure time didnt help much with the fps in my case.

@skywo1f
Copy link
Author

skywo1f commented Apr 9, 2020

in my implementation of _display_frame, I am only getting 15 fps:
`
from pymba import Vimba, VimbaException
from _display_frame_fast import display_frame
import time

if name == 'main':

with Vimba() as vimba:
    camera = vimba.camera(0)
    camera.open()

    camera.arm('SingleFrame')

    # capture a single frame, more than once if desired
    for i in range(100):
        start_time = time.time() # start time of the loop
        try:
            frame = camera.acquire_frame()
            display_frame(frame, 0)
            print("FPS: ", 1.0 / (time.time() - start_time))
            
        except VimbaException as e:
            # rearm camera upon frame timeout
            if e.error_code == VimbaException.ERR_TIMEOUT:
                print(e)
                camera.disarm()
                camera.arm('SingleFrame')
                
            else:
                raise

    camera.disarm()

    camera.close()

`

@jakove
Copy link

jakove commented Apr 10, 2020

Are you able to change the values with the VimbaViewer?

you are still using: camera.arm('SingleFrame')
To achive high framerates it is necessary to use the 'Continuous' mode.

The following example shows how to stream images:
https://github.com/morefigs/pymba/blob/master/examples/camera/opencv_acquire_streaming_images.py

@skywo1f
Copy link
Author

skywo1f commented Apr 10, 2020

The problem with the Continuous mode example is that it doesn't include a line like
frame = camera.acquire_frame()
so that I can load the frame and send it out for processing

I can somewhat change the values with the vimba viewer, though at the moment it is just giving me one frame at a time (whenever I press play).

@jakove
Copy link

jakove commented Apr 17, 2020

In https://github.com/morefigs/pymba/blob/master/examples/camera/_display_frame.py
line 21:
image = frame.buffer_data_numpy()

This is the line you need for processing.
Then there are several ways to continue. If your algorthm is fast you can handle all in the callback function. But you can also use Queues or sth. similar to process your image in another thread or send it direct to gpu with PyCUDA.

So you are not able to view a live stream in VimbaViewer?

@skywo1f
Copy link
Author

skywo1f commented Apr 21, 2020

I tried grabbing the frame using the method you suggested, then sending it over to another thread via Queue, but I am not getting anything on the other side:
'
from time import sleep
from pymba import Vimba
from _display_frame import display_frame
import time
import cv2
from queue import Queue
import threading

def camCapture(camera,imageHolder):
try:
camera.arm('Continuous',display_frame)
camera.start_frame_acquisition()
while (True):
start_time = time.time() # start time of the loop
imageHolder.put(frame.buffer_data_numpy())

except: 
    camera.stop_frame_acquisition()
    camera.disarm()
    camera.close()

def camShow(imageHolder):
time.sleep(1) #wait for camera to start up
while True:
image = imageHolder.get()
cv2.imshow('ImageWindow', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
print("FPS: ", 1.0 / (time.time() - start_time))

if name == 'main':

with Vimba() as vimba:
    camera = vimba.camera(0)
    camera.open()
    featureAM = camera.feature('DeviceLinkThroughputLimitMode')
    value = featureAM.value
    featureAM.value = 'Off'

    feature = camera.feature('PixelFormat')
    value = feature.value
    feature.value = 'BGR8'

    featureH = camera.feature('Height')
    value = featureH.value
    featureH.value = 1944                           #default 1944   small 1146

    featureW = camera.feature('Width')
    value = featureW.value
    featureW.value = 2592                           #default 2592   small 2200


    featureGA = camera.feature('GainAuto')
    value = featureGA.value
    featureGA.value = 'Continuous'

    featureBWA = camera.feature('BalanceWhiteAuto')
    value = featureBWA.value
    featureBWA.value = 'Once'

    featureET = camera.feature('ExposureTime')
    value = featureET.value
    featureET.value = 4000                                           #default 4000

    imageHolder = Queue()

    capture_thread = threading.Thread(target=camCapture,args=(camera,imageHolder))
    capture_thread.daemon = True
    capture_thread.start()

    show_thread = threading.Thread(target=camShow,args=(imageHolder, ))
    show_thread.daemon = True
    show_thread.start()

    try:
        while(True):
            time.sleep(4)
    except:
        camera.stop_frame_acquisition()
        camera.disarm()
        camera.close()

'

@mvalvaa
Copy link

mvalvaa commented Sep 21, 2020

Did you resolve this problem? I am using an Alvium 1800U and have the same problem.

My camera have 29 max fps but in Vimba Viewer and using python acquire image example I only get 5fps.
In Vimba viewer if I change from SingleFrame to Continuous, fps maintain equal (5fps). In python if I use Continous mode I get the same error as @skywo1f, VimbaException: Operation is invalid with the current access mode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants