Beispiel #1
0
void mitk::PointSetReader::GenerateData()
{
    // Switch the current locale to "C"
    LocaleSwitch localeSwitch("C");

    m_Success = false;
    if (m_FileName == "")
    {
        itkWarningMacro(<< "Sorry, filename has not been set!");
        return;
    }
void mitk::ItkImageFileReader::GenerateData()
{
  mitk::LocaleSwitch localeSwitch("C");
  mitk::Image::Pointer image = this->GetOutput();

  const unsigned int MINDIM = 2;
  const unsigned int MAXDIM = 4;

  MITK_INFO("mitkItkImageFileReader") << "loading " << m_FileName << " via itk::ImageIOFactory... " << std::endl;

  // Check to see if we can read the file given the name or prefix
  if ( m_FileName == "" )
  {
    mitkThrow() << "Empty filename in mitk::ItkImageFileReader ";
    return ;
  }

  itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( m_FileName.c_str(), itk::ImageIOFactory::ReadMode );
  if ( imageIO.IsNull() )
  {
    //itkWarningMacro( << "File Type not supported!" );
    mitkThrow() << "Could not create itk::ImageIOBase object for filename " << m_FileName;
    return ;
  }

  // Got to allocate space for the image. Determine the characteristics of
  // the image.
  imageIO->SetFileName( m_FileName.c_str() );
  imageIO->ReadImageInformation();

  unsigned int ndim = imageIO->GetNumberOfDimensions();
  if ( ndim < MINDIM || ndim > MAXDIM )
  {
    itkWarningMacro( << "Sorry, only dimensions 2, 3 and 4 are supported. The given file has " << ndim << " dimensions! Reading as 4D." );
    ndim = MAXDIM;
  }
void mitk::DiffusionImageNrrdWriterService::Write()
{
  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image *>(this->GetInput());

  VectorImageType::Pointer itkImg;
  mitk::CastToItkImage(input,itkImg);

  if (input.IsNull())
  {
    MITK_ERROR <<"Sorry, input to DiffusionImageNrrdWriterService is NULL!";
    return;
  }
  if ( this->GetOutputLocation().empty() )
  {
    MITK_ERROR << "Sorry, filename has not been set!";
    return ;
  }
  mitk::LocaleSwitch localeSwitch("C");

  char keybuffer[512];
  char valbuffer[512];

  //itk::MetaDataDictionary dic = input->GetImage()->GetMetaDataDictionary();

  vnl_matrix_fixed<double,3,3> measurementFrame = mitk::DiffusionPropertyHelper::GetMeasurementFrame(input);
  if (measurementFrame(0,0) || measurementFrame(0,1) || measurementFrame(0,2) ||
    measurementFrame(1,0) || measurementFrame(1,1) || measurementFrame(1,2) ||
    measurementFrame(2,0) || measurementFrame(2,1) || measurementFrame(2,2))
  {
    sprintf( valbuffer, " (%lf,%lf,%lf) (%lf,%lf,%lf) (%lf,%lf,%lf)", measurementFrame(0,0), measurementFrame(0,1), measurementFrame(0,2), measurementFrame(1,0), measurementFrame(1,1), measurementFrame(1,2), measurementFrame(2,0), measurementFrame(2,1), measurementFrame(2,2));
    itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string("measurement frame"),std::string(valbuffer));
  }

  sprintf( valbuffer, "DWMRI");
  itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string("modality"),std::string(valbuffer));

  if(mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size())
  {
    sprintf( valbuffer, "%1f", mitk::DiffusionPropertyHelper::GetReferenceBValue(input) );
    itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string("DWMRI_b-value"),std::string(valbuffer));
  }

  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
  {
    sprintf( keybuffer, "DWMRI_gradient_%04d", i );

    /*if(itk::ExposeMetaData<std::string>(input->GetMetaDataDictionary(),
    std::string(keybuffer),tmp))
    continue;*/

    sprintf( valbuffer, "%1f %1f %1f", mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(0),
      mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(1), mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(2));

    itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string(keybuffer),std::string(valbuffer));
  }

  typedef itk::VectorImage<short,3> ImageType;

  std::string ext = this->GetMimeType()->GetExtension(this->GetOutputLocation());
  ext = itksys::SystemTools::LowerCase(ext);

  // default extension is .dwi
  if( ext == "")
  {
    ext = ".nrrd";
    this->SetOutputLocation(this->GetOutputLocation() + ext);
  }

  if (ext == ".hdwi" || ext == ".nrrd" || ext == ".dwi")
  {

    MITK_INFO << "Extension " << ext;
    itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
    //io->SetNrrdVectorType( nrrdKindList );
    io->SetFileType( itk::ImageIOBase::Binary );
    io->UseCompressionOn();

    typedef itk::ImageFileWriter<ImageType> WriterType;
    WriterType::Pointer nrrdWriter = WriterType::New();
    nrrdWriter->UseInputMetaDataDictionaryOn();
    nrrdWriter->SetInput( itkImg );
    nrrdWriter->SetImageIO(io);
    nrrdWriter->SetFileName(this->GetOutputLocation());
    nrrdWriter->UseCompressionOn();
    nrrdWriter->SetImageIO(io);
    try
    {
      nrrdWriter->Update();
    }
    catch (itk::ExceptionObject e)
    {
      std::cout << e << std::endl;
      throw;
    }

  }
}
std::vector<itk::SmartPointer<mitk::BaseData>> mitk::PointSetReaderService::Read()
{
    // Switch the current locale to "C"
    LocaleSwitch localeSwitch("C");

    std::vector<itk::SmartPointer<mitk::BaseData>> result;

    InputStream stream(this);

    TiXmlDocument doc;
    stream >> doc;
    if (!doc.Error())
    {
        TiXmlHandle docHandle(&doc);
        // unsigned int pointSetCounter(0);
        for (TiXmlElement *currentPointSetElement =
                    docHandle.FirstChildElement("point_set_file").FirstChildElement("point_set").ToElement();
                currentPointSetElement != NULL;
                currentPointSetElement = currentPointSetElement->NextSiblingElement())
        {
            mitk::PointSet::Pointer newPointSet = mitk::PointSet::New();

            // time geometry assembled for addition after all points
            // else the SetPoint method would already transform the points that we provide it
            mitk::ProportionalTimeGeometry::Pointer timeGeometry = mitk::ProportionalTimeGeometry::New();

            if (currentPointSetElement->FirstChildElement("time_series") != NULL)
            {
                for (TiXmlElement *currentTimeSeries = currentPointSetElement->FirstChildElement("time_series")->ToElement();
                        currentTimeSeries != NULL;
                        currentTimeSeries = currentTimeSeries->NextSiblingElement())
                {
                    unsigned int currentTimeStep(0);
                    TiXmlElement *currentTimeSeriesID = currentTimeSeries->FirstChildElement("time_series_id");

                    currentTimeStep = atoi(currentTimeSeriesID->GetText());

                    timeGeometry->Expand(currentTimeStep + 1); // expand (default to identity) in any case
                    TiXmlElement *geometryElem = currentTimeSeries->FirstChildElement("Geometry3D");
                    if (geometryElem)
                    {
                        Geometry3D::Pointer geometry = Geometry3DToXML::FromXML(geometryElem);
                        if (geometry.IsNotNull())
                        {
                            timeGeometry->SetTimeStepGeometry(geometry, currentTimeStep);
                        }
                        else
                        {
                            MITK_ERROR << "Could not deserialize Geometry3D element.";
                        }
                    }
                    else
                    {
                        MITK_WARN << "Fallback to legacy behavior: defining PointSet geometry as identity";
                    }

                    newPointSet = this->ReadPoints(newPointSet, currentTimeSeries, currentTimeStep);
                }
            }
            else
            {
                newPointSet = this->ReadPoints(newPointSet, currentPointSetElement, 0);
            }

            newPointSet->SetTimeGeometry(timeGeometry);

            result.push_back(newPointSet.GetPointer());
        }
    }
    else
    {
        mitkThrow() << "Parsing error at line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc();
    }

    return result;
}
  std::vector<BaseData::Pointer> DICOMSegmentationIO::Read()
  {
    mitk::LocaleSwitch localeSwitch("C");

    LabelSetImage::Pointer labelSetImage;
    std::vector<BaseData::Pointer> result;

    const std::string path = this->GetLocalFileName();

    MITK_INFO << "loading " << path << std::endl;

    if (path.empty())
      mitkThrow() << "Empty filename in mitk::ItkImageIO ";

    try
    {
      // Get the dcm data set from file path
      DcmFileFormat dcmFileFormat;
      OFCondition status = dcmFileFormat.loadFile(path.c_str());
      if (status.bad())
        mitkThrow() << "Can't read the input file!";

      DcmDataset *dataSet = dcmFileFormat.getDataset();
      if (dataSet == nullptr)
        mitkThrow() << "Can't read data from input file!";

      // Read the DICOM SEG images (segItkImages) and DICOM tags (metaInfo)
      dcmqi::ImageSEGConverter *converter = new dcmqi::ImageSEGConverter();
      pair<map<unsigned, ImageType::Pointer>, string> dcmqiOutput = converter->dcmSegmentation2itkimage(dataSet);

      map<unsigned, ImageType::Pointer> segItkImages = dcmqiOutput.first;

      // For each itk image add a layer to the LabelSetImage output
      for (auto &element : segItkImages)
      {
        // Get the labeled image and cast it to mitkImage
        typedef itk::CastImageFilter<itkInternalImageType, itkInputImageType> castItkImageFilterType;
        castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New();
        castFilter->SetInput(element.second);
        castFilter->Update();

        Image::Pointer layerImage;
        CastToMitkImage(castFilter->GetOutput(), layerImage);

        // Get pixel value of the label
        itkInternalImageType::ValueType segValue = 1;
        typedef itk::ImageRegionIterator<const itkInternalImageType> IteratorType;
        // Iterate over the image to find the pixel value of the label
        IteratorType iter(element.second, element.second->GetLargestPossibleRegion());
        iter.GoToBegin();
        while (!iter.IsAtEnd())
        {
          itkInputImageType::PixelType value = iter.Get();
          if (value != 0)
          {
            segValue = value;
            break;
          }
          ++iter;
        }

        dcmqi::JSONSegmentationMetaInformationHandler metaInfo(dcmqiOutput.second.c_str());
        metaInfo.read();
        MITK_INFO << "Input " << metaInfo.getJSONOutputAsString();
        // TODO: Read all DICOM Tags

        // Get the label information from segment attributes
        vector<map<unsigned, dcmqi::SegmentAttributes *>>::const_iterator segmentIter =
          metaInfo.segmentsAttributesMappingList.begin();
        map<unsigned, dcmqi::SegmentAttributes *> segmentMap = (*segmentIter);
        map<unsigned, dcmqi::SegmentAttributes *>::const_iterator segmentMapIter = (*segmentIter).begin();
        dcmqi::SegmentAttributes *segmentAttr = (*segmentMapIter).second;

        OFString labelName;

        if (segmentAttr->getSegmentedPropertyTypeCodeSequence() != nullptr)
          segmentAttr->getSegmentedPropertyTypeCodeSequence()->getCodeMeaning(labelName);
        else
        {
          labelName = std::to_string(segmentAttr->getLabelID()).c_str();
          if (labelName.empty())
            labelName = "Unnamed";
        }

        float tmp[3] = {0.0, 0.0, 0.0};
        if (segmentAttr->getRecommendedDisplayRGBValue() != nullptr)
        {
          tmp[0] = segmentAttr->getRecommendedDisplayRGBValue()[0] / 255.0;
          tmp[1] = segmentAttr->getRecommendedDisplayRGBValue()[1] / 255.0;
          tmp[2] = segmentAttr->getRecommendedDisplayRGBValue()[2] / 255.0;
        }

        // If labelSetImage do not exists (first image)
        if (labelSetImage.IsNull())
        {
          // Initialize the labelSetImage with the read image
          labelSetImage = LabelSetImage::New();
          labelSetImage->InitializeByLabeledImage(layerImage);
          // Already a label was generated, so set the information to this
          Label *activeLabel = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer());
          activeLabel->SetName(labelName.c_str());
          activeLabel->SetColor(Color(tmp));
          activeLabel->SetValue(segValue);
        }
        else
        {
          // Add a new layer to the labelSetImage. Background label is set automatically
          labelSetImage->AddLayer(layerImage);

          // Add new label
          Label *newLabel = new Label;
          newLabel->SetName(labelName.c_str());
          newLabel->SetColor(Color(tmp));
          newLabel->SetValue(segValue);

          labelSetImage->GetLabelSet(labelSetImage->GetActiveLayer())->AddLabel(newLabel);
        }

        ++segmentIter;
      }
      // Clean up
      if (converter != nullptr)
        delete converter;
    }
    catch (const std::exception &e)
    {
      MITK_ERROR << "An error occurred while reading the DICOM Seg file: " << e.what();
      return result;
    }

    // Set active layer to th first layer of the labelset image
    if (labelSetImage->GetNumberOfLayers() > 1 && labelSetImage->GetActiveLayer() != 0)
      labelSetImage->SetActiveLayer(0);

    result.push_back(labelSetImage.GetPointer());

    return result;
  }
  void DICOMSegmentationIO::Write()
  {
    ValidateOutputLocation();

    mitk::LocaleSwitch localeSwitch("C");
    LocalFile localFile(this);
    const std::string path = localFile.GetFileName();

    auto input = dynamic_cast<const LabelSetImage *>(this->GetInput());
    if (input == nullptr)
      mitkThrow() << "Cannot write non-image data";

    // Get DICOM information from referenced image
    vector<DcmDataset *> dcmDatasets;
    DcmFileFormat *readFileFormat = new DcmFileFormat();
    try
    {
      // TODO: Generate dcmdataset witk DICOM tags from property list; ATM the source are the filepaths from the
      // property list
      mitk::StringLookupTableProperty::Pointer filesProp =
        dynamic_cast<mitk::StringLookupTableProperty *>(input->GetProperty("files").GetPointer());

      if (filesProp.IsNull())
      {
        mitkThrow() << "No property with dicom file path.";
        return;
      }

      StringLookupTable filesLut = filesProp->GetValue();
      const StringLookupTable::LookupTableType &lookUpTableMap = filesLut.GetLookupTable();

      for (auto it : lookUpTableMap)
      {
        const char *fileName = (it.second).c_str();
        if (readFileFormat->loadFile(fileName, EXS_Unknown).good())
          dcmDatasets.push_back(readFileFormat->getAndRemoveDataset());
      }
    }
    catch (const std::exception &e)
    {
      MITK_ERROR << "An error occurred while getting the dicom informations: " << e.what() << endl;
      return;
    }

    // Iterate over all layers. For each a dcm file will be generated
    for (unsigned int layer = 0; layer < input->GetNumberOfLayers(); ++layer)
    {
      vector<itkInternalImageType::Pointer> segmentations;

      try
      {
        // Cast mitk layer image to itk
        ImageToItk<itkInputImageType>::Pointer imageToItkFilter = ImageToItk<itkInputImageType>::New();
        // BUG: It must be the layer image, but there are some errors with it (dcmqi: generate the dcmSeg "No frame data
        // available") --> input->GetLayerImage(layer)
        imageToItkFilter->SetInput(input);
        imageToItkFilter->Update();

        // Cast from original itk type to dcmqi input itk image type
        typedef itk::CastImageFilter<itkInputImageType, itkInternalImageType> castItkImageFilterType;
        castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New();
        castFilter->SetInput(imageToItkFilter->GetOutput());
        castFilter->Update();

        itkInternalImageType::Pointer itkLabelImage = castFilter->GetOutput();
        itkLabelImage->DisconnectPipeline();

        // Iterate over all labels. For each a segmentation image will be created
        const LabelSet *labelSet = input->GetLabelSet(layer);
        for (auto itLabel = labelSet->IteratorConstBegin(); itLabel != labelSet->IteratorConstEnd(); ++itLabel)
        {
          // Thresold over the image with the given label value
          itk::ThresholdImageFilter<itkInternalImageType>::Pointer thresholdFilter =
            itk::ThresholdImageFilter<itkInternalImageType>::New();
          thresholdFilter->SetInput(itkLabelImage);
          thresholdFilter->ThresholdOutside(itLabel->first, itLabel->first);
          thresholdFilter->SetOutsideValue(0);
          thresholdFilter->Update();
          itkInternalImageType::Pointer segmentImage = thresholdFilter->GetOutput();
          segmentImage->DisconnectPipeline();

          segmentations.push_back(segmentImage);
        }
      }
      catch (const itk::ExceptionObject &e)
      {
        MITK_ERROR << e.GetDescription() << endl;
        return;
      }

      // Create segmentation meta information
      const std::string &tmpMetaInfoFile = this->CreateMetaDataJsonFile(layer);

      MITK_INFO << "Writing image: " << path << std::endl;
      try
      {
        // Convert itk segmentation images to dicom image
        dcmqi::ImageSEGConverter *converter = new dcmqi::ImageSEGConverter();
        DcmDataset *result = converter->itkimage2dcmSegmentation(dcmDatasets, segmentations, tmpMetaInfoFile);

        // Write dicom file
        DcmFileFormat dcmFileFormat(result);

        std::string filePath = path.substr(0, path.find_last_of("."));
        // If there is more than one layer, we have to write more than 1 dicom file
        if (input->GetNumberOfLayers() != 1)
          filePath = filePath + std::to_string(layer) + ".dcm";
        else
          filePath = filePath + ".dcm";

        dcmFileFormat.saveFile(filePath.c_str(), EXS_LittleEndianExplicit);

        // Clean up
        if (converter != nullptr)
          delete converter;
        if (result != nullptr)
          delete result;
      }
      catch (const std::exception &e)
      {
        MITK_ERROR << "An error occurred during writing the DICOM Seg: " << e.what() << endl;
        return;
      }
    } // Write a dcm file for the next layer

    // End of image writing; clean up
    if (readFileFormat)
      delete readFileFormat;

    for (auto obj : dcmDatasets)
      delete obj;
    dcmDatasets.clear();
  }
