a voxel (i,j,k) to 3D point (x,y,z) conversion matrix
an array of 3D points (x,y,z) defining a closed surface
As I am new to VTK, I was looking for help to see what would be the most efficient / shortest way to compute a boolean 3D matrix that tells me which points of the 3D voxel grid are inside the contour, and which ones are not. I would prefer not to use external batch-processes, just C++ API libraries like VTK or ITK.
I was taking a look at different examples (see below), and wanted to ask about what would be in your opinion the best way to go.
Note: the original XYZ contour data are coming from a DICOM RTstruct, so they are arranged as a stack of 2D closed contour slices. Maybe the PointInPolygon2D function might be the most straightforward solution?
RT structure sets are horrible. We worked on developing custom VTK filters for converting it to closed surface in SlicerRT (with support for keyhole technique, branching, smooth end-capping, etc.). If you only need to process special cases (e.g., no branching, no keyholes) then you can find lots of naive implementations out there, but if you need a full solution, which is expected to work for all data sets, then the only open-source solution that I’m aware of is in SlicerRT.
You can link MRML library and SlicerRT logic classes into your own application, but it is much simpler to not dissect these libraries but use as is. You can run the conversion from command-line, or use it from 3D Slicer’s Python environment (just another virtual Python environment where you can install any other Python packages, etc.), with an application GUI, without a GUI, or using Slicer as a Jupyter notebook kernel.
See a script for converting a DICOM folder structure containing of RT Structure sets to labelmap volumes in NRRD format (and optionally corresponding CTs as well) and usage instructions here:
It is recommended to provide input CT images as well, because RT structure set does not contain slice spacing information, so without CT images the algorithm just tries to guess the spacing from the closest contour distance, which is of course not always optimal.
I managed to call the Python script you suggested from my C++ application, and then reading the NRRD back in C++. However, I am unsure what would be the best way to convert the NRRD file content into a raw boolean 3D matrix with the dimensions of the CT.
bool roi[61][61][46];
where roi[i][j][k] would tell you if voxel i,j,k is part of the ROI or not.
I would recommend to start using SlicerRT using its GUI in 3D Slicer. Once you confirmed that it does what you need you can start using it via Python scripting or C++ (there is a complete example here for using SlicerRT for creating a solid segmentation object from a set of contours - for importing Osirix ROI files).