[vtkusers] 3D numpy array to vtkDataSet

Cory Quammen cory.quammen at kitware.com
Tue Jul 21 08:42:39 EDT 2015


Quentan,

Great, I'm glad that part is solved.

Sorry, I don't know why the seemingly odd transpose arguments are needed
that way. Maybe someone with more experience converting numpy arrays to VTK
arrays can chime in.

Thanks,
Cory

On Tue, Jul 21, 2015 at 3:58 AM, Quentan Qi <quentan at gmail.com> wrote:

> Dear Cory,
>
> Thank you so much for your explanation! My problem is solved!
>
> One more thing is the array order in the conversion from numpy array to
> vtkArray, which should change to [2, 0, 1] instead of [2, 1, 0]. It
> guarantees the rendering result will not be up-side-down or with other
> disordered results.
>
> ```Python
> vtk_array = numpy_support.numpy_to_vtk(
>     num_array=quadric_2.transpose(2, 0, 1).ravel(),  # was (2, 1, 0)
>     deep=True,
>     array_type=vtk.VTK_FLOAT)
> ```
>
> It confused me actually that numpy has opposite array order against VTK,
> but here it seems not. What happened?
>
> Cheers,
> Quentan
>
>
> On 21 Jul 2015, at 04:07, Cory Quammen <cory.quammen at kitware.com> wrote:
>
> Quentan,
>
> Thank you for posting the excellent code sample. With it, I could see what
> the problem was right away.
>
> The problem is that vtkImageData has the notion of an origin, and you are
> not setting it. By default, vtkImageData have a corner at (0, 0, 0), but
> your function in numpy starts at (-1, -1, -1). By not setting the origin to
> (-1, -1, -1), you are accidentally shifting your data. You'll need to set
> the origin in your vtk_image_data via
>
> vtk_image_data.SetOrigin(-1, -1, -1)
>
> You'll also need to figure out your vtk_image_data's spacing. For the
> x-component, this can be computed with
>
> (x_max - x_min) / (x_dim - 1)
>
> where x_{max, min} are the maximum and minimum x coordinate and x_dim is
> the number of voxels in the x direction.
>
> I hope that helps,
> Cory
>
>
>
> On Sun, Jul 19, 2015 at 1:40 PM, Quentan Qi <quentan at gmail.com> wrote:
>
>> Dear Cory,
>>
>> I may fail to explain my problem, so I made an example
>> <https://github.com/quentan/Test_ImageData> to show what I want to
>> express, as you suggested. https://github.com/quentan/Test_ImageData
>>
>> This example generates a quadric with its implicit form: F(x,y,z) =
>> a0*x^2 + a1*y^2 + a2*z^2 + a3*x*y + a4*y*z + a5*x*z + a6*x + a7*y + a8*z +
>> a9
>>
>> The left viewport renders the quadric with vtkQuadric, which works
>> perfectly.
>>
>> The right viewport renders the same quadric with a meshgrid generated
>> with numpy. The meshgrid is converted to vtkFloatArray then to
>> vtkImageData. Its shape is right, but locates at wrong position, which
>> seems like it was scaled to some positive values.
>>
>> Note the small perpendicular coordinate lines in the corner.
>>
>> I guess the issue raises around line 120 - 123. If any other wrongs
>> happen, point it for me, please.
>>
>> Cheers,
>> Quentan
>>
>>
>> On 18 Jul 2015, at 15:09, Cory Quammen <cory.quammen at kitware.com> wrote:
>>
>> Quentan,
>>
>> vtkImageData is in fact a subclass of vtkDataSet, so no conversion is
>> needed. You said, "vtkImageData scales all points to positive integer
>> values", but this should not be the case. Something strange is going on.
>>
>> Could you expand the code above into a complete example that can be run
>> through vtkpython? That will make it easier to take a look. In particular,
>> please add a part that shows the vtkImageData are being scaled to positive
>> integers. It's fine if you fill the array with random values.
>>
>> Thanks,
>> Cory
>>
>>
>> On Sat, Jul 18, 2015 at 6:08 AM, Quentan Qi <quentan at gmail.com> wrote:
>>
>>> Hi there,
>>>
>>> I am going to read a set of discrete 3D points (float value, not int
>>> value) and show both the points and the fitting surface via VTK’s implicit
>>> functions, say vtkImplicitVolume or vtkImplicitDataSet.
>>>
>>> It works fine of the numpy arrary to vtkImageData conversion in the
>>> following code, but is out of my mind how to convert it to vtkDataSet,
>>> which is my requirement.
>>>
>>> ```Python
>>>     # Convert numpy array to VTK array (vtkFloatArray)
>>>     vtk_data_array = numpy_support.numpy_to_vtk(
>>>         num_array=ndarray.transpose(2, 1, 0).ravel(),  # ndarray
>>> contains the fitting result from the points. It is a 3D array
>>>         deep=True,
>>>         array_type=vtk.VTK_FLOAT)
>>>
>>>     # Convert the VTK array to vtkImageData
>>>     img_vtk = vtk.vtkImageData()
>>>     img_vtk.SetDimensions(ndarray.shape)
>>>     img_vtk.SetSpacing(spacing[::-1])
>>>     img_vtk.GetPointData().SetScalars(vtk_data_array)
>>>
>>>     # …
>>>     implicit_volume = vtk.vtkImplicitVolume()  # I want a
>>> vtkImplicitDataSet, whose input is a vtkDataSet
>>>     implicit_volume.SetVolume(img_vtk)
>>> ```
>>>
>>> Because vtkImageData scales all points to positive integer values so
>>> that the rendering result mismatches the original points, I deem vtkDataSet
>>> or its subclass can do it. Anybody knows how to convert?
>>>
>>> Cheers,
>>> Quentan
>>>
>>> _______________________________________________
>>> Powered by www.kitware.com
>>>
>>> Visit other Kitware open-source projects at
>>> http://www.kitware.com/opensource/opensource.html
>>>
>>> Please keep messages on-topic and check the VTK FAQ at:
>>> http://www.vtk.org/Wiki/VTK_FAQ
>>>
>>> Search the list archives at: http://markmail.org/search/?q=vtkusers
>>>
>>> Follow this link to subscribe/unsubscribe:
>>> http://public.kitware.com/mailman/listinfo/vtkusers
>>>
>>>
>>
>>
>> --
>> Cory Quammen
>> R&D Engineer
>> Kitware, Inc.
>>
>>
>>
>
>
> --
> Cory Quammen
> R&D Engineer
> Kitware, Inc.
>
>
>


-- 
Cory Quammen
R&D Engineer
Kitware, Inc.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20150721/0a54856b/attachment-0001.html>


More information about the vtkusers mailing list