void mitk::ParRecFileReader::GenerateOutputInformation()
{
  mitk::Image::Pointer output = this->GetOutput();

  if ((output->IsInitialized()) && (this->GetMTime() <= m_ReadHeaderTime.GetMTime()))
    return;

  itkDebugMacro(<<"Reading PAR file for GenerateOutputInformation()" << m_FileName);

  // Check to see if we can read the file given the name or prefix
  //
  if ( m_FileName == "" && m_FilePrefix == "" )
  {
    throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty");
  }

  m_RecFileName = "";
  if( m_FileName != "")
  {
    int extPos=m_FileName.find_last_of(".");
    if(extPos>=-1)
    {
      const char *ext=m_FileName.c_str()+extPos+1;
      if(stricmp(ext,"par")==0)
        m_RecFileName = m_FileName.substr(0,extPos);
      else
        m_RecFileName = m_FileName;
    }
    else
        m_RecFileName = m_FileName;

    m_RecFileName.append(".rec");

    bool headerRead = false;

    bool signedCharType = true;
    unsigned int dimension=0;
    unsigned int dimensions[4]={0,0,1,1};
    float sliceThickness=0.0;
    float sliceGap=0.0;
    float sliceSpacing=0.0;
    mitk::Vector3D thickness; thickness.Fill(1.0);
    mitk::Vector3D gap; gap.Fill(0.0);
    mitk::Vector3D spacing;

    FILE *f;
    f=fopen(m_FileName.c_str(), "r");
    if(f!=nullptr)
    {
      while(!feof(f))
      {
        char s[300], *p;
        char* ignored = fgets(s,200,f);
        ++ignored;
        if(strstr(s,"Max. number of cardiac phases"))
        {
          p=strchr(s,':')+1;
          dimensions[3]=atoi(p);
          if(dimensions[3]>1)
            dimension=4;
        }
        else
        if(strstr(s,"Max. number of slices/locations"))
        {
          p=strchr(s,':')+1;
          dimensions[2]=atoi(p);
          if(dimension==0)
          {
            if(dimensions[2]>1)
              dimension=3;
            else
              dimension=2;
          }
        }
        else
        if(strstr(s,"Image pixel size"))
        {
          p=strchr(s,':')+1;
          int bpe=atoi(p);
          if(bpe!=8)
            signedCharType = false;
        }
        else
        if(strstr(s,"Recon resolution"))
        {
          p=s+strcspn(s,"0123456789");
          sscanf(p,"%u %u", dimensions, dimensions+1);
        }
        else
        if(strstr(s,"FOV (ap,fh,rl) [mm]"))
        {
          p=s+strcspn(s,"0123456789");
          mitk::LocaleSwitch localeSwitch("C");
          sscanf(p,"%lf %lf %lf", &thickness[0], &thickness[1], &thickness[2]);
        }
        else
        if(strstr(s,"Slice thickness [mm]"))
        {
          p=s+strcspn(s,"0123456789");
          mitk::LocaleSwitch localeSwitch("C");
          sscanf(p,"%f", &sliceThickness);
        }
        else
        if(strstr(s,"Slice gap [mm]"))
        {
          p=s+strcspn(s,"-0123456789");
          mitk::LocaleSwitch localeSwitch("C");
          sscanf(p,"%f", &sliceGap);
        }
      }
      fclose(f);

//C:\home\ivo\data\coronaries\ucsf-wholeheart-2.par
      sliceSpacing = sliceThickness+sliceGap;
      if((dimension>0) && (dimensions[0]>0) && (dimensions[1]>0) && (sliceThickness>0) && (sliceSpacing>0))
      {
        headerRead = true;
        if(fabs(thickness[0]/dimensions[2]-sliceSpacing)<0.0001)
          thickness[0]=thickness[1];
        else
        if(fabs(thickness[1]/dimensions[2]-sliceSpacing)<0.0001)
          thickness[1]=thickness[0];
        thickness[2]=sliceSpacing;

        thickness[0]/=dimensions[0];
        thickness[1]/=dimensions[1];
        spacing=thickness+gap;
      }
    }

    if( headerRead == false)
    {
      itk::ImageFileReaderException e(__FILE__, __LINE__);
      std::ostringstream msg;
      msg << " Could not read file "
        << m_FileName.c_str();
      e.SetDescription(msg.str().c_str());
      throw e;
      return;
    }

    // define types
    mitk::PixelType SCType = mitk::MakeScalarPixelType<signed char>();
    mitk::PixelType SSType = mitk::MakeScalarPixelType<signed short>();

    if( signedCharType )
      output->Initialize(SCType, dimension, dimensions);
    else
      output->Initialize(SSType, dimension, dimensions);

    output->GetSlicedGeometry()->SetSpacing(spacing);

    //output->GetSlicedGeometry()->SetPlaneGeometry(mitk::Image::BuildStandardPlanePlaneGeometry(output->GetSlicedGeometry(), dimensions).GetPointer(), 0);
    output->GetSlicedGeometry()->SetEvenlySpaced();
  }

  m_ReadHeaderTime.Modified();
}
std::vector<itk::SmartPointer<BaseData> > BaseDICOMReaderService::Read()
{
  std::vector<BaseData::Pointer> result;

  //special handling of Philips 3D US DICOM.
  //Copied from DICOMSeriesReaderService

  std::string fileName = this->GetLocalFileName();
  if (DicomSeriesReader::IsPhilips3DDicom(fileName))
  {
      MITK_INFO << "it is a Philips3D US Dicom file" << std::endl;
      mitk::LocaleSwitch localeSwitch("C");
      std::locale previousCppLocale(std::cin.getloc());
      std::locale l("C");
      std::cin.imbue(l);

      DataNode::Pointer node = DataNode::New();
      mitk::DicomSeriesReader::StringContainer stringvec;
      stringvec.push_back(fileName);
      if (DicomSeriesReader::LoadDicomSeries(stringvec, *node))
      {
          BaseData::Pointer data = node->GetData();
          StringProperty::Pointer nameProp = StringProperty::New(itksys::SystemTools::GetFilenameName(fileName));
          data->GetPropertyList()->SetProperty("name", nameProp);
          result.push_back(data);
      }
      std::cin.imbue(previousCppLocale);
      return result;
  }

  //Normal DICOM handling (It wasn't a Philips 3D US)
  mitk::StringList relevantFiles = this->GetRelevantFiles();

  mitk::DICOMFileReader::Pointer reader = this->GetReader(relevantFiles);

  reader->SetAdditionalTagsOfInterest(mitk::GetCurrentDICOMTagsOfInterest());
  reader->SetTagLookupTableToPropertyFunctor(mitk::GetDICOMPropertyForDICOMValuesFunctor);
  reader->SetInputFiles(relevantFiles);
  reader->AnalyzeInputFiles();
  reader->LoadImages();

  for (unsigned int i = 0; i < reader->GetNumberOfOutputs(); ++i)
  {
    const mitk::DICOMImageBlockDescriptor& desc = reader->GetOutput(i);
    mitk::BaseData::Pointer data = desc.GetMitkImage().GetPointer();

    std::string nodeName = "Unnamed_DICOM";

    std::string studyDescription = desc.GetPropertyAsString("studyDescription");
    std::string seriesDescription = desc.GetPropertyAsString("seriesDescription");

    if (!studyDescription.empty())
    {
      nodeName = studyDescription;
    }

    if (!seriesDescription.empty())
    {
      if (!studyDescription.empty())
      {
        nodeName += "/";
      }
      nodeName += seriesDescription;
    }

    StringProperty::Pointer nameProp = StringProperty::New(nodeName);
    data->SetProperty("name", nameProp);

    result.push_back(data);
  }

  return result;
}
  std::vector<BaseData::Pointer> ItkImageIO::Read()
  {
    std::vector<BaseData::Pointer> result;
    mitk::LocaleSwitch localeSwitch("C");

    Image::Pointer image = Image::New();

    const unsigned int MINDIM = 2;
    const unsigned int MAXDIM = 4;

    const std::string path = this->GetLocalFileName();

    MITK_INFO << "loading " << path << " via itk::ImageIOFactory... " << std::endl;

    // Check to see if we can read the file given the name or prefix
    if (path.empty())
    {
      mitkThrow() << "Empty filename in mitk::ItkImageIO ";
    }

    // Got to allocate space for the image. Determine the characteristics of
    // the image.
    m_ImageIO->SetFileName(path);
    m_ImageIO->ReadImageInformation();

    unsigned int ndim = m_ImageIO->GetNumberOfDimensions();
    if (ndim < MINDIM || ndim > MAXDIM)
    {
      MITK_WARN << "Sorry, only dimensions 2, 3 and 4 are supported. The given file has " << ndim
                << " dimensions! Reading as 4D.";
      ndim = MAXDIM;
    }

    itk::ImageIORegion ioRegion(ndim);
    itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize();
    itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex();

    unsigned int dimensions[MAXDIM];
    dimensions[0] = 0;
    dimensions[1] = 0;
    dimensions[2] = 0;
    dimensions[3] = 0;

    ScalarType spacing[MAXDIM];
    spacing[0] = 1.0f;
    spacing[1] = 1.0f;
    spacing[2] = 1.0f;
    spacing[3] = 1.0f;

    Point3D origin;
    origin.Fill(0);

    unsigned int i;
    for (i = 0; i < ndim; ++i)
    {
      ioStart[i] = 0;
      ioSize[i] = m_ImageIO->GetDimensions(i);
      if (i < MAXDIM)
      {
        dimensions[i] = m_ImageIO->GetDimensions(i);
        spacing[i] = m_ImageIO->GetSpacing(i);
        if (spacing[i] <= 0)
          spacing[i] = 1.0f;
      }
      if (i < 3)
      {
        origin[i] = m_ImageIO->GetOrigin(i);
      }
    }

    ioRegion.SetSize(ioSize);
    ioRegion.SetIndex(ioStart);

    MITK_INFO << "ioRegion: " << ioRegion << std::endl;
    m_ImageIO->SetIORegion(ioRegion);
    void *buffer = new unsigned char[m_ImageIO->GetImageSizeInBytes()];
    m_ImageIO->Read(buffer);

    image->Initialize(MakePixelType(m_ImageIO), ndim, dimensions);
    image->SetImportChannel(buffer, 0, Image::ManageMemory);

    const itk::MetaDataDictionary &dictionary = m_ImageIO->GetMetaDataDictionary();

    // access direction of itk::Image and include spacing
    mitk::Matrix3D matrix;
    matrix.SetIdentity();
    unsigned int j, itkDimMax3 = (ndim >= 3 ? 3 : ndim);
    for (i = 0; i < itkDimMax3; ++i)
      for (j = 0; j < itkDimMax3; ++j)
        matrix[i][j] = m_ImageIO->GetDirection(j)[i];

    // re-initialize PlaneGeometry with origin and direction
    PlaneGeometry *planeGeometry = image->GetSlicedGeometry(0)->GetPlaneGeometry(0);
    planeGeometry->SetOrigin(origin);
    planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix);

    // re-initialize SlicedGeometry3D
    SlicedGeometry3D *slicedGeometry = image->GetSlicedGeometry(0);
    slicedGeometry->InitializeEvenlySpaced(planeGeometry, image->GetDimension(2));
    slicedGeometry->SetSpacing(spacing);

    MITK_INFO << slicedGeometry->GetCornerPoint(false, false, false);
    MITK_INFO << slicedGeometry->GetCornerPoint(true, true, true);

    // re-initialize TimeGeometry
    TimeGeometry::Pointer timeGeometry;

    if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TYPE) || dictionary.HasKey(PROPERTY_KEY_TIMEGEOMETRY_TYPE))
    { // also check for the name because of backwards compatibility. Past code version stored with the name and not with
      // the key
      itk::MetaDataObject<std::string>::ConstPointer timeGeometryTypeData = nullptr;
      if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TYPE))
      {
        timeGeometryTypeData =
          dynamic_cast<const itk::MetaDataObject<std::string> *>(dictionary.Get(PROPERTY_NAME_TIMEGEOMETRY_TYPE));
      }
      else
      {
        timeGeometryTypeData =
          dynamic_cast<const itk::MetaDataObject<std::string> *>(dictionary.Get(PROPERTY_KEY_TIMEGEOMETRY_TYPE));
      }

      if (timeGeometryTypeData->GetMetaDataObjectValue() == ArbitraryTimeGeometry::GetStaticNameOfClass())
      {
        MITK_INFO << "used time geometry: " << ArbitraryTimeGeometry::GetStaticNameOfClass() << std::endl;
        typedef std::vector<TimePointType> TimePointVector;
        TimePointVector timePoints;

        if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS))
        {
          timePoints = ConvertMetaDataObjectToTimePointList(dictionary.Get(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS));
        }
        else if (dictionary.HasKey(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS))
        {
          timePoints = ConvertMetaDataObjectToTimePointList(dictionary.Get(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS));
        }

        if (timePoints.size() - 1 != image->GetDimension(3))
        {
          MITK_ERROR << "Stored timepoints (" << timePoints.size() - 1 << ") and size of image time dimension ("
                     << image->GetDimension(3) << ") do not match. Switch to ProportionalTimeGeometry fallback"
                     << std::endl;
        }
        else
        {
          ArbitraryTimeGeometry::Pointer arbitraryTimeGeometry = ArbitraryTimeGeometry::New();
          TimePointVector::const_iterator pos = timePoints.begin();
          TimePointVector::const_iterator prePos = pos++;

          for (; pos != timePoints.end(); ++prePos, ++pos)
          {
            arbitraryTimeGeometry->AppendTimeStepClone(slicedGeometry, *pos, *prePos);
          }

          timeGeometry = arbitraryTimeGeometry;
        }
      }
    }

    if (timeGeometry.IsNull())
    { // Fallback. If no other valid time geometry has been created, create a ProportionalTimeGeometry
      MITK_INFO << "used time geometry: " << ProportionalTimeGeometry::GetStaticNameOfClass() << std::endl;
      ProportionalTimeGeometry::Pointer propTimeGeometry = ProportionalTimeGeometry::New();
      propTimeGeometry->Initialize(slicedGeometry, image->GetDimension(3));
      timeGeometry = propTimeGeometry;
    }

    image->SetTimeGeometry(timeGeometry);

    buffer = NULL;
    MITK_INFO << "number of image components: " << image->GetPixelType().GetNumberOfComponents() << std::endl;

    for (itk::MetaDataDictionary::ConstIterator iter = dictionary.Begin(), iterEnd = dictionary.End(); iter != iterEnd;
         ++iter)
    {
      if (iter->second->GetMetaDataObjectTypeInfo() == typeid(std::string))
      {
        const std::string &key = iter->first;
        std::string assumedPropertyName = key;
        std::replace(assumedPropertyName.begin(), assumedPropertyName.end(), '_', '.');

        std::string mimeTypeName = GetMimeType()->GetName();

        // Check if there is already a info for the key and our mime type.
        IPropertyPersistence::InfoResultType infoList = mitk::CoreServices::GetPropertyPersistence()->GetInfoByKey(key);

        auto predicate = [mimeTypeName](const PropertyPersistenceInfo::ConstPointer &x) {
          return x.IsNotNull() && x->GetMimeTypeName() == mimeTypeName;
        };
        auto finding = std::find_if(infoList.begin(), infoList.end(), predicate);

        if (finding == infoList.end())
        {
          auto predicateWild = [](const PropertyPersistenceInfo::ConstPointer &x) {
            return x.IsNotNull() && x->GetMimeTypeName() == PropertyPersistenceInfo::ANY_MIMETYPE_NAME();
          };
          finding = std::find_if(infoList.begin(), infoList.end(), predicateWild);
        }

        PropertyPersistenceInfo::ConstPointer info;

        if (finding != infoList.end())
        {
          assumedPropertyName = (*finding)->GetName();
          info = *finding;
        }
        else
        { // we have not found anything suitable so we generate our own info
          PropertyPersistenceInfo::Pointer newInfo = PropertyPersistenceInfo::New();
          newInfo->SetNameAndKey(assumedPropertyName, key);
          newInfo->SetMimeTypeName(PropertyPersistenceInfo::ANY_MIMETYPE_NAME());
          info = newInfo;
        }

        std::string value =
          dynamic_cast<itk::MetaDataObject<std::string> *>(iter->second.GetPointer())->GetMetaDataObjectValue();

        mitk::BaseProperty::Pointer loadedProp = info->GetDeserializationFunction()(value);

        image->SetProperty(assumedPropertyName.c_str(), loadedProp);

        // Read properties should be persisted unless they are default properties
        // which are written anyway
        bool isDefaultKey(false);

        for (const auto &defaultKey : m_DefaultMetaDataKeys)
        {
          if (defaultKey.length() <= assumedPropertyName.length())
          {
            // does the start match the default key
            if (assumedPropertyName.substr(0, defaultKey.length()).find(defaultKey) != std::string::npos)
            {
              isDefaultKey = true;
              break;
            }
          }
        }

        if (!isDefaultKey)
        {
          mitk::CoreServices::GetPropertyPersistence()->AddInfo(info);
        }
      }
    }

    MITK_INFO << "...finished!" << std::endl;

    result.push_back(image.GetPointer());
    return result;
  }
