I used vtkImageReslice to obtain slices for each axis and was able to fuse multiple slices. However, after using vtkImageMapToColors, there was a problem where the projection relationship between the color mapped image and the volume rendering was incorrect. Is there any way to solve this problem? Below is a demo of the perspective relationship error bug that I described
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkVolume.h>
#include <vtkVolumeProperty.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkPiecewiseFunction.h>
#include <vtkColorTransferFunction.h>
#include <vtkImageResliceMapper.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkImageCast.h>
#include <vtkCamera.h>
#include <vtkImageMapToColors.h>
#include <vtkLookupTable.h>
int main(int argc, char* argv[])
{
// 创建体数据 (Volume Data)
vtkSmartPointer<vtkImageData> volumeData = vtkSmartPointer<vtkImageData>::New();
volumeData->SetDimensions(20, 20, 20);
volumeData->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
// 填充体数据
for (int z = 0; z < 20; z++)
{
for (int y = 0; y < 20; y++)
{
for (int x = 0; x < 20; x++)
{
unsigned char* pixel = static_cast<unsigned char*>(volumeData->GetScalarPointer(x, y, z));
if (x > 10 | y>10|z>10)
pixel[0] = static_cast<unsigned char>(0);
else
{
pixel[0] = static_cast<unsigned char>((x + y + z) % 256); // 生成简单的体数据
}
}
}
}
// 创建颜色传递函数和不透明度传递函数
vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction = vtkSmartPointer<vtkColorTransferFunction>::New();
colorTransferFunction->AddRGBPoint(0.0, 0.0, 1.0, 0.0);
colorTransferFunction->AddRGBPoint(255.0, 0, 1.0, 0);
vtkSmartPointer<vtkPiecewiseFunction> opacityTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
opacityTransferFunction->AddPoint(0.0, 0.3);
opacityTransferFunction->AddPoint(255.0, 1);
// 创建体绘制属性
vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetColor(colorTransferFunction);
volumeProperty->SetScalarOpacity(opacityTransferFunction);
volumeProperty->ShadeOn();
volumeProperty->SetInterpolationTypeToLinear();
// 创建体绘制映射器
vtkSmartPointer<vtkGPUVolumeRayCastMapper> volumeMapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
volumeMapper->SetInputData(volumeData);
volumeMapper->SetBlendModeToComposite();
// 创建体对象
vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);
// 创建 ImageActor 来显示切片
vtkSmartPointer<vtkImageActor> imageActor = vtkSmartPointer<vtkImageActor>::New();
vtkSmartPointer<vtkImageMapToColors> colorMapper = vtkSmartPointer<vtkImageMapToColors>::New();
vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
colorMapper->SetInputData(volumeData);
lookupTable->SetNumberOfTableValues(256);
lookupTable->SetAlphaRange(1.0, 1.0); // 设置 alpha 值范围为完全不透明
lookupTable->Build();
// 设置颜色,例如将灰度映射为红色到蓝色的渐变
for (int i = 0; i < 256; i++)
{
lookupTable->SetTableValue(i, i / 255.0, 0.0, 1.0 - i / 255.0, 1); // 红色到蓝色渐变
}
colorMapper->SetLookupTable(lookupTable);
imageActor->GetMapper()->SetInputConnection(colorMapper->GetOutputPort());
//imageActor->GetMapper()->SetInputData(volumeData);
imageActor->SetPosition(0.0, 0.0, 30); // 将 ImageActor 放置在 z=25 的位置
// 创建渲染器并添加体和 ImageActor
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(imageActor);
renderer->AddVolume(volume);
renderer->SetBackground(0.1, 0.2, 0.4); // 设置背景颜色
// 创建渲染窗口
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
// 创建交互器并设置交互样式
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
renderWindowInteractor->SetInteractorStyle(style);
// 开始渲染
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}