aravis icon indicating copy to clipboard operation
aravis copied to clipboard

Crash with DFK 33UX273 Camera at 200 FPS and 1000 Exposure, Works Fine with Basler QCAM-UC1440-220CE

Open bulverismo opened this issue 1 year ago • 7 comments

Hi!

Describe the bug When I use a camera The Imaging Source DFK 33UX273 with 200 fps and exposure 1000 my application crashes, but when I use a Basler QCAM-UC1440-220CE camera it doesn't crash

To Reproduce I set the camera to 1000 us of exposure and set the fps to 200

Expected behavior I hope to get the images for later processing with any camera

Camera description: CAMERA THAT OCCURS THE BUG

  • Manufacturer The Imaging Source
  • Model DFK 33UX273
  • Interface USB3

CAMERA THAT DOESN'T OCCUR THE BUG

  • Manufacturer Basler
  • Model DFK QCAM-UC1440-220CE
  • Interface USB3

Platform description:

  • Aravis version 0.8.31
  • OS: Debian GNU/Linux 12 (bookworm)
  • Hardware Intel Atom(R) x6413E Processor @ 1.50GHz - 8G Memory

Additional context

capture loop `
  def __non_triggered_capture(self):
      with self.lock_var_to_update:
          for i in range(1, 10):
              buffer = self._stream.timeout_pop_buffer(10000 * 1000)

              if buffer:
                  if not (buffer.get_status().value_name == 'ARV_BUFFER_STATUS_SUCCESS'):
                      continue
                  logging.info(self._stream.get_statistics())
                  img = self._converter(buffer)
                  timestamp = buffer.get_timestamp()
                  self._stream.push_buffer(buffer) 
                  self.frame_id = (self.frame_id + 1) % (sys.maxsize - 1)
                  if img is None:
                      raise CameraError("Camera capture failed")
                  return img, self.frame_id, timestamp / 1000000

          logging.warning(f"Failed capturing from camera {self.camera_id}, model {self.dev}. Retrying {10 - i} times")
          raise CameraError("Camera capture failed")

`

Log the imaging source Logs basler

bulverismo avatar Jul 24 '24 13:07 bulverismo

                  img = self._converter(buffer)
                  if img is None:
                      raise CameraError("Camera capture failed")

Capture failed is raised when the call to converter() return a None. I don't know what converter() is supposed to do.

EmmanuelP avatar Aug 12 '24 15:08 EmmanuelP

It is a function to convert img in raw format to numpy array

def _converter(self, buf):
        if not buf:
            return None
        pixel_format = buf.get_image_pixel_format()
        bits_per_pixel = pixel_format >> 16 & 0xff
        # Determine the appropriate ctypes data type based on bits per pixel
        if bits_per_pixel == 8:
            INTP = ctypes.POINTER(ctypes.c_uint8)
            bytes_per_pixel = 1
        elif bits_per_pixel == 16:
            INTP = ctypes.POINTER(ctypes.c_uint16)
            bytes_per_pixel = 2
        elif bits_per_pixel == 24:
            INTP = ctypes.POINTER(ctypes.c_uint8)
            bytes_per_pixel = 3
        elif bits_per_pixel == 32:
            INTP = ctypes.POINTER(ctypes.c_uint8)
            bytes_per_pixel = 4
        else:
            raise ValueError(f"Unsupported bits per pixel: {bits_per_pixel}")


        addr = buf.get_data()
        ptr = ctypes.cast(addr, INTP)

        height = buf.get_image_height()
        width = buf.get_image_width()

        # Determine the number of channels based on bytes per pixel
        if bytes_per_pixel == 1:
            im = np.ctypeslib.as_array(ptr, (height, width))
        else:
            im = np.ctypeslib.as_array(ptr, (height, width, bytes_per_pixel))

        # Copy the image to ensure it is not a view into the original buffer
        im = im.copy()

        return im

bulverismo avatar Aug 14 '24 14:08 bulverismo

Thanks.

At some point in the log, the payload size returned in the image trailer packet changes from 4665600 to 187396. Do you change some features between 2 call to __non_triggered_capture ?

EmmanuelP avatar Aug 14 '24 14:08 EmmanuelP

Yes, after initializing the camera the application starts capturing(using __non_triggered_capture) and then during the capture the application configure some features, such as exposure, gain and gamma, for example.

bulverismo avatar Aug 14 '24 15:08 bulverismo

exposure, gain and gamma

Is this an exhaustive list ? Any feature that may modify the payload size ?

EmmanuelP avatar Aug 14 '24 15:08 EmmanuelP

Full list: frame rate region exposure time exposure auto gain gamma balance ration balance white auto trigger activation trigger delay trigger

I think the only part that can change the payload size is the part where I configure the image size(which I called region in the list above).

set window size method

        # makes the x's and y's a multiple of 4
        x0 -= x0 % 4
        x1 -= x1 % 4
        y0 -= y0 % 4
        y1 -= y1 % 4

        self.cam.stop_acquisition()
        self.cam.set_region(
            x0,  # offset x
            y0,  # offset y
            max(x1 - x0, 16),  # 16*8 pixel minimal image
            max(y1 - y0, 8),
        )

        self.create_buffer()
        self.cam.start_acquisition()

create buffer method

def create_buffer(self):

    if hasattr(self, '_stream'):
        del self._stream

    self._stream = self.cam.create_stream(None, None)
    payload = self.cam.get_payload()
    for _ in range(0, 10):
        self._stream.push_buffer(Aravis.Buffer.new_allocate(payload))

bulverismo avatar Aug 14 '24 16:08 bulverismo

You should also stop the acquisition thread when you want to set the region, otherwise there will still be buffer with the wrong size in the queues. Please have a look at tests/arvroitest.c, switch_roi() function.

EmmanuelP avatar Aug 14 '24 17:08 EmmanuelP