Beispiel #10
0
std::string mitk::CustomTagParser::GetOffsetString(std::string samplingType, std::string offset, std::string measurements)
{
  mitk::LocaleSwitch localeSwitch("C");
  std::stringstream results;

  std::string normalizationIndicatingOffset = "-300";

  double offsetDouble = 0.0;
  int measurementsInt = 0;

  bool validOffset = false;
  bool validMeasurements = false;

  if ("" != offset)
  {
    validOffset = true;
    offsetDouble = std::stod(offset);
  }
  if ("" != measurements)
  {
    validMeasurements = true;
    measurementsInt = std::stoi(measurements);
  }

  std::vector<double> offsetVector;

  if (validOffset && validMeasurements)
  {
    for (int step = 0; step < measurementsInt -1; ++step)
    {
      double currentOffset = -offsetDouble + 2 * step * offsetDouble / (measurementsInt - 2.0);
      offsetVector.push_back(currentOffset);
    }
  }
  else
  {
    MITK_WARN << "Invalid offset or measurements, offset calculation will only work for list sampling type.";
  }

  if (samplingType == "1" || samplingType == "Regular")
  {
    if (validOffset && validMeasurements)
    {
      results << normalizationIndicatingOffset << " ";
      for (const auto& entry : offsetVector)
      {
        results << entry << " ";
      }
    }
  }
  else if (samplingType == "2" || samplingType == "Alternating")
  {
    if (validOffset && validMeasurements)
    {
      results << normalizationIndicatingOffset << " ";
      for (auto& entry : offsetVector)
      {
        entry = std::abs(entry);
      }

      std::sort(offsetVector.begin(), offsetVector.end(), std::greater<>());

      for (unsigned int index = 0; index < offsetVector.size(); ++index)
      {
        offsetVector[index] = std::pow(-1, index) * offsetVector[index];
      }

      for (auto& entry : offsetVector)
      {
        results << entry << " ";
      }
    }
  }
  else if (samplingType == "3" || samplingType == "List")
  {
    std::string listPath = m_DicomDataPath + "/LIST.txt";
    std::ifstream list(listPath.c_str());

    if (list.good())
    {
      std::string currentOffset;
      while (std::getline(list, currentOffset))
      {
        results << currentOffset << " ";
      }
    }
    else
    {
      MITK_ERROR << "Could not load list at " << listPath;
    }
  }
  else if (samplingType == "4" || samplingType == "SingleOffset")
  {
    if (validOffset && validMeasurements)
    {
      results << normalizationIndicatingOffset << " ";
      for (int step = 0; step < measurementsInt - 1; ++step)
      {
        results << offsetDouble << " ";
      }
    }
  }
  else
  {
    MITK_WARN << "Encountered unknown sampling type.";
  }

  std::string resultString = results.str();
  // replace multiple spaces by a single space
  std::string::iterator newEnditerator =
    std::unique(resultString.begin(), resultString.end(),
      [=](char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }
  );
  resultString.erase(newEnditerator, resultString.end());

  if ((resultString.length() > 0) && (resultString.at(resultString.length() - 1) == ' '))
  {
    resultString.erase(resultString.end() - 1, resultString.end());
  }

  if ((resultString.length() > 0) && (resultString.at(0) == ' '))
  {
    resultString.erase(resultString.begin(), ++(resultString.begin()));
  }

  return resultString;
}
void
mitk::TeemDiffusionTensor3DReconstructionImageFilter<D,T>
::Update()
{
  itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randgen = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
  randgen->SetSeed();

  // save input image to nrrd file in temp-folder
  char filename[512];
  int random_integer = randgen->GetIntegerVariate();
  sprintf( filename, "dwi_%d.nhdr",random_integer);

  try
  {
    mitk::IOUtil::Save(m_Input, filename);
  }
  catch (itk::ExceptionObject e)
  {
    std::cout << e << std::endl;
  }

  file_replace(filename,"vector","list");

  // build up correct command from input params
  char command[4096];
  sprintf( command, "tend estim -i %s -B kvp -o tensors_%d.nhdr -knownB0 true",
    filename, random_integer);

  //m_DiffusionImages;
  if(m_EstimateErrorImage)
  {
    sprintf( command, "%s -ee error_image_%d.nhdr", command, random_integer);
  }

  if(m_Sigma != -19191919)
  {
    sprintf( command, "%s -sigma %f", command, m_Sigma);
  }

  switch(m_EstimationMethod)
  {
  case TeemTensorEstimationMethodsLLS:
    sprintf( command, "%s -est lls", command);
    break;
  case TeemTensorEstimationMethodsMLE:
    sprintf( command, "%s -est mle", command);
    break;
  case TeemTensorEstimationMethodsNLS:
    sprintf( command, "%s -est nls", command);
    break;
  case TeemTensorEstimationMethodsWLS:
    sprintf( command, "%s -est wls", command);
    break;
  }

  sprintf( command, "%s -wlsi %d", command, m_NumIterations);

  if(m_ConfidenceThreshold != -19191919.0)
  {
    sprintf( command, "%s -t %f", command, m_ConfidenceThreshold);
  }

  sprintf( command, "%s -soft %f", command, m_ConfidenceFuzzyness);
  sprintf( command, "%s -mv %f", command, m_MinPlausibleValue);

  // call tend estim command
  std::cout << "Calling <" << command << ">" << std::endl;
  int success = system(command);
  if(!success)
  {
    MITK_ERROR << "system command could not be called!";
  }

  remove(filename);
  sprintf( filename, "dwi_%d.raw", random_integer);
  remove(filename);

  // change kind from tensor to vector
  sprintf( filename, "tensors_%d.nhdr", random_integer);
  file_replace(filename,"3D-masked-symmetric-matrix","vector");

  mitk::LocaleSwitch localeSwitch("C");
  // read result as mitk::Image and provide it in m_Output
  typedef itk::ImageFileReader<VectorImageType> FileReaderType;
  typename FileReaderType::Pointer reader = FileReaderType::New();
  reader->SetFileName(filename);
  reader->Update();
  typename VectorImageType::Pointer vecImage = reader->GetOutput();

  remove(filename);
  sprintf( filename, "tensors_%d.raw", random_integer);
  remove(filename);

  typename ItkTensorImageType::Pointer itkTensorImage = ItkTensorImageType::New();
  itkTensorImage->SetSpacing( vecImage->GetSpacing() );   // Set the image spacing
  itkTensorImage->SetOrigin( vecImage->GetOrigin() );     // Set the image origin
  itkTensorImage->SetDirection( vecImage->GetDirection() );  // Set the image direction
  itkTensorImage->SetLargestPossibleRegion( vecImage->GetLargestPossibleRegion() );
  itkTensorImage->SetBufferedRegion( vecImage->GetLargestPossibleRegion() );
  itkTensorImage->SetRequestedRegion( vecImage->GetLargestPossibleRegion() );
  itkTensorImage->Allocate();

  itk::ImageRegionIterator<VectorImageType> it(vecImage,
    vecImage->GetLargestPossibleRegion());

  itk::ImageRegionIterator<ItkTensorImageType> it2(itkTensorImage,
    itkTensorImage->GetLargestPossibleRegion());
  it2 = it2.Begin();

  //#pragma omp parallel private (it)
  {
    for(it=it.Begin();!it.IsAtEnd(); ++it, ++it2)
    {
      //#pragma omp single nowait
      {
        VectorType vec = it.Get();
        TensorType tensor;
        for(int i=1;i<7;i++)
          tensor[i-1] = vec[i] * vec[0];
        it2.Set( tensor );
      }
    } // end for
  } // end ompparallel

  m_OutputItk = mitk::TensorImage::New();
  m_OutputItk->InitializeByItk(itkTensorImage.GetPointer());
  m_OutputItk->SetVolume( itkTensorImage->GetBufferPointer() );

  // in case: read resulting error-image and provide it in m_ErrorImage
  if(m_EstimateErrorImage)
  {
    // open error image here
  }

}
std::vector<itk::SmartPointer<mitk::BaseData>> mitk::GeometryDataReaderService::Read()
{
  // Switch the current locale to "C"
  LocaleSwitch localeSwitch("C");

  std::vector<itk::SmartPointer<BaseData>> result;

  InputStream stream(this);

  TiXmlDocument doc;
  stream >> doc;
  if (!doc.Error())
  {
    TiXmlHandle docHandle(&doc);

    for (TiXmlElement *geomDataElement = docHandle.FirstChildElement("GeometryData").ToElement();
         geomDataElement != nullptr;
         geomDataElement = geomDataElement->NextSiblingElement())
    {
      for (TiXmlElement *currentElement = geomDataElement->FirstChildElement(); currentElement != nullptr;
           currentElement = currentElement->NextSiblingElement())
      {
        // different geometries could have been serialized from a GeometryData
        // object:
        std::string tagName = currentElement->Value();
        if (tagName == "Geometry3D")
        {
          Geometry3D::Pointer restoredGeometry = Geometry3DToXML::FromXML(currentElement);
          if (restoredGeometry.IsNotNull())
          {
            GeometryData::Pointer newGeometryData = GeometryData::New();
            newGeometryData->SetGeometry(restoredGeometry);
            result.push_back(newGeometryData.GetPointer());
          }
          else
          {
            MITK_ERROR << "Invalid <Geometry3D> tag encountered. Skipping.";
          }
        }
        else if (tagName == "ProportionalTimeGeometry")
        {
          ProportionalTimeGeometry::Pointer restoredTimeGeometry =
            ProportionalTimeGeometryToXML::FromXML(currentElement);
          if (restoredTimeGeometry.IsNotNull())
          {
            GeometryData::Pointer newGeometryData = GeometryData::New();
            newGeometryData->SetTimeGeometry(restoredTimeGeometry);
            result.push_back(newGeometryData.GetPointer());
          }
          else
          {
            MITK_ERROR << "Invalid <ProportionalTimeGeometry> tag encountered. Skipping.";
          }
        }
      } // for child of <GeometryData>
    }   // for <GeometryData>
  }
  else
  {
    mitkThrow() << "Parsing error at line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc();
  }

  if (result.empty())
  {
    mitkThrow() << "Did not read a single GeometryData object from input.";
  }

  return result;
}
TiXmlElement* mitk::TransferFunctionPropertySerializer::Serialize()
{
  if (const TransferFunctionProperty* prop = dynamic_cast<const TransferFunctionProperty*>(mitk::BasePropertySerializer::m_Property.GetPointer()))
  {
    LocaleSwitch localeSwitch("C");

    TransferFunction* transferfunction = prop->GetValue();
    if (!transferfunction)
      return nullptr;

    auto  element = new TiXmlElement("TransferFunction");

    // serialize scalar opacity function
    auto  scalarOpacityPointlist = new TiXmlElement( "ScalarOpacity" );

    TransferFunction::ControlPoints scalarOpacityPoints = transferfunction->GetScalarOpacityPoints();
    for ( auto iter = scalarOpacityPoints.begin();
      iter != scalarOpacityPoints.end();
      ++iter )
    {
      auto  pointel = new TiXmlElement("point");
      pointel->SetAttribute("x", boost::lexical_cast<std::string>(iter->first));
      pointel->SetAttribute("y", boost::lexical_cast<std::string>(iter->second));
      scalarOpacityPointlist->LinkEndChild( pointel );
    }
    element->LinkEndChild( scalarOpacityPointlist );
    // serialize gradient opacity function
    auto  gradientOpacityPointlist = new TiXmlElement( "GradientOpacity" );
    TransferFunction::ControlPoints gradientOpacityPoints = transferfunction->GetGradientOpacityPoints();
    for ( auto iter = gradientOpacityPoints.begin();
      iter != gradientOpacityPoints.end();
      ++iter )
    {
      auto  pointel = new TiXmlElement("point");
      pointel->SetAttribute("x", boost::lexical_cast<std::string>(iter->first));
      pointel->SetAttribute("y", boost::lexical_cast<std::string>(iter->second));
      gradientOpacityPointlist->LinkEndChild( pointel );
    }
    element->LinkEndChild( gradientOpacityPointlist );

    // serialize color function
    vtkColorTransferFunction* ctf = transferfunction->GetColorTransferFunction();
    if (ctf == nullptr)
      return nullptr;
    auto  pointlist = new TiXmlElement("Color");
    for (int i = 0; i < ctf->GetSize(); i++ )
    {
      double myVal[6];
      ctf->GetNodeValue(i, myVal);
      auto  pointel = new TiXmlElement("point");
      pointel->SetAttribute("x", boost::lexical_cast<std::string>(myVal[0]));
      pointel->SetAttribute("r", boost::lexical_cast<std::string>(myVal[1]));
      pointel->SetAttribute("g", boost::lexical_cast<std::string>(myVal[2]));
      pointel->SetAttribute("b", boost::lexical_cast<std::string>(myVal[3]));
      pointel->SetAttribute("midpoint", boost::lexical_cast<std::string>(myVal[4]));
      pointel->SetAttribute("sharpness", boost::lexical_cast<std::string>(myVal[5]));
      pointlist->LinkEndChild( pointel );
    }
    element->LinkEndChild( pointlist );
    return element;
  }
  else return nullptr;
}
BaseProperty::Pointer mitk::TransferFunctionPropertySerializer::Deserialize(TiXmlElement* element)
{
  if (!element)
    return nullptr;

  mitk::LocaleSwitch localeSwitch("C");

  TransferFunction::Pointer tf = TransferFunction::New();

  // deserialize scalar opacity function
  TiXmlElement* scalarOpacityPointlist = element->FirstChildElement("ScalarOpacity");
  if (scalarOpacityPointlist == nullptr)
  {
    return nullptr;
  }

  tf->ClearScalarOpacityPoints();

  try
  {
    for( TiXmlElement* pointElement = scalarOpacityPointlist->FirstChildElement("point");
         pointElement != nullptr;
         pointElement = pointElement->NextSiblingElement("point"))
    {
      std::string x;
      std::string y;
      if (pointElement->QueryStringAttribute("x", &x) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("y", &y) != TIXML_SUCCESS) return nullptr;
      tf->AddScalarOpacityPoint(boost::lexical_cast<double>(x), boost::lexical_cast<double>(y));
    }

    TiXmlElement* gradientOpacityPointlist = element->FirstChildElement("GradientOpacity");
    if (gradientOpacityPointlist == nullptr)
    {
      return nullptr;
    }

    tf->ClearGradientOpacityPoints();

    for( TiXmlElement* pointElement = gradientOpacityPointlist->FirstChildElement("point");
         pointElement != nullptr;
         pointElement = pointElement->NextSiblingElement("point"))
    {
      std::string x;
      std::string y;
      if (pointElement->QueryStringAttribute("x", &x) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("y", &y) != TIXML_SUCCESS) return nullptr;
      tf->AddGradientOpacityPoint(boost::lexical_cast<double>(x), boost::lexical_cast<double>(y));
    }

    TiXmlElement* rgbPointlist = element->FirstChildElement("Color");
    if (rgbPointlist == nullptr)
    {
      return nullptr;
    }
    vtkColorTransferFunction* ctf = tf->GetColorTransferFunction();
    if (ctf == nullptr)
    {
      return nullptr;
    }

    ctf->RemoveAllPoints();

    for( TiXmlElement* pointElement = rgbPointlist->FirstChildElement("point");
         pointElement != nullptr;
         pointElement = pointElement->NextSiblingElement("point"))
    {
      std::string x;
      std::string r,g,b, midpoint, sharpness;
      if (pointElement->QueryStringAttribute("x", &x) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("r", &r) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("g", &g) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("b", &b) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("midpoint", &midpoint) != TIXML_SUCCESS) return nullptr;
      if (pointElement->QueryStringAttribute("sharpness", &sharpness) != TIXML_SUCCESS) return nullptr;
      ctf->AddRGBPoint(boost::lexical_cast<double>(x),
                       boost::lexical_cast<double>(r), boost::lexical_cast<double>(g), boost::lexical_cast<double>(b),
                       boost::lexical_cast<double>(midpoint),
                       boost::lexical_cast<double>(sharpness));
    }
  }
  catch ( boost::bad_lexical_cast& e )
  {
    MITK_ERROR << "Could not parse string as number: " << e.what();

    return nullptr;
  }

  return TransferFunctionProperty::New(tf).GetPointer();
}
Beispiel #15
0
void ItkImageIO::Write()
{
  const mitk::Image* image = dynamic_cast<const mitk::Image*>(this->GetInput());

  if (image == NULL)
  {
    mitkThrow() << "Cannot write non-image data";
  }

  struct LocaleSwitch
  {
    LocaleSwitch(const std::string& newLocale)
      : m_OldLocale(std::setlocale(LC_ALL, NULL))
      , m_NewLocale(newLocale)
    {
      if (m_OldLocale == NULL)
      {
        m_OldLocale = "";
      }
      else if (m_NewLocale != m_OldLocale)
      {
        // set the locale
        if (std::setlocale(LC_ALL, m_NewLocale.c_str()) == NULL)
        {
          MITK_INFO << "Could not set locale " << m_NewLocale;
          m_OldLocale = NULL;
        }
      }
    }

    ~LocaleSwitch()
    {
      if (m_OldLocale != NULL && std::setlocale(LC_ALL, m_OldLocale) == NULL)
      {
        MITK_INFO << "Could not reset locale " << m_OldLocale;
      }
    }

  private:
    const char* m_OldLocale;
    const std::string m_NewLocale;
  };

  // Switch the current locale to "C"
  LocaleSwitch localeSwitch("C");

  // Clone the image geometry, because we might have to change it
  // for writing purposes
  BaseGeometry::Pointer geometry = image->GetGeometry()->Clone();

  // Check if geometry information will be lost
  if (image->GetDimension() == 2 &&
      !geometry->Is2DConvertable())
  {
    MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might consider using Convert2Dto3DImageFilter before saving.";

    // set matrix to identity
    mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New();
    affTrans->SetIdentity();
    mitk::Vector3D spacing = geometry->GetSpacing();
    mitk::Point3D origin = geometry->GetOrigin();
    geometry->SetIndexToWorldTransform(affTrans);
    geometry->SetSpacing(spacing);
    geometry->SetOrigin(origin);
  }

  LocalFile localFile(this);
  const std::string path = localFile.GetFileName();

  MITK_INFO << "Writing image: " << path << std::endl;

  try
  {
    // Implementation of writer using itkImageIO directly. This skips the use
    // of templated itkImageFileWriter, which saves the multiplexing on MITK side.

    const unsigned int dimension = image->GetDimension();
    const unsigned int* const dimensions = image->GetDimensions();
    const mitk::PixelType pixelType = image->GetPixelType();
    const mitk::Vector3D mitkSpacing = geometry->GetSpacing();
    const mitk::Point3D mitkOrigin = geometry->GetOrigin();

    // Due to templating in itk, we are forced to save a 4D spacing and 4D Origin,
    // though they are not supported in MITK
    itk::Vector<double, 4u> spacing4D;
    spacing4D[0] = mitkSpacing[0];
    spacing4D[1] = mitkSpacing[1];
    spacing4D[2] = mitkSpacing[2];
    spacing4D[3] = 1; // There is no support for a 4D spacing. However, we should have a valid value here

    itk::Vector<double, 4u> origin4D;
    origin4D[0] = mitkOrigin[0];
    origin4D[1] = mitkOrigin[1];
    origin4D[2] = mitkOrigin[2];
    origin4D[3] = 0; // There is no support for a 4D origin. However, we should have a valid value here

    // Set the necessary information for imageIO
    m_ImageIO->SetNumberOfDimensions(dimension);
    m_ImageIO->SetPixelType(pixelType.GetPixelType());
    m_ImageIO->SetComponentType(pixelType.GetComponentType() < PixelComponentUserType ?
                                  static_cast<itk::ImageIOBase::IOComponentType>(pixelType.GetComponentType()) :
                                  itk::ImageIOBase::UNKNOWNCOMPONENTTYPE);
    m_ImageIO->SetNumberOfComponents( pixelType.GetNumberOfComponents() );

    itk::ImageIORegion ioRegion( dimension );

    for(unsigned int i = 0; i < dimension; i++)
    {
      m_ImageIO->SetDimensions(i, dimensions[i]);
      m_ImageIO->SetSpacing(i, spacing4D[i]);
      m_ImageIO->SetOrigin(i, origin4D[i]);

      mitk::Vector3D mitkDirection;
      mitkDirection.SetVnlVector(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i));
      itk::Vector<double, 4u> direction4D;
      direction4D[0] = mitkDirection[0];
      direction4D[1] = mitkDirection[1];
      direction4D[2] = mitkDirection[2];

      // MITK only supports a 3x3 direction matrix. Due to templating in itk, however, we must
      // save a 4x4 matrix for 4D images. in this case, add an homogneous component to the matrix.
      if (i == 3)
      {
        direction4D[3] = 1; // homogenous component
      }
      else
      {
        direction4D[3] = 0;
      }
      vnl_vector<double> axisDirection(dimension);
      for(unsigned int j = 0; j < dimension; j++)
      {
        axisDirection[j] = direction4D[j] / spacing4D[i];
      }
      m_ImageIO->SetDirection(i, axisDirection);

      ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i));
      ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i));
    }

    //use compression if available
    m_ImageIO->UseCompressionOn();

    m_ImageIO->SetIORegion(ioRegion);
    m_ImageIO->SetFileName(path);

    // ***** Remove const_cast after bug 17952 is fixed ****
    ImageReadAccessor imageAccess(const_cast<mitk::Image*>(image));
    m_ImageIO->Write(imageAccess.GetData());
  }
  catch (const std::exception& e)
  {
    mitkThrow() << e.what();
  }
}
// do the work
void mitk::GEDicomDiffusionImageHeaderReader::Update()
{

  // check if there are filenames
  if(m_DicomFilenames.size())
  {
    mitk::LocaleSwitch localeSwitch("C");

    // adapted from namic-sandbox
    // DicomToNrrdConverter.cxx

    VolumeReaderType::DictionaryArrayRawPointer inputDict
      = m_VolumeReader->GetMetaDataDictionaryArray();

    ReadPublicTags();

    float x0, y0, z0;
    float x1, y1, z1;
    std::string tag;
    tag.clear();
    itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0020|0032", tag );
    sscanf( tag.c_str(), "%f\\%f\\%f", &x0, &y0, &z0 );
    std::cout << "Slice 0: " << tag << std::endl;
    tag.clear();

    // assume volume interleaving, i.e. the second dicom file stores
    // the second slice in the same volume as the first dicom file
    itk::ExposeMetaData<std::string> ( *(*inputDict)[1], "0020|0032", tag );
    sscanf( tag.c_str(), "%f\\%f\\%f", &x1, &y1, &z1 );
    std::cout << "Slice 1: " << tag << std::endl;
    x1 -= x0; y1 -= y0; z1 -= z0;
    x0 = x1*this->m_Output->xSlice + y1*this->m_Output->ySlice + z1*this->m_Output->zSlice;
    if (x0 < 0)
    {
      m_SliceOrderIS = false;
    }

    ReadPublicTags2();

    int nSliceInVolume;
    int nVolume;

    nSliceInVolume = m_sliceLocations.size();
    nVolume = m_nSlice/nSliceInVolume;

    // assume volume interleaving
    std::cout << "Number of Slices: " << m_nSlice << std::endl;
    std::cout << "Number of Volume: " << nVolume << std::endl;
    std::cout << "Number of Slices in each volume: " << nSliceInVolume << std::endl;

    for (int k = 0; k < m_nSlice; k += nSliceInVolume)
    {
      tag.clear();
      bool exist = itk::ExposeMetaData<std::string> ( *(*inputDict)[k], "0043|1039",  tag);
      float b = atof( tag.c_str() );
      this->m_Output->bValue = b;

      vnl_vector_fixed<double, 3> vect3d;
      if (!exist || b == 0)
      {
        vect3d.fill( 0 );
        this->m_Output->DiffusionVector = vect3d;
        continue;
      }

      vect3d.fill( 0 );
      tag.clear();
      itk::ExposeMetaData<std::string> ( *(*inputDict)[k], "0019|10bb",  tag);
      vect3d[0] = atof( tag.c_str() );

      tag.clear();
      itk::ExposeMetaData<std::string> ( *(*inputDict)[k], "0019|10bc",  tag);
      vect3d[1] = atof( tag.c_str() );

      tag.clear();
      itk::ExposeMetaData<std::string> ( *(*inputDict)[k], "0019|10bd",  tag);
      vect3d[2] = atof( tag.c_str() );

      vect3d.normalize();
      this->m_Output->DiffusionVector = vect3d;
    }

    TransformGradients();
  }
}
void mitk::DicomDiffusionImageHeaderReader::ReadPublicTags()
{
  mitk::LocaleSwitch localeSwitch("C");

  VolumeReaderType::DictionaryArrayRawPointer inputDict
    = m_VolumeReader->GetMetaDataDictionaryArray();

  // load in all public tags
  m_nSlice = inputDict->size();
  std::string tag;

  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0008|103e", tag );
  this->m_Output->seriesDescription = tag.c_str();

  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0020|0011", tag );
  this->m_Output->seriesNumber = atoi(tag.c_str());

  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0010|0010", tag );
  this->m_Output->patientName = tag.c_str();

  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0028|0010", tag );
  this->m_Output->nRows = atoi( tag.c_str() );

  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0028|0011", tag );
  this->m_Output->nCols = atoi( tag.c_str() );

  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0028|0030", tag );
  sscanf( tag.c_str(), "%f\\%f", &this->m_Output->xRes, &this->m_Output->yRes );

  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0020|0032", tag );
  sscanf( tag.c_str(), "%f\\%f\\%f", &this->m_Output->xOrigin, &this->m_Output->yOrigin, &this->m_Output->zOrigin );

  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0018|0050", tag );
  this->m_Output->sliceThickness = atof( tag.c_str() );

  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0018|0088", tag );
  this->m_Output->sliceSpacing = atof( tag.c_str() );

  // figure out how many slices are there in a volume, each unique
  // SliceLocation represent one slice
  for (int k = 0; k < m_nSlice; k++)
  {
    tag.clear();
    itk::ExposeMetaData<std::string> ( *(*inputDict)[k], "0020|1041",  tag);
    float sliceLocation = atof( tag.c_str() );
    InsertUnique( m_sliceLocations, sliceLocation );
  }

  // check ImageOrientationPatient and figure out slice direction in
  // L-P-I (right-handed) system.
  // In Dicom, the coordinate frame is L-P by default. Look at
  // http://medical.nema.org/dicom/2007/07_03pu.pdf ,  page 301
  tag.clear();
  itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0020|0037", tag );
  float xRow, yRow, zRow, xCol, yCol, zCol, xSlice, ySlice, zSlice /*, orthoSliceSpacing*/;
  sscanf( tag.c_str(), "%f\\%f\\%f\\%f\\%f\\%f", &xRow, &yRow, &zRow, &xCol, &yCol, &zCol );

  // In Dicom, the measurement frame is L-P by default. Look at
  // http://medical.nema.org/dicom/2007/07_03pu.pdf ,  page 301, in
  // order to make this compatible with Slicer's RAS frame, we
  // multiply the direction cosines by the negatives of the resolution
  // (resolution is required by nrrd format). Direction cosine is not
  // affacted since the resulting frame is still a right-handed frame.
  xRow = -xRow;
  yRow = -yRow;

  xCol = -xCol;
  yCol = -yCol;

  // Cross product, this gives I-axis direction
  xSlice = (yRow*zCol-zRow*yCol)*this->m_Output->sliceSpacing;
  ySlice = (zRow*xCol-xRow*zCol)*this->m_Output->sliceSpacing;
  zSlice = (xRow*yCol-yRow*xCol)*this->m_Output->sliceSpacing;

  xRow *= this->m_Output->xRes;
  yRow *= this->m_Output->xRes;
  zRow *= this->m_Output->xRes;

  xCol *= this->m_Output->yRes;
  yCol *= this->m_Output->yRes;
  zCol *= this->m_Output->yRes;

  this->m_Output->xRow = xRow;
  this->m_Output->yRow = yRow;
  this->m_Output->zRow = zRow;
  this->m_Output->xCol = xCol;
  this->m_Output->yCol = yCol;
  this->m_Output->zCol = zCol;
  this->m_Output->xSlice = xSlice;
  this->m_Output->ySlice = ySlice;
  this->m_Output->zSlice = zSlice;
}
  std::vector<itk::SmartPointer<BaseData> > NrrdTensorImageReader::Read()
  {
    std::vector<itk::SmartPointer<mitk::BaseData> > result;
    std::string location = GetInputLocation();

    if ( location == "")
    {
      throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename is empty!");
    }
    else
    {
      try
      {
        mitk::LocaleSwitch localeSwitch("C");

        try
        {
          std::string fname3 = mitk::IOUtil::GetTempPath()+"/temp_dti.nii.gz";

          int c = 0;
          while( itksys::SystemTools::FileExists(fname3) )
          {
            fname3 = mitk::IOUtil::GetTempPath()+"/temp_dti_" + boost::lexical_cast<std::string>(c) + ".nii.gz";
            ++c;
          }

          itksys::SystemTools::CopyAFile(location.c_str(), fname3.c_str());

          typedef itk::VectorImage<float,3> ImageType;
          itk::NiftiImageIO::Pointer io = itk::NiftiImageIO::New();
          typedef itk::ImageFileReader<ImageType> FileReaderType;
          FileReaderType::Pointer reader = FileReaderType::New();
          reader->SetImageIO(io);
          reader->SetFileName(fname3);
          reader->Update();
          ImageType::Pointer img = reader->GetOutput();

          TensorImage::ItkTensorImageType::Pointer vecImg = TensorImage::ItkTensorImageType::New();
          vecImg->SetSpacing( img->GetSpacing() );   // Set the image spacing
          vecImg->SetOrigin( img->GetOrigin() );     // Set the image origin
          vecImg->SetDirection( img->GetDirection() );  // Set the image direction
          vecImg->SetRegions( img->GetLargestPossibleRegion());
          vecImg->Allocate();

          itk::ImageRegionIterator<TensorImage::ItkTensorImageType> ot (vecImg, vecImg->GetLargestPossibleRegion() );
          ot.GoToBegin();

          itk::ImageRegionIterator<ImageType> it (img, img->GetLargestPossibleRegion() );
          it.GoToBegin();

          typedef ImageType::PixelType  VarPixType;
          typedef TensorImage::PixelType FixPixType;
          int numComponents = img->GetNumberOfComponentsPerPixel();

          if (numComponents==6)
          {
            MITK_INFO << "Trying to load dti as 6-comp nifti ...";
            while (!it.IsAtEnd())
            {
              VarPixType vec = it.Get();
              FixPixType fixVec(vec.GetDataPointer());

              TensorImage::PixelType tensor;
              tensor.SetElement(0, vec.GetElement(0));
              tensor.SetElement(1, vec.GetElement(1));
              tensor.SetElement(2, vec.GetElement(2));
              tensor.SetElement(3, vec.GetElement(3));
              tensor.SetElement(4, vec.GetElement(4));
              tensor.SetElement(5, vec.GetElement(5));

              fixVec = tensor;

              ot.Set(fixVec);
              ++ot;
              ++it;
            }
          }
          else if(numComponents==9)
          {
            MITK_INFO << "Trying to load dti as 9-comp nifti ...";
            while (!it.IsAtEnd())
            {
              VarPixType vec = it.Get();
              TensorImage::PixelType tensor;
              tensor.SetElement(0, vec.GetElement(0));
              tensor.SetElement(1, vec.GetElement(1));
              tensor.SetElement(2, vec.GetElement(2));
              tensor.SetElement(3, vec.GetElement(4));
              tensor.SetElement(4, vec.GetElement(5));
              tensor.SetElement(5, vec.GetElement(8));

              FixPixType fixVec(tensor);
              ot.Set(fixVec);
              ++ot;
              ++it;
            }
          }
          else if (numComponents==1)
          {
            MITK_INFO << "Trying to load dti as 4D nifti ...";
            typedef itk::Image<float,4> ImageType;
            typedef itk::ImageFileReader<ImageType> FileReaderType;
            FileReaderType::Pointer reader = FileReaderType::New();
            reader->SetImageIO(io);
            reader->SetFileName(fname3);
            reader->Update();
            ImageType::Pointer img = reader->GetOutput();

            itk::Size<4> size = img->GetLargestPossibleRegion().GetSize();

            while (!ot.IsAtEnd())
            {
              TensorImage::PixelType tensor;
              ImageType::IndexType idx;
              idx[0] = ot.GetIndex()[0]; idx[1] = ot.GetIndex()[1]; idx[2] = ot.GetIndex()[2];

              if (size[3]==6)
              {
                for (unsigned int te=0; te<size[3]; te++)
                {
                  idx[3] = te;
                  tensor.SetElement(te, img->GetPixel(idx));
                }
              }
              else if (size[3]==9)
              {
                idx[3] = 0;
                tensor.SetElement(0, img->GetPixel(idx));
                idx[3] = 1;
                tensor.SetElement(1, img->GetPixel(idx));
                idx[3] = 2;
                tensor.SetElement(2, img->GetPixel(idx));
                idx[3] = 4;
                tensor.SetElement(3, img->GetPixel(idx));
                idx[3] = 5;
                tensor.SetElement(4, img->GetPixel(idx));
                idx[3] = 8;
                tensor.SetElement(5, img->GetPixel(idx));
              }
              else
                throw itk::ImageFileReaderException(__FILE__, __LINE__, "Unknown number of components for DTI file. Should be 6 or 9!");

              FixPixType fixVec(tensor);
              ot.Set(fixVec);
              ++ot;
            }
          }
          OutputType::Pointer resultImage = OutputType::New();
          resultImage->InitializeByItk( vecImg.GetPointer() );
          resultImage->SetVolume( vecImg->GetBufferPointer() );
          result.push_back( resultImage.GetPointer() );
        }
        catch(...)
        {
          MITK_INFO << "Trying to load dti as nrrd ...";

          typedef itk::VectorImage<float,3> ImageType;
          itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
          typedef itk::ImageFileReader<ImageType> FileReaderType;
          FileReaderType::Pointer reader = FileReaderType::New();
          reader->SetImageIO(io);
          reader->SetFileName(location);
          reader->Update();
          ImageType::Pointer img = reader->GetOutput();

          TensorImage::ItkTensorImageType::Pointer vecImg = TensorImage::ItkTensorImageType::New();
          vecImg->SetSpacing( img->GetSpacing() );   // Set the image spacing
          vecImg->SetOrigin( img->GetOrigin() );     // Set the image origin
          vecImg->SetDirection( img->GetDirection() );  // Set the image direction
          vecImg->SetRegions( img->GetLargestPossibleRegion());
          vecImg->Allocate();

          itk::ImageRegionIterator<TensorImage::ItkTensorImageType> ot (vecImg, vecImg->GetLargestPossibleRegion() );
          ot.GoToBegin();

          itk::ImageRegionIterator<ImageType> it (img, img->GetLargestPossibleRegion() );
          it.GoToBegin();

          typedef ImageType::PixelType  VarPixType;
          typedef TensorImage::PixelType FixPixType;
          int numComponents = img->GetNumberOfComponentsPerPixel();

          itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary();
          std::vector<std::string> imgMetaKeys = imgMetaDictionary.GetKeys();
          std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
          std::string metaString;

          bool readFrame = false;
          double xx, xy, xz, yx, yy, yz, zx, zy, zz;
          MeasurementFrameType measFrame;
          measFrame.SetIdentity();
          MeasurementFrameType measFrameTransp;
          measFrameTransp.SetIdentity();

          for (; itKey != imgMetaKeys.end(); itKey ++)
          {
            itk::ExposeMetaData<std::string> (imgMetaDictionary, *itKey, metaString);
            if (itKey->find("measurement frame") != std::string::npos)
            {
              sscanf(metaString.c_str(), " ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) \n", &xx, &xy, &xz, &yx, &yy, &yz, &zx, &zy, &zz);

              if (xx>10e-10 || xy>10e-10 || xz>10e-10 ||
                yx>10e-10 || yy>10e-10 || yz>10e-10 ||
                zx>10e-10 || zy>10e-10 || zz>10e-10 )
              {
                readFrame = true;

                measFrame(0,0) = xx;
                measFrame(0,1) = xy;
                measFrame(0,2) = xz;
                measFrame(1,0) = yx;
                measFrame(1,1) = yy;
                measFrame(1,2) = yz;
                measFrame(2,0) = zx;
                measFrame(2,1) = zy;
                measFrame(2,2) = zz;

                measFrameTransp = measFrame.GetTranspose();
              }
            }
          }

          if (numComponents==6)
          {
            while (!it.IsAtEnd())
            {
              // T'=RTR'
              VarPixType vec = it.Get();
              FixPixType fixVec(vec.GetDataPointer());

              if(readFrame)
              {
                TensorImage::PixelType tensor;
                tensor.SetElement(0, vec.GetElement(0));
                tensor.SetElement(1, vec.GetElement(1));
                tensor.SetElement(2, vec.GetElement(2));
                tensor.SetElement(3, vec.GetElement(3));
                tensor.SetElement(4, vec.GetElement(4));
                tensor.SetElement(5, vec.GetElement(5));

                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame));
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp));
                fixVec = tensor;
              }

              ot.Set(fixVec);
              ++ot;
              ++it;
            }
          }
          else if(numComponents==9)
          {
            while (!it.IsAtEnd())
            {
              VarPixType vec = it.Get();
              TensorImage::PixelType tensor;
              tensor.SetElement(0, vec.GetElement(0));
              tensor.SetElement(1, vec.GetElement(1));
              tensor.SetElement(2, vec.GetElement(2));
              tensor.SetElement(3, vec.GetElement(4));
              tensor.SetElement(4, vec.GetElement(5));
              tensor.SetElement(5, vec.GetElement(8));

              if(readFrame)
              {
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame));
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp));
              }

              FixPixType fixVec(tensor);
              ot.Set(fixVec);
              ++ot;
              ++it;
            }
          }
          else if (numComponents==1)
          {
            typedef itk::Image<float,4> ImageType;
            itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
            typedef itk::ImageFileReader<ImageType> FileReaderType;
            FileReaderType::Pointer reader = FileReaderType::New();
            reader->SetImageIO(io);
            reader->SetFileName(location);
            reader->Update();
            ImageType::Pointer img = reader->GetOutput();

            itk::Size<4> size = img->GetLargestPossibleRegion().GetSize();

            while (!ot.IsAtEnd())
            {
              TensorImage::PixelType tensor;
              ImageType::IndexType idx;
              idx[0] = ot.GetIndex()[0]; idx[1] = ot.GetIndex()[1]; idx[2] = ot.GetIndex()[2];

              if (size[3]==6)
              {
                for (unsigned int te=0; te<size[3]; te++)
                {
                  idx[3] = te;
                  tensor.SetElement(te, img->GetPixel(idx));
                }
              }
              else if (size[3]==9)
              {
                idx[3] = 0;
                tensor.SetElement(0, img->GetPixel(idx));
                idx[3] = 1;
                tensor.SetElement(1, img->GetPixel(idx));
                idx[3] = 2;
                tensor.SetElement(2, img->GetPixel(idx));
                idx[3] = 4;
                tensor.SetElement(3, img->GetPixel(idx));
                idx[3] = 5;
                tensor.SetElement(4, img->GetPixel(idx));
                idx[3] = 8;
                tensor.SetElement(5, img->GetPixel(idx));
              }
              else
                throw itk::ImageFileReaderException(__FILE__, __LINE__, "Unknown number of komponents for DTI file. Should be 6 or 9!");

              if(readFrame)
              {
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame));
                tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp));
              }
              FixPixType fixVec(tensor);
              ot.Set(fixVec);
              ++ot;
            }
          }
          else
          {
            throw itk::ImageFileReaderException(__FILE__, __LINE__, "Image has wrong number of pixel components!");
          }

          OutputType::Pointer resultImage = OutputType::New();
          resultImage->InitializeByItk( vecImg.GetPointer() );
          resultImage->SetVolume( vecImg->GetBufferPointer() );
          result.push_back( resultImage.GetPointer() );
        }

      }
      catch(std::exception& e)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what());
      }
      catch(...)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested DTI file!");
      }
    }

    return result;
  }
