在Python的3D图像处理中,通常用numpy array来进行非常方便的计算或者转化,这里记录一下numpy数据的VTK可视化基本流程,包括面绘制(Surfase Rendering)和体绘制(Volume Rendering)。除去数据格式转化,面绘制和体绘制在C++中也是类似的处理方法。
numpy数据转成vtkImageData
首先得把numpy数据转成vtk里可以用的格式:numpy array -> vtkIImageData。这里的numpy array是一个离散的三维空间数据场,0代表背景,非0代表前景点。
方法一:numpy_to_vtk
可以直接使用vtk.util.numpy_support
里的转换方法,非常方便。这是它的说明文档:
numpy_to_vtk(num_array, deep=0, array_type=None)
Converts a contiguous real numpy Array to a VTK array object.
This function only works for real arrays that are contiguous.
Complex arrays are NOT handled. It also works for multi-component
arrays. However, only 1, and 2 dimensional arrays are supported.
This function is very efficient, so large arrays should not be a
problem.
If the second argument is set to 1, the array is deep-copied from
from numpy. This is not as efficient as the default behavior
(shallow copy) and uses more memory but detaches the two arrays
such that the numpy array can be released.
WARNING: You must maintain a reference to the passed numpy array, if
the numpy data is gc'd and VTK will point to garbage which will in
the best case give you a segfault.
Parameters
----------
- num_array : a contiguous 1D or 2D, real numpy array.
对于3D array,可以用flatten
或者ravel
先转成1D array就可以使用了。这里的1D array得是C order(row-major order),最好使用deep copy以免出现一些内存管理的问题。
import numpy as np
import vtk
from vtk.util import numpy_support
# numpy_data is a 3D numpy array
shape = numpy_data.shape[::-1]
vtk_data = numpy_support.numpy_to_vtk(numpy_data.ravel(), 1, vtk.VTK_SHORT)
vtk_image_data = vtk.vtkImageData()
vtk_image_data.SetDimensions(shape)
vtk_image_data.SetSpacing(spacing)
vtk_image_data.SetOrigin(origin)
vtk_image_data.GetPointData().SetScalars(vtk_data)
# vtk_image_data: ready to use
方法二:vtkImageImport
使用Python也可以用vtkImageImport
来直接导入C array,就是要先把numpy array变成string。
import numpy as np
import vtk
numpy_str = numpy_data.astype(np.int16).tostring()
x_extent = numpy_data.shape[2]
y_extent = numpy_data.shape[1]
z_extent = numpy_data.shape[0]
image_import = vtk.vtkImageImport()
image_import.SetImportVoidPointer(numpy_str, len(numpy_str))
# 也可以使用CopyImportVoidPointer() 会copy一份numpy_str
image_import.SetWholeExtent(0, x_extent-1, 0, y_extent-1, 0, z_extent-1)
image_import.SetDataExtent(0, x_extent-1, 0, y_extent-1, 0, z_extent-1)
image_import.SetDataScalarTypeToShort() # 根据需求指定数据类型
image_import.SetNumberOfScalarComponents(1)
# 如果是RGB数据的话,SetNumberOfScalarComponents(3)
image_import.Update()
vtk_image_data = vtk.vtkImageData()
vtk_image_data.SetSpacing(spacing)
vtk_image_data.SetOrigin(origin)
# vtk_image_data: ready to use
绘制
参考:https://www.cnblogs.com/XDU-Lakers/p/10822840.html
这个作者总结的很全面,还有代码示例
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)