[Prev] [Up]

Last update 09-Aug-2012

4. VTKをPythonで動かす --- 3Dイメージ可視化に向けて

VTKを使う ---概要---

3次元(3D)画像データをどのように観るか?

2次元(2D)データの場合は画面に映し出すだけでよく、いろいろなソフトウェアが利用出来ます。特にImageJはいろいろなフォーマットの画像データファイルに対応しており、広く用いられています。ImageJの特徴は、本体がJavaで書かれておりJavaで比較的容易にプラグインが作成できることです。実際、いろいろなプラグインが利用可能です。しかしImageJはもともと2Dイメージ用に開発されたものであり、3Dイメージデータの可視化や解析にはあまり向いていません。

3D画像データの扱いは、多くの人たち、とりわけCT画像やMRI画像を扱う医療関係者にとって大きな問題であり、この分野でソフトウェアの開発が行われて来ています。汎用性のある基礎的なプログラムを集めたライブラリとしては、OpenCV (Computer Vision)、VTK (Visualization Toolkit)、ITK (Insight Segmentation and Registration Toolkit)などがあります。ここではまず、3D画像データの可視化を主な目的としているVTKの利用を目指します。

VTKは、画像処理用のいろいろなツールを集めた巨大なライブラリです。それらをプログラムから呼んで利用します。VTK自体はC/C++で書かれていますが、呼ぶ側のプログラム言語としては、C/C++、Python、Tclの利用が可能です。手軽さを重視すると、現時点では呼ぶプログラム側の言語にPythonを使用するのが妥当と思われます。

VTKは膨大なライブラリであり、その全体像を把握することは容易ではありません。利用するにはexample programを走らせコードを理解し、自らの目的にあうパーツを集めてプログラムを作成していく必要があるようです。そのためにはかなりの経験(時間の浪費)が必要と予想されます。

とりあえずこの説明では、VTKを利用するためのシステムをWindowsで準備し、簡単なプログラムを走らせてみることにします。3D可視化のもう少し理論的なことは別の機会に。

必要なハードウェア

ある程度のメモリ量とグラフィック機能が必要なようです。
MacBook Air 11インチ(2 GBメモリ、NVIDIA GeForce 320M)でもそこそこ快適。
DELL Optiplex 760 (4 GBメモリ、Intel Core 2 Duo, E7400, on-chip graphics)では、かなりしんどい。

Windows機でグラフィックカードを試してみたところ、
NVIDIA GeForce 210ではまずまずの快適さ、
NVIDIA GeForce GT440を期待して入れたが、速さは一応OKだが、3D画像を回転した時に残像が残る、
ATI Radeon HD 2600 XTあるいはNVIDIA Quadro 600では問題のない快適、

となりました。

VTKのグラフィックはOpenGLを利用するので、同じNVIDIAの製品でもDirect X向きではなくOpenGL向きのボードの方が適しているのではないかと思います(NVIDIAではGeForceよりQuadro系列)。

必要なソフトウェア

  1. Microsoft Visual Studio 2010
    VTKのライブラリをBuildするために使用する。フリーのexpress版がダウンロード可能
    http://www.microsoft.com/japan/msdn/vstudio/express/
  2. CMake
    多数のファイルから構成されるプログラム、ライブラリを作成する時のツール。ライブラリをBuildするための下準備をする。
  3. Python
    科学計算などに適したインタープリタ言語。
  4. numpy
    Pythonのライブラリ
  5. scipy
    Pythonのライブラリ
  6. VTK
    2D/3D画像データを扱うライブラリ。ソースコードが公開されており、利用するにはBuildが必要。
  7. Qt4
    オプションとしてあれば操作性の優れたGUIを使うことが出来ます。

CMakeのインストール

CMakeダウンロードサイトより, Windows用のインストールファイル(cmake-2.8.8-win32-x86.exe)をダウンロード。

インストールするにはファイルをクリック。オプションはデフォールトのままでOK。

cmakeを起動するには、Windowsのスタート→すべてのプログラム→CMake 2.8→CMake (cmake-gui)をクリックします。