Beispiel #19
0
/**
 * Convert files from one ending to the other
 */
int main(int argc, char* argv[])
{
  mitkCommandLineParser parser;
  parser.setArgumentPrefix("--", "-");
  parser.addArgument("", "i", mitkCommandLineParser::String, "Input image", "input raw dwi", us::Any(), false, false, false, mitkCommandLineParser::Input);
  parser.addArgument("", "o", mitkCommandLineParser::String, "Output image", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output);
  parser.addArgument("b0_threshold", "", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0);
  parser.addArgument("correct_negative_eigenv", "", mitkCommandLineParser::Bool, "Correct negative eigenvalues", "correct negative eigenvalues", us::Any(false));

  parser.setCategory("Signal Modelling");
  parser.setTitle("Tensor Reconstruction");
  parser.setDescription("");
  parser.setContributor("MIC");

  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
  if (parsedArgs.size()==0)
    return EXIT_FAILURE;

  std::string inFileName = us::any_cast<std::string>(parsedArgs["i"]);
  std::string outfilename = us::any_cast<std::string>(parsedArgs["o"]);
  if (!itksys::SystemTools::GetFilenamePath(outfilename).empty())
    outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename);
  else
    outfilename = itksys::SystemTools::GetFilenameWithoutExtension(outfilename);
  outfilename += ".dti";

  int threshold = 0;
  if (parsedArgs.count("b0_threshold"))
    threshold = us::any_cast<int>(parsedArgs["b0_threshold"]);

  bool correct_negative_eigenv = false;
  if (parsedArgs.count("correct_negative_eigenv"))
    correct_negative_eigenv = us::any_cast<bool>(parsedArgs["correct_negative_eigenv"]);

  try
  {
    mitk::Image::Pointer dwi = mitk::IOUtil::Load<mitk::Image>(inFileName);

    mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New();
    mitk::CastToItkImage(dwi, itkVectorImagePointer);

    if (correct_negative_eigenv)
    {
      typedef itk::TensorReconstructionWithEigenvalueCorrectionFilter< short, float > TensorReconstructionImageFilterType;
      TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
      filter->SetBValue(mitk::DiffusionPropertyHelper::GetReferenceBValue(dwi));
      filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer);
      filter->SetB0Threshold(threshold);
      filter->Update();

      // Save tensor image
      itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
      io->SetFileType( itk::ImageIOBase::Binary );
      io->UseCompressionOn();

      mitk::LocaleSwitch localeSwitch("C");
      itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New();
      writer->SetInput(filter->GetOutput());
      writer->SetFileName(outfilename);
      writer->SetImageIO(io);
      writer->UseCompressionOn();
      writer->Update();
    }
    else {
      typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, float > TensorReconstructionImageFilterType;
      TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
      filter->SetGradientImage( mitk::DiffusionPropertyHelper::GetGradientContainer(dwi), itkVectorImagePointer );
      filter->SetBValue( mitk::DiffusionPropertyHelper::GetReferenceBValue( dwi ));
      filter->SetThreshold(threshold);
      filter->Update();

      // Save tensor image
      itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
      io->SetFileType( itk::ImageIOBase::Binary );
      io->UseCompressionOn();

      mitk::LocaleSwitch localeSwitch("C");
      itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New();
      writer->SetInput(filter->GetOutput());
      writer->SetFileName(outfilename);
      writer->SetImageIO(io);
      writer->UseCompressionOn();
      writer->Update();
    }

  }
  catch ( itk::ExceptionObject &err)
  {
    std::cout << "Exception: " << err;
  }
  catch ( std::exception err)
  {
    std::cout << "Exception: " << err.what();
  }
  catch ( ... )
  {
    std::cout << "Exception!";
  }
  return EXIT_SUCCESS;

}
  void ItkImageIO::Write()
  {
    const mitk::Image *image = dynamic_cast<const mitk::Image *>(this->GetInput());

    if (image == NULL)
    {
      mitkThrow() << "Cannot write non-image data";
    }

    // Switch the current locale to "C"
    LocaleSwitch localeSwitch("C");

    // Clone the image geometry, because we might have to change it
    // for writing purposes
    BaseGeometry::Pointer geometry = image->GetGeometry()->Clone();

    // Check if geometry information will be lost
    if (image->GetDimension() == 2 && !geometry->Is2DConvertable())
    {
      MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might "
                   "consider using Convert2Dto3DImageFilter before saving.";

      // set matrix to identity
      mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New();
      affTrans->SetIdentity();
      mitk::Vector3D spacing = geometry->GetSpacing();
      mitk::Point3D origin = geometry->GetOrigin();
      geometry->SetIndexToWorldTransform(affTrans);
      geometry->SetSpacing(spacing);
      geometry->SetOrigin(origin);
    }

    LocalFile localFile(this);
    const std::string path = localFile.GetFileName();

    MITK_INFO << "Writing image: " << path << std::endl;

    try
    {
      // Implementation of writer using itkImageIO directly. This skips the use
      // of templated itkImageFileWriter, which saves the multiplexing on MITK side.

      const unsigned int dimension = image->GetDimension();
      const unsigned int *const dimensions = image->GetDimensions();
      const mitk::PixelType pixelType = image->GetPixelType();
      const mitk::Vector3D mitkSpacing = geometry->GetSpacing();
      const mitk::Point3D mitkOrigin = geometry->GetOrigin();

      // Due to templating in itk, we are forced to save a 4D spacing and 4D Origin,
      // though they are not supported in MITK
      itk::Vector<double, 4u> spacing4D;
      spacing4D[0] = mitkSpacing[0];
      spacing4D[1] = mitkSpacing[1];
      spacing4D[2] = mitkSpacing[2];
      spacing4D[3] = 1; // There is no support for a 4D spacing. However, we should have a valid value here

      itk::Vector<double, 4u> origin4D;
      origin4D[0] = mitkOrigin[0];
      origin4D[1] = mitkOrigin[1];
      origin4D[2] = mitkOrigin[2];
      origin4D[3] = 0; // There is no support for a 4D origin. However, we should have a valid value here

      // Set the necessary information for imageIO
      m_ImageIO->SetNumberOfDimensions(dimension);
      m_ImageIO->SetPixelType(pixelType.GetPixelType());
      m_ImageIO->SetComponentType(pixelType.GetComponentType() < PixelComponentUserType ?
                                    static_cast<itk::ImageIOBase::IOComponentType>(pixelType.GetComponentType()) :
                                    itk::ImageIOBase::UNKNOWNCOMPONENTTYPE);
      m_ImageIO->SetNumberOfComponents(pixelType.GetNumberOfComponents());

      itk::ImageIORegion ioRegion(dimension);

      for (unsigned int i = 0; i < dimension; i++)
      {
        m_ImageIO->SetDimensions(i, dimensions[i]);
        m_ImageIO->SetSpacing(i, spacing4D[i]);
        m_ImageIO->SetOrigin(i, origin4D[i]);

        mitk::Vector3D mitkDirection;
        mitkDirection.SetVnlVector(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i));
        itk::Vector<double, 4u> direction4D;
        direction4D[0] = mitkDirection[0];
        direction4D[1] = mitkDirection[1];
        direction4D[2] = mitkDirection[2];

        // MITK only supports a 3x3 direction matrix. Due to templating in itk, however, we must
        // save a 4x4 matrix for 4D images. in this case, add an homogneous component to the matrix.
        if (i == 3)
        {
          direction4D[3] = 1; // homogenous component
        }
        else
        {
          direction4D[3] = 0;
        }
        vnl_vector<double> axisDirection(dimension);
        for (unsigned int j = 0; j < dimension; j++)
        {
          axisDirection[j] = direction4D[j] / spacing4D[i];
        }
        m_ImageIO->SetDirection(i, axisDirection);

        ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i));
        ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i));
      }

      // use compression if available
      m_ImageIO->UseCompressionOn();

      m_ImageIO->SetIORegion(ioRegion);
      m_ImageIO->SetFileName(path);

      // Handle time geometry
      const ArbitraryTimeGeometry *arbitraryTG = dynamic_cast<const ArbitraryTimeGeometry *>(image->GetTimeGeometry());
      if (arbitraryTG)
      {
        itk::EncapsulateMetaData<std::string>(m_ImageIO->GetMetaDataDictionary(),
                                              PROPERTY_KEY_TIMEGEOMETRY_TYPE,
                                              ArbitraryTimeGeometry::GetStaticNameOfClass());

        std::stringstream stream;
        stream << arbitraryTG->GetTimeBounds(0)[0];
        for (TimeStepType pos = 0; pos < arbitraryTG->CountTimeSteps(); ++pos)
        {
          stream << " " << arbitraryTG->GetTimeBounds(pos)[1];
        }
        std::string data = stream.str();

        itk::EncapsulateMetaData<std::string>(
          m_ImageIO->GetMetaDataDictionary(), PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS, data);
      }

      // Handle properties
      mitk::PropertyList::Pointer imagePropertyList = image->GetPropertyList();

      for (const auto &property : *imagePropertyList->GetMap())
      {
        IPropertyPersistence::InfoResultType infoList =
          mitk::CoreServices::GetPropertyPersistence()->GetInfo(property.first, GetMimeType()->GetName(), true);

        if (infoList.empty())
        {
          continue;
        }

        std::string value = infoList.front()->GetSerializationFunction()(property.second);

        if (value == mitk::BaseProperty::VALUE_CANNOT_BE_CONVERTED_TO_STRING)
        {
          continue;
        }

        std::string key = infoList.front()->GetKey();

        itk::EncapsulateMetaData<std::string>(m_ImageIO->GetMetaDataDictionary(), key, value);
      }

      ImageReadAccessor imageAccess(image);
      m_ImageIO->Write(imageAccess.GetData());
    }
    catch (const std::exception &e)
    {
      mitkThrow() << e.what();
    }
  }
