aravis icon indicating copy to clipboard operation
aravis copied to clipboard

Using multiple cameras at the same time (python)

Open javi-desp opened this issue 2 years ago • 2 comments

Describe the bug

I'm using Aravis with python, and I'm facing problems while receiving data from 2 cameras at the same time. At first I get more or less 3/4 frame rate and i receive the images with an offset of 2s.

however when i try the arv-viewer I don't have this issue... Any idea?

To Reproduce

my python code:

class Camera():
  def __init__(self):
      self.rds = redis.Redis(host='localhost', port=6379, db=20)
      Aravis.update_device_list()
      n_devices = Aravis.get_n_devices()

      self.camera = Aravis.Camera.new (Aravis.get_device_id(1))
      self.camera.set_region (0,0,1440,980)
      #self.camera.set_frame_rate (200.0)
      self.camera.set_exposure_time_auto(0) #SET MANUAL
      self.camera.set_gain_auto(1) #SET AUTO
      self.camera.set_exposure_time(3105)
      self.camera.uv_set_usb_mode(Aravis.UvUsbMode(0))
      self.camera.set_pixel_format (Aravis.PIXEL_FORMAT_RGB_8_PACKED)
      Aravis.make_thread_high_priority(1)

      self.shutted_down = False
      self.payload = self.camera.get_payload ()
      self.x, self.y, self.width, self.height = self.camera.get_region ()
      print("!")
      self.create_stream_camera()

  def create_stream_camera(self):
      self.stream = self.camera.create_stream (None, None)
      #PREPARE 10 BUFFERS WITH A IMAGE PAYLOAD SIZE
      for i in range(0,10):
          self.stream.push_buffer (Aravis.Buffer.new_allocate (self.payload))
      self.camera.start_acquisition ()

  def get_images(self):
      self.frames = 0
      self.start_time = time.time()
      while True:
          time.sleep(0.0015)
          image = self.stream.try_pop_buffer()
          if image != None:
              self.stream.push_buffer(image)
              self.data_from_buffer = image.get_data()
              #########################################
              self.frames+=1
              if time.time() - self.start_time > 1:
                  print(" FPS = ", self.frames)
                  self.frames = 0
                  self.start_time = time.time()
              #########################################
          
  def run(self):
      self.frames = 0
      self.start_time = time.time()
      self.data_from_buffer = None
      threading.Thread(target=self.get_images, daemon = True).start()
      while True:
          time.sleep(0.001)
          if self.data_from_buffer != None:
              try:
                      if Aravis.PIXEL_FORMAT_MONO_8 == self.camera.get_pixel_format():
                          img_data_greyscale = np.ndarray(buffer=self.data_from_buffer, dtype=np.uint8, shape=(self.camera.get_region()[3], self.camera.get_region()[2], 1))
                          three_channel_gray_img= cv2.cvtColor(img_data_greyscale, cv2.COLOR_GRAY2BGR)
                      elif Aravis.PIXEL_FORMAT_MONO_16 == self.camera.get_pixel_format():
                          img_data_greyscale = np.ndarray(buffer=self.data_from_buffer, dtype=np.uint16, shape=(self.camera.get_region()[3], self.camera.get_region()[2], 1))
                          three_channel_gray_img= cv2.cvtColor(img_data_greyscale, cv2.COLOR_GRAY2BGR)
                      elif Aravis.PIXEL_FORMAT_RGB_8_PACKED == self.camera.get_pixel_format():
                          decoded = np.frombuffer(self.data_from_buffer, dtype=np.uint8)
                          img_data_rgb = decoded.reshape((self.camera.get_region()[3], self.camera.get_region()[2],3))
                          img_data= cv2.cvtColor(img_data_rgb, cv2.COLOR_BGR2RGB)
                          img_data_gray= cv2.cvtColor(img_data, cv2.COLOR_RGB2GRAY)
                          three_channel_gray_img = np.stack((img_data_gray,)*3, axis=-1)
                      else:
                          print("SEND ERROR --> ")
                          exit()
                      cv2.imshow("capture ", img_data)
                      cv2.waitKey(1)
              except KeyboardInterrupt as e:
                  print("LOL")
                  print(e)
                  print("SEND ALARM")
                  self.camera.stop_acquisition ()
                  exit()
          else:
              pass


  if __name__ == '__main__':
      camera_controller = Camera()
      camera_controller.run()

javi-desp avatar Jan 18 '23 11:01 javi-desp

Hi @javi-desp , it would help if you could modify your example and make it runnable without modification.

When you say you are acquiring multiple cameras simultaneously, is it from the same program, or several instances ?

EmmanuelP avatar May 19 '23 05:05 EmmanuelP

Hey, The problem was with my computer, it turns out that when using the USB ports from the same hub, apart from reducing the number of received frames per second (fps), there was a delay of about 1 second in sending images, which made it impossible to control the images in real time. In the end, I fixed it by inserting a separate USB3 module.

I don't know if this is normal...

javi-desp avatar Jun 16 '23 10:06 javi-desp