Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature to create a mask from an image. #113

Merged
merged 2 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Anima/math-tools/common_tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ add_subdirectory(convert_image)
add_subdirectory(convert_shape)
add_subdirectory(merge_block_images)
add_subdirectory(vectorize_images)
add_subdirectory(image_to_mask)

35 changes: 35 additions & 0 deletions Anima/math-tools/common_tools/image_to_mask/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
if(BUILD_TOOLS)

project(animaImageToMask)

## #############################################################################
## List Sources
## #############################################################################

list_source_files(${PROJECT_NAME}
${CMAKE_CURRENT_SOURCE_DIR}
)

## add executable
## #############################################################################

add_executable(${PROJECT_NAME}
${${PROJECT_NAME}_CFILES}
)


## #############################################################################
## Link
## #############################################################################

target_link_libraries(${PROJECT_NAME}
${ITKIO_LIBRARIES}
)

## #############################################################################
## install
## #############################################################################

set_exe_install_rules(${PROJECT_NAME})

endif()
143 changes: 143 additions & 0 deletions Anima/math-tools/common_tools/image_to_mask/animaImageToMask.cxx
Gregoire-V marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include <tclap/CmdLine.h>
#include <iostream>
#include <string>

#include <itkImage.h>
#include <itkVectorImage.h>
#include <itkImageRegionIterator.h>

#include <animaReadWriteFunctions.h>

/**
* @brief Converts an input image (either vectorial or not) into a mask
* The output mask will be 0 in the voxels where the input image is 0 (or a null vector) and 1 elsewhere
*/
int main(int argc, char **argv)
{
TCLAP::CmdLine cmd("INRIA / IRISA - VisAGeS/Empenn Team", ' ',ANIMA_VERSION);

//Define arguments
TCLAP::ValueArg<std::string> inArg("i","inputfile","input image",true,"","input image",cmd);
TCLAP::ValueArg<std::string> outArg("o","outputfile","output mask",true,"","output mask",cmd);

//Try to parse
try
{
cmd.parse(argc,argv);
}
catch (TCLAP::ArgException& e)
{
std::cerr << "Error: " << e.error() << "for argument " << e.argId() << std::endl;
return(1);
}

//Define types
typedef itk::Image <double,3> ImageType;
typedef itk::Image <double,4> Image4DType;
typedef itk::VectorImage <double,3> VectorImageType;

//Read input image
itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(inArg.getValue().c_str(),
itk::IOFileModeEnum::ReadMode);

imageIO->SetFileName(inArg.getValue());
imageIO->ReadImageInformation();

//Initialize the output image (which is a mask) and allocate memory
ImageType::Pointer outImage = ImageType::New();

//Determine if the input image is a vector image (each voxel value is a vector) or not
bool vectorImage = (imageIO->GetNumberOfComponents() > 1);

if (vectorImage)
{
//Case of a vector image

//Read input image and store in the correct format
VectorImageType::Pointer image = anima::readImage <VectorImageType> (inArg.getValue());

//Set the output image with the same properties as the input image
outImage->Initialize();
outImage->SetDirection(image->GetDirection());
outImage->SetSpacing(image->GetSpacing());
outImage->SetOrigin(image->GetOrigin());

//Allocate the correct size for output image. region (image->GetLargestPossibleRegion()) is the whole image
VectorImageType::RegionType region = image->GetLargestPossibleRegion();
outImage->SetRegions(region);
outImage->Allocate();

//Create a vector with as many components as there are for each voxel, and with each component equal to 0
VectorImageType::PixelType zeroVec(image->GetNumberOfComponentsPerPixel());
zeroVec.Fill(0);

//Create iterators on input and output images
itk::ImageRegionIterator <VectorImageType> inItr(image,region);
itk::ImageRegionIterator <ImageType> outItr(outImage,outImage->GetLargestPossibleRegion());

//Main algorithm
while (!outItr.IsAtEnd())
{
if(inItr.Get() == zeroVec)
{
//The voxel in the input image is a constant vector equal to 0, so this voxel in the output mask will be 0.
outItr.Set(0);
}
else
{
//The voxel in the input image is not a constant vector equal to 0, so this voxel in the output mask will be 1.
outItr.Set(1);
}

//Move to following voxel
++inItr;
++outItr;
}
}
else
{
//Case of a non-vector image

//Read input image and store in the correct format
ImageType::Pointer image = anima::readImage <ImageType> (inArg.getValue());

//Set the output image with the same properties as the input image
outImage->Initialize();
outImage->SetDirection(image->GetDirection());
outImage->SetSpacing(image->GetSpacing());
outImage->SetOrigin(image->GetOrigin());

//Allocate the correct size for output image. largestRegion (image->GetLargestPossibleRegion()) is the whole image
ImageType::RegionType largestRegion = image->GetLargestPossibleRegion();
outImage->SetRegions(largestRegion);
outImage->Allocate();
outImage->FillBuffer(0.0);

//Create iterators on input and output images
itk::ImageRegionIterator <ImageType> inItr(image,image->GetLargestPossibleRegion());
itk::ImageRegionIterator <ImageType> outItr(outImage,outImage->GetLargestPossibleRegion());

//Main algorithm
while (!outItr.IsAtEnd())
{
if(inItr.Get() == 0.0)
{
//The voxel in the input image is 0, so this voxel in the output mask will be 0.
outItr.Set(0);
}
else
{
//The voxel in the input image is not 0, so this voxel in the output mask will be 1.
outItr.Set(1);
}

//Move to following voxel
++inItr;
++outItr;
}
}

//Write output image and exit
anima::writeImage <ImageType> (outArg.getValue(),outImage);
return EXIT_SUCCESS;
}
Loading