2017-07-28 38 views
3

私はvtkライブラリをC++で使用して、特定の色と透明度のマッピングを使っていくつかの合成ボクセルデータを生成して可視化しています。例を以下に示します。 Sample ImageVTKボリュームの可視化の問題

図に示すように、データは一般に3Dであり、うまくいきます。ただし、特定のケースでは、データが2Dになったときにと表示されます。

私のコードのほんの一部が役に立つと思われます。

imageData = vtkSmartPointer<vtkImageData>::New(); 
imageData->SetDimensions(X1, X2, X3); //For 2D, one of X1,X2 & X3=1 
imageData->AllocateScalars(VTK_INT, 1); 
int* I = new int[X1X2X3](); //int X1X2X3 = X1*X2*X3 
I = static_cast<int*>(imageData->GetScalarPointer()); 

2Dの場合、X1 = 1またはX2 = 1またはX3 = 1です。 提案がありますか?

EDIT:

main.cppに

//#include <vtkAutoInit.h> // if not using CMake to compile, necessary to use this macro 
//#define vtkRenderingCore_AUTOINIT 3(vtkInteractionStyle, vtkRenderingFreeType, vtkRenderingOpenGL2) 
//#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL2) 
//#define vtkRenderingContext2D_AUTOINIT 1(vtkRenderingContextOpenGL2) 
#include <vtkSmartPointer.h> 
#include <vtkActor.h> 
#include <vtkRenderWindow.h> 
#include <vtkRenderer.h> 
#include <vtkRenderWindowInteractor.h> 
#include <vtkSmartVolumeMapper.h> 
#include <vtkColorTransferFunction.h> 
#include <vtkVolumeProperty.h> 
#include <vtkSampleFunction.h> 
#include <vtkPiecewiseFunction.h> 
#include <vtkImageData.h> 
#include <stdlib.h> 
using namespace std; 

int main() 
{ 
    //Declaring Variables 
    vtkSmartPointer<vtkImageData> imageData; 
    vtkSmartPointer<vtkVolumeProperty> volumeProperty; 
    vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity; 
    vtkSmartPointer<vtkColorTransferFunction> color; 
    vtkSmartPointer<vtkVolume> volume; 
    vtkSmartPointer<vtkSmartVolumeMapper> mapper; 
    vtkSmartPointer<vtkActor> actor; 
    vtkSmartPointer<vtkRenderer> renderer; 
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor; 
    vtkSmartPointer<vtkRenderWindow> renderWindow; 
    int* I; 
    int X1, X2, X3, X1X2X3; 

    //Assigning Values , Allocating Memory 
    X1 = 10; 
    X2 = 10; 
    X3 = 10; 
    X1X2X3 = X1*X2*X3; 
    I = new int[X1X2X3](); 
    imageData = vtkSmartPointer<vtkImageData>::New(); 
    volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New(); 
    compositeOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New(); 
    color = vtkSmartPointer<vtkColorTransferFunction>::New(); 
    volume = vtkSmartPointer<vtkVolume>::New(); 
    mapper = vtkSmartPointer<vtkSmartVolumeMapper>::New(); 
    actor = vtkSmartPointer<vtkActor>::New(); 
    renderer = vtkSmartPointer<vtkRenderer>::New(); 
    renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); 
    renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); 
    volumeProperty->ShadeOff(); 
    volumeProperty->SetInterpolationType(0); 
    volumeProperty->SetColor(color); 
    volumeProperty->SetScalarOpacity(compositeOpacity); 
    imageData->SetDimensions(X1, X2, X3); 
    imageData->AllocateScalars(VTK_INT, 1); 
    I = static_cast<int*>(imageData->GetScalarPointer()); 
    renderWindow->AddRenderer(renderer); 
    renderWindowInteractor->SetRenderWindow(renderWindow); 
    renderer->SetBackground(0.5, 0.5, 0.5); 
    renderWindow->SetSize(800, 800);  
    mapper->SetBlendModeToComposite(); 
    imageData->UpdateCellGhostArrayCache(); 
    mapper->SetRequestedRenderModeToRayCast(); 
    mapper->SetInputData(imageData); 
    volume->SetMapper(mapper); 
    volume->SetProperty(volumeProperty); 
    renderer->AddViewProp(volume); 
    volumeProperty->ShadeOff(); 

    //Setting Voxel Data and Its Properties 
    for (int i = 0; i < X1X2X3; i++) 
    { 
     I[i] = i; 
     compositeOpacity->AddPoint(i, 1); 
     color->AddRGBPoint(i, double(rand())/RAND_MAX, double(rand())/RAND_MAX, double(rand())/RAND_MAX); 
    } 

    renderer->ResetCamera(); 
    renderWindow->Render(); 
    renderWindowInteractor->Start(); 
    getchar(); 
    return 0; 
} 

