genicam / harvesters

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

ia.start() freezing? #350

Closed jeong-jasonji closed 1 year ago

jeong-jasonji commented 2 years ago

Describe the Bug Similar to the bug described in #348, #342, and #158 I am having trouble acquiring the images from the cameras through Harvester. I am using the examples in the tutorials and in the FAQs: https://github.com/genicam/harvesters#harvester-on-ipython

The code the way up to ia.start() seems to be working correctly as I can check devices, change node maps, and etc. However, when I try to start the acquisition using ia.start() it seems like nothing is happening for over 15+min and seems like it's frozen or stuck in an infinite loop. There are no error messages nor any outputs and python is telling me that previous command is running and I should wait for it to finish.

Configuration OS: [Windows 10 Pro] Python: [3.7.13] Harvester: [1.3.8] GenICam: [1.0.0] GenTL Producer: [Active Silicon Firebird] Camera: [JAI Ltd., Japan SP-5000M-CXP2]

To Reproduce/Sample Code

import numpy as np
from harvesters.core import Harvester

# instance Harvester
h = Harvester()
# load CTI file to communicate with the GenTL Producer
active_silicon_cti = r'C:\Program Files\Active Silicon\FireBird CXP\GenTL\win64\TLActiveSilicon.cti'
h.add_file(active_silicon_cti)
# check files
h.files
# update the harvester with the CTI file
h.update()
h.device_info_list
# create an image acquirer
ia = h.create()
# change image size
ia.remote_device.node_map.Width.value = 64
ia.remote_device.node_map.Height.value = 64
ia.remote_device.node_map.PixelFormat.value = 'Mono8'
# start acquiring images
ia.start()
with ia.fetch() as buffer:
    # Let's create an alias of the 2D image component:
    component = buffer.payload.components[0]

    # Note that the number of components can be vary. If your
    # target remote device transmits a multi-part information, then
    # you'd get two or more components in the payload. However, now
    # we're working with a remote device that transmits only a 2D image.
    # So we manipulate only index 0 of the list object, components.

    # Let's see the acquired data in 1D:
    _1d = component.data
    print('1D: {0}'.format(_1d))

    # Reshape the NumPy array into a 2D array:
    _2d = component.data.reshape(component.height, component.width)
    print('2D: {0}'.format(_2d))

    # Here are some trivial calculations:
    print('AVE: {0}, MIN: {1}, MAX: {2}'.format(np.average(_2d), _2d.min(), _2d.max()))

If applicable, please paste the actual output (its whole traceback, etc) here: The only thing that outputs when running the code above is the following:

GenTL producer does not implement IFGetParentTL
GenTL producer does not implement DevGetParentIF
GenTL producer does not implement DSGetParentDev
GenTL producer does not implement DSGetNumBufferParts
GenTL producer does not implement DSGetBufferPartInfo

Expected Behavior Just like the example: https://github.com/genicam/harvesters#harvester-on-ipython I expect some output like this:

1D: [123 124 125 126 127 128 129 130 124 125 126 127 128 129 130 131 125 126
 127 128 129 130 131 132 126 127 128 129 130 131 132 133 127 128 129 130
 131 132 133 134 128 129 130 131 132 133 134 135 129 130 131 132 133 134
 135 136 130 131 132 133 134 135 136 137]
2D: [[123 124 125 126 127 128 129 130]
 [124 125 126 127 128 129 130 131]
 [125 126 127 128 129 130 131 132]
 [126 127 128 129 130 131 132 133]
 [127 128 129 130 131 132 133 134]
 [128 129 130 131 132 133 134 135]
 [129 130 131 132 133 134 135 136]
 [130 131 132 133 134 135 136 137]]
AVE: 130.0, MIN: 123, MAX: 137

Reproducibility This phenomenon can be stably reproduced.

Actions You Have Taken

C:\Users\Owner\anaconda3\envs\gentl_37\lib\site-packages\harvesters_gui\frontend\pyqt5.py:474: DeprecationWarning: please consider to use create() instead of create_image_acquirer().
  self.device_list.currentIndex()
C:\Users\Owner\anaconda3\envs\gentl_37\lib\site-packages\harvesters_gui\frontend\pyqt5.py:588: DeprecationWarning: please consider to use is_acquiring() instead of is_acquiring_images().
  if not self.ia.is_acquiring_images() or \
C:\Users\Owner\anaconda3\envs\gentl_37\lib\site-packages\harvesters_gui\_private\frontend\canvas.py:136: DeprecationWarning: please consider to use fetch() instead of fetch_buffer().
  buffer = self.ia.fetch_buffer(timeout=0.0001)
C:\Users\Owner\anaconda3\envs\gentl_37\lib\site-packages\harvesters_gui\frontend\pyqt5.py:582: DeprecationWarning: please consider to use start_acquisition() instead of start_image_acquisition().
  self.ia.start_image_acquisition()