Python、numpy、scipyのインストール

PythonにはVersion 2の系列とVersion 3の系列がありますが、Version 3に後方互換性はありません。現在のVTKはVersion 3に未対応であるため、Python version 2.7.3を使用。

Pythonの公式サイトダウンロードサイトより、Windows用のインストーラをダウンロード。32ビットの64ビットのどちらを選ぶかは、使用しているWindowsが32ビット版か64ビット版であるかに依存。もしWindowsが64ビット版であれば64ビットを選ぶ方がよい。それ以外は32ビットを選ぶ。

ダウンロードした.msiファイルをクリック。オプションはデフォールトでOK。PATHを通しておく必要があります。

numpyとscipyは、コンパイルしてライブラリを作成する方法もりますが、ここでは簡便に作成されたライブラリをダウンロードします。

http://www.lfd.uci.edu/~gohlke/pythonlibs/より、numpy、scipyのインストールファイルをダウンロード。

Pythonが32ビット版の場合はnumpy-MKL-1.6.1-win32-py2.7.exe、Pythonが64ビット版の場合はnumpy-MKL-1.6.1-amd64-py2.7.exe。同じようにnumpyをダウンロード。numpy、scipyの順序でインストール。いずれも順番にクリックしていくだけでインストール出来るはずです。

これらが問題なくインストール出来ているかどうかの確認は、

  1. コマンドプロンプトを開く。
  2. pythonと入力
    Python 2.7.3....と表示され、プロンプト>>>が示される。
  3. 続けて、import numpyと入力すると、エラーメッセージなくプロンプトがでる。
  4. 続けて、import scipyと入力すると、エラーメッセージなくプロンプトがでる。
  5. Pythonを終了するには、quit()

VTKライブラリのBuild

  1. 最終的にVTKがインストールされる場所を決めます。ここでは例として、C:/WINAPP/VTKということにしておきます。
  2. VTKダウンロードサイトより、VTKのソースファイルvtk.5.10.0.zipを適当なフォルダー(例えばデスクトップ)にダウンロードする。クリックして解凍。vtk-5.10.0という名前のフォルダが作られ、そのなかにソースコード等が展開されます。
  3. ついでに例に使用されるデータをダウンロード。vtkdata-5.10.0.zip。C:/WINAPP/VTKの中に解凍(もしくは解凍して、フォルダを移します)。
  4. 大まかな流れとしては、まずcmakeでBuildの作業指令ファイルを作成し、それに基づいてVisual StuidoでBuildすることになります。
  5. CMakeを起動。
    一番上のソースコードのテキストボックスに、上記の解凍したvtk-5.10.0のフォルダ名を入れます。例えばC:/Users/xyz/Desktop/vtk-5.10.0とする。
    次のテキストボックスには、作成されたものが置かれるフォルダ名を入れます。例えば、C:/Users/xyz/Desktop/vtkBuildとします。
    中程にあるConfigureボタンをクリック。Buildフォルダがなければ作成するか尋ねられるのでYes。
    次にCMakeが何を作成するかを尋ねてくる。
    今まで32ビットで来ているならVisual Studio 10、64ビットで来ているならVisual Studio 10 Win64を選ぶ。
    compilerの指定はnativeのままでOK。Finishをクリック。しばらく時間(10分程度?)がかかる。
  6. 前の操作でCMakeはdefaultの設定を作成し、それらをCMakeCache.txtというファイルに書き出している。また画面の上半分が赤画面になって条件が示されている。この画面で条件を細かく設定しconfigureを繰り返すことになる。
  7. Advancedボックス(上の方の真ん中やや右寄り)をチェック
    BUILD_SHARED_LIBS → check
    CMAKE_CONFIGURATION_TYPES → Release
    CMAKE_INSTALL_PREFIX → C:/WINAPP/VTK
    VTK_DATA_ROOT → C:/WINAPP/VTK/vtkdata-5.10.0
    (Qt4を使用する場合は、VTK_USE_QT → check)
    VTK_WRAP_PYTHON → check
    ここで一度Configure。エラーが出てくる。指示に従ってVTK_USE_TKのcheckをはずし、再びConfigure。
    Python関係で次のように設定されているはず。
    PYTHON_EXECUTABLE C:/Python27/python.exe
    PYTHON_INCLUDE_DIR C:/Python27/include
    PYTHON_LIBRARY C:/Python27/libs/python27.lib
    もう一度Configure。エラーメッセージが出なければConfigureはこれで終了。
  8. Generateボタンをクリック。これでVTK.slnがvtkBuild内に作られます。cmakeを終了します。
  9. VTK.slnを右ボタンクリックし、Visula Studioを起動。画面の上のConfigurationにはReleaseが、Platformにはwin32もしくはx64が表示されます。
  10. Visual StudioのSolution ExplorerにALL_BUILDというプロジェクトが表示されるので、右クリックでBuild。膨大な数のファイルをコンパイル、リンクするので時間がかかります(1〜数時間)。数分見て、エラーなしに動いているようであれば、後は放置。
  11. ALL_BUILDが無事終わったなら、Solution ExplorerのRUN_TESTを右クリックでBuild。テストプログラムが走ります。見ていると画面がすぐに切り替わるのでよくわかりませんが、このようなことが出来るのか、という感触は得られます。必ずしもすべてのテストプログラムをパス出来るわけではありません。
  12. Solution ExplorerのINSTALLを右クリックでBuild。Pythonの関係も含めてプログラム類がインストールフォルダにコピーされます。
  13. PythonとVTKを結びつける必要があります。通常、追加されたPythonパッケージは、Pythonフォルダのlib/site-packages以下に置かれます。上記のインストールではvtkのpython関係ファイルは、VTKインストールフォルダの/lib/site-packagesに置かれているので、これらをつなぐために、C:/Python27/lib/site-packagesにvtk.pthという名前のテキストファイルを作成し、内容はC:/WINAPP/VTK/lib/site-packagesとすします。。
  14. 問題なくインストール出来ているかは、コマンドプロンプトからPythonを起動し、import vtkでエラーが起きるかどうかで判断出来ます。

