VimbaPython icon indicating copy to clipboard operation
VimbaPython copied to clipboard

multithreading with 3 camera

Open adri994 opened this issue 1 year ago • 4 comments

When I connect 3 camera at the time of the code I execute this line of code:

with self.producers_lock: for producer in self.producers.values(): producer.start()

tells me the following: camera with id XXXXX could not be found.

it should be noted that the camera is recognized and saved in the producer without any problem. this error only happens when I connect 3 or more cameras.

adri994 avatar Jul 20 '23 09:07 adri994

Can you stream all 3 cameras with the same settings in Vimba Viewer? If not, then this might be a bandwidth problem. To look into it further yu would need to provide more information about the camera and your setup and code. I would suggest you send a support request through our webform or post you full code here on Github. https://www.alliedvision.com/en/about-us/contact-us/technical-support-repair-/-rma/

Teresa-AlliedVision avatar Jul 20 '23 13:07 Teresa-AlliedVision

Right now seeing me it works but if I put a time.sleep at this point.

with self.producers_lock: for producer in self.producers.values(): producer.start() time.sleep(0.08)

the problem is that the thread system stops working because the frames are generated in a different order. without that it does not allow me to use the with cam

PD: I am using the same code as the example

adri994 avatar Jul 20 '23 14:07 adri994

``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()
    self.lock = threading.Lock

def __call__(self, cam: Camera, stream: Stream, frame: Frame):
    
    logger.info('{} {}'.format(frame, self.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 run(self):
    logger.info('Thread \'FrameProducer({})\' started.'.format(self.cam.get_id()))
    try:
        with self.cam:
            #self.setup_camera()

            try:   
                self.cam.start_streaming(self,buffer_count=5)
                self.killswitch.wait()
            finally:
                self.cam.stop_streaming()
    except VmbCameraError:
        pass

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

    logger.info('Thread \'FrameProducer({})\' terminated.'.format(self.cam.get_id()))

class MainThread(threading.Thread): def init(self,configuration): threading.Thread.init(self)

    self.frame_queue = queue.Queue(maxsize=FRAME_QUEUE_SIZE)
    self.producers = {}
    self.producers_lock = threading.Lock()
    self.configuration = configuration

def __call__(self, cam: Camera, event: CameraEvent):
    if event == CameraEvent.Detected:
        with self.producers_lock:
            self.producers[cam.get_id()] = FrameProducer(cam, self.frame_queue)
            self.producers[cam.get_id()].start()

    elif event == CameraEvent.Missing:
        with self.producers_lock:
            producer = self.producers.pop(cam.get_id())
            producer.stop()
            producer.join()

def run(self):
    global count_cameras_used
    log = Log.get_instance()
    consumer = FrameConsumer(self.frame_queue, self.configuration['processing']['max-num-frame'])

    vmb = VmbSystem.get_instance()
    vmb.enable_log(LOG_CONFIG_INFO_CONSOLE_ONLY)

    log.info('Thread \'MainThread\' started.')

    with vmb:
        
        cams = vmb.get_all_cameras()
            
        logger.info('Creating configuration files')
        for cam in cams:
                try:
                    self.producers[cam.get_id()] = FrameProducer(cam, self.frame_queue)
                    #create_configuration_file(cam,self.configuration['processing']['xml-settings-path'], self.configuration['processing']['max-num-frame'])
                except:
                    logger.critical('Error!! could not configure the cameras')
        
        count_cameras_used = len(self.producers)    
        with self.producers_lock:
            for producer in self.producers.values():
                producer.start()

        # Start and wait for consumer to terminate
        vmb.register_camera_change_handler(self)
        consumer.start()
        consumer.join()
        vmb.unregister_camera_change_handler(self)

        # Stop all FrameProducer threads
        with self.producers_lock:
            # Initiate concurrent shutdown
            for producer in self.producers.values():
                producer.stop()

            # Wait for shutdown to complete
            for producer in self.producers.values():
                producer.join()

        logger.info('Thread \'MainThread\' terminated.')``

fails in the 'with' when there are more than 2 cameras, it does not recognize the cameras

adri994 avatar Jul 21 '23 08:07 adri994

Hi, pleasse check first of all, if all of the cameras can be accessed and stream in Vimba Viewer at the same time. This is to make sure that there is no problem with the setup or installation. Once that is clear, we can have a closer look at the code and specifically the Vimba Python setup.

Teresa-AlliedVision avatar Aug 09 '23 11:08 Teresa-AlliedVision