diff --git a/apps/VoxelizerTool/VoxelizerTool.cpp b/apps/VoxelizerTool/VoxelizerTool.cpp index 3b9f7ba..9e70d48 100644 --- a/apps/VoxelizerTool/VoxelizerTool.cpp +++ b/apps/VoxelizerTool/VoxelizerTool.cpp @@ -1,147 +1,149 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1390 $ (last changed revision) // @date $Date: 2016-07-13 09:57:44 +0200 (Mi, 13 Jul 2016) $ (last change date) // @author $Author: strubel $ (last changed by) */ #include #include "VoxelizerToolHelper.h" #include "VoxelizerToolCmdLineParser.h" #include "VoxelizerToolApplicationData.h" #include "rttbDoseLoader.cpp" #include "rttbStructLoader.cpp" int main(int argc, const char** argv) { rttb::apps::voxelizerTool::ApplicationData appData; const std::string appCategory = "RT-Toolbox App"; const std::string appName = "VoxelizerTool"; const std::string appDesc = "An App to voxelize RT structures in a reference image."; const std::string appContributor = "SIDT@DKFZ"; const std::string appVersion = RTTB_FULL_VERSION_STRING; boost::shared_ptr argParser; try { argParser = boost::make_shared(argc, argv, appName, appVersion, appDesc, appContributor, appCategory); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; return 5; } // This is vital. The application needs to exit if the "help" or "version" parameter is set // because this means the other parameters won't be parsed. if (argParser->isSet(argParser->OPTION_HELP) || argParser->isSet(argParser->OPTION_VERSION) || argParser->isSet(argParser->OPTION_XML)) { return 0; } rttb::apps::voxelizerTool::populateAppData(argParser, appData); std::cout << std::endl << "*******************************************" << std::endl; std::cout << "Struct file: " << appData._structFile << std::endl; std::cout << "Reference Image: " << appData._referenceFile << std::endl; std::cout << "Output file: " << appData._outputFilename << std::endl; std::cout << "Struct regex: " << appData._regEx << std::endl; std::cout << "Add structures: " << appData._addStructures << std::endl; std::cout << "Multiple Struct: " << appData._multipleStructs << std::endl; - std::cout << "No Strict voxelization: " << appData._noStrictVoxelization << std::endl << std::endl; + std::cout << "Strict voxelization: " << !appData._noStrictVoxelization << std::endl << std::endl; std::cout << "reading reference and structure file..." << std::endl; try { appData._dose = rttb::io::utils::loadDose(appData._referenceFile, appData._referenceFileLoadStyle); } catch (rttb::core::Exception& e) { std::cerr << "RTTB Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 2; } catch (const std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 2; } catch (...) { std::cerr << "Error!!! unknown error while reading input dose image." << std::endl; return 2; } try { appData._struct = rttb::io::utils::loadStruct(appData._structFile, appData._structFileLoadStyle, appData._regEx); } catch (rttb::core::Exception& e) { std::cerr << "RTTB Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 2; } catch (const std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 2; } catch (...) { std::cerr << "Error!!! unknown error while reading input struct image." << std::endl; return 2; } + std::cout << "done." << std::endl; + try { rttb::apps::voxelizerTool::processData(appData); } catch (rttb::core::Exception& e) { std::cerr << "RTTB Error while doing voxelization!!!" << std::endl; std::cerr << e.what() << std::endl; return 2; } catch (itk::ExceptionObject& err) { std::cerr << "ExceptionObject caught !" << std::endl; std::cerr << err << std::endl; return 3; } catch (const std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 3; } catch (...) { std::cerr << "Error!!! unknown error while doing voxelization." << std::endl; return 3; } return 0; } diff --git a/apps/VoxelizerTool/VoxelizerToolHelper.cpp b/apps/VoxelizerTool/VoxelizerToolHelper.cpp index f270d09..8b1bb8b 100644 --- a/apps/VoxelizerTool/VoxelizerToolHelper.cpp +++ b/apps/VoxelizerTool/VoxelizerToolHelper.cpp @@ -1,238 +1,240 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1127 $ (last changed revision) // @date $Date: 2015-10-01 13:33:33 +0200 (Do, 01 Okt 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include #include "rttbBoostMaskAccessor.h" #include "itkMacro.h" #include "VoxelizerToolHelper.h" #include "VoxelizerToolApplicationData.h" #include "rttbITKImageMaskAccessorConverter.h" #include "rttbImageWriter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkAddImageFilter.h" #include #include #include #include "rttbDicomFileStructureSetGenerator.h" void rttb::apps::voxelizerTool::removeSpecialCharacters(std::string& label) { //Replace / to avoid problems with directories (struct "Magen/DD" --> Magen/DD.mhd), delete trailing . to avoid filenames with two trailing points (Niere re. --> Niere re..mhd) while (label.find("/") != std::string::npos) { label.replace(label.find("/"), 1, "_"); } if (*label.rbegin() == '.') { label.replace(label.size() - 1, 1, ""); } } std::string rttb::apps::voxelizerTool::getFilenameWithoutEnding(const std::string& outfilename) { boost::filesystem::path p(outfilename); return p.replace_extension("").string(); } std::string rttb::apps::voxelizerTool::getFileEnding(const std::string& outfilename) { boost::filesystem::path p(outfilename); return p.extension().string(); } rttb::core::MaskAccessorInterface::MaskAccessorPointer rttb::apps::voxelizerTool::createMask( rttb::core::DoseAccessorInterface::DoseAccessorPointer doseAccessorPtr, rttb::core::Structure::StructTypePointer structurePtr, bool strict) { rttb::core::MaskAccessorInterface::MaskAccessorPointer maskAccessorPtr; if (doseAccessorPtr != nullptr && structurePtr != nullptr) { maskAccessorPtr = boost::make_shared (structurePtr, doseAccessorPtr->getGeometricInfo(), strict); maskAccessorPtr->updateMask(); } return maskAccessorPtr; } void rttb::apps::voxelizerTool::writeMaskToFile(std::vector maskVector, const std::string& outputFileName, bool voxelization) { if (!maskVector.empty()) { io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer itkImage; if (maskVector.size() > 1) { itkImage = addMultipleStructsToImage(maskVector); } else { io::itk::ITKImageMaskAccessorConverter maskAccessorConverter(maskVector.at(0)); maskAccessorConverter.process(); itkImage = maskAccessorConverter.getITKImage(); } if (voxelization) { itkImage = applyThresholdFilter(itkImage); } io::itk::ImageWriter writer(outputFileName, itkImage); writer.writeFile(); } } rttb::io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer rttb::apps::voxelizerTool::addMultipleStructsToImage( std::vector maskVector) { std::vector listOfITKImages; for (const auto & i : maskVector) { io::itk::ITKImageMaskAccessorConverter maskAccessorConverter(i); maskAccessorConverter.process(); listOfITKImages.push_back(maskAccessorConverter.getITKImage()); } itk::AddImageFilter , itk::Image>::Pointer addFilter = itk::AddImageFilter , itk::Image>::New(); io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer filterResult; for (int k = 1; k < listOfITKImages.size(); k++) { if (k == 1) { addFilter->SetInput1(listOfITKImages.at(0)); } else { addFilter->SetInput1(filterResult); } addFilter->SetInput2(listOfITKImages.at(k)); addFilter->Update(); filterResult = addFilter->GetOutput(); } io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer filterResultConst(filterResult); return filterResultConst; } rttb::io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer rttb::apps::voxelizerTool::applyThresholdFilter( io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer itkImage) { itk::BinaryThresholdImageFilter< itk::Image, itk::Image >::Pointer filter = itk::BinaryThresholdImageFilter< itk::Image, itk::Image >::New(); filter->SetInput(itkImage); filter->SetLowerThreshold(0.5); filter->SetUpperThreshold(1.0); filter->SetInsideValue(1.0); filter->Update(); return filter->GetOutput(); } void rttb::apps::voxelizerTool::writeITKImageToFile(io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer& itkImage, const std::string& outputfilename, bool useCompression) { itk::ImageFileWriter< itk::Image >::Pointer writer = itk::ImageFileWriter< itk::Image >::New(); writer->SetFileName(outputfilename); writer->SetUseCompression(useCompression); writer->SetInput(itkImage); writer->Update(); } void rttb::apps::voxelizerTool::processData(rttb::apps::voxelizerTool::ApplicationData& appData) { if (appData._struct->getNumberOfStructures()>0) { std::vector maskVector; if (appData._addStructures) { for (size_t i=0; igetNumberOfStructures(); i++ ) { std::cout << "creating mask #" << i << "..."; maskVector.push_back(createMask(appData._dose, appData._struct->getStructure(i), !appData._noStrictVoxelization)); std::cout << "done" << std::endl; } std::cout << "writing mask to file..."; writeMaskToFile(maskVector, appData._outputFilename, appData._binaryVoxelization); std::cout << "done" << std::endl; } else { //default behavior: read only first struct that matches the regex unsigned int maxIterationCount = 1; //only if specified: read all structs that matches the regex if (appData._multipleStructs) { maxIterationCount = appData._struct->getNumberOfStructures(); } for (size_t i = 0; igetStructure(i), !appData._noStrictVoxelization); std::cout << "done" << std::endl; std::string labelOfInterest = appData._struct->getStructure(i)->getLabel(); removeSpecialCharacters(labelOfInterest); std::string outputName = appData._outputFilename; if (appData._multipleStructs) { std::string fileName = getFilenameWithoutEnding( appData._outputFilename); std::string fileEnding = getFileEnding(appData._outputFilename); outputName = fileName + "_" + labelOfInterest + fileEnding; } std::vector currenMaskVector{ currentMask }; + std::cout << "writing mask #" << i << " to file..."; writeMaskToFile(currenMaskVector, outputName, appData._binaryVoxelization); + std::cout << "done" << std::endl; } } } else { std::cout << "No struct found" << std::endl; } } \ No newline at end of file