CMakeLists.txt

私が直面しています正確な問題を示すであろう、同等のコードを追加してい
cmake_minimum_required(VERSION 3.0) 
project(EvoSim) 
set(CMAKE_CXX_STANDARD 14) 
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) 
set(CMAKE_USE_RELATIVE_PATHS ON) 
#GRABBING VTK 
find_package(VTK REQUIRED) 
include(${VTK_USE_FILE}) 

add_executable(MAIN main.cpp) 
target_link_libraries(MAIN ${VTK_LIBRARIES}) 

これは、以下のような出力につながります(X1 = X2 = X3 = 10の場合) enter image description here

ただし、X1 = 1にすると、出力ウィンドウは空になります。

EDIT:

私は画面に表示され、特定の次元に沿ったボクセルの数ことが観察され、常にその寸法のボクセルの最大数より1少ないです。たとえば、X1 = X2 = X3 = 10の場合、vtkwindowに表示される各次元のボクセルの数は9です。これは私が期待するものではありません。私はこれがX1 = 1の問題であると考えています.1 = 0のボクセル表示になります。 提案がありますか?

+0

を見ているので、あなたのデータは実際にそれが一つだけある、2Dなりません。ボクセルの単層?単層画像データのセル数が期待どおりであるかどうかを確認しましたか?おそらく何らかの番号の問題がありますが、それ以上のコードを見ることなく言うのは難しいです。 – mululu

+0

はい、単なるボクセルの1つのレイヤーです。私は単層の画像データのセル数を確認しましたが、それは期待通りです。すぐに最低限の同等のコードを投稿します。 –

答えて

1

これは長い間答えられていませんでした。だから私は私のソリューション/回避策を追加しています。 画像データの各次元に余分なダミーレイヤーを追加する必要がありました。 [コードimageData-> SetDimensions(X1 +1、X2 + 1、X3 + 1)のこの行を参照してください。]。休息は自明です。

#pragma once 
//#include <vtkAutoInit.h> // if not using CMake to compile, necessary to use this macro 
//#define vtkRenderingCore_AUTOINIT 3(vtkInteractionStyle, vtkRenderingFreeType, vtkRenderingOpenGL2) 
//#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL2) 
//#define vtkRenderingContext2D_AUTOINIT 1(vtkRenderingContextOpenGL2) 
#include <vtkSmartPointer.h> 
#include <vtkActor.h> 
#include <vtkRenderWindow.h> 
#include <vtkRenderer.h> 
#include <vtkRenderWindowInteractor.h> 
#include <vtkSmartVolumeMapper.h> 
#include <vtkColorTransferFunction.h> 
#include <vtkVolumeProperty.h> 
#include <vtkSampleFunction.h> 
#include <vtkPiecewiseFunction.h> 
#include <vtkImageData.h> 
#include <stdlib.h> 
#include <numeric>  // std::iota 
using namespace std; 

