Skip to content

Commit

Permalink
Fix #2338 - Mesh generation from distance transforms.
Browse files Browse the repository at this point in the history
The code I had added to handle the segmentations was only meant for segmentations, not distance transforms.
  • Loading branch information
akenmorris committed Oct 13, 2024
1 parent d201bb5 commit 94ffc5f
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 8 deletions.
6 changes: 4 additions & 2 deletions Libs/Analyze/MeshGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ MeshHandle MeshGenerator::build_mesh_from_image(ImageType::Pointer image, float
try {
// only interested in 1's and 0's
Image itk_image = Image(image);
itk_image.binarize(0, 1);
image = itk_image.getITKImage();
if (!itk_image.isDistanceTransform()) {
itk_image.binarize(0, 1);
image = itk_image.getITKImage();
}

// connect to VTK
vtkSmartPointer<vtkImageImport> vtk_image = vtkSmartPointer<vtkImageImport>::New();
Expand Down
11 changes: 10 additions & 1 deletion Libs/Image/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ Point3 Image::centerOfMass(PixelType minVal, PixelType maxVal) const {
return com;
}

Image::StatsPtr Image::statsFilter() {
Image::StatsPtr Image::statsFilter() const {
using FilterType = itk::StatisticsImageFilter<ImageType>;
FilterType::Pointer filter = FilterType::New();

Expand Down Expand Up @@ -1159,6 +1159,15 @@ Image& Image::fill(PixelType value) {
return *this;
}

//-------------------------------------------------------------------------
bool Image::isDistanceTransform() const {
auto stats = statsFilter();
// examine scalar range of image
auto min = stats->GetMinimum();
auto max = stats->GetMaximum();
return (min < 0 && max > 0);
}

//-------------------------------------------------------------------------
TransformPtr Image::createCenterOfMassTransform() {
AffineTransformPtr xform(AffineTransform::New());
Expand Down
14 changes: 9 additions & 5 deletions Libs/Image/Image.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ class Image {
using InterpolatorType = itk::LinearInterpolateImageFunction<ImageType>;

// constructors and assignment operators //
Image(const Dims dims);
Image(const std::string& pathname) : itk_image_(read(pathname)) {}
Image(ImageType::Pointer imagePtr) : itk_image_(imagePtr) {
explicit Image(const Dims dims);
explicit Image(const std::string& pathname) : itk_image_(read(pathname)) {}
explicit Image(ImageType::Pointer imagePtr) : itk_image_(imagePtr) {
if (!itk_image_) throw std::invalid_argument("null imagePtr");
}
Image(const vtkSmartPointer<vtkImageData> vtkImage);
explicit Image(const vtkSmartPointer<vtkImageData> vtkImage);

Image(Image&& img) : itk_image_(nullptr) { this->itk_image_.Swap(img.itk_image_); }
Image(const Image& img) : itk_image_(cloneData(img.itk_image_)) {}
Image& operator=(const Image& img); /// lvalue assignment operator
Expand Down Expand Up @@ -306,6 +307,9 @@ class Image {
//! fill with value
Image& fill(PixelType value);

//! Return if the image is a distance transform
bool isDistanceTransform() const;

//! Return supported file types
static std::vector<std::string> getSupportedTypes() {
return {"nrrd", "nii", "nii.gz", "mhd", "tiff", "jpeg", "jpg", "png", "dcm", "ima"};
Expand Down Expand Up @@ -340,7 +344,7 @@ class Image {
/// pad image by the given dims (always positive) in each direction
Image& pad(Dims lowerExtendRegion, Dims upperExtendRegion, PixelType value = 0.0);

StatsPtr statsFilter();
StatsPtr statsFilter() const;

ImageType::Pointer itk_image_;

Expand Down

0 comments on commit 94ffc5f

Please sign in to comment.