using the channel_axis kwarg causes problems when using a transformation matrix(np.array) throwing an IndexError. When using napari.utils.transforms.Affine for the affine kwarg a TypeError is thrown as setting the channel_axis makes the other kwargs match the len of channels.
from skimage.data import astronaut
import napari
from napari.utils import transforms
rgb_astro = astronaut()
mc_astro = np.rollaxis(rgb_astro, 2)
aff_mat = transforms.Affine(rotate=45).affine_matrix
with napari.gui_qt():
viewer = napari.Viewer()
viewer.add_image(
rgb_astro,
name="45 rot RGB",
affine=aff_mat,
)
viewer.add_image(
mc_astro,
channel_axis=0,
name="45 rot mc",
affine=aff_mat,
)
ERROR:root:Unhandled exception:
Traceback (most recent call last):
File "C:\miniconda3\envs\bc\lib\site-packages\napari\_qt\event_loop.py", line 79, in gui_qt
yield app
File "<ipython-input-185-65466d9eb63b>", line 15, in <module>
viewer.add_image(
File "C:\miniconda3\envs\bc\lib\site-packages\napari\components\viewer_model.py", line 776, in add_image
layer = self.add_layer(image_class(image, **i_kwargs))
File "C:\miniconda3\envs\bc\lib\site-packages\napari\layers\image\image.py", line 209, in __init__
super().__init__(
File "C:\miniconda3\envs\bc\lib\site-packages\napari\layers\intensity_mixin.py", line 22, in __init__
super().__init__(*args, **kwargs)
File "C:\miniconda3\envs\bc\lib\site-packages\napari\layers\base\base.py", line 224, in __init__
data2world_transform = Affine(
File "C:\miniconda3\envs\bc\lib\site-packages\napari\utils\transforms\transforms.py", line 313, in __init__
linear_matrix = affine_matrix[:-1, :-1]
IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed
with napari.gui_qt():
viewer = napari.Viewer()
viewer.add_image(
rgb_astro,
name="45 rot RGB",
affine=aff_mat,
)
viewer.add_image(
mc_astro,
channel_axis=0,
name="45 rot mc",
affine=transforms.Affine(rotate=45),
)
```python
ERROR:root:Unhandled exception:
Traceback (most recent call last):
File "C:miniconda3\envs\bc\lib\site-packages\napari_qt\event_loop.py", line 79, in gui_qt
yield app
File "
viewer.add_image(
File "C:miniconda3\envs\bc\lib\site-packages\napari\components\viewer_model.py", line 772, in add_image
layerdata_list = split_channels(data, channel_axis, **kwargs)
File "C:miniconda3\envs\bc\lib\site-packages\napari\layers\utils\stack_utils.py", line 76, in split_channels
kwargs[key] = iter(ensure_iterable(val))
TypeError: 'Affine' object is not iterable
### works
```python
aff_mat = transforms.Affine(rotate=45).affine_matrix
with napari.gui_qt():
viewer = napari.Viewer()
viewer.add_image(
rgb_astro,
name="45 rot RGB",
affine=aff_mat,
)
viewer.add_image(
mc_astro,
channel_axis=0,
name="45 rot mc",
affine=[
aff_mat,
aff_mat,
aff_mat
],
)
aff_mat = transforms.Affine(rotate=45).affine_matrix
with napari.gui_qt():
viewer = napari.Viewer()
viewer.add_image(
rgb_astro,
name="45 rot RGB",
affine=aff_mat,
)
viewer.add_image(
mc_astro,
channel_axis=0,
name="45 rot mc",
affine=[
aff_mat,
],
)
When setting a channel axis, a single transform should transform all channels when passed in affine, but shouldn't be a requirement (for an instance where each channel needs corrective transformation). This seems to be handled here:
https://github.com/napari/napari/blob/d8d2d301b71af79a6a7f8f4bafa1f55a18317dd8/napari/layers/utils/stack_utils.py#L13
('napari: 0.4.2'
'Platform: Windows-10-10.0.19041-SP0'
'Python: 3.8.6 | packaged by conda-forge | (default, Oct 7 2020, 18:22:52) '
'[MSC v.1916 64 bit (AMD64)]'
'Qt: 5.14.2'
'PyQt5: 5.14.2'
'NumPy: 1.19.2'
'SciPy: 1.5.2'
'Dask: 2.30.0'
'VisPy: 0.6.5'
'GL version: 4.6.0 - Build 26.20.100.7325'
'MAX_TEXTURE_SIZE: 16384'
'Plugins:'
' - napari_plugin_engine: 0.1.8'
' - svg: 0.1.4')
I think I have fixed this. I'll open a PR soon.
Most helpful comment
I think I have fixed this. I'll open a PR soon.