int main() 
{ 
    //Declaring Variables 
    vtkSmartPointer<vtkImageData> imageData; 
    vtkSmartPointer<vtkVolumeProperty> volumeProperty; 
    vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity; 
    vtkSmartPointer<vtkColorTransferFunction> color; 
    vtkSmartPointer<vtkVolume> volume; 
    vtkSmartPointer<vtkSmartVolumeMapper> mapper; 
    vtkSmartPointer<vtkActor> actor; 
    vtkSmartPointer<vtkRenderer> renderer; 
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor; 
    vtkSmartPointer<vtkRenderWindow> renderWindow; 
    int X1, X2, X3, X1X2X3; 
    //Assigning Values , Allocating Memory 
    X1 = 10; 
    X2 = 10; 
    X3 = 10; 
    X1X2X3 = X1*X2*X3; 
    imageData = vtkSmartPointer<vtkImageData>::New(); 
    imageData->SetDimensions(X1 + 1, X2 + 1, X3 + 1); 
    imageData->AllocateScalars(VTK_INT, 1); 
    volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New(); 
    compositeOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New(); 
    color = vtkSmartPointer<vtkColorTransferFunction>::New(); 
    volume = vtkSmartPointer<vtkVolume>::New(); 
    mapper = vtkSmartPointer<vtkSmartVolumeMapper>::New(); 
    actor = vtkSmartPointer<vtkActor>::New(); 
    renderer = vtkSmartPointer<vtkRenderer>::New(); 
    renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); 
    renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); 
    volumeProperty->ShadeOff(); 
    volumeProperty->SetInterpolationType(0); 
    volumeProperty->SetColor(color); 
    volumeProperty->SetScalarOpacity(compositeOpacity); 
    imageData->AllocateScalars(VTK_INT, 1); 
    renderWindow->AddRenderer(renderer); 
    renderWindowInteractor->SetRenderWindow(renderWindow); 
    renderer->SetBackground(0.5, 0.5, 0.5); 
    renderWindow->SetSize(800, 800); 
    mapper->SetBlendModeToComposite(); 
    imageData->UpdateCellGhostArrayCache(); 
    mapper->SetRequestedRenderModeToRayCast(); 
    mapper->SetInputData(imageData); 
    volume->SetMapper(mapper); 
    volume->SetProperty(volumeProperty); 
    renderer->AddViewProp(volume); 
    volumeProperty->ShadeOff(); 

    //I is supposed to store the 3D data which has to be shown as volume visualization. This 3D data is stored 
    //as a 1D array in which the order of iteration over 3 dimensions is x->y->z, this leads to the following 
    //3D to 1D index conversion farmula index1D = i + X1*j + X1*X2*k 
    vector<int> I(X1X2X3,0); // No need to use int* I = new int[X1X2X3] //Vectors are good 
    std::iota(&I[0], &I[0] + X1X2X3, 1); //Creating dummy data as 1,2,3...X1X2X3 

    //Setting Voxel Data and Its Properties 
    for (int k = 0; k < X3 + 1 ; k++) 
    { 
     for (int j = 0; j < X2 + 1 ; j++) 
     { 
      for (int i = 0; i < X1 + 1 ; i++) 
      { 
       int* voxel = static_cast<int*>(imageData->GetScalarPointer(i, j, k)); 

       if (i==X1 || j== X2 || k==X3) 
       { 
        //Assigning zeros to dummy voxels, these will not be displayed anyways 
        voxel[0] = 0; 
       } 

       else 
       { 
        //copying data from I to imagedata voxel 
        voxel[0] = I[i + X1*j + X1*X2*k]; 
       }    
      } 
     } 
    } 

    //Setting Up Display Properties 
    for (int i = 1; i < X1X2X3; i++) 
    { 
     compositeOpacity->AddPoint(i, 1); 
     color->AddRGBPoint(i, double(rand())/RAND_MAX, double(rand())/RAND_MAX, double(rand())/RAND_MAX); 
    } 

    renderer->ResetCamera(); 
    renderWindow->Render(); 
    renderWindowInteractor->Start(); 
    getchar(); 
    return 0; 
} 

今、各寸法(上記のコードあたりの10)内のボクセル数の期待値は、正しく

enter image description here