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

can't save RGB image #49

Open
dani-ham opened this issue Jan 7, 2025 · 1 comment
Open

can't save RGB image #49

dani-ham opened this issue Jan 7, 2025 · 1 comment

Comments

@dani-ham
Copy link

dani-ham commented Jan 7, 2025

error in extrema_image function.
note : I used napari built-in sample image(astronaut)

before
after

ValueError                                Traceback (most recent call last)
File ~\anaconda3\Lib\site-packages\app_model\backends\qt\_qaction.py:59, in QCommandAction._on_triggered(self=QMenuItemAction(MenuItem(when=None, group='4_sav...tle=None, toggled=None), alt=None), app='napari'), checked=False)
     55 def _on_triggered(self, checked: bool) -> None:
     56     # execute_command returns a Future, for the sake of eventually being
     57     # asynchronous without breaking the API.  For now, we call result()
     58     # to raise any exceptions.
---> 59     self._app.commands.execute_command(self._command_id).result()
        self._command_id = 'napari.window.file.save_layers_dialog'
        self = QMenuItemAction(MenuItem(when=None, group='4_save', order=None, command=CommandRule(id='napari.window.file.save_layers_dialog', title='Save All Layers...', category=None, tooltip=None, status_tip=None, icon=None, icon_visible_in_menu=True, enablement=Expr.parse('num_layers > 0'), short_title=None, toggled=None), alt=None), app='napari')
        self._app = Application('napari')

File ~\anaconda3\Lib\site-packages\app_model\registries\_commands_reg.py:247, in CommandsRegistry.execute_command(self=<CommandsRegistry at 0x2972a013790 (144 commands)>, id='napari.window.file.save_layers_dialog', execute_asynchronously=False, *args=(), **kwargs={})
    243 except Exception as e:
    244     if self._raise_synchronous_exceptions:
    245         # note, the caller of this function can also achieve this by
    246         # calling `future.result()` on the returned future object.
--> 247         raise e
    248     future.set_exception(e)
    250 return future

File ~\anaconda3\Lib\site-packages\app_model\registries\_commands_reg.py:242, in CommandsRegistry.execute_command(self=<CommandsRegistry at 0x2972a013790 (144 commands)>, id='napari.window.file.save_layers_dialog', execute_asynchronously=False, *args=(), **kwargs={})
    240 future: Future = Future()
    241 try:
--> 242     future.set_result(cmd(*args, **kwargs))
        future = <Future at 0x2972f52e3d0 state=pending>
        cmd = <function QtViewer._save_layers_dialog at 0x000002972D416660>
        args = ()
        kwargs = {}
    243 except Exception as e:
    244     if self._raise_synchronous_exceptions:
    245         # note, the caller of this function can also achieve this by
    246         # calling `future.result()` on the returned future object.

File ~\anaconda3\Lib\site-packages\in_n_out\_store.py:934, in Store.inject_processors.<locals>._deco.<locals>._exec(*args=(), **kwargs={})
    932 @wraps(func)
    933 def _exec(*args: P.args, **kwargs: P.kwargs) -> R:
--> 934     result = func(*args, **kwargs)
        func = <function QtViewer._save_layers_dialog at 0x000002972D414680>
        args = ()
        kwargs = {}
    935     if result is not None:
    936         self.process(
    937             result,
    938             type_hint=type_hint,
   (...)
    941             _funcname=getattr(func, "__qualname__", str(func)),
    942         )

File ~\anaconda3\Lib\site-packages\in_n_out\_store.py:804, in Store.inject.<locals>._inner.<locals>._exec(*args=(), **kwargs={})
    797 logger.debug(
    798     "  Calling %s with %r (injected %r)",
    799     _fname,
    800     bound.arguments,
    801     _injected_names,
    802 )
    803 try:
--> 804     result = func(**bound.arguments)
        bound = <BoundArguments (selected=False, self=<napari._qt.qt_viewer.QtViewer object at 0x0000029729FBA0E0>)>
        func = <function QtViewer._save_layers_dialog at 0x0000029729FF8720>
        bound.arguments = {'selected': False, 'self': <napari._qt.qt_viewer.QtViewer object at 0x0000029729FBA0E0>}
    805 except TypeError as e:
    806     if "missing" not in e.args[0]:

File ~\anaconda3\Lib\site-packages\napari\_qt\qt_viewer.py:804, in QtViewer._save_layers_dialog(self=<napari._qt.qt_viewer.QtViewer object>, selected=False)
    800 writer = _npe2_decode_selected_filter(
    801     ext_str, selected_filter, writers
    802 )
    803 with warnings.catch_warnings(record=True) as wa:
--> 804     saved = self.viewer.layers.save(
        self = <napari._qt.qt_viewer.QtViewer object at 0x0000029729FBA0E0>
        self.viewer.layers = [<Image layer 'astronaut' at 0x29737646490>]
        self.viewer = Viewer(camera=Camera(center=(0.0, 255.5, 255.5), zoom=1.3818603515625, angles=(0.0, 0.0, 90.0), perspective=0.0, mouse_pan=True, mouse_zoom=True), cursor=Cursor(position=(-129.4882576906172, -5.380194161691563), scaled=True, style=<CursorStyle.STANDARD: 'standard'>, size=1.0), dims=Dims(ndim=2, ndisplay=2, order=(0, 1), axis_labels=('0', '1'), rollable=(True, True), range=(RangeTuple(start=0.0, stop=511.0, step=1.0), RangeTuple(start=0.0, stop=511.0, step=1.0)), margin_left=(0.0, 0.0), margin_right=(0.0, 0.0), point=(255.0, 255.0), last_used=0), grid=GridCanvas(stride=1, shape=(-1, -1), enabled=False), layers=[<Image layer 'astronaut' at 0x29737646490>], help='use <2> for transform', status='', tooltip=Tooltip(visible=False, text=''), theme='dark', title='napari', mouse_over_canvas=False, mouse_move_callbacks=[], mouse_drag_callbacks=[], mouse_double_click_callbacks=[<function double_click_to_zoom at 0x0000029729930D60>], mouse_wheel_callbacks=[<function dims_scroll at 0x0000029729930CC0>], _persisted_mouse_event={}, _mouse_drag_gen={}, _mouse_wheel_gen={}, _keymap={})
        filename = 'C:/Users/kei/export/astronaut.svg'
        selected = False
        writer = WriterContribution(command='napari-svg.svg_writer', layer_types=['image*', 'labels*', 'points*', 'shapes*', 'vectors*'], filename_extensions=['.svg'], display_name='')
    805         filename, selected=selected, _writer=writer
    806     )
    807     logging.debug('Saved %s', saved)
    808     error_messages = '\n'.join(str(x.message.args[0]) for x in wa)

File ~\anaconda3\Lib\site-packages\napari\components\layerlist.py:486, in LayerList.save(self=[<Image layer 'astronaut' at 0x29737646490>], path='C:/Users/kei/export/astronaut.svg', selected=False, plugin=None, _writer=WriterContribution(command='napari-svg.svg_write...], filename_extensions=['.svg'], display_name=''))
    483     warnings.warn(msg)
    484     return []
--> 486 return save_layers(path, layers, plugin=plugin, _writer=_writer)
        layers = [<Image layer 'astronaut' at 0x29737646490>]
        path = 'C:/Users/kei/export/astronaut.svg'
        plugin = None
        _writer = WriterContribution(command='napari-svg.svg_writer', layer_types=['image*', 'labels*', 'points*', 'shapes*', 'vectors*'], filename_extensions=['.svg'], display_name='')

File ~\anaconda3\Lib\site-packages\napari\plugins\io.py:244, in save_layers(path='C:/Users/kei/export/astronaut.svg', layers=[<Image layer 'astronaut'>], plugin=None, _writer=WriterContribution(command='napari-svg.svg_write...], filename_extensions=['.svg'], display_name=''))
    240     written, writer_name = _write_multiple_layers_with_plugins(
    241         path, layers, plugin_name=plugin, _writer=_writer
    242     )
    243 elif len(layers) == 1:
--> 244     _written, writer_name = _write_single_layer_with_plugins(
        writer_name = ''
        layers = [<Image layer 'astronaut' at 0x29737646490>]
        path = 'C:/Users/kei/export/astronaut.svg'
        plugin = None
        _writer = WriterContribution(command='napari-svg.svg_writer', layer_types=['image*', 'labels*', 'points*', 'shapes*', 'vectors*'], filename_extensions=['.svg'], display_name='')
        layers[0] = <Image layer 'astronaut' at 0x29737646490>
    245         path, layers[0], plugin_name=plugin, _writer=_writer
    246     )
    247     written = [_written] if _written else []
    248 else:

File ~\anaconda3\Lib\site-packages\napari\plugins\io.py:457, in _write_single_layer_with_plugins(path='C:/Users/kei/export/astronaut.svg', layer=<Image layer 'astronaut'>, plugin_name=None, _writer=WriterContribution(command='napari-svg.svg_write...], filename_extensions=['.svg'], display_name=''))
    420 """Write single layer data with a plugin.
    421
    422 If ``plugin_name`` is not provided then we just directly call
   (...)
    453     Name of the plugin selected to write the data.
    454 """
    456 # Try to use NPE2 first
--> 457 written_paths, writer_name = _npe2.write_layers(
        _npe2 = <module 'napari.plugins._npe2' from 'C:\\Users\\kei\\anaconda3\\Lib\\site-packages\\napari\\plugins\\_npe2.py'>
        path = 'C:/Users/kei/export/astronaut.svg'
        [layer] = [<Image layer 'astronaut' at 0x29737646490>]
        plugin_name = None
        _writer = WriterContribution(command='napari-svg.svg_writer', layer_types=['image*', 'labels*', 'points*', 'shapes*', 'vectors*'], filename_extensions=['.svg'], display_name='')
        layer = <Image layer 'astronaut' at 0x29737646490>
    458     path, [layer], plugin_name, _writer
    459 )
    460 if writer_name:
    461     return (written_paths[0], writer_name)

File ~\anaconda3\Lib\site-packages\napari\plugins\_npe2.py:115, in write_layers(path='C:/Users/kei/export/astronaut.svg', layers=[<Image layer 'astronaut'>], plugin_name=None, writer=WriterContribution(command='napari-svg.svg_write...], filename_extensions=['.svg'], display_name=''))
    113 n = sum(ltc.max() for ltc in writer.layer_type_constraints())
    114 args = (path, *layer_data[0][:2]) if n <= 1 else (path, layer_data)
--> 115 res = writer.exec(args=args)
        args = ('C:/Users/kei/export/astronaut.svg', [(array([[[154, 147, 151],
        [109, 103, 124],
        ...,
        [120, 117, 106],
        [125, 119, 110]],

       [[177, 171, 171],
        [144, 141, 143],
        ...,
        [124, 115, 108],
        [121, 116, 105]],

       ...,

       [[183, 169, 170],
        [182, 167, 171],
        ...,
        [  1,   1,   1],
        [  0,   0,   0]],

       [[184, 167, 172],
        [183, 165, 169],
        ...,
        [  1,   1,   1],
        [  0,   0,   0]]], dtype=uint8), {'affine': array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]]), 'axis_labels': ('axis -2', 'axis -1'), 'blending': 'translucent_no_depth', 'experimental_clipping_planes': [], 'metadata': {}, 'name': 'astronaut', 'opacity': 1.0, 'projection_mode': <ImageProjectionMode.NONE: 'none'>, 'rotate': [[1.0, 0.0], [0.0, 1.0]], 'scale': [1.0, 1.0], 'shear': [0.0], 'translate': [0.0, 0.0], 'units': (<Unit('pixel')>, <Unit('pixel')>), 'visible': True, 'rgb': True, 'multiscale': False, 'colormap': {'colors': ColorArray([[0.     , 0.     , 0.     , 1.     ],
            [0.00392, 0.00392, 0.00392, 1.     ],
            ...,
            [0.99608, 0.99608, 0.99608, 1.     ],
            [1.     , 1.     , 1.     , 1.     ]], dtype=float32), 'name': 'gray', 'interpolation': <ColormapInterpolationMode.LINEAR: 'linear'>, 'controls': array([0.     , 0.00392, ..., 0.99608, 1.     ], dtype=float32)}, 'contrast_limits': [0, 255], 'interpolation2d': 'nearest', 'interpolation3d': 'linear', 'rendering': 'mip', 'depiction': 'volume', 'plane': {'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'iso_threshold': 127.5, 'attenuation': 0.05, 'gamma': 1.0, 'custom_interpolation_kernel_2d': array([[1.]], dtype=float32)}, 'image')])
        writer = WriterContribution(command='napari-svg.svg_writer', layer_types=['image*', 'labels*', 'points*', 'shapes*', 'vectors*'], filename_extensions=['.svg'], display_name='')
    116 if isinstance(
    117     res, str
    118 ):  # pragma: no cover # it shouldn't be... bad plugin.
    119     return [res], writer.plugin_name

File ~\anaconda3\Lib\site-packages\npe2\manifest\utils.py:61, in Executable.exec(self=WriterContribution(command='napari-svg.svg_write...], filename_extensions=['.svg'], display_name=''), args=('C:/Users/kei/export/astronaut.svg', [(array([[[154, 147, 151],
        [109, 103, 124]... 1,   1],
        [  0,   0,   0]]], dtype=uint8), {'affine': array([[1., 0., 0.],
       [0., 1., ...olation_kernel_2d': array([[1.]], dtype=float32)}, 'image')]), kwargs={}, _registry=None)
     59     kwargs = {}
     60 reg = _registry or kwargs.pop("_registry", None)
---> 61 return self.get_callable(reg)(*args, **kwargs)
        reg = None
        kwargs = {}
        args = ('C:/Users/kei/export/astronaut.svg', [(array([[[154, 147, 151],
        [109, 103, 124],
        ...,
        [120, 117, 106],
        [125, 119, 110]],

       [[177, 171, 171],
        [144, 141, 143],
        ...,
        [124, 115, 108],
        [121, 116, 105]],

       ...,

       [[183, 169, 170],
        [182, 167, 171],
        ...,
        [  1,   1,   1],
        [  0,   0,   0]],

       [[184, 167, 172],
        [183, 165, 169],
        ...,
        [  1,   1,   1],
        [  0,   0,   0]]], dtype=uint8), {'affine': array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]]), 'axis_labels': ('axis -2', 'axis -1'), 'blending': 'translucent_no_depth', 'experimental_clipping_planes': [], 'metadata': {}, 'name': 'astronaut', 'opacity': 1.0, 'projection_mode': <ImageProjectionMode.NONE: 'none'>, 'rotate': [[1.0, 0.0], [0.0, 1.0]], 'scale': [1.0, 1.0], 'shear': [0.0], 'translate': [0.0, 0.0], 'units': (<Unit('pixel')>, <Unit('pixel')>), 'visible': True, 'rgb': True, 'multiscale': False, 'colormap': {'colors': ColorArray([[0.     , 0.     , 0.     , 1.     ],
            [0.00392, 0.00392, 0.00392, 1.     ],
            ...,
            [0.99608, 0.99608, 0.99608, 1.     ],
            [1.     , 1.     , 1.     , 1.     ]], dtype=float32), 'name': 'gray', 'interpolation': <ColormapInterpolationMode.LINEAR: 'linear'>, 'controls': array([0.     , 0.00392, ..., 0.99608, 1.     ], dtype=float32)}, 'contrast_limits': [0, 255], 'interpolation2d': 'nearest', 'interpolation3d': 'linear', 'rendering': 'mip', 'depiction': 'volume', 'plane': {'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'iso_threshold': 127.5, 'attenuation': 0.05, 'gamma': 1.0, 'custom_interpolation_kernel_2d': array([[1.]], dtype=float32)}, 'image')])
        self = WriterContribution(command='napari-svg.svg_writer', layer_types=['image*', 'labels*', 'points*', 'shapes*', 'vectors*'], filename_extensions=['.svg'], display_name='')

File ~\anaconda3\Lib\site-packages\napari_svg\hook_implementations.py:83, in writer(path='C:/Users/kei/export/astronaut.svg', layer_data=[(array([[[154, 147, 151],
        [109, 103, 124]... 1,   1],
        [  0,   0,   0]]], dtype=uint8), {'affine': array([[1., 0., 0.],
       [0., 1., ...olation_kernel_2d': array([[1.]], dtype=float32)}, 'image')])
     81 for ld in layer_data:
     82     function_string = ld[2] + '_to_xml(ld[0], ld[1])'
---> 83     layer_xml, extrema = eval(function_string)
        function_string = 'image_to_xml(ld[0], ld[1])'
     84     full_xml_list.append(layer_xml)
     85     if full_extrema is None:

File <string>:1

File ~\anaconda3\Lib\site-packages\napari_svg\layer_to_xml.py:182, in image_to_xml(data=array([[[154, 147, 151],
        [109, 103, 124]... 1,   1],
        [  0,   0,   0]]], dtype=uint8), meta={'affine': array([[1., 0., 0.],
       [0., 1., ...olation_kernel_2d': array([[1.]], dtype=float32)})
    179     image = data
    181 # Find extrema of data
--> 182 extrema = extrema_image(image, meta)
        meta = {'affine': array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]]), 'axis_labels': ('axis -2', 'axis -1'), 'blending': 'translucent_no_depth', 'experimental_clipping_planes': [], 'metadata': {}, 'name': 'astronaut', 'opacity': 1.0, 'projection_mode': <ImageProjectionMode.NONE: 'none'>, 'rotate': [[1.0, 0.0], [0.0, 1.0]], 'scale': [1.0, 1.0], 'shear': [0.0], 'translate': [0.0, 0.0], 'units': (<Unit('pixel')>, <Unit('pixel')>), 'visible': True, 'rgb': True, 'multiscale': False, 'colormap': {'colors': ColorArray([[0.     , 0.     , 0.     , 1.     ],
            [0.00392, 0.00392, 0.00392, 1.     ],
            ...,
            [0.99608, 0.99608, 0.99608, 1.     ],
            [1.     , 1.     , 1.     , 1.     ]], dtype=float32), 'name': 'gray', 'interpolation': <ColormapInterpolationMode.LINEAR: 'linear'>, 'controls': array([0.     , 0.00392, ..., 0.99608, 1.     ], dtype=float32)}, 'contrast_limits': [0, 255], 'interpolation2d': 'nearest', 'interpolation3d': 'linear', 'rendering': 'mip', 'depiction': 'volume', 'plane': {'normal': (1.0, 0.0, 0.0), 'position': (0.0, 0.0, 0.0), 'thickness': 1.0}, 'iso_threshold': 127.5, 'attenuation': 0.05, 'gamma': 1.0, 'custom_interpolation_kernel_2d': array([[1.]], dtype=float32)}
        image = array([[[154, 147, 151],
        [109, 103, 124],
        ...,
        [120, 117, 106],
        [125, 119, 110]],

       [[177, 171, 171],
        [144, 141, 143],
        ...,
        [124, 115, 108],
        [121, 116, 105]],

       ...,

       [[183, 169, 170],
        [182, 167, 171],
        ...,
        [  1,   1,   1],
        [  0,   0,   0]],

       [[184, 167, 172],
        [183, 165, 169],
        ...,
        [  1,   1,   1],
        [  0,   0,   0]]], dtype=uint8)
    184 if rgb:
    185     mapped_image = image

File ~\anaconda3\Lib\site-packages\napari_svg\layer_to_xml.py:116, in extrema_image(image=array([[[154, 147, 151],
        [109, 103, 124]... 1,   1],
        [  0,   0,   0]]], dtype=uint8), meta={'affine': array([[1., 0., 0.],
       [0., 1., ...olation_kernel_2d': array([[1.]], dtype=float32)})
    114 def extrema_image(image, meta):
    115     """Compute the extrema of an image layer, accounting for transforms."""
--> 116     coords = np.array([[0, 0], list(image.shape)])
        np = <module 'numpy' from 'C:\\Users\\kei\\anaconda3\\Lib\\site-packages\\numpy\\__init__.py'>
        image = array([[[154, 147, 151],
        [109, 103, 124],
        ...,
        [120, 117, 106],
        [125, 119, 110]],

       [[177, 171, 171],
        [144, 141, 143],
        ...,
        [124, 115, 108],
        [121, 116, 105]],

       ...,

       [[183, 169, 170],
        [182, 167, 171],
        ...,
        [  1,   1,   1],
        [  0,   0,   0]],

       [[184, 167, 172],
        [183, 165, 169],
        ...,
        [  1,   1,   1],
        [  0,   0,   0]]], dtype=uint8)
    117     return extrema_coords(coords, meta)

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.

np.array received rgb image shape.([512, 512, 3])
this shape not match 1st arg [0, 0].

for example can use this fix.

coords = np.array([[0, 0],  list(image.shape)])

to

coords = np.array([[0, 0], list(image.shape[:2])])

thx.

log

@jni
Copy link
Member

jni commented Jan 10, 2025

Thanks for the report @dani-ham! This is the same as #50, which is good cos I'd missed this issue. 😂 The fix is detailed in this comment. We'd welcome a contribution to address this! 🙏

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

No branches or pull requests

2 participants