【问题标题】:VTK Volume Visualization IssueVTK 体积可视化问题
【发布时间】:2018-01-04 01:33:36
【问题描述】:

我正在使用带有 C++ 的 vtk 库来生成和可视化一些具有给定颜色和透明度映射的合成体素数据。一个例子如下所示:

如图,数据一般是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。 有什么建议吗?

编辑: 我正在添加一个等效代码,它将演示我面临的确切问题:

ma​​in.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)

但是,如果我让 X1=1,输出窗口是空的。

编辑:

我刚刚观察到,屏幕上显示的某个维度上的体素数量总是比该维度中的最大体素数量少一。例如,如果 X1=X2=X3=10,则在 vtkwindow 上显示的每个维度中的体素数为 9。这不是我所期望的。我认为这是 X1=1 的问题,它使 1-1=0 体素显示。 有什么建议??

【问题讨论】:

  • 所以你的数据并没有真正变成二维的,它只是一层体素?你检查过你的单层图像数据的单元格数量是否符合你的预期吗?也许存在某种编号问题,但如果不查看更多代码,这很难说。
  • 是的,它只是一层体素。我检查了单层图像数据中的单元格数量,与预期一致。我将很快发布最低限度的等效代码。

标签: c++ image-processing visualization vtk cellular-automata


【解决方案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 个)

【讨论】:

    猜你喜欢
    • 2018-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多