2014-02-19 42 views
1

我一直在使用vtkImageData和一个组件进行体绘制。现在我想基于现有的vtkImageData创建一个新的vtkImageData。新的vtkImageData有两个组件,第一个组件存储标量数据与现有的相同,第二个组件存储我将分配的数据。我的代码片段是这样的:vtkImageData如何存储多个组件以及如何渲染它

// I read a series of dicom file: 
vtkImageData *originalData = reader->GetOutput(); 
int dim[3]; 
double spa[3], ori[3]; 
originalData->GetDimensions(dim); 
originalData->GetSpacing(spa); 
originalData->GetOrigin(ori); 

//newData is created based on the originalData's dimensions spacing and origin. 
vtkImageData *newData = vtkImagaData::New(); 
newData->SetDimensions(dim); 
newData->SetScalarTypeToShort(); 
newData->SetSpacing(spa); 
newData->SetNumberOfScalarComponents(2);//newData's component is two 
newData->SetOrigin(ori); 
newData->AllocateScalars(); 

//Now I have some puzzles:How does the vtkImageData store multiple components, I think it store data one point by one point, because each point now have two components, so it looks like this in memory: Point1(component1, component2), Point2(component1, component2), Point3.... is it right??? 
//Then I traverse the new data and assign each component of each point 
short *originalDataPointer = (short *)originalData->GetScalarPointer(); 
short *newDataPointer = (short *)newData->GetScalarPointer(); 
for(int i = 0; i < dim[0]*dim[1]*dim[2]; i++){ 
    //I assign each point's first component and second component the same data as the original data. 
    originalDataPointer[i*2] = newDataPointer[i]; 
    originalDataPointer[i*2 + 1] = newDataPointer[i]; 
} 

vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction = 
    vtkSmartPointer<vtkColorTransferFunction>::New(); 
colorTransferFunction->AddRGBPoint(0.0, 0.0, 0.5, 0.0); 
colorTransferFunction->AddRGBPoint(60.0, 1.0, 0.0, 0.0); 
colorTransferFunction->AddRGBPoint(128.0, 0.2, 0.1, 0.9); 
colorTransferFunction->AddRGBPoint(196.0, 0.27, 0.21, 0.1); 
colorTransferFunction->AddRGBPoint(255.0, 0.8, 0.8, 0.8); 
vtkSmartPointer<vtkPiecewiseFunction> piecewiseFunction = 
    vtkSmartPointer<vtkPiecewiseFunction>::New(); 
piecewiseFunction->AddPoint(20, 0.0); 
piecewiseFunction->AddPoint(120, 0.1); 
piecewiseFunction->AddPoint(255, 0.2); 
vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> fixedPointVolumeRayCastMapper = 
    vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New(); 
fixedPointVolumeRayCastMapper->SetNumberOfThreads(1); 

fixedPointVolumeRayCastMapper->SetInput(newData); 
vtkSmartPointer<vtkVolumeProperty> volumeProperty = 
    vtkSmartPointer<vtkVolumeProperty>::New(); 
//I want to use the first component as the input of opacity transfer function 
volumeProperty->SetScalarOpacity(0, piecewiseFunction); 
// I want to use the second component as the input of color transfer function 
volumeProperty->SetColor(1, colorTransferFunction); 

vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New(); 
volume->SetMapper(fixedPointVolumeRayCastMapper); 
volume->SetProperty(volumeProperty); 

vtkSmartPointer<vtkOpenGLRenderer> renderer = vtkSmartPointer<vtkOpenGLRenderer>::New(); 
renderer->AddVolume(volume); 
vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New(); 
renWin->AddRenderer(renderer); 
renWin->Render(); 

体绘制的结果是仅具有相同的传递函数的一个部件的原始数据的结果不同势。结果应该不一样吗?

每个像素都有两个分量,第一个确定它是不透明的,第二个确定它的颜色,我该怎么做?

+0

您是否希望每个像素都应具有不透明度变量以及用于体绘制目的的强度? – Tab

+0

每个像素都有两个分量,第一个确定是不透明度,第二个确定是不是颜色,我应该怎么做@Tab – user3197205

+0

通常我们会为不是每个像素分配一个不透明度,而是指定一个特定的强度。你可以做一件事情,设置一个新的标量字段,它将是不透明的,并设置为有效标量字段,您可以为其设置不同的不透明度传输函数。 HTH – Tab

回答

1

如果有人仍然在意:您必须关闭“独立组件”。

volumeProperty->IndependentComponentsOff() 

默认为打开。

同时设定第一色功能:

volumeProperty->SetColor(colorTransferFunction); // not SetColor(1,... 

http://www.vtk.org/doc/release/5.10/html/classvtkVolumeProperty.html

数据是否具有独立的组件,或者做一些只定义颜色?如果IndependentComponents处于On状态(默认状态),则每个组件都将独立通过查找表以确定RGBA,并着色。某些卷映射器可以处理1至4个组件无符号字符或无符号短数据(请参阅每个映射器头文件以确定功能)。如果IndependentComponents处于关闭状态,则必须有2个或4个组件数据。 对于2分量数据,第一个通过第一个颜色转移函数,第二个分量通过第一个不透明度转移函数。法线将从第二个组件生成。对于4个分量数据,前三个将直接表示RGB(无查找表)。第四个分量将通过不透明度的第一个标量不透明度传递函数。法线将从第四个组件生成。

相关问题