22 #include "itkCastImageFilter.h" 23 #include "itkImageDuplicator.h" 24 #include "itkImageRegionIterator.h" 34 template <
typename TPixel,
unsigned int VDimensions>
36 itk::Image<TPixel, VDimensions> *,
38 itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer segmentationPixelTypeImage)
40 typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>
InputImageType;
42 typedef itk::CastImageFilter<InputImageType, OutputImageType> CastImageFilterType;
44 typename CastImageFilterType::Pointer castImageFilter = CastImageFilterType::New();
45 castImageFilter->SetInput(segmentationPixelTypeImage);
46 castImageFilter->Update();
48 tempItkImage->DisconnectPipeline();
56 if (inputImage.IsNull() || inputImage->GetDimension() != 2)
58 itkExceptionMacro(
"CorrectorAlgorithm needs a 2D image as input.");
63 itkExceptionMacro(
"CorrectorAlgorithm needs a Contour object as input.");
71 if (inputImage->GetTimeGeometry())
73 originalGeometry = inputImage->GetTimeGeometry()->Clone();
78 itkExceptionMacro(
"Original image does not have a 'Time sliced geometry'! Cannot copy.");
85 itk::Image<DefaultSegmentationDataType, 2>::Pointer correctPixelTypeImage;
87 assert(correctPixelTypeImage.IsNotNull());
95 itk::Image<DefaultSegmentationDataType, 2>::DirectionType imageDirection;
97 imageDirection.SetIdentity();
108 if (inputImage->GetChannelDescriptor().GetPixelType().GetComponentType() == itk::ImageIOBase::USHORT)
117 temporarySlice->SetTimeGeometry(originalGeometry);
120 template <
typename ScalarType>
125 itk::Size<5> size =
m_WorkingImage->GetLargestPossibleRegion().GetSize();
134 itk::Image<DefaultSegmentationDataType, 2>::Pointer pic)
165 if (projectedContour.IsNull() || projectedContour->GetNumberOfVertices() < 2)
169 auto contourIter = projectedContour->Begin();
170 if (contourIter == projectedContour->End())
174 previousIndex = ensureIndexInImage((*contourIter)->Coordinates[0], (*contourIter)->Coordinates[1]);
177 int currentColor = (pic->GetPixel(previousIndex) ==
m_FillColor);
179 int countOfSegments = 1;
181 bool firstSegment =
true;
182 auto contourEnd = projectedContour->End();
183 for (; contourIter != contourEnd; ++contourIter)
187 currentIndex = ensureIndexInImage((*contourIter)->Coordinates[0] + 0.5, (*contourIter)->Coordinates[1] + 0.5);
190 double slopeX = currentIndex[0] - previousIndex[0];
191 double slopeY = currentIndex[1] - previousIndex[1];
192 double length = std::sqrt(slopeX * slopeX + slopeY * slopeY);
193 double deltaX = slopeX / length;
194 double deltaY = slopeY / length;
196 for (
double i = 0; i <= length && length > 0; i += 1)
199 temporaryIndex = ensureIndexInImage(previousIndex[0] + deltaX * i, previousIndex[1] + deltaY * i);
201 if (!pic->GetLargestPossibleRegion().IsInside(temporaryIndex))
203 if ((pic->GetPixel(temporaryIndex) ==
m_FillColor) != currentColor)
205 currentSegment.
points.push_back(temporaryIndex);
212 firstSegment =
false;
216 currentColor = (pic->GetPixel(temporaryIndex) ==
m_FillColor);
218 currentSegment.
points.push_back(temporaryIndex);
220 previousIndex = currentIndex;
226 void mitk::CorrectorAlgorithm::ColorSegment(
228 itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic)
237 std::vector<itk::Index<2>>::const_iterator indexIterator;
238 std::vector<itk::Index<2>>::const_iterator indexEnd;
240 indexIterator = segment.
points.begin();
241 indexEnd = segment.
points.end();
243 for (; indexIterator != indexEnd; ++indexIterator)
245 pic->SetPixel(*indexIterator, color);
249 itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer mitk::CorrectorAlgorithm::CloneImage(
250 itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic)
252 typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2> ItkImageType;
253 typedef itk::ImageDuplicator<ItkImageType> DuplicatorType;
254 DuplicatorType::Pointer duplicator = DuplicatorType::New();
255 duplicator->SetInputImage(pic);
256 duplicator->Update();
258 return duplicator->GetOutput();
263 itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic)
267 std::vector<itk::Index<2>>::const_iterator indexIterator;
268 std::vector<itk::Index<2>>::const_iterator indexEnd;
270 indexIterator = segment.
points.begin();
271 indexEnd = segment.
points.end();
275 for (; indexIterator != indexEnd; ++indexIterator)
277 for (
int xOffset = -1; xOffset < 2; ++xOffset)
281 index = ensureIndexInImage((*indexIterator)[0] - xOffset, (*indexIterator)[1] -
yOffset);
283 if ((pic->GetPixel(index) ==
m_FillColor) != colorMode)
290 mitkThrow() <<
"No Starting point is found next to the curve.";
293 std::vector<itk::Index<2>> mitk::CorrectorAlgorithm::FindSeedPoints(
295 itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic)
297 typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer ItkImagePointerType;
299 std::vector<itk::Index<2>> seedPoints;
304 seedPoints.push_back(firstPoint);
311 if (segment.
points.size() < 4)
314 std::vector<itk::Index<2>>::const_iterator indexIterator;
315 std::vector<itk::Index<2>>::const_iterator indexEnd;
317 indexIterator = segment.
points.begin();
318 indexEnd = segment.
points.end();
320 ItkImagePointerType listOfPoints = CloneImage(pic);
321 listOfPoints->FillBuffer(0);
322 listOfPoints->SetPixel(seedPoints[0], 1);
323 for (; indexIterator != indexEnd; ++indexIterator)
325 listOfPoints->SetPixel(*indexIterator, 2);
327 indexIterator = segment.
points.begin();
332 for (; indexIterator != indexEnd; ++indexIterator)
334 bool pointFound =
true;
340 for (
int xOffset = -1; xOffset < 2; ++xOffset)
344 index = ensureIndexInImage((*indexIterator)[0] - xOffset, (*indexIterator)[1] -
yOffset);
347 if (listOfPoints->GetPixel(index2) > 0)
350 index[0] = index[0] - 1;
351 index = ensureIndexInImage(index[0], index[1]);
352 if (listOfPoints->GetPixel(index) == 1)
355 seedPoints.push_back(index2);
356 listOfPoints->SetPixel(index2, 1);
360 index[0] = index[0] + 2;
361 index = ensureIndexInImage(index[0], index[1]);
362 if (listOfPoints->GetPixel(index) == 1)
365 seedPoints.push_back(index2);
366 listOfPoints->SetPixel(index2, 1);
370 index[0] = index[0] - 1;
371 index[1] = index[1] - 1;
372 index = ensureIndexInImage(index[0], index[1]);
373 if (listOfPoints->GetPixel(index) == 1)
376 seedPoints.push_back(index2);
377 listOfPoints->SetPixel(index2, 1);
381 index[1] = index[1] + 2;
382 index = ensureIndexInImage(index[0], index[1]);
383 if (listOfPoints->GetPixel(index) == 1)
386 seedPoints.push_back(index2);
387 listOfPoints->SetPixel(index2, 1);
397 int mitk::CorrectorAlgorithm::FillRegion(
399 itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer pic)
401 int numberOfPixel = 0;
402 int mode = (pic->GetPixel(seedPoints[0]) ==
m_FillColor);
409 std::vector<itk::Index<2>> workPoints;
410 workPoints = seedPoints;
412 while (workPoints.size() > 0)
415 workPoints.pop_back();
416 if ((pic->GetPixel(currentIndex) ==
m_FillColor) == mode)
418 pic->SetPixel(currentIndex, drawColor);
420 currentIndex = ensureIndexInImage(currentIndex[0] - 1, currentIndex[1]);
421 if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) ==
m_FillColor) == mode)
422 workPoints.push_back(currentIndex);
424 currentIndex = ensureIndexInImage(currentIndex[0] + 2, currentIndex[1]);
425 if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) ==
m_FillColor) == mode)
426 workPoints.push_back(currentIndex);
428 currentIndex = ensureIndexInImage(currentIndex[0] - 1, currentIndex[1] - 1);
430 if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) ==
m_FillColor) == mode)
431 workPoints.push_back(currentIndex);
433 currentIndex = ensureIndexInImage(currentIndex[0], currentIndex[1] + 2);
434 if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) ==
m_FillColor) == mode)
435 workPoints.push_back(currentIndex);
438 return numberOfPixel;
441 void mitk::CorrectorAlgorithm::OverwriteImage(
442 itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer source,
443 itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>::Pointer target)
445 typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2> ItkImageType;
446 typedef itk::ImageRegionIterator<ItkImageType> ImageIteratorType;
448 ImageIteratorType sourceIter(source, source->GetLargestPossibleRegion());
449 ImageIteratorType targetIter(target, target->GetLargestPossibleRegion());
450 while (!sourceIter.IsAtEnd())
452 targetIter.Set(sourceIter.Get());
459 itk::Image<DefaultSegmentationDataType, 2>::Pointer pic)
461 typedef itk::Image<DefaultSegmentationDataType, 2>::Pointer ItkImagePointerType;
463 ItkImagePointerType firstSideImage = CloneImage(pic);
464 ColorSegment(segment, firstSideImage);
465 ItkImagePointerType secondSideImage = CloneImage(firstSideImage);
467 std::vector<itk::Index<2>> seedPoints = FindSeedPoints(segment, firstSideImage);
468 if (seedPoints.size() < 1)
470 int firstSidePixel = FillRegion(seedPoints, firstSideImage);
472 std::vector<itk::Index<2>> secondSeedPoints = FindSeedPoints(segment, firstSideImage);
473 if (secondSeedPoints.size() < 1)
475 int secondSidePixel = FillRegion(secondSeedPoints, secondSideImage);
477 if (firstSidePixel < secondSidePixel)
479 OverwriteImage(firstSideImage, pic);
483 OverwriteImage(secondSideImage, pic);
void ConvertBackToCorrectPixelType(itk::Image< TPixel, VDimensions > *, mitk::Image::Pointer target, itk::Image< mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2 >::Pointer segmentationPixelTypeImage)
itk::SmartPointer< Self > Pointer
~CorrectorAlgorithm() override
#define AccessByItk_n(mitkImage, itkImageTypeFunction, va_tuple)
Access a MITK image by an ITK image with one or more parameters.
bool ModifySegment(const TSegData &segment, itk::Image< DefaultSegmentationDataType, 2 >::Pointer pic)
bool ImprovedHeimannCorrectionAlgorithm(itk::Image< DefaultSegmentationDataType, 2 >::Pointer pic)
mitk::Image InputImageType
ContourModel::Pointer m_Contour
An object of this class represents an exception of MITK. Please don't instantiate exceptions manually...
Calculated difference image.
static ContourModel::Pointer ProjectContourTo2DSlice(Image *slice, ContourModel *contourIn3D, bool correctionForIpSegmentation, bool constrainToInside)
Projects a contour onto an image point by point. Converts from world to index coordinates.
mitk::Image OutputImageType
Some convenient typedefs.
Superclass of all classes having one or more Images as input and generating Images as output...
Image::Pointer m_WorkingImage
InputImageType * GetInput(void)
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
std::vector< itk::Index< 2 > > points
OutputType * GetOutput()
Get the output data of this image source object.
void GenerateData() override