Mac/LinuxでのBuild

MacOSもしくはLinuxの場合は、cmakeを利用してMakefileを作成し、makeでライブラリをbuildします。そして管理者権限を有する状態で、make installを行います。MacOSの場合は、cmakeで.xcodeprojを作成し、XCodeを用いてbuildすることも出来ます。cmakeでの設定条件は、基本的にはWindowsの場合と同じです。

データファイルの準備

レーザー走査顕微鏡で得たデータとしては、モノクロ16ビットデータが基本的なものだと思われます。モノクロ16ビットデータのTIFFファイルをVTKで読むことは出来ますが、ファイル内に複数の画像が含まれる形式(multi-page format)はプログラムのバグのために読めない様です(下記参照)。

このバグを回避するためには、multi-pageファイルを単ページファイルに変換し、それを取り込むクラスvtkTIFFReaderがあります。ファイルの変換は、ImageJ(またはImageJ64)を用いて行うのが便利です。変換の時に、Voxelサイズ(x, y, z)値を正確に設定しておくことが大切です(特にz)。

  1. ImageJを起動し、multi-page TIFFファイルを開く(例としてNeuron.tifとしておく)。
  2. File → Save As → Image Sequence . . .
  3. Format: TIFF
    Name → Neuron_ (適当なファイルの名前)
    Start At → 0
    Digits → 2 (ファイル名の数値の桁数)
    OKとするとファイルを作成するフォルダを尋ねてくるので、しかるべきところを指定してOK。
  4. Neuron_00.tif ∼ Neuron_40.tif(例えば)が作られます。

vtkTIFFReaderのバグ修正

