python 2.7 - VTK: 3D matrix's volume has wrong dimensions -
i want visualize 3-d matrix (z slices of x*y resolution) classic 3-d voxel. generate matrix in matlab , import in python. then, following code here , here, come solution. demonstration using matrix should generate 3d image containing 4 slices of 2*3 voxels.
in matlab
c(:,:,1) = 5 5 5 5 5 5 c(:,:,2) = 15 15 15 15 15 15 c(:,:,3) = 25 25 25 25 25 25 c(:,:,4) = 35 35 35 35 35 35
in python:
cmat = spio.loadmat('cmat.mat')['c'] >>>print cmat.shape (2, 3, 4) cmat = np.ascontiguousarray(cmat.t) >>>print cmat [[[ 5 5] [ 5 5] [ 5 5]] [[15 15] [15 15] [15 15]] [[25 25] [25 25] [25 25]] [[35 35] [35 35] [35 35]]]
and code follow produces image (which rotated convenience):
the resulting shape not 2*3*4 , slices have not same size, doing wrong? tried tweak
dataimporter.setdataextent dataimporter.setwholeextent dataimporter.setdataspacing
and reshaping matrix in many ways, if change dataimporter.setdataextent(0,1,0,1,0,1) dataimporter.setwholeextent(0,1,0,1,0,1)
i obtain 2x2x2 cube expected if call
dataimporter.setdataextent(0, 1, 0, 2, 0, 1) dataimporter.setwholeextent(0, 1, 0, 2, 0, 1)
i obtain 2x4x2 solid (instead of 2x3x2)
if call
dataimporter.setdataextent(0, 1, 0, 10, 0, 2) dataimporter.setwholeextent(0, 1, 0, 10, 0, 2)
this appears contradict documentation setdataextent , setwholeextent:
*the dimensions of data must equal (extent1-extent[0]+1) * (extent4-extent3+1) * (extent5-dataextent4+1). example, 2d image use (0,width-1, 0,height-1, 0,0).*
any idea?
full code below matlab:
c = zeros(2,3,4) c(:,:,1) = 5; c(:,:,2) = 15; c(:,:,3) = 25; c(:,:,4) = 35; save cmat c
python:
import vtk numpy import * import numpy np import scipy.io spio data_matrix = zeros([2, 3, 4], dtype=uint8) cmat = spio.loadmat('cmat.mat')['c'] cmat = np.ascontiguousarray(cmat.t) print cmat data_matrix = cmat # vtk able use data, must stored vtk-image. can done vtkimageimport-class # imports raw data , stores it. dataimporter = vtk.vtkimageimport() # created array converted string of chars , imported. data_string = data_matrix.tostring() dataimporter.copyimportvoidpointer(data_string, len(data_string)) # type of newly imported data set unsigned char (uint8) dataimporter.setdatascalartypetounsignedchar() # because data imported contains intensity value (it isn't rgb-coded or similar), importer # must told case. dataimporter.setnumberofscalarcomponents(1) # following 2 functions describe how data stored , dimensions of array stored in. dataimporter.setdataextent(0, 1, 0, 2, 0, 3) dataimporter.setwholeextent(0, 1, 0, 2, 0, 3) # class stores color data , can create color tables few color points. demo, want 3 cubes # of colors red green , blue. colorfunc = vtk.vtkcolortransferfunction() colorfunc.addrgbpoint(5, 1, 0.0, 0.0) # red colorfunc.addrgbpoint(15, 0.0, 1, 0.0) # green colorfunc.addrgbpoint(25, 0.0, 0.0, 1) # blue colorfunc.addrgbpoint(35, 0.0, 0, 0.0) # black # previous 2 classes stored properties. because want apply these properties volume want render, # have store them in class stores volume properties. volumeproperty = vtk.vtkvolumeproperty() volumeproperty.setcolor(colorfunc) volumemapper = vtk.vtkopenglgpuvolumeraycastmapper() volumemapper.setinputconnection(dataimporter.getoutputport()) # class vtkvolume used pair declared volume properties used when rendering volume. volume = vtk.vtkvolume() volume.setmapper(volumemapper) volume.setproperty(volumeproperty) # else ready, time initialize renderer , window, creating method exiting application renderer = vtk.vtkrenderer() renderwin = vtk.vtkrenderwindow() renderwin.addrenderer(renderer) renderinteractor = vtk.vtkrenderwindowinteractor() renderinteractor.setrenderwindow(renderwin) # add volume renderer ... renderer.addvolume(volume) # ... set background color white ... renderer.setbackground(1, 1, 1) # ... , set window size. renderwin.setsize(400, 400) # simple function called when user decides quit application. def exitcheck(obj, event): if obj.geteventpending() != 0: obj.setabortrender(1) # tell application use function exit check. renderwin.addobserver("abortcheckevent", exitcheck) renderinteractor.initialize() # because nothing rendered without input, order first render manually before control handed on main-loop. renderwin.render() renderinteractor.start()
the hypotesis have these voxels not cubes 1 of dimensions twice others. still not explain why 2 of 4 slices impacted this.
[update]: seems first , last slices half size of other ones. 20x30x40 matrix can seen first , last slices thinner rest.
Comments
Post a Comment