void mitk::ExtractDirectedPlaneImageFilterNew::ItkSliceExtraction(const itk::Image<TPixel, VImageDimension> *inputImage) { typedef itk::Image<TPixel, VImageDimension> InputImageType; typedef itk::Image<TPixel, VImageDimension - 1> SliceImageType; typedef itk::ImageRegionConstIterator<SliceImageType> SliceIterator; // Creating an itk::Image that represents the sampled slice typename SliceImageType::Pointer resultSlice = SliceImageType::New(); typename SliceImageType::IndexType start; start[0] = 0; start[1] = 0; Point3D origin = m_CurrentWorldPlaneGeometry->GetOrigin(); Vector3D right = m_CurrentWorldPlaneGeometry->GetAxisVector(0); Vector3D bottom = m_CurrentWorldPlaneGeometry->GetAxisVector(1); // Calculation the sample-spacing, i.e the half of the smallest spacing existing in the original image Vector3D newPixelSpacing = m_ImageGeometry->GetSpacing(); float minSpacing = newPixelSpacing[0]; for (unsigned int i = 1; i < newPixelSpacing.Size(); i++) { if (newPixelSpacing[i] < minSpacing) { minSpacing = newPixelSpacing[i]; } } newPixelSpacing[0] = 0.5 * minSpacing; newPixelSpacing[1] = 0.5 * minSpacing; newPixelSpacing[2] = 0.5 * minSpacing; float pixelSpacing[2]; pixelSpacing[0] = newPixelSpacing[0]; pixelSpacing[1] = newPixelSpacing[1]; // Calculating the size of the sampled slice typename SliceImageType::SizeType size; Vector2D extentInMM; extentInMM[0] = m_CurrentWorldPlaneGeometry->GetExtentInMM(0); extentInMM[1] = m_CurrentWorldPlaneGeometry->GetExtentInMM(1); // The maximum extent is the lenght of the diagonal of the considered plane double maxExtent = sqrt(extentInMM[0] * extentInMM[0] + extentInMM[1] * extentInMM[1]); unsigned int xTranlation = (maxExtent - extentInMM[0]); unsigned int yTranlation = (maxExtent - extentInMM[1]); size[0] = (maxExtent + xTranlation) / newPixelSpacing[0]; size[1] = (maxExtent + yTranlation) / newPixelSpacing[1]; // Creating an ImageRegion Object typename SliceImageType::RegionType region; region.SetSize(size); region.SetIndex(start); // Defining the image`s extent and origin by passing the region to it and allocating memory for it resultSlice->SetRegions(region); resultSlice->SetSpacing(pixelSpacing); resultSlice->Allocate(); /* * Here we create an new geometry so that the transformations are calculated correctly (our resulting slice has a * different bounding box and spacing) * The original current worldgeometry must be cloned because we have to keep the directions of the axis vector which * represents the rotation */ right.Normalize(); bottom.Normalize(); // Here we translate the origin to adapt the new geometry to the previous calculated extent origin[0] -= xTranlation * right[0] + yTranlation * bottom[0]; origin[1] -= xTranlation * right[1] + yTranlation * bottom[1]; origin[2] -= xTranlation * right[2] + yTranlation * bottom[2]; // Putting it together for the new geometry mitk::BaseGeometry::Pointer newSliceGeometryTest = dynamic_cast<BaseGeometry *>(m_CurrentWorldPlaneGeometry->Clone().GetPointer()); newSliceGeometryTest->ChangeImageGeometryConsideringOriginOffset(true); // Workaround because of BUG (#6505) newSliceGeometryTest->GetIndexToWorldTransform()->SetMatrix( m_CurrentWorldPlaneGeometry->GetIndexToWorldTransform()->GetMatrix()); // Workaround end newSliceGeometryTest->SetOrigin(origin); ScalarType bounds[6] = {0, static_cast<ScalarType>(size[0]), 0, static_cast<ScalarType>(size[1]), 0, 1}; newSliceGeometryTest->SetBounds(bounds); newSliceGeometryTest->SetSpacing(newPixelSpacing); newSliceGeometryTest->Modified(); // Workaround because of BUG (#6505) itk::MatrixOffsetTransformBase<mitk::ScalarType, 3, 3>::MatrixType tempTransform = newSliceGeometryTest->GetIndexToWorldTransform()->GetMatrix(); // Workaround end /* * Now we iterate over the recently created slice. * For each slice - pixel we check whether there is an according * pixel in the input - image which can be set in the slice. * In this way a slice is sampled out of the input - image regrading to the given PlaneGeometry */ Point3D currentSliceIndexPointIn2D; Point3D currentImageWorldPointIn3D; typename InputImageType::IndexType inputIndex; SliceIterator sliceIterator(resultSlice, resultSlice->GetLargestPossibleRegion()); sliceIterator.GoToBegin(); while (!sliceIterator.IsAtEnd()) { /* * Here we add 0.5 to to assure that the indices are correctly transformed. * (Because of the 0.5er Bug) */ currentSliceIndexPointIn2D[0] = sliceIterator.GetIndex()[0] + 0.5; currentSliceIndexPointIn2D[1] = sliceIterator.GetIndex()[1] + 0.5; currentSliceIndexPointIn2D[2] = 0; newSliceGeometryTest->IndexToWorld(currentSliceIndexPointIn2D, currentImageWorldPointIn3D); m_ImageGeometry->WorldToIndex(currentImageWorldPointIn3D, inputIndex); if (m_ImageGeometry->IsIndexInside(inputIndex)) { resultSlice->SetPixel(sliceIterator.GetIndex(), inputImage->GetPixel(inputIndex)); } else { resultSlice->SetPixel(sliceIterator.GetIndex(), 0); } ++sliceIterator; } Image::Pointer resultImage = ImageToImageFilter::GetOutput(); GrabItkImageMemory(resultSlice, resultImage, nullptr, false); resultImage->SetClonedGeometry(newSliceGeometryTest); // Workaround because of BUG (#6505) resultImage->GetGeometry()->GetIndexToWorldTransform()->SetMatrix(tempTransform); // Workaround end }