Beispiel #21
0
mitk::PropertyList::Pointer mitk::CustomTagParser::ParseDicomPropertyString(std::string dicomPropertyString)
{
  auto results = mitk::PropertyList::New();
  if ("" == dicomPropertyString)
  {
    //MITK_ERROR << "Could not parse empty custom dicom string";
    return results;
  }

  std::map<std::string, std::string> privateParameters;

  // convert hex to ascii
  // the Siemens private tag contains the information like this
  // "43\52\23\34" we jump over each \ and convert the number
  int len = dicomPropertyString.length();
  std::string asciiString;
  for (int i = 0; i < len; i += 3)
  {
    std::string byte = dicomPropertyString.substr(i, 2);
    auto chr = (char)(int)strtol(byte.c_str(), nullptr, 16);
    asciiString.push_back(chr);
  }

  // extract parameter list
  std::size_t beginning = asciiString.find("### ASCCONV BEGIN ###") + 21;
  std::size_t ending = asciiString.find("### ASCCONV END ###");
  std::string parameterListString = asciiString.substr(beginning, ending - beginning);

  boost::replace_all(parameterListString, "\r\n", "\n");
  boost::char_separator<char> newlineSeparator("\n");
  boost::tokenizer<boost::char_separator<char>> parameters(parameterListString, newlineSeparator);
  for (const auto &parameter : parameters)
  {
    std::vector<std::string> parts;
    boost::split(parts, parameter, boost::is_any_of("="));

    if (parts.size() == 2)
    {
      parts[0].erase(std::remove(parts[0].begin(), parts[0].end(), ' '), parts[0].end());
      parts[1].erase(parts[1].begin(), parts[1].begin() + 1); // first character is a space
      privateParameters[parts[0]] = parts[1];
    }
  }

  std::string revisionString = "";

  try
  {
    revisionString = ExtractRevision(privateParameters["tSequenceFileName"]);
  }
  catch (const std::exception &e)
  {
    MITK_ERROR << "Cannot deduce revision information. Reason: "<< e.what();
    return results;
  }

  results->SetProperty(m_RevisionPropertyName, mitk::StringProperty::New(revisionString));

  std::string jsonString = GetRevisionAppropriateJSONString(revisionString);

  boost::property_tree::ptree root;
  std::istringstream jsonStream(jsonString);
  try
  {
    boost::property_tree::read_json(jsonStream, root);
  }
  catch (const boost::property_tree::json_parser_error &e)
  {
    mitkThrow() << "Could not parse json file. Error was:\n" << e.what();
  }

  for (auto it : root)
  {
    if (it.second.empty())
    {
      std::string propertyName = m_CESTPropertyPrefix + it.second.data();
      if (m_JSONRevisionPropertyName == propertyName)
      {
        results->SetProperty(propertyName, mitk::StringProperty::New(it.first));
      }
      else
      {
        results->SetProperty(propertyName, mitk::StringProperty::New(privateParameters[it.first]));
      }
    }
    else
    {
      MITK_ERROR << "Currently no support for nested dicom tag descriptors in json file.";
    }
  }

  std::string offset = "";
  std::string measurements = "";
  results->GetStringProperty("CEST.Offset", offset);
  results->GetStringProperty("CEST.measurements", measurements);

  if ("" == measurements)
  {
    std::string stringRepetitions = "";
    std::string stringAverages = "";
    results->GetStringProperty("CEST.repetitions", stringRepetitions);
    results->GetStringProperty("CEST.averages", stringAverages);
    std::stringstream  measurementStream;
    try
    {
      measurementStream << std::stoi(stringRepetitions) + std::stoi(stringAverages);
      measurements = measurementStream.str();
      MITK_INFO << "Could not find measurements, assuming repetitions + averages. Which is: " << measurements;
    }
    catch (const std::invalid_argument &ia)
    {
      MITK_ERROR
        << "Could not find measurements, fallback assumption of repetitions + averages could not be determined either: "
        << ia.what();
    }
  }

  std::string preparationType = "";
  std::string recoveryMode = "";
  std::string spoilingType = "";
  results->GetStringProperty(CEST_PROPERTY_NAME_PREPERATIONTYPE().c_str(), preparationType);
  results->GetStringProperty(CEST_PROPERTY_NAME_RECOVERYMODE().c_str(), recoveryMode);
  results->GetStringProperty(CEST_PROPERTY_NAME_SPOILINGTYPE().c_str(), spoilingType);

  if (this->IsT1Sequence(preparationType, recoveryMode, spoilingType, revisionString))
  {
    MITK_INFO << "Parsed as T1 image";

    mitk::LocaleSwitch localeSwitch("C");

    std::stringstream trecStream;

    std::string trecPath = m_DicomDataPath + "/TREC.txt";
    std::ifstream list(trecPath.c_str());

    if (list.good())
    {
      std::string currentTime;
      while (std::getline(list, currentTime))
      {
        trecStream << currentTime << " ";
      }
    }
    else
    {
      MITK_WARN << "Assumed T1, but could not load TREC at " << trecPath;
    }

    results->SetStringProperty(CEST_PROPERTY_NAME_TREC().c_str(), trecStream.str().c_str());
  }
  else
  {
    MITK_INFO << "Parsed as CEST or WASABI image";
    std::string sampling = "";
    bool hasSamplingInformation = results->GetStringProperty("CEST.SamplingType", sampling);
    if (hasSamplingInformation)
    {
      std::string offsets = GetOffsetString(sampling, offset, measurements);
      results->SetStringProperty(m_OffsetsPropertyName.c_str(), offsets.c_str());
    }
    else
    {
      MITK_WARN << "Could not determine sampling type.";
    }
  }


  //persist all properties
  mitk::IPropertyPersistence *persSrv = GetPersistenceService();
  if (persSrv)
  {
    auto propertyMap = results->GetMap();
    for (auto const &prop : *propertyMap)
    {
      PropertyPersistenceInfo::Pointer info = PropertyPersistenceInfo::New();
      std::string key = prop.first;
      std::replace(key.begin(), key.end(), '.', '_');
      info->SetNameAndKey(prop.first, key);

      persSrv->AddInfo(info);
    }
  }

  return results;
}