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

Three Basler acA4024-29uc cannot capture more than 3 FPS same time #5

Open
tannguyen1110 opened this issue Nov 24, 2023 · 1 comment

Comments

@tannguyen1110
Copy link

Hello,
I have three Basler acA4024-29uc (all 3 connect to 1 usb hub and then to a laptop) and I want them capture image at least 5 FPS at the same time. But the fastest FPS I can reach is 2,5 (time to retrieved each image is 0.4 sec). If I change FPS more than 3 the result time to retrieved each image cannot lower 0.37 sec.
If I run with only 1 camera, time to retrieved is around 0.05 sec.
Please help, this is my code:
Thank you.

##============================================
from pypylon import pylon
import numpy as np

import traceback

import time
import random

def BackGroundLoopSample():
print("hello multicam_cont")

maxCamerasToUse = 3

img = pylon.PylonImage()

ipo = pylon.ImagePersistenceOptions()
quality = 100
ipo.SetQuality(quality)

# Get the transport layer factory.
tlFactory = pylon.TlFactory.GetInstance()

# Get all attached devices and exit application if no device is found.
devices = tlFactory.EnumerateDevices()
if len(devices) == 0:
    raise pylon.RuntimeException("No camera present.")

# Create an array of instant cameras for the found devices and avoid exceeding a maximum number of devices.
cameras = pylon.InstantCameraArray(min(len(devices), maxCamerasToUse))

l = cameras.GetSize()

# Create and attach all Pylon Devices.
for i, cam_z in enumerate(cameras):
    cam_z.Attach(tlFactory.CreateDevice(devices[i]))

    # Print the model name of the camera.
    print("Using device ", cam_z.GetDeviceInfo().GetModelName(), cam_z.GetDeviceInfo().GetSerialNumber())

for i in range(l):
    cameras[i].Open()
    cameras[i].PixelFormat = "RGB8"
    cameras[i].ExposureTime = 1000

    cameras[i].AcquisitionFrameRateEnable = True
    cameras[i].AcquisitionFrameRate = 2.5


class ImageHandler(pylon.ImageEventHandler):

    
    def __init__(self, cam: pylon.InstantCameraArray):
        # count img
        self.count_z = 0
        # Take a "snapshot" of the camera's current timestamp value
        cam.TimestampLatch.Execute()
        # Get the timestamp value
        self.t0= cam.TimestampLatchValue.GetValue()
        self.tn= cam.TimestampLatchValue.GetValue()
        super().__init__()
        self.img_sum = np.zeros((cam.Height.Value, cam.Width.Value), dtype=np.uint16)
        
    def OnImageGrabbed(self, camera, grabResult):
        """ we get called on every image
            !! this code is run in a pylon thread context
            always wrap your code in the try .. except to capture
            errors inside the grabbing as this can't be properly reported from 
            the background thread to the foreground python code
        """
        try:
            if grabResult.GrabSucceeded():
                # check image contents
                img = grabResult.Array
                #self.img_sum += img
                self.count_z = self.count_z + 1
                # Take a "snapshot" of the camera's current timestamp value
                camera.TimestampLatch.Execute()
                # Get the timestamp value
                self.tn= camera.TimestampLatchValue.GetValue()
                print("success ", self.count_z, "time ", self.tn - self.t0)
                self.t0 = self.tn
            else:
                raise RuntimeError("Grab Failed")
        except Exception as e:
            traceback.print_exc()

# instantiate callback handler
handler0 = ImageHandler(cameras[0])
handler1 = ImageHandler(cameras[1])
handler2 = ImageHandler(cameras[2])
# register with the pylon loop
cameras[0].RegisterImageEventHandler( handler0 , pylon.RegistrationMode_ReplaceAll, pylon.Cleanup_None)
cameras[1].RegisterImageEventHandler( handler1 , pylon.RegistrationMode_ReplaceAll, pylon.Cleanup_None)
cameras[2].RegisterImageEventHandler( handler2 , pylon.RegistrationMode_ReplaceAll, pylon.Cleanup_None)

# fetch some images with background loop
cameras[0].StartGrabbingMax( 10, pylon.GrabStrategy_LatestImages, pylon.GrabLoop_ProvidedByInstantCamera)
cameras[1].StartGrabbingMax( 10, pylon.GrabStrategy_LatestImages, pylon.GrabLoop_ProvidedByInstantCamera)
cameras[2].StartGrabbingMax( 10, pylon.GrabStrategy_LatestImages, pylon.GrabLoop_ProvidedByInstantCamera)
# cameras[0].StartGrabbing(pylon.GrabStrategy_LatestImages, pylon.GrabLoop_ProvidedByInstantCamera)
# cameras[1].StartGrabbing(pylon.GrabStrategy_LatestImages, pylon.GrabLoop_ProvidedByInstantCamera)
# cameras[2].StartGrabbing(pylon.GrabStrategy_LatestImages, pylon.GrabLoop_ProvidedByInstantCamera)


while cameras[0].IsGrabbing() or cameras[1].IsGrabbing() or cameras[2].IsGrabbing():
    continue    
    # random exposuretime changes every 100ms
    # cam.ExposureTime = random.uniform(cam.ExposureTime.Min, 1000)
    # time.sleep(0.001)

cameras[0].StopGrabbing()
cameras[0].DeregisterImageEventHandler(handler0)
cameras[1].StopGrabbing()
cameras[1].DeregisterImageEventHandler(handler1)
cameras[2].StopGrabbing()
cameras[2].DeregisterImageEventHandler(handler2)


return handler0.img_sum

#background_average = _.average / 100

if name == 'main':
BackGroundLoopSample()

@thiesmoeller
Copy link
Collaborator

Some comments:

Limit the amount of work in the OnImageGrabbed handler as much as possible
* Communicating with the camera for every frame to get the current timestamp takes time
- if you wanted to get the image timestamp it is simply grabResult.TimeStamp
* Printing to console is very slow

You share the bandwidth of all three cameras over one USB host controller. You'll see stronger jitter in when you receive the frame, compared to like having three direct ports to the host.

Have you tested your exact setup in pylonviewer or in the bandwidthmanager( -> from tools menu ) that all three camera work in the pylonviewer?

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

2 participants