ITKHelper

Source

index.js
import macro from 'vtk.js/Sources/macro';
import vtkImageData from 'vtk.js/Sources/Common/DataModel/ImageData';
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';

const { vtkErrorMacro } = macro;

/**
* Converts an itk.js image to a vtk.js image.
*
* Requires an itk.js image as input.
*/
function convertItkToVtkImage(itkImage, options = {}) {
const vtkImage = {
origin: [0, 0, 0],
spacing: [1, 1, 1],
};

const dimensions = [1, 1, 1];
const direction = [1, 0, 0, 0, 1, 0, 0, 0, 1];

for (let idx = 0; idx < itkImage.imageType.dimension; ++idx) {
vtkImage.origin[idx] = itkImage.origin[idx];
vtkImage.spacing[idx] = itkImage.spacing[idx];
dimensions[idx] = itkImage.size[idx];
for (let col = 0; col < itkImage.imageType.dimension; ++col) {
// ITK (and VTKMath) use a row-major index axis, but the direction
// matrix on the vtkImageData is a webGL matrix, which uses a
// column-major data layout. Transpose the direction matrix from
// itkImage when instantiating that vtkImageData direction matrix.
direction[col + idx * 3] =
itkImage.direction.data[idx + col * itkImage.imageType.dimension];
}
}

// Create VTK Image Data
const imageData = vtkImageData.newInstance(vtkImage);

// Create VTK point data -- the data associated with the pixels / voxels
const pointData = vtkDataArray.newInstance({
name: options.scalarArrayName || 'Scalars',
values: itkImage.data,
numberOfComponents: itkImage.imageType.components,
});

imageData.setDirection(direction);
imageData.setDimensions(...dimensions);
// Always associate multi-component pixel types with vtk.js point data
// scalars to facilitate multi-component volume rendering
imageData.getPointData().setScalars(pointData);

// Associate the point data that are 3D vectors / tensors
// Refer to itk-js/src/PixelTypes.js for numerical values
switch (itkImage.imageType.pixelType) {
case 1: // Scalar
break;
case 2: // RGB
break;
case 3: // RGBA
break;
case 4: // Offset
break;
case 5: // Vector
if (
itkImage.imageType.dimension === 3 &&
itkImage.imageType.components === 3
) {
imageData.getPointData().setVectors(pointData);
}
break;
case 6: // Point
break;
case 7: // CovariantVector
if (
itkImage.imageType.dimension === 3 &&
itkImage.imageType.components === 3
) {
imageData.getPointData().setVectors(pointData);
}
break;
case 8: // SymmetricSecondRankTensor
if (
itkImage.imageType.dimension === 3 &&
itkImage.imageType.components === 6
) {
imageData.getPointData().setTensors(pointData);
}
break;
case 9: // DiffusionTensor3D
if (
itkImage.imageType.dimension === 3 &&
itkImage.imageType.components === 6
) {
imageData.getPointData().setTensors(pointData);
}
break;
case 10: // Complex
break;
case 11: // FixedArray
break;
case 12: // Array
break;
case 13: // Matrix
break;
case 14: // VariableLengthVector
break;
case 15: // VariableSizeMatrix
break;
default:
vtkErrorMacro(
`Cannot handle unexpected ITK.js pixel type ${
itkImage.imageType.pixelType
}`
);
return null;
}

return imageData;
}

export default {
convertItkToVtkImage,
};