vtkTIFFReaderはTIFFファイルを読み込むためのクラスです。単一画像のファイルは問題なく読めます。モノクロ16ビットでmulti-pageのファイルはエラーで中断してしまいます。ソースファイルを調べたところ、multi-pageファイルを読む場合は、ReadVolumeという名前の関数が用いられますが、その関数をよぶ前にOutputExtent変数が設定されていないためにエラーが起きるという事がわかりました。その応急的な修正は下記の通りです。この修正が他に影響を及ぼす可能性については検討していません。もともとこの応急的修正はvtk-5.8用のものですが、vtk-5.10でも働きます。

  1. vtkTIFFReader.h
    100行目あたりに、publicな関数として、
    void SetOutputExtentInternalXXX( int* outExt );
    を加える。
  2. vtkTIFFReader.cxx
    場所はどこでもよいが、関係するReadImageInternalの直前ということであれば1520行目あたり。
    関数の本体を加える。
    void vtkTIFFReader::SetOutputExtentInternalXXX( int* outExt )
    {
        this->OutputExtent = outExt;
    }
  3. vtkTIFFReader.cxx
    570行目あたりで、
    self->ReadVolume( outPtr );
    の直前に
    self->SetOutputExtentInternalXXX( outExtent );
    を加える。

別の方法として、vtkTIFFReader.cxxの570行目あたりの
self->ReadVolume( outPtr );
の前に、その20行程下で用いられている関数
vtkTIFFReaderUpdate2(self, reader, outPtr2, outExtent);
を加えるだけでもよいのかもしれませんが、十分テストしていません。


3D可視化プログラム vol05.py

バグ修正後のライブラリで動作します。
作業フォルダに、このpythonプログラムファイルとデータファイルが置かれていることを想定しています。コマンドプロンプトを起動し、cdにより作業フォルダに移動し、
python vol05.py
でプログラムを動かします。

#!/usr/local/bin/python
import os
import vtk
from vtk.util.colors import *
    
def readFile(filename):
    print filename
reader = vtk.vtkTIFFReader() reader.SetFileName(filename) reader.GetOutput().SetOrigin(0.0,0.0,0.0) reader.SetDataExtent(0,511,0,511,0,40) reader.SetDataSpacing(1.0, 1.0, 1.0) reader.Update() print reader.GetOutput().GetDimensions() print reader.GetOutput().GetScalarSize() return reader.GetOutput() def cellSurface(cell): med = vtk.vtkImageMedian3D() med.SetInput(cell) med.SetKernelSize(3,3,2) med.ReleaseDataFlagOff() surface = vtk.vtkMarchingCubes() surface.SetInputConnection(med.GetOutputPort()) surface.ComputeGradientsOn() surface.ComputeScalarsOff() surface.SetValue(0, 380) return surface.GetOutput() def main(): neuron = readFile('./Neuron2.tif') glia = readFile('./Microglia2.tif') neuronSurface = cellSurface(neuron) gliaSurface = cellSurface(glia) # mapper mapper1 = vtk.vtkDataSetMapper() mapper1.SetInput(neuronSurface) mapper2 = vtk.vtkDataSetMapper() mapper2.SetInput(gliaSurface) # actor actor1 = vtk.vtkActor() actor1.SetMapper(mapper1) actor1.GetProperty().SetColor(green) actor2 = vtk.vtkActor() actor2.SetMapper(mapper2) actor2.GetProperty().SetColor(red) # renderer ren = vtk.vtkRenderer() ren.AddActor(actor1) ren.AddActor(actor2) ren.SetBackground(0.3,0.4,0.2) # render window and interactor renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren) renWin.SetSize(800,800) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) iren.Initialize() iren.Start() if __name__ == '__main__': main()

VTK windowでのマウス・キー操作

  1. J: joystickモード。左クリックで回転し続ける
  2. T: trackballモード。左クリックで画像を動かす
  3. R: 画像をreset
  4. F: Fly toもしくはFocus
  5. 右クリック:画面上半分では画像拡大、画面下半分では画像縮小

動画への出力

mpegファイルに出力する事が可能です。しかし著作権の問題を避けるために、VTKのパッケージにはmepgのエンコーダーは含まれていないので、mpeg2encoderを別にダウンロードし、ライブラリlibMPEG2Encodeを作らなくてはなりません。


[Prev] [Up]