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); }
void mitk::ImageToContourFilter::Itk2DContourExtraction(const itk::Image<TPixel, VImageDimension> *sliceImage) { typedef itk::Image<TPixel, VImageDimension> ImageType; typedef itk::ContourExtractor2DImageFilter<ImageType> ContourExtractor; typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadFilterType; typename PadFilterType::Pointer padFilter = PadFilterType::New(); typename ImageType::SizeType lowerExtendRegion; lowerExtendRegion[0] = 1; lowerExtendRegion[1] = 1; typename ImageType::SizeType upperExtendRegion; upperExtendRegion[0] = 1; upperExtendRegion[1] = 1; /* * We need to pad here, since the ITK contour extractor fails if the * segmentation touches more than one image edge. * By padding the image for one row at each edge we overcome this issue */ padFilter->SetInput(sliceImage); padFilter->SetConstant(0); padFilter->SetPadLowerBound(lowerExtendRegion); padFilter->SetPadUpperBound(upperExtendRegion); typename ContourExtractor::Pointer contourExtractor = ContourExtractor::New(); contourExtractor->SetInput(padFilter->GetOutput()); contourExtractor->SetContourValue(0.5); contourExtractor->Update(); unsigned int foundPaths = contourExtractor->GetNumberOfOutputs(); vtkSmartPointer<vtkPolyData> contourSurface = vtkSmartPointer<vtkPolyData>::New(); vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New(); unsigned int pointId(0); for (unsigned int i = 0; i < foundPaths; i++) { const ContourPath *currentPath = contourExtractor->GetOutput(i)->GetVertexList(); vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New(); polygon->GetPointIds()->SetNumberOfIds(currentPath->Size()); Point3D currentPoint; Point3D currentWorldPoint; for (unsigned int j = 0; j < currentPath->Size(); j++) { currentPoint[0] = currentPath->ElementAt(j)[0]; currentPoint[1] = currentPath->ElementAt(j)[1]; currentPoint[2] = 0; m_SliceGeometry->IndexToWorld(currentPoint, currentWorldPoint); points->InsertPoint(pointId, currentWorldPoint[0], currentWorldPoint[1], currentWorldPoint[2]); polygon->GetPointIds()->SetId(j, pointId); pointId++; } // for2 polygons->InsertNextCell(polygon); } // for1 contourSurface->SetPoints(points); contourSurface->SetPolys(polygons); contourSurface->BuildLinks(); Surface::Pointer finalSurface = this->GetOutput(); finalSurface->SetVtkPolyData(contourSurface); }
void mitk::ImageToContourModelFilter::Itk2DContourExtraction (const itk::Image<TPixel, VImageDimension>* sliceImage) { typedef itk::Image<TPixel, VImageDimension> ImageType; typedef itk::ContourExtractor2DImageFilter<ImageType> ContourExtractor; typedef itk::PolyLineParametricPath<2> PolyLineParametricPath2D; typedef PolyLineParametricPath2D::VertexListType ContourPath; typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadFilterType; typename PadFilterType::Pointer padFilter = PadFilterType::New(); typename ImageType::SizeType lowerExtendRegion; lowerExtendRegion[0] = 1; lowerExtendRegion[1] = 1; typename ImageType::SizeType upperExtendRegion; upperExtendRegion[0] = 1; upperExtendRegion[1] = 1; /* * We need to pad here, since the ITK contour extractor fails if the * segmentation touches more than one image edge. * By padding the image for one row at each edge we overcome this issue */ padFilter->SetInput(sliceImage); padFilter->SetConstant(0); padFilter->SetPadLowerBound(lowerExtendRegion); padFilter->SetPadUpperBound(upperExtendRegion); typename ContourExtractor::Pointer contourExtractor = ContourExtractor::New(); contourExtractor->SetInput(padFilter->GetOutput()); contourExtractor->SetContourValue(m_ContourValue); contourExtractor->Update(); unsigned int foundPaths = contourExtractor->GetNumberOfOutputs(); this->SetNumberOfIndexedOutputs(foundPaths); for (unsigned int i = 0; i < foundPaths; i++) { const ContourPath* currentPath = contourExtractor->GetOutput(i)->GetVertexList(); mitk::Point3D currentPoint; mitk::Point3D currentWorldPoint; mitk::ContourModel::Pointer contour = this->GetOutput(i); if (contour.IsNull()) { contour = mitk::ContourModel::New(); } if (contour.IsNull()) contour = mitk::ContourModel::New(); for (unsigned int j = 0; j < currentPath->Size(); j++) { currentPoint[0] = currentPath->ElementAt(j)[0]; currentPoint[1] = currentPath->ElementAt(j)[1]; currentPoint[2] = 0; m_SliceGeometry->IndexToWorld(currentPoint, currentWorldPoint); contour->AddVertex(currentWorldPoint); }//for2 contour->Close(); }//for1 }