2017-02-20 8 views
0

numpy/vtkを使用してCTスキャンで取得した画像を表示しようとしています。そうするために、私はこのsample codeと答えをthis questionに従ったが、私は良い結果を得ていないし、その理由を知らない。3D画像レンダリングと可視化のVTK/numpy

私はそれをレンダリングするとき、私は何か間違ったことをやっているようですので、私は正確にデータをロードすることを、それをチェックアウトしました。どんなタイプの助けも高く評価されます。これは今まで私の結果である:事前に

This is the 3D image that I obtain

感謝。

これは私のコードです:

import os 
import sys 
import pylab 
import glob 

import vtk 
import numpy as np 

#We order all the directories by name 
path="data/Images/" 
tulip_files = [t for t in os.listdir(path)] 
tulip_files.sort() #the os.listdir function do not give the files in the right order so we need to sort them 

#Function that open all the images of a folder and save them in a images list 
def imageread(filePath):  
    filenames = [img for img in glob.glob(filePath)] 
    filenames.sort() 

    temp = pylab.imread(filenames[0]) 
    d, w = temp.shape 
    h = len(filenames) 
    print 'width, depth, height : ',w,d,h 

    volume = np.zeros((w, d, h), dtype=np.uint16) 
    k=0 
    for img in filenames: #assuming tif  
     im=pylab.imread(img) 
     assert im.shape == (500,500), 'Image with an unexpected size' 
     volume[:,:,k] = im 
     k+=1 
    return volume 

#We create the data we want to render. We create a 3D-image by a X-ray CT-scan made to an object. We store the values of each 
#slice and we complete the volume with them in the z axis 
matrix_full = imageread(path+'Image15/raw/reconstruction/*.tif') 

# For VTK to be able to use the data, it must be stored as a VTK-image. This can be done by the vtkImageImport-class which 
# imports raw data and stores it. 
dataImporter = vtk.vtkImageImport() 
# The previously created array is converted to a string of chars and imported. 
data_string = matrix_full.tostring() 
dataImporter.CopyImportVoidPointer(data_string, len(data_string)) 
# The type of the newly imported data is set to unsigned short (uint16) 
dataImporter.SetDataScalarTypeToUnsignedShort() 
# Because the data that is imported only contains an intensity value (it isnt RGB-coded or someting similar), the importer 
# must be told this is the case. 
dataImporter.SetNumberOfScalarComponents(1) 

# The following two functions describe how the data is stored and the dimensions of the array it is stored in. 
w, h, d = tulip_matrix_full.shape 
dataImporter.SetDataExtent(0, h-1, 0, d-1, 0, w-1) 
dataImporter.SetWholeExtent(0, h-1, 0, d-1, 0, w-1) 

# This class stores color data and can create color tables from a few color points. 
colorFunc = vtk.vtkPiecewiseFunction() 
colorFunc.AddPoint(0, 0.0); 
colorFunc.AddPoint(65536, 1); 

# The following class is used to store transparency-values for later retrieval. 

alphaChannelFunc = vtk.vtkPiecewiseFunction() 
#Create transfer mapping scalar value to opacity 
alphaChannelFunc.AddPoint(0, 0.0); 
alphaChannelFunc.AddPoint(65536, 1); 

# The previous two classes stored properties. Because we want to apply these properties to the volume we want to render, 
# we have to store them in a class that stores volume properties. 
volumeProperty = vtk.vtkVolumeProperty() 
volumeProperty.SetColor(colorFunc) 
volumeProperty.SetScalarOpacity(alphaChannelFunc) 
#volumeProperty.ShadeOn(); 

# This class describes how the volume is rendered (through ray tracing). 
compositeFunction = vtk.vtkVolumeRayCastCompositeFunction() 
# We can finally create our volume. We also have to specify the data for it, as well as how the data will be rendered. 
volumeMapper = vtk.vtkVolumeRayCastMapper() 
volumeMapper.SetMaximumImageSampleDistance(0.01) # function to reduce the spacing between each image 
volumeMapper.SetVolumeRayCastFunction(compositeFunction) 
volumeMapper.SetInputConnection(dataImporter.GetOutputPort()) 

# The class vtkVolume is used to pair the previously declared volume as well as the properties to be used when rendering that volume. 
volume = vtk.vtkVolume() 
volume.SetMapper(volumeMapper) 
volume.SetProperty(volumeProperty) 

# With almost everything else ready, its time to initialize the renderer and window, as well as creating a method for exiting the application 
renderer = vtk.vtkRenderer() 
renderWin = vtk.vtkRenderWindow() 
renderWin.AddRenderer(renderer) 
renderInteractor = vtk.vtkRenderWindowInteractor() 
renderInteractor.SetRenderWindow(renderWin) 

# We add the volume to the renderer ... 
renderer.AddVolume(volume) 
# ... set background color to white ... 
renderer.SetBackground(1,1,1) 
# ... and set window size. 
renderWin.SetSize(550, 550) 
renderWin.SetMultiSamples(4) 

# A simple function to be called when the user decides to quit the application. 
def exitCheck(obj, event): 
    if obj.GetEventPending() != 0: 
     obj.SetAbortRender(1) 

# Tell the application to use the function as an exit check. 
renderWin.AddObserver("AbortCheckEvent", exitCheck) 

renderInteractor.Initialize() 
# Because nothing will be rendered without any input, we order the first render manually before control is handed over to the main-loop. 
renderWin.Render() 
renderInteractor.Start() 
+0

レンダリング時に「何かが間違っている」よりも少し具体的になりますか?多分あなたは軸を交換したでしょうか? – Benjamin

+0

@Benjaminあなたのリプレイをありがとう。上記の画像によれば、私は視覚化しようとしているものと非常によく似ていますが、1つの平面(そのような種類の円)でしかありません。私は "深さ"の軸に何も表示されないので、私はレンダリングに何か問題があると思う傾向があります。私は軸をもう一度チェックアウトします! –

答えて

0

は最後に、私は解決策を見つけました。

  1. 変更不透明度が値:私は2つの重要な変更を行いました。黒ボクセルが多いので、不透明度を黒(0.0)と見なすように変更します。

    alphaChannelFunc.AddPoint(15000、0.0)。
    alphaChannelFunc.AddPoint(65536、1);

  2. 変更配列順序。 VTKの配列順序がFortran orderあると思われるので、私は正しく軸を定義するために次の機能が変更された:

    dataImporter.SetDataExtent(0、H-1、0、D-1、0、W-1)
    dataImporter.SetWholeExtent(0、H-1、0、D-1、0、W-1)

そして今、それは動作します!

関連する問題