Hi, if I want to modify an element in a matrix, in ITK 4.13.3, I can code like
But in ITK 5.2.1, the same code seems fail to change the element.
I’d like to know what’s the way to do this in ITK 5. Thanks in advance.
Hi, if I want to modify an element in a matrix, in ITK 4.13.3, I can code like
@matt.mccormick, trying the above code on my computer also gives me an error, in two different environments:
Python 3.8.13 | packaged by conda-forge | (default, Mar 25 2022, 05:59:45) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import itk
>>> a=itk.Matrix[itk.D,3,3]
>>> a.GetVnlMatrix().set(0,0,1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: GetVnlMatrix() missing 1 required positional argument: 'self'
>>> itk.__file__
'C:\\Users\\Dzenan\\miniconda3\\envs\\deep_learning\\lib\\site-packages\\itk\\__init__.py'
>>> itk.__version__
'5.2.1'
Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import itk
>>> a=itk.Matrix[itk.D,3,3]
>>> a.GetVnlMatrix().set(0,0,1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: GetVnlMatrix() missing 1 required positional argument: 'self'
>>> itk.__file__
'M:\\a\\ITK-py\\Wrapping\\Generators\\Python\\itk\\__init__.py'
>>> itk.__version__
'5.3.0'
Ooops, I forgot instantiation parentheses. With that I get the same output as @zhuangming.shen in both of these enviroments.
I think the use of set
was incorrect originally. vnl_matrix
has a set
method, but it’s not doing what you are trying to do there.
//: Fills (laminates) this matrix with the given data, then returns it.
// A synonym for copy_in()
vnl_matrix& set(T const *d) { return copy_in(d); }
If you want to set a pixel in a vnl_matrix
, you need to use put
instead of set
. Or probably easier, use itk.GetArrayViewFromVnlMatrix
. And use numpy
operator []
to manipulate it.
I am not sure if the ITK4 code is calling a constructor on-the-fly with arguments (0, 0, 1)
and passing it to set
?
Umm, the problem is that the GetVnlMatrix() returns a copy, instead of a reference.
In [2]: m = itk.Matrix[itk.D, 3,3]()
In [3]: m
Out[3]: itkMatrixD33 ([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])
In [4]: m.GetVnlMatrix()
Out[4]: <itk.vnl_matrix_fixedPython.vnl_matrix_fixedD_3_3; proxy of <Swig Object of type 'vnl_matrix_fixedD_3_3 *' at 0x7fb3662bdb90> >
In [5]: m.GetVnlMatrix()
Out[5]: <itk.vnl_matrix_fixedPython.vnl_matrix_fixedD_3_3; proxy of <Swig Object of type 'vnl_matrix_fixedD_3_3 *' at 0x7fb423e87240> >
It was changed here:
Opened an issue here:
Thanks for reporting it @zhuangming.shen
I am not sure right now how to modify an element from an itk.Matrix in python.
Since ITK can now convert matrices from / to NumPy arrays, I think the best is to do something like
>>> import itk
>>> import numpy as np
>>> m = itk.Matrix[itk.D, 3,3]()
>>> m.GetVnlMatrix().get(0,0)
0.0
>>> a=itk.array_from_matrix(m)
>>> a[0,0]=1
>>> m=itk.matrix_from_array(a)
>>> m.GetVnlMatrix().get(0,0)
1.0