SimpleITK add filter / module

simpleitk
dicom

(Gustavo Tajes Genga) #1

Hi all,

I have a very simple ITK pipeline wrote some time ago that reads a dicom serie and generate a mesh, based in this example:

bool VtkGenerator::generate() {
using PixelType = unsigned short;
constexpr unsigned int Dimension = 3;
using ImageType = itk::Image< PixelType, Dimension >;

using ReaderType = itk::ImageSeriesReader< ImageType >;
ReaderType::Pointer reader = ReaderType::New();

using ImageIOType = itk::GDCMImageIO;
ImageIOType::Pointer dicomIO = ImageIOType::New();
reader->SetImageIO( dicomIO );

using NamesGeneratorType = itk::GDCMSeriesFileNames;
NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
nameGenerator->SetUseSeriesDetails( true );
nameGenerator->AddSeriesRestriction("0008|0021" );
nameGenerator->SetDirectory( directory );

using SeriesIdContainer = std::vector< std::string >;
const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
auto seriesItr = seriesUID.begin();
auto seriesEnd = seriesUID.end();
std::cout << std::endl << "The directory: " << std::endl;
std::cout << std::endl << directory << std::endl << std::endl;
std::cout << "Contains the following DICOM Series: ";
std::cout << std::endl << std::endl;
while( seriesItr != seriesEnd )
{
    std::cout << seriesItr->c_str() << std::endl;
    ++seriesItr;
}

std::string seriesIdentifier = seriesUID.begin()->c_str();

std::cout << std::endl << std::endl;
std::cout << "Now reading series: " << std::endl << std::endl;
std::cout << seriesIdentifier << std::endl;
std::cout << std::endl << std::endl;

using FileNamesContainer = std::vector< std::string >;
FileNamesContainer fileNames;
fileNames = nameGenerator->GetFileNames( seriesIdentifier );

std::cout << std::endl << std::endl;
std::cout << "List of filenames: " << std::endl << std::endl;

for (std::string file : fileNames) {
    std::cout << file << std::endl;
    std::cout << std::endl;
}

reader->SetFileNames( fileNames );

try {
    reader->Update();
} catch (itk::ExceptionObject &ex) {
    std::cout << ex << std::endl;
    return false;
}

using MeshType = itk::Mesh< double, Dimension >;
using WriterType = itk::MeshFileWriter< MeshType >;

using FilterType = itk::BinaryMask3DMeshSource< ImageType, MeshType >;
FilterType::Pointer filter = FilterType::New();
filter->SetInput( reader->GetOutput() );
filter->SetObjectValue( 255 );

WriterType::Pointer writer = WriterType::New();
char * res = new char();
strcpy(res, directory);
strcat(res, outputFile);

std::cout << "Using output filename:" << std::endl;
std::cout << res << std::endl;

writer->SetFileName( res );
writer->SetInput( filter->GetOutput() );

try {
    writer->Update();
} catch (itk::ExceptionObject &ex) {
    std::cout << ex << std::endl;
    return false;
}

return true;
}

This works well, but I need to migrate it to java, so I’m using SimpleITK, but for my surprise, BinaryMask3DMeshSource is not in sitk modules by default.
I trying to add it in the build using -DModule_ITKMesh:BOOL=ON option for superbuild with cmake, but the result was the same.

Could anyone help me with this?
What are the steps to add additional filter/modules to SITK?

Thanks,

Gustavo


(Dženan Zukić) #2

Brad and Ziv are spearheading SimpleITK. Can you pitch in, @blowekamp and @zivy.


(Gustavo Tajes Genga) #3

Hello @blowekamp, @zivy

Could you help me with the issue posted above? I was reading this comment from @blowekamp and I created this json:

{
  "name": "BinaryMask3DMeshSource",
  "template_code_filename" : "ImageFilter",
  "template_test_filename" : "ImageFilter",
  "number_of_inputs" : 0,
  "doc" : "Some global documentation",
  "pixel_types" : "BasicPixelIDTypeList",
  "output_pixel_type": "double"
  "filter_type" : "itk::itk::BinaryMask3DMeshSource<InputImageType, itk::Mesh< double,     TImageType::ImageDimension>>",
  "members" : [
    {
      "name" : "ObjectValue",
      "type" : "double",
      "default" : 1,
      "doc" : "Value to assign to object pixels",
      "custom_itk_cast" : "filter->SetObjectValue(static_cast<typename FilterType::PixelType>(this->GetObjectValue()) );"
    }
  ],
  "tests" : [],
  "briefdescription" : "Construct a 3D mesh surface based on a binary mask",
  "detaileddescription" : "This class tries to construct a 3D mesh surface based on a binary mask. It can be used to integrate a region-based segmentation method and a deformable model into one hybrid framework. To construct a mesh, we need to construct elements in a voxel and combine those elements later to form the final mesh. Before go through every voxel in the 3D volume, we first construct 2 look up tables. The index of these 2 tables are the on-off combination of the 8 nodes that form the voxel. So both of these tables has the size of $2^8$ bytes. According to previous work, all those $2^8$ combination of the nodes can be grouped into 16 final combinations. In the first table, we record the final combination that can be transformed from the current combination. The entries of the second table are made up of the transforming sequence that is necessary for the current combination transform to one of the final combinations., We then go through the 3D volume voxel by voxel, using those two tables we have defined to construct elements within each voxel. We then merge all these mesh elements into one 3D mesh.",
  "itk_module" : "ITKMesh",
  "itk_group" : "Core"
}

and rebuild SITK, but the filter isn’t in java wrap.

Please, could you address me about the steps?

Thanks!

Gustavo


(Bradley Lowekamp) #4

Hello,

You should have gotten some compiler errors. You need to re-run CMake for the build system to detect new files.

Unfortunately, SimpleITK does not support ITK’s Meshes. You need to use the native ITK Python wrapping. @dzenanz


(Matt McCormick) #5

ITK has the infrastructure available for Java wrapping , but it requires some tender love and maintenance care to bring it up to speed with the Python wrapping.


(Gustavo Tajes Genga) #6

Thanks! I’ll check the python wrapping.