alliedvision / VimbaPython

Old Allied Vision Vimba Python API. The successor to this API is VmbPy
BSD 2-Clause "Simplified" License
93 stars 40 forks source link

multithreading_opencv.py cannot handle 3 or more camera #161

Open BOX-LEO opened 1 year ago

BOX-LEO commented 1 year ago

I am trying to set up a streaming system using three allied cameras (5k monochrome). I am currently using the multithreading_opencv.py script, but I've encountered an issue where only two threads are working after I disabled the set_nearest_value function in the setup_camera method to avoid cropping the image and ensure that the entire frame is displayed on the screen.while the others are not running. To identify the problem, I added a print(cam.get_id()) statement in the FrameProducer's call function. However, it only prints the IDs of at most two cameras, even though there are three cameras connected to the computer. I noticed that only one CPU core is being utilized, and the memory usage remains around 7%. So I don't think there are band width issue.

I have core i7 9700k and 16gb ram. code are running on ubuntu 18

Could you please assist me in resolving these issues? Here is the code:

class FrameProducer(threading.Thread):
    def __init__(self, cam: Camera, frame_queue: queue.Queue):
        threading.Thread.__init__(self)
        self.log = Log.get_instance()
        self.cam = cam
        self.frame_queue = frame_queue
        self.killswitch = threading.Event()

    def __call__(self, cam: Camera, frame: Frame):
        # This method is executed within VimbaC context. All incoming frames
        # are reused for later frame acquisition. If a frame shall be queued, the
        # frame must be copied and the copy must be sent, otherwise the acquired
        # frame will be overridden as soon as the frame is reused.
        print(cam.get_id())
        if frame.get_status() == FrameStatus.Complete:

            if not self.frame_queue.full():
                frame_cpy = copy.deepcopy(frame)
                try_put_frame(self.frame_queue, cam, frame_cpy)

        cam.queue_frame(frame)

    def stop(self):
        self.killswitch.set()

    def setup_camera(self):
        # set_nearest_value(self.cam, 'Height', FRAME_HEIGHT)
        # set_nearest_value(self.cam, 'Width', FRAME_WIDTH)

        # Try to enable automatic exposure time setting
        try:
            self.cam.ExposureAuto.set('Once')

        except (AttributeError, VimbaFeatureError):
            self.log.info('Camera {}: Failed to set Feature \'ExposureAuto\'.'.format(
                          self.cam.get_id()))

        self.cam.set_pixel_format(PixelFormat.Mono8)

    def run(self):
        self.log.info('Thread \'FrameProducer({})\' started.'.format(self.cam.get_id()))

        try:
            with self.cam:
                self.setup_camera()

                try:
                    self.cam.start_streaming(self)
                    self.killswitch.wait()

                finally:
                    self.cam.stop_streaming()

        except VimbaCameraError:
            pass

        finally:
            try_put_frame(self.frame_queue, self.cam, None)

        self.log.info('Thread \'FrameProducer({})\' terminated.'.format(self.cam.get_id()))
Teresa-AlliedVision commented 1 year ago

What camera model are you using, especially what interface and how are they connected to the PC? Do all cameras stream when opening them in Vimba Viewer?

BOX-LEO commented 1 year ago

all 4 cameras in my hand are 1800 U-500m (USB3, monochrome camera, resolution 2,592 x 1,944). All camera are connected to the pc with USB3 cable. All camera stream in Vimba Viewer.

Teresa-AlliedVision commented 1 year ago

My questions were not worded clear enough: Do they all stream simulatenously in Vimba Viewer? What USB card do you use?

BOX-LEO commented 1 year ago

something interesting happened. all camera can stream simultaneously in Vimba Viewer on Windows10 but not working on Ubuntu18. I will try to run my code on windows10 to see if it works.

here are usb hubs: Bus 002 Device 005: ID 1ab2:0001
Bus 002 Device 004: ID 1ab2:0001
Bus 002 Device 003: ID 1ab2:0001
Bus 002 Device 002: ID 1ab2:0001
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 004: ID 046d:0ab7 Logitech, Inc. Bus 001 Device 003: ID 04b4:0823 Cypress Semiconductor Corp. Bus 001 Device 005: ID 8087:0aaa Intel Corp. Bus 001 Device 002: ID 046d:c08b Logitech, Inc. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Teresa-AlliedVision commented 1 year ago

For Linux based systems we recommend setting a larger USBFS Buffer. Check the buffer size with this: cat /sys/module/usbcore/parameters/usbfs_memory_mb Either change it temporarily with sudo sh -c 'echo 1024 > /sys/module/usbcore/parameters/usbfs_memory_mb' or permanently with either of these: GRUB 2

  1. Open /etc/default/grub
  2. Replace: GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" (or other contents within the quotation marks depending on your system) with: GRUB_CMDLINE_LINUX_DEFAULT="quiet splash usbcore.usbfs_memory_mb=1024"
  3. Update grub: sudo update-grub
  4. Reboot the system.

Syslinux

  1. Open /boot/extlinux/extlinux.conf
  2. Add usbcore.usbfs_memory_mb=1024 to the APPEND line
  3. Reboot the system.