Ejemplo n.º 1
0
void mitk::AutoCropImageFilter::GenerateOutputInformation()
{
  mitk::Image::Pointer input = const_cast<mitk::Image*> (this->GetInput());
  mitk::Image::Pointer output = this->GetOutput();

  if(input->GetDimension() <= 2)
  {
    MITK_ERROR << "Only 3D any 4D images are supported." << std::endl;
    return;
  }

  ComputeNewImageBounds();

  if ((output->IsInitialized()) && (output->GetPipelineMTime() <= m_TimeOfHeaderInitialization.GetMTime()))
    return;

  itkDebugMacro(<<"GenerateOutputInformation()");

  // PART I: initialize input requested region. We do this already here (and not
  // later when GenerateInputRequestedRegion() is called), because we
  // also need the information to setup the output.

  // pre-initialize input-requested-region to largest-possible-region
  // and correct time-region; spatial part will be cropped by
  // bounding-box of bounding-object below
  m_InputRequestedRegion = input->GetLargestPossibleRegion();

  // build region out of index and size calculated in ComputeNewImageBounds()

  mitk::SlicedData::IndexType index;
  index[0] = m_RegionIndex[0];
  index[1] = m_RegionIndex[1];
  index[2] = m_RegionIndex[2];
  index[3] = m_InputRequestedRegion.GetIndex()[3];
  index[4] = m_InputRequestedRegion.GetIndex()[4];

  mitk::SlicedData::SizeType  size;
  size[0] = m_RegionSize[0];
  size[1] = m_RegionSize[1];
  size[2] = m_RegionSize[2];
  size[3] = m_InputRequestedRegion.GetSize()[3];
  size[4] = m_InputRequestedRegion.GetSize()[4];

  mitk::SlicedData::RegionType cropRegion(index, size);

  // crop input-requested-region with cropping region computed from the image data
  if(m_InputRequestedRegion.Crop(cropRegion)==false)
  {
    // crop not possible => do nothing: set time size to 0.
    size.Fill(0);
    m_InputRequestedRegion.SetSize(size);
    return;
  }

  // set input-requested-region, because we access it later in
  // GenerateInputRequestedRegion (there we just set the time)
  input->SetRequestedRegion(&m_InputRequestedRegion);


  // PART II: initialize output image
  unsigned int dimension = input->GetDimension();
  unsigned int *dimensions = new unsigned int [dimension];
  itk2vtk(m_InputRequestedRegion.GetSize(), dimensions);
  if(dimension>3)
    memcpy(dimensions+3, input->GetDimensions()+3, (dimension-3)*sizeof(unsigned int));

  // create basic slicedGeometry that will be initialized below
  output->Initialize(mitk::PixelType( GetOutputPixelType() ), dimension, dimensions);
  delete [] dimensions;

  //clone the IndexToWorldTransform from the input, otherwise we will overwrite it, when adjusting the origin of the output image!!
  itk::ScalableAffineTransform< mitk::ScalarType,3 >::Pointer cloneTransform = itk::ScalableAffineTransform< mitk::ScalarType,3 >::New();
  cloneTransform->Compose(input->GetGeometry()->GetIndexToWorldTransform());
  output->GetGeometry()->SetIndexToWorldTransform( cloneTransform.GetPointer() );

  // Position the output Image to match the corresponding region of the input image
  mitk::SlicedGeometry3D* slicedGeometry = output->GetSlicedGeometry();
  mitk::SlicedGeometry3D::Pointer inputGeometry = input->GetSlicedGeometry();
  const mitk::SlicedData::IndexType& start = m_InputRequestedRegion.GetIndex();
  mitk::Point3D origin; vtk2itk(start, origin);
  input->GetSlicedGeometry()->IndexToWorld(origin, origin);
  slicedGeometry->SetOrigin(origin);

  // get the PlaneGeometry for the first slice of the original image
  mitk::PlaneGeometry::Pointer plane = dynamic_cast<mitk::PlaneGeometry*>( inputGeometry->GetGeometry2D( 0 )->Clone().GetPointer() );
  assert( plane );

  // re-initialize the plane according to the new requirements:
  // dimensions of the cropped image
  // right- and down-vector as well as spacing do not change, so use the ones from
  // input image
  ScalarType dimX = output->GetDimensions()[0];
  ScalarType dimY = output->GetDimensions()[1];
  mitk::Vector3D right = plane->GetAxisVector(0);
  mitk::Vector3D down = plane->GetAxisVector(1);
  mitk::Vector3D spacing = plane->GetSpacing();
  plane->InitializeStandardPlane( dimX, dimY, right, down, &spacing );
  // set the new origin on the PlaneGeometry as well
  plane->SetOrigin(origin);

  // re-initialize the slicedGeometry with the correct planeGeometry
  // in order to get a fully initialized SlicedGeometry3D
  slicedGeometry->InitializeEvenlySpaced( plane, inputGeometry->GetSpacing()[2], output->GetSlicedGeometry()->GetSlices() );


  mitk::TimeGeometry* timeSlicedGeometry = output->GetTimeGeometry();
  mitk::ProportionalTimeGeometry* propTimeGeometry = dynamic_cast<ProportionalTimeGeometry*>(timeSlicedGeometry);
  propTimeGeometry->Initialize(slicedGeometry, output->GetDimension(3));

  m_TimeOfHeaderInitialization.Modified();

  output->SetPropertyList(input->GetPropertyList()->Clone());
}
Ejemplo n.º 2
0
void BoundingObjectCutter::GenerateOutputInformation()
{
    mitk::Image::Pointer output = this->GetOutput();
    if ((output->IsInitialized()) && (output->GetPipelineMTime() <= m_TimeOfHeaderInitialization.GetMTime()))
        return;

    mitk::Image::Pointer input = const_cast< mitk::Image * > ( this->GetInput() );

    if(input.IsNull())
    {
        MITK_WARN << "Input is not a mitk::Image";
        return;
    }
    itkDebugMacro(<<"GenerateOutputInformation()");
    unsigned int dimension = input->GetDimension();

    if (dimension < 3)
    {
        MITK_WARN << "ImageCropper cannot handle 1D or 2D Objects. Operation aborted.";
        return;
    }

    if((m_BoundingObject.IsNull()) || (m_BoundingObject->GetTimeGeometry()->CountTimeSteps() == 0))
        return;

    mitk::BaseGeometry* boGeometry =  m_BoundingObject->GetGeometry();
    mitk::BaseGeometry* inputImageGeometry = input->GetSlicedGeometry();
    // calculate bounding box of bounding-object relative to the geometry
    // of the input image. The result is in pixel coordinates of the input
    // image (because the m_IndexToWorldTransform includes the spacing).
    mitk::BoundingBox::Pointer boBoxRelativeToImage = boGeometry->CalculateBoundingBoxRelativeToTransform( inputImageGeometry->GetIndexToWorldTransform() );

    // PART I: initialize input requested region. We do this already here (and not
    // later when GenerateInputRequestedRegion() is called), because we
    // also need the information to setup the output.

    // pre-initialize input-requested-region to largest-possible-region
    // and correct time-region; spatial part will be cropped by
    // bounding-box of bounding-object below
    m_InputRequestedRegion = input->GetLargestPossibleRegion();

    // build region out of bounding-box of bounding-object
    mitk::SlicedData::IndexType  index=m_InputRequestedRegion.GetIndex(); //init times and channels
    mitk::BoundingBox::PointType min = boBoxRelativeToImage->GetMinimum();
    index[0] = (mitk::SlicedData::IndexType::IndexValueType)(std::ceil(min[0]));
    index[1] = (mitk::SlicedData::IndexType::IndexValueType)(std::ceil(min[1]));
    index[2] = (mitk::SlicedData::IndexType::IndexValueType)(std::ceil(min[2]));

    mitk::SlicedData::SizeType   size = m_InputRequestedRegion.GetSize(); //init times and channels
    mitk::BoundingBox::PointType max = boBoxRelativeToImage->GetMaximum();
    size[0] = (mitk::SlicedData::SizeType::SizeValueType)(std::ceil(max[0])-index[0]);
    size[1] = (mitk::SlicedData::SizeType::SizeValueType)(std::ceil(max[1])-index[1]);
    size[2] = (mitk::SlicedData::SizeType::SizeValueType)(std::ceil(max[2])-index[2]);

    mitk::SlicedData::RegionType boRegion(index, size);

    if(m_UseWholeInputRegion == false)
    {
        // crop input-requested-region with region of bounding-object
        if(m_InputRequestedRegion.Crop(boRegion)==false)
        {
            // crop not possible => do nothing: set time size to 0.
            size.Fill(0);
            m_InputRequestedRegion.SetSize(size);
            boRegion.SetSize(size);
            m_BoundingObject->SetRequestedRegion(&boRegion);
            return;
        }
    }

    // set input-requested-region, because we access it later in
    // GenerateInputRequestedRegion (there we just set the time)
    input->SetRequestedRegion(&m_InputRequestedRegion);

    // PART II: initialize output image

    unsigned int *dimensions = new unsigned int [dimension];
    itk2vtk(m_InputRequestedRegion.GetSize(), dimensions);
    if(dimension>3)
        memcpy(dimensions+3, input->GetDimensions()+3, (dimension-3)*sizeof(unsigned int));
    output->Initialize(mitk::PixelType(GetOutputPixelType()), dimension, dimensions);
    delete [] dimensions;

    // now we have everything to initialize the transform of the output
    mitk::SlicedGeometry3D* slicedGeometry = output->GetSlicedGeometry();

    // set the transform: use the transform of the input;
    // the origin will be replaced afterwards
    AffineTransform3D::Pointer indexToWorldTransform = AffineTransform3D::New();
    indexToWorldTransform->SetParameters(input->GetSlicedGeometry()->GetIndexToWorldTransform()->GetParameters());
    slicedGeometry->SetIndexToWorldTransform(indexToWorldTransform);

    // Position the output Image to match the corresponding region of the input image
    const mitk::SlicedData::IndexType& start = m_InputRequestedRegion.GetIndex();
    mitk::Point3D origin;
    vtk2itk(start, origin);
    inputImageGeometry->IndexToWorld(origin, origin);
    slicedGeometry->SetOrigin(origin);

    m_TimeOfHeaderInitialization.Modified();
}