C:\Users\Owner\anaconda3\envs\gentl_37\lib\site-packages\harvesters\core.py:2026: DeprecationWarning: please consider to use start() instead of start_acquisition().
  self.start_acquisition(run_in_background=run_in_background)

Additional context I've looked in the tutorials and other issues and tried the specific configurations they mention but I can't even reproduce those errors in acquiring images as there seems to be compatibility issues I'm running against with python, numpy, and/or Harvester as mentioned above.

kazunarikudo commented 2 years ago

@jeong-jasonji Hi, thank you for the report. Would this approach resolve the issue? Regards, Kazunari.

jeong-jasonji commented 2 years ago

Unfortunately no. I don't think it is the ia.fetch() method that is causing the problem but the ia.start() method.

If I modify the code above to this:

...
# start acquiring images
ia.start()
print('after start')
with ia.fetch() as buffer:
    # Let's create an alias of the 2D image component:
    component = buffer.payload.components[0]
...

I do not see the print statement at all and only see:

GenTL producer does not implement IFGetParentTL
GenTL producer does not implement DevGetParentIF
GenTL producer does not implement DSGetParentDev
GenTL producer does not implement DSGetNumBufferParts
GenTL producer does not implement DSGetBufferPartInfo

If the ia.start() method worked or didn't freeze, I would expect something like:

GenTL producer does not implement IFGetParentTL
GenTL producer does not implement DevGetParentIF
GenTL producer does not implement DSGetParentDev
GenTL producer does not implement DSGetNumBufferParts
GenTL producer does not implement DSGetBufferPartInfo
after start

Also, after going through the source code and trying to debug, it seems like the problem/freezing happens when the ia.start() method is trying to queue announced buffers?

self._queue_announced_buffers(
                    data_stream=ds, buffers=self._announced_buffers)

Within the self._queue_announced_buffers it freezes at:

        for buffer in buffers:
            data_stream.queue_buffer(buffer)  ###<- freezes here
            _logger.debug('queued: {0}'.format(_family_tree(buffer)))
kazunarikudo commented 2 years ago

Hi,

If I modify the code above to this: ... ia.start() print('after start') with ia.fetch() as buffer: component = buffer.payload.components[0] ...

Could you point at the lines where you changed, please?

jeong-jasonji commented 2 years ago

The only lines from the harvester-on-ipython that I changed (other than some comments for my own sake) is this:

# start acquiring images
ia.start()
print('after start')  ###<- added this line
with ia.fetch() as buffer:
    # Let's create an alias of the 2D image component:
    component = buffer.payload.components[0]
kazunarikudo commented 2 years ago

Well,

if I modify the code above to this: ... I do not see the print statement at all and only see:

With your comments above, I had guessed you programmatically "modified" the code. but had not interpreted inserting the single print function call as a modification... Anyway,

for buffer in buffers:
    data_stream.queue_buffer(buffer)  ###<- freezes here
    _logger.debug('queued: {0}'.format(_family_tree(buffer)))

I had never faced the reported case where the program freezes at that method call. Maybe it'd be better to ask the Active Silicon support for further investigation. I am sure that they will take this seriously. If the support hesitates to start working on it, then just please tell me. I know some people at Active Silicon. Cheers, Kazunari.

jeong-jasonji commented 2 years ago

What would I ask the people at Active Silicon? I'm not sure what the issue would be on the Active Silicon end nor how I should direct any enquiries...

Like should I ask them about GenICam or GenTL Producer .cti files? or more about their specific frame grabbers?

kazunarikudo commented 2 years ago

What would I ask the people at Active Silicon?

Please ask them a question as follows: "I'm working with your GenTL Producer with Harvester. On a simple image acquisition program, it hangs at the line where Harvester calls DSQueueBuffer function call. I have asked the Harvester maintainer a question and he recommended reporting the observation as mentioned earlier and asking you for help."

That should be fine for the icebreaker. By the way, you are working with a GenTL Producer from Active Silicon, right? If so, everything should be ready.

jeong-jasonji commented 2 years ago

Thank you so much for the suggestion! And yes, I am using the GenTL Producer from Active Silicon.

Hopefully they can get to the bottom of this.

kazunarikudo commented 2 years ago

You are welcome. I admit there always be a chance where any defect slips in Harvester. If there's inconsistency on Harvester's side then I will gladly fix the issue.

jeong-jasonji commented 2 years ago

Hi, I got in touch with Active Silicon and they essentially said that they essentially said that they can't help us without purchasing their tech support and/or their most recent SDK and that costs a decent amount.

Is there a way to verify that this DSQueueBuffer problem is on the side of Active Silicon and that purchasing their SDK (and probably getting their most recent *.cti file and maybe tech support as well) can resolve this problem?

kazunarikudo commented 2 years ago

Thank you for the update. I had thought you were working on an Active Silicon product that you purchased by yourself. I am sorry, but everybody is running his/her own business; I do not have anything that I can help you with this situation. I hope you understand the limitation. Thank you.