Beispiel #1
0
void WorkbenchUtils::resampleImageItk(itk::Image <PixelType, ImageDimension> *itkImage, Interpolator interpolType,
                                      unsigned int *newDimensions, Image::Pointer outImage) {
    typedef itk::Image <PixelType, ImageDimension> ImageType;

    // get original image informations
    const typename ImageType::RegionType &inputRegion = itkImage->GetLargestPossibleRegion();
    const typename ImageType::SizeType &inputDimensions = inputRegion.GetSize();
    const typename ImageType::SpacingType &inputSpacing = itkImage->GetSpacing();

    // calculate spacing
    double outputSpacing[ImageDimension];
    itk::Size <ImageDimension> outputSize;
    for (unsigned int i = 0; i < ImageDimension; ++i) {
        outputSpacing[i] = inputSpacing[i] * (double) inputDimensions[i] / newDimensions[i];
        outputSize[i] = newDimensions[i];
    }

    // transform
    typedef itk::IdentityTransform<double, ImageDimension> TransformType;
    typename TransformType::Pointer transform = TransformType::New();
    transform->SetIdentity();

    // interpolator typedefs
    typedef double CoordinateType;
    typedef itk::LinearInterpolateImageFunction <ImageType, CoordinateType> LinearInterpolatorType;
    typedef itk::NearestNeighborInterpolateImageFunction <ImageType, CoordinateType> NearestNeighborInterpolatorType;
    typedef itk::GaussianInterpolateImageFunction <ImageType, CoordinateType> GaussianInterpolatorType;
    typedef itk::BSplineInterpolateImageFunction <ImageType, CoordinateType> BSplineInterpolatorType;

    // set up the filter
    typedef itk::ResampleImageFilter <ImageType, ImageType> ResampleFilterType;
    typename ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New();
    resampleFilter->SetTransform(transform);
    resampleFilter->SetOutputOrigin(itkImage->GetOrigin());
    resampleFilter->SetOutputSpacing(outputSpacing);
    resampleFilter->SetSize(outputSize);
    switch (interpolType) {
        case Interpolator::LINEAR: // the default;
            resampleFilter->SetInterpolator(LinearInterpolatorType::New());
            break;
        case Interpolator::NEAREST_NEIGHBOR:
            resampleFilter->SetInterpolator(NearestNeighborInterpolatorType::New());
            break;
        case Interpolator::GAUSSIAN:
            resampleFilter->SetInterpolator(GaussianInterpolatorType::New());
            break;
        case Interpolator::BSPLINE:
            resampleFilter->SetInterpolator(BSplineInterpolatorType::New());
            break;
    }
    resampleFilter->SetInput(itkImage);
    resampleFilter->UpdateLargestPossibleRegion();

    // get the results and cast them back to mitk. return via out parameter.
    outImage->InitializeByItk(resampleFilter->GetOutput());
    CastToMitkImage(resampleFilter->GetOutput(), outImage);
}
Beispiel #2
0
void WorkbenchUtils::addPaddingItk(itk::Image <PixelType, ImageDimension> *itkImage, Axis axis, bool append,
                                   int numberOfSlices, float pixelValue, Image::Pointer outImage) {
    // pixel type is templated. The input field for the value is set to float, so the user might enter some invalid values for the image type at hand.
    // since all primitive built-in types have well defined casting behaviour between each other, we'll just do a typecast. we will clip the entered
    // value at PixelTypes min/max to prevent an overflow. The possible loss of precision is ignored.
    float lower = itk::NumericTraits<PixelType>::min();
    float upper = itk::NumericTraits<PixelType>::max();
    float clippedPixelValue = std::max(lower, std::min(pixelValue, upper));

    PixelType paddingPixelValue = (PixelType) clippedPixelValue;

    typedef itk::Image <PixelType, ImageDimension> ImageType;

    // gather all data
    typename ImageType::SizeType lowerBound;
    typename ImageType::SizeType upperBound;
    lowerBound.Fill(0);
    upperBound.Fill(0);

    unsigned int itkAxis = convertToItkAxis(axis);
    if (append) {
        upperBound[itkAxis] = numberOfSlices;
    } else {
        lowerBound[itkAxis] = numberOfSlices;
    }

    // setup the filter
    typedef itk::ConstantPadImageFilter <ImageType, ImageType> PadFilterType;
    typename PadFilterType::Pointer padFilter = PadFilterType::New();
    padFilter->SetInput(itkImage);
    padFilter->SetConstant(paddingPixelValue);
    padFilter->SetPadLowerBound(lowerBound);
    padFilter->SetPadUpperBound(upperBound);
    padFilter->UpdateLargestPossibleRegion();

    // Update the origin, since padding creates negative index that is lost when returned to MITK
    typename ImageType::Pointer paddedImage = padFilter->GetOutput();
    typename ImageType::RegionType paddedImageRegion = paddedImage->GetLargestPossibleRegion();
    typename ImageType::PointType origin;
    paddedImage->TransformIndexToPhysicalPoint(paddedImageRegion.GetIndex(), origin);
    paddedImage->SetOrigin(origin);

    // get the results and cast them back to mitk. return via out parameter.
    outImage->InitializeByItk(paddedImage.GetPointer());
    CastToMitkImage(paddedImage, outImage);
}