int BatchedFolderRegistration( int argc, char* argv[] ) { ctkCommandLineParser parser; parser.setArgumentPrefix("--","-"); // Add command line argument names parser.addArgument("help", "h",ctkCommandLineParser::Bool, "Show this help text"); parser.addArgument("xml", "x",ctkCommandLineParser::Bool, "Print a XML description of this modules command line interface"); //parser.addArgument("usemask", "u", QVariant::Bool, "Use segmentations (derived resources) to exclude areas from registration metrics"); parser.addArgument("input", "i", ctkCommandLineParser::String, "Input folder",us::Any(),false); parser.addArgument("output", "o", ctkCommandLineParser::String, "Output folder (ending with /)",us::Any(),false); parser.addArgument("fixed", "f", ctkCommandLineParser::String, "Suffix for fixed image",us::Any(),false); parser.addArgument("moving", "m", ctkCommandLineParser::String, "Suffix for moving images",us::Any(),false); parser.addArgument("derived", "d", ctkCommandLineParser::String, "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true); parser.addArgument("silent", "s", ctkCommandLineParser::Bool, "No xml progress output."); // Feature currently disabled //parser.addArgument("resample", "r", QVariant::String, "Reference Image for resampling (optional), is not applied to tensor data"); map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv); // Handle special arguments bool silent = false; { if (parsedArgs.size() == 0) { MITK_ERROR << "Missig arguements" ; return EXIT_FAILURE; } if (parsedArgs.count("xml")) { MITK_ERROR << "This is to be handled by shell script"; return EXIT_SUCCESS; } if (parsedArgs.count("silent")) silent = true; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } } std::string outputPath = us::any_cast<string>(parsedArgs["output"]); std::string refPattern = us::any_cast<string>(parsedArgs["fixed"]); std::string inputPath = us::any_cast<string>(parsedArgs["input"]); std::string movingImgPattern = us::any_cast<string>(parsedArgs["moving"]); //QString resampleReference = parsedArgs["resample"].toString(); //bool maskTumor = parsedArgs["usemask"].toBool(); // if derived sources pattern is provided, populate QStringList with possible filename postfixes std::vector<std::string> derPatterns; if (parsedArgs.count("derived") || parsedArgs.count("d") ) { std::string arg = us::any_cast<string>(parsedArgs["derived"]); derPatterns = split(arg ,','); } MITK_INFO << "Input Folder : " << inputPath; MITK_INFO << "Looking for reference image ..."; FileListType referenceFileList = CreateFileList(inputPath,refPattern); if (referenceFileList.size() != 1) { MITK_ERROR << "None or more than one possible reference images (" << refPattern <<") found. Exiting." << referenceFileList.size(); MITK_INFO << "Choose a fixed arguement that is unique in the given folder!"; return EXIT_FAILURE; } std::string referenceFileName = referenceFileList.at(0); MITK_INFO << "Loading Reference (fixed) image: " << referenceFileName; mitk::Image::Pointer refImage = mitk::IOUtil::LoadImage(referenceFileName); if (refImage.IsNull()) MITK_ERROR << "Loaded fixed image is NULL"; // Copy reference image to destination std::string savePathAndFileName = GetSavePath(outputPath, referenceFileName); mitk::IOUtil::SaveImage(refImage, savePathAndFileName); // Copy all derived resources also to output folder, adding _reg suffix referenceFileList = CreateDerivedFileList(referenceFileName, movingImgPattern,derPatterns); CopyResources(referenceFileList, outputPath); std::string derivedResourceFilename; mitk::Image::Pointer referenceMask = NULL; // union of all segmentations if (!silent) { // XML Output to report progress std::cout << "<filter-start>"; std::cout << "<filter-name>Batched Registration</filter-name>"; std::cout << "<filter-comment>Starting registration ... </filter-comment>"; std::cout << "</filter-start>"; } // Now iterate over all files and register them to the reference image, // also register derived resources based on file patterns // ------------------------------------------------------------------------------ // Create File list FileListType movingImagesList = CreateFileList(inputPath, movingImgPattern); // TODO Reactivate Resampling Feature // mitk::Image::Pointer resampleImage = NULL; // if (QFileInfo(resampleReference).isFile()) // { // resampleImage = mitk::IOUtil::LoadImage(resampleReference.toStdString()); // } for (unsigned int i =0; i < movingImagesList.size(); i++) { std::string fileMorphName = movingImagesList.at(i); if (fileMorphName == referenceFileName) { // do not process reference image again continue; } MITK_INFO << "Processing image " << fileMorphName; // 1 Register morphological file to reference image if (!itksys::SystemTools::FileExists(fileMorphName.c_str())) { MITK_WARN << "File does not exit. Skipping entry."; continue; } // Origin of images is cancelled // TODO make this optional!! double transf[6]; double offset[3]; { mitk::Image::Pointer movingImage = mitk::IOUtil::LoadImage(fileMorphName); MITK_ERROR << "REF COUNT MOVING 0 " << movingImage->GetReferenceCount(); if (movingImage.IsNull()) MITK_ERROR << "Loaded moving image is NULL"; // Store transformation, apply it to morph file MITK_INFO << "----------Registering moving image to reference----------"; MITK_ERROR << "REF COUNT MOVING 1 " << movingImage->GetReferenceCount(); //mitk::RegistrationWrapper::GetTransformation(refImage, movingImage, transf, offset, referenceMask); MITK_ERROR << "REF COUNT MOVING 2 " << movingImage->GetReferenceCount(); mitk::RegistrationWrapper::ApplyTransformationToImage(movingImage, transf,offset, NULL); // , resampleImage MITK_ERROR << "REF COUNT MOVING 3 " << movingImage->GetReferenceCount(); savePathAndFileName = GetSavePath(outputPath, fileMorphName); std::string fileType = itksys::SystemTools::GetFilenameExtension(fileMorphName); SaveImage(savePathAndFileName,movingImage,fileType ); } if (!silent) { std::cout << "<filter-progress-text progress=\"" << (float)i / (float)movingImagesList.size() << "\" >.</filter-progress-text>"; } // Now parse all derived resource and apply the above calculated transformation to them // ------------------------------------------------------------------------------------ FileListType fList = CreateDerivedFileList(fileMorphName, movingImgPattern,derPatterns); if (fList.size() > 0) MITK_INFO << "----------DERIVED RESOURCES ---------"; for (unsigned int j=0; j < fList.size(); j++) { derivedResourceFilename = fList.at(j); MITK_INFO << "----Processing derived resource " << derivedResourceFilename << " ..."; mitk::Image::Pointer derivedMovingResource = mitk::IOUtil::LoadImage(derivedResourceFilename); // Apply transformation to derived resource, treat derived resource as binary mitk::RegistrationWrapper::ApplyTransformationToImage(derivedMovingResource, transf,offset, NULL, true); savePathAndFileName = GetSavePath(outputPath, derivedResourceFilename); std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); SaveImage(savePathAndFileName,derivedMovingResource,fileType ); } } if (!silent) std::cout << "<filter-end/>"; return EXIT_SUCCESS; }
int main( int argc, char* argv[] ) { mitkCommandLineParser parser; parser.setArgumentPrefix("--","-"); parser.setTitle("Folder Registration"); parser.setCategory("Preprocessing Tools"); parser.setDescription("For detail description see http://docs.mitk.org/nightly/DiffusionMiniApps.html"); parser.setContributor("MBI"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help", "Show this help text"); //parser.addArgument("usemask", "u", QVariant::Bool, "Use segmentations (derived resources) to exclude areas from registration metrics"); parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input:", "Input folder",us::Any(),false); parser.addArgument("output", "o", mitkCommandLineParser::OutputDirectory, "Output:", "Output folder (ending with /)",us::Any(),false); parser.addArgument("fixed", "f", mitkCommandLineParser::String, "Fixed images:", "Suffix for fixed image (if none is supplied first file matching moving pattern is chosen)",us::Any(),true); parser.addArgument("moving", "m", mitkCommandLineParser::String, "Moving images:", "Suffix for moving images",us::Any(),false); parser.addArgument("derived", "d", mitkCommandLineParser::String, "Derived resources:", "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true); parser.addArgument("silent", "s", mitkCommandLineParser::Bool, "Silent:", "No xml progress output."); parser.addArgument("resample", "r", mitkCommandLineParser::String, "Resample (x,y,z)mm:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any()); parser.addArgument("binary", "b", mitkCommandLineParser::Bool, "Binary:", "Speficies that derived resource are binary (interpolation using nearest neighbor)",us::Any()); parser.addArgument("correct-origin", "c", mitkCommandLineParser::Bool, "Origin correction:", "Correct for large origin displacement. Use switch when you reveive: Joint PDF summed to zero ",us::Any()); parser.addArgument("sinc-int", "s", mitkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any()); map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv); // Handle special arguments bool silent = false; bool isBinary = false; bool alignOrigin = false; bool useLinearInterpol = true; { if (parsedArgs.size() == 0) { return EXIT_FAILURE; } if (parsedArgs.count("sinc-int")) useLinearInterpol = false; if (parsedArgs.count("silent")) silent = true; if (parsedArgs.count("binary")) isBinary = true; if (parsedArgs.count("correct-origin")) alignOrigin = true; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } } std::string refPattern = ""; bool useFirstMoving = false; std::string movingImgPattern = us::any_cast<string>(parsedArgs["moving"]); if (parsedArgs.count("fixed")) { refPattern = us::any_cast<string>(parsedArgs["fixed"]); } else { useFirstMoving = true; refPattern = movingImgPattern; } std::string outputPath = us::any_cast<string>(parsedArgs["output"]); std::string inputPath = us::any_cast<string>(parsedArgs["input"]); //QString resampleReference = parsedArgs["resample"].toString(); //bool maskTumor = parsedArgs["usemask"].toBool(); // if derived sources pattern is provided, populate QStringList with possible filename postfixes std::vector<std::string> derPatterns; if (parsedArgs.count("derived") || parsedArgs.count("d") ) { std::string arg = us::any_cast<string>(parsedArgs["derived"]); derPatterns = split(arg ,','); } std::vector<std::string> spacings; float spacing[3]; bool doResampling = false; if (parsedArgs.count("resample") || parsedArgs.count("d") ) { std::string arg = us::any_cast<string>(parsedArgs["resample"]); spacings = split(arg ,','); spacing[0] = atoi(spacings.at(0).c_str()); spacing[1] = atoi(spacings.at(1).c_str()); spacing[2] = atoi(spacings.at(2).c_str()); doResampling = true; } MITK_INFO << "Input Folder : " << inputPath; MITK_INFO << "Looking for reference image ..."; FileListType referenceFileList = CreateFileList(inputPath,refPattern); if ((!useFirstMoving && referenceFileList.size() != 1) || (useFirstMoving && referenceFileList.size() == 0)) { MITK_ERROR << "None or more than one possible reference images (" << refPattern <<") found. Exiting." << referenceFileList.size(); MITK_INFO << "Choose a fixed arguement that is unique in the given folder!"; return EXIT_FAILURE; } std::string referenceFileName = referenceFileList.at(0); MITK_INFO << "Loading Reference (fixed) image: " << referenceFileName; std::string fileType = itksys::SystemTools::GetFilenameExtension(referenceFileName); mitk::Image::Pointer refImage = ExtractFirstTS(mitk::IOUtil::LoadImage(referenceFileName), fileType); mitk::Image::Pointer resampleReference = NULL; if (doResampling) { refImage = ResampleBySpacing(refImage,spacing); resampleReference = refImage; } if (refImage.IsNull()) MITK_ERROR << "Loaded fixed image is NULL"; // Copy reference image to destination std::string savePathAndFileName = GetSavePath(outputPath, referenceFileName); mitk::IOUtil::SaveImage(refImage, savePathAndFileName); // Copy all derived resources also to output folder, adding _reg suffix referenceFileList = CreateDerivedFileList(referenceFileName, movingImgPattern,derPatterns); CopyResources(referenceFileList, outputPath); std::string derivedResourceFilename; mitk::Image::Pointer referenceMask = NULL; // union of all segmentations if (!silent) { // XML Output to report progress std::cout << "<filter-start>"; std::cout << "<filter-name>Batched Registration</filter-name>"; std::cout << "<filter-comment>Starting registration ... </filter-comment>"; std::cout << "</filter-start>"; } // Now iterate over all files and register them to the reference image, // also register derived resources based on file patterns // ------------------------------------------------------------------------------ // Create File list FileListType movingImagesList = CreateFileList(inputPath, movingImgPattern); // TODO Reactivate Resampling Feature // mitk::Image::Pointer resampleImage = NULL; // if (QFileInfo(resampleReference).isFile()) // { // resampleImage = mitk::IOUtil::LoadImage(resampleReference.toStdString()); // } for (unsigned int i =0; i < movingImagesList.size(); i++) { std::string fileMorphName = movingImagesList.at(i); if (fileMorphName == referenceFileName) { // do not process reference image again continue; } MITK_INFO << "Processing image " << fileMorphName; // 1 Register morphological file to reference image if (!itksys::SystemTools::FileExists(fileMorphName.c_str())) { MITK_WARN << "File does not exit. Skipping entry."; continue; } // Origin of images is cancelled // TODO make this optional!! double transf[6]; double offset[3]; { std::string fileType = itksys::SystemTools::GetFilenameExtension(fileMorphName); mitk::Image::Pointer movingImage = ExtractFirstTS(mitk::IOUtil::LoadImage(fileMorphName), fileType); if (movingImage.IsNull()) MITK_ERROR << "Loaded moving image is NULL"; // Store transformation, apply it to morph file MITK_INFO << "----------Registering moving image to reference----------"; mitk::RegistrationWrapper::GetTransformation(refImage, movingImage, transf, offset, alignOrigin, referenceMask); mitk::RegistrationWrapper::ApplyTransformationToImage(movingImage, transf,offset, resampleReference); // , resampleImage savePathAndFileName = GetSavePath(outputPath, fileMorphName); if (fileType == ".dwi") fileType = "dwi"; if (movingImage->GetData() == nullptr) MITK_INFO <<"POST DATA is null"; mitk::IOUtil::Save(movingImage, savePathAndFileName); } if (!silent) { std::cout << "<filter-progress-text progress=\"" << (float)i / (float)movingImagesList.size() << "\" >.</filter-progress-text>"; } // Now parse all derived resource and apply the above calculated transformation to them // ------------------------------------------------------------------------------------ FileListType fList = CreateDerivedFileList(fileMorphName, movingImgPattern,derPatterns); if (fList.size() > 0) MITK_INFO << "----------DERIVED RESOURCES ---------"; for (unsigned int j=0; j < fList.size(); j++) { derivedResourceFilename = fList.at(j); MITK_INFO << "----Processing derived resorce " << derivedResourceFilename << " ..."; std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename); mitk::Image::Pointer derivedMovingResource = ExtractFirstTS(mitk::IOUtil::LoadImage(derivedResourceFilename), fileType); // Apply transformation to derived resource, treat derived resource as binary mitk::RegistrationWrapper::ApplyTransformationToImage(derivedMovingResource, transf,offset, resampleReference,isBinary); savePathAndFileName = GetSavePath(outputPath, derivedResourceFilename); mitk::IOUtil::SaveImage(derivedMovingResource, savePathAndFileName); } } if (!silent) std::cout << "<filter-end/>"; return EXIT_SUCCESS; }