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;
}
Esempio n. 2
0
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;
}