Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
bulverismo opened this issue Jul 24, 2024 · 7 comments
Labels
2. Needs informations Needs additional informations

Comments

@bulverismo
Copy link

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

@EmmanuelP
Copy link
Contributor

                  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 EmmanuelP added the 2. Needs informations Needs additional informations label Aug 12, 2024
@bulverismo
Copy link
Author

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

@EmmanuelP
Copy link
Contributor

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 ?

@bulverismo
Copy link
Author

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.

@EmmanuelP
Copy link
Contributor

exposure, gain and gamma

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

@bulverismo
Copy link
Author

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

@EmmanuelP
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2. Needs informations Needs additional informations
Projects
None yet
Development

No branches or pull requests

2 participants