genicam / harvesters

Image Acquisition Library for GenICam-based Machine Vision System
Apache License 2.0
513 stars 88 forks source link

Freezing when trying to fetch a frame #348

Open bth5 opened 2 years ago

bth5 commented 2 years ago

Describe the Bug I try to acquire a frame using the example from: https://github.com/genicam/harvesters#harvester-on-ipython, using my own .cti file. This seems to work well until i try to acquire a frame, where i don't get a response. The excecution hangs indefenetely.

To Reproduce Steps to reproduce the behavior:

  1. Use Anaconda
  2. create env python 3.8.13
  3. install CMD.exe Prompt
  4. install jupyter lab
  5. pip install Harvesters (version: 1.3.8)
  6. Open jupyter notebook
  7. Copy code from: https://github.com/genicam/harvesters#harvester-on-ipython
  8. update cti path

Sample Code I can show a piece of code that demonstrates the reported phenomenon:

If yes, please provide a sample code:

NOTE: The error is printed when i interrupt the kernel.


from harvesters.core import Harvester
import numpy as np 

h = Harvester()

h.add_file('C:\Program Files\Allied Vision\Vimba_6.0\VimbaGigETL\Bin\Win64\VimbaGigETL.cti')

print(h.files)

['C:\\Program Files\\Allied Vision\\Vimba_6.0\\VimbaGigETL\\Bin\\Win64\\VimbaGigETL.cti']

h.update()

len(h.device_info_list)

1

h.device_info_list[0]

{'access_status': 1000, 'display_name': 'Mako', 'id_': 'DEV_000F315D00FF', 'model': 'Mako G-234C (6409)', 'parent': <genicam.gentl.Interface; proxy of <Swig Object of type 'std::shared_ptr< GenTLCpp::TLInterface > *' at 0x00000267E58210C0> >, 'serial_number': '50-0536966271', 'tl_type': 'GEV', 'user_defined_name': None, 'vendor': 'Allied Vision Technologies', 'version': None}

ia = h.create(0)

ia.remote_device.node_map.Width.value = 8

ia.remote_device.node_map.Height.value = 8

ia.remote_device.node_map.PixelFormat.value = 'Mono8'

ia.start()

with ia.fetch() as buffer:
    component = buffer.payload.components[0]
    _1d = component.data
    print('1D: {0}'.format(_1d))
    _2d = component.data.reshape(
        component.height, component.width
    )
    print('2D: {0}'.format(_2d))
    print(
        'AVE: {0}, MIN: {1}, MAX: {2}'.format(
            np.average(_2d), _2d.min(), _2d.max()
        )
    )

---------------------------------------------------------------------------
TimeoutException                          Traceback (most recent call last)
File ~\Documents\Anaconda\envs\Genicam_test\lib\site-packages\harvesters\core.py:2266, in ImageAcquirer._fetch(self, manager, timeout_on_client_fetch_call, throw_except)
   2265 try:
-> 2266     manager.update_event_data(self.timeout_period_on_update_event_data_call)
   2267 except TimeoutException:

File ~\Documents\Anaconda\envs\Genicam_test\lib\site-packages\genicam\gentl.py:1458, in EventManagerNewBuffer.update_event_data(self, timeout)
   1447 """
   1448 
   1449 Updates its event data. Having called this method, its event data that is provided through its properties are overwritten with the latest one.
   (...)
   1456 
   1457 """
-> 1458 return _gentl.EventManagerNewBuffer_update_event_data(self, timeout)

TimeoutException: GenTL exception: Operation timed out before completion. (Message from the source: An operation's timeout time expired) (ID: -1011)

During handling of the above exception, another exception occurred:

KeyboardInterrupt                         Traceback (most recent call last)
Input In [15], in <cell line: 1>()
----> 1 with ia.fetch() as buffer:
      2     component = buffer.payload.components[0]
      3     _1d = component.data

File ~\Documents\Anaconda\envs\Genicam_test\lib\site-packages\harvesters\core.py:2384, in ImageAcquirer.fetch(self, timeout, is_raw, cycle_s)
   2382             time.sleep(cycle_s if cycle_s else 0.0001)
   2383     else:
-> 2384         raw_buffer = self._fetch(
   2385             manager=self._event_new_buffer_managers[0],
   2386             timeout_on_client_fetch_call=timeout, throw_except=True)
   2387         buffer = self._finalize_fetching_process(raw_buffer, is_raw)
   2389 return buffer

File ~\Documents\Anaconda\envs\Genicam_test\lib\site-packages\harvesters\core.py:2267, in ImageAcquirer._fetch(self, manager, timeout_on_client_fetch_call, throw_except)
   2265 try:
   2266     manager.update_event_data(self.timeout_period_on_update_event_data_call)
-> 2267 except TimeoutException:
   2268     continue
   2269 except GenTL_GenericException as e:

KeyboardInterrupt: 

Expected Behavior Acquisition of image as in example: https://github.com/genicam/harvesters#harvester-on-ipython

Configuration

Reproducibility

This phenomenon can be stably reproduced:

If applicable, please provide your observation about the reproducibility.

Actions You Have Taken

kazunarikudo commented 2 years ago

Hi, thank you for the report.

If the time out is expected by design in your application, I would recommend calling either the fetch method or the try_fech method so that the program does not hang at the fetch call:

  1. ImageAcquirer.fetch(timeout=some_timeout_value), or
  2. ImageAcquirer.try_fetch(timeout=some_timeout_value).

On the 1st option, you will get the genicam.gentl.TimeoutException once it's timed out. On the 2nd option, you will get the None object. Note that calling ImageAcquirer.fetch() without a time-out value means the function call waits until a buffer is filled up with an image.

bth5 commented 2 years ago

Hi,

Thank you for the reply.

I just played around with adding timeout=some_timeout_value


with ia.fetch(timeout=20) as buffer:
    component = buffer.payload.components[0]
    _1d = component.data
    print('1D: {0}'.format(_1d))
    _2d = component.data.reshape(
        component.height, component.width
    )
    print('2D: {0}'.format(_2d))
    print(
        'AVE: {0}, MIN: {1}, MAX: {2}'.format(
            np.average(_2d), _2d.min(), _2d.max()
        )
    )

And i get the error:

---------------------------------------------------------------------------
TimeoutException                          Traceback (most recent call last)
Input In [17], in <cell line: 1>()
----> 1 with ia.fetch(timeout=20) as buffer:
      2     component = buffer.payload.components[0]
      3     _1d = component.data

File ~\Documents\Anaconda\envs\Genicam_test\lib\site-packages\harvesters\core.py:2384, in ImageAcquirer.fetch(self, timeout, is_raw, cycle_s)
   2382             time.sleep(cycle_s if cycle_s else 0.0001)
   2383     else:
-> 2384         raw_buffer = self._fetch(
   2385             manager=self._event_new_buffer_managers[0],
   2386             timeout_on_client_fetch_call=timeout, throw_except=True)
   2387         buffer = self._finalize_fetching_process(raw_buffer, is_raw)
   2389 return buffer

File ~\Documents\Anaconda\envs\Genicam_test\lib\site-packages\harvesters\core.py:2261, in ImageAcquirer._fetch(self, manager, timeout_on_client_fetch_call, throw_except)
   2257     _logger.debug(
   2258         'timeout: elapsed {0} sec.'.format(
   2259             timeout_on_client_fetch_call))
   2260 if throw_except:
-> 2261     raise TimeoutException
   2262 else:
   2263     return None

TimeoutException: 

So now i can produce the timeout error, but i would like to solve acquiring an image. I know possibly there could be many reasons for a time out, but are there a way that i can debug this?

Thanks!

kazunarikudo commented 2 years ago

Hi, thanks for the update.

So now i can produce the timeout error, but i would like to solve acquiring an image.

In the image acquisition process, Harvester is just an observer. It asks a GenTL Producer if it has a buffer that is ready to be exposed but the function call can fail when no image has been delivered to the GenTL Producer.

No matter what the issue was, you will need to debug the signal path that an image comes through. For example, you should be sure that the camera is triggered as expected and any hardware equipment is not blocking to delivery of the data; say, a poor cable can drop the data. You may be able to intentionally reduce the amont of the data size by decreasing the image resolution or decreasing the trgger frequency or the image acquisition frequency on the device side.