Skip to content
This repository has been archived by the owner on Apr 18, 2024. It is now read-only.

multithreading with 3 camera #168

Open
adri994 opened this issue Jul 20, 2023 · 4 comments
Open

multithreading with 3 camera #168

adri994 opened this issue Jul 20, 2023 · 4 comments

Comments

@adri994
Copy link

adri994 commented Jul 20, 2023

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.

@Teresa-AlliedVision
Copy link

Teresa-AlliedVision commented Jul 20, 2023

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/

@adri994
Copy link
Author

adri994 commented Jul 20, 2023

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
Copy link
Author

adri994 commented Jul 21, 2023

``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

@Teresa-AlliedVision
Copy link

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.

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

No branches or pull requests

2 participants