27 #include "itkCastImageFilter.h"
28 #include "itkImageDuplicator.h"
29 #include "itkImageRegionIterator.h"
39 template <
typename TPixel,
unsigned int VDimensions>
41 itk::Image<TPixel, VDimensions> *reference,
45 typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2>
InputImageType;
46 typedef itk::Image<TPixel, 2> OutputImageType;
47 typedef itk::CastImageFilter<InputImageType, OutputImageType> CastImageFilterType;
50 castImageFilter->SetInput(segmentationPixelTypeImage);
51 castImageFilter->Update();
53 tempItkImage->DisconnectPipeline();
61 if (inputImage.IsNull() || inputImage->GetDimension() != 2)
63 itkExceptionMacro(
"CorrectorAlgorithm needs a 2D image as input.");
66 if (m_Contour.IsNull())
68 itkExceptionMacro(
"CorrectorAlgorithm needs a Contour object as input.");
72 m_WorkingImage = inputImage;
76 if (inputImage->GetTimeGeometry())
78 originalGeometry = inputImage->GetTimeGeometry()->Clone();
79 m_WorkingImage->SetTimeGeometry(originalGeometry);
83 itkExceptionMacro(
"Original image does not have a 'Time sliced geometry'! Cannot copy.");
92 assert(correctPixelTypeImage.IsNotNull());
100 itk::Image<DefaultSegmentationDataType, 2>::DirectionType imageDirection;
102 imageDirection.SetIdentity();
105 temporarySlice = this->GetOutput();
110 ImprovedHeimannCorrectionAlgorithm(correctPixelTypeImage);
113 if (inputImage->GetChannelDescriptor().GetPixelType().GetComponentType() == itk::ImageIOBase::USHORT)
122 temporarySlice->SetTimeGeometry(originalGeometry);
125 template <
typename ScalarType>
130 itk::Size<5> size = m_WorkingImage->GetLargestPossibleRegion().GetSize();
170 bool firstPointIsFillingColor =
false;
172 if (projectedContour.IsNull() || projectedContour->GetNumberOfVertices() < 2)
179 if (contourIter == projectedContour->End())
183 previousIndex = ensureIndexInImage((*contourIter)->Coordinates[0], (*contourIter)->Coordinates[1]);
186 int currentColor = (pic->GetPixel(previousIndex) == m_FillColor);
187 firstPointIsFillingColor = currentColor;
189 int countOfSegments = 1;
191 bool firstSegment =
true;
193 for (; contourIter != contourEnd; ++contourIter)
197 currentIndex = ensureIndexInImage((*contourIter)->Coordinates[0] + 0.5, (*contourIter)->Coordinates[1] + 0.5);
200 double slopeX = currentIndex[0] - previousIndex[0];
201 double slopeY = currentIndex[1] - previousIndex[1];
202 double length = std::sqrt(slopeX * slopeX + slopeY * slopeY);
203 double deltaX = slopeX / length;
204 double deltaY = slopeY / length;
206 for (
double i = 0; i <= length && length > 0; i += 1)
209 temporaryIndex = ensureIndexInImage(previousIndex[0] + deltaX * i, previousIndex[1] + deltaY * i);
211 if (!pic->GetLargestPossibleRegion().IsInside(temporaryIndex))
213 if ((pic->GetPixel(temporaryIndex) == m_FillColor) != currentColor)
215 currentSegment.
points.push_back(temporaryIndex);
218 ModifySegment(currentSegment, pic);
222 firstSegment =
false;
226 currentColor = (pic->GetPixel(temporaryIndex) == m_FillColor);
228 currentSegment.
points.push_back(temporaryIndex);
230 previousIndex = currentIndex;
236 void mitk::CorrectorAlgorithm::ColorSegment(
240 int colorMode = (pic->GetPixel(segment.
points[0]) == m_FillColor);
243 color = m_EraseColor;
247 std::vector<itk::Index<2>>::const_iterator indexIterator;
248 std::vector<itk::Index<2>>::const_iterator indexEnd;
250 indexIterator = segment.
points.begin();
251 indexEnd = segment.
points.end();
253 for (; indexIterator != indexEnd; ++indexIterator)
255 pic->SetPixel(*indexIterator, color);
262 typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2> ItkImageType;
263 typedef itk::ImageDuplicator<ItkImageType> DuplicatorType;
265 duplicator->SetInputImage(pic);
266 duplicator->Update();
268 return duplicator->GetOutput();
275 int colorMode = (pic->GetPixel(segment.
points[0]) == m_FillColor);
277 std::vector<itk::Index<2>>::const_iterator indexIterator;
278 std::vector<itk::Index<2>>::const_iterator indexEnd;
280 indexIterator = segment.
points.begin();
281 indexEnd = segment.
points.end();
285 for (; indexIterator != indexEnd; ++indexIterator)
287 for (
int xOffset = -1; xOffset < 2; ++xOffset)
289 for (
int yOffset = -1; yOffset < 2; ++yOffset)
291 index = ensureIndexInImage((*indexIterator)[0] - xOffset, (*indexIterator)[1] - yOffset);
293 if ((pic->GetPixel(index) == m_FillColor) != colorMode)
300 mitkThrow() <<
"No Starting point is found next to the curve.";
303 std::vector<itk::Index<2>> mitk::CorrectorAlgorithm::FindSeedPoints(
307 typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2> ItkImageType;
310 std::vector<itk::Index<2>> seedPoints;
315 seedPoints.push_back(firstPoint);
322 if (segment.
points.size() < 4)
325 std::vector<itk::Index<2>>::const_iterator indexIterator;
326 std::vector<itk::Index<2>>::const_iterator indexEnd;
328 indexIterator = segment.
points.begin();
329 indexEnd = segment.
points.end();
331 ItkImagePointerType listOfPoints = CloneImage(pic);
332 listOfPoints->FillBuffer(0);
333 listOfPoints->SetPixel(seedPoints[0], 1);
334 for (; indexIterator != indexEnd; ++indexIterator)
336 listOfPoints->SetPixel(*indexIterator, 2);
338 indexIterator = segment.
points.begin();
343 for (; indexIterator != indexEnd; ++indexIterator)
345 bool pointFound =
true;
351 for (
int xOffset = -1; xOffset < 2; ++xOffset)
353 for (
int yOffset = -1; yOffset < 2; ++yOffset)
355 index = ensureIndexInImage((*indexIterator)[0] - xOffset, (*indexIterator)[1] - yOffset);
358 if (listOfPoints->GetPixel(index2) > 0)
361 index[0] = index[0] - 1;
362 index = ensureIndexInImage(index[0], index[1]);
363 if (listOfPoints->GetPixel(index) == 1)
366 seedPoints.push_back(index2);
367 listOfPoints->SetPixel(index2, 1);
371 index[0] = index[0] + 2;
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[0] = index[0] - 1;
382 index[1] = index[1] - 1;
383 index = ensureIndexInImage(index[0], index[1]);
384 if (listOfPoints->GetPixel(index) == 1)
387 seedPoints.push_back(index2);
388 listOfPoints->SetPixel(index2, 1);
392 index[1] = index[1] + 2;
393 index = ensureIndexInImage(index[0], index[1]);
394 if (listOfPoints->GetPixel(index) == 1)
397 seedPoints.push_back(index2);
398 listOfPoints->SetPixel(index2, 1);
408 int mitk::CorrectorAlgorithm::FillRegion(
412 int numberOfPixel = 0;
413 int mode = (pic->GetPixel(seedPoints[0]) == m_FillColor);
414 int drawColor = m_FillColor;
417 drawColor = m_EraseColor;
420 std::vector<itk::Index<2>> workPoints;
421 workPoints = seedPoints;
423 while (workPoints.size() > 0)
426 workPoints.pop_back();
427 if ((pic->GetPixel(currentIndex) == m_FillColor) == mode)
429 pic->SetPixel(currentIndex, drawColor);
431 currentIndex = ensureIndexInImage(currentIndex[0] - 1, currentIndex[1]);
432 if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == m_FillColor) == mode)
433 workPoints.push_back(currentIndex);
435 currentIndex = ensureIndexInImage(currentIndex[0] + 2, currentIndex[1]);
436 if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == m_FillColor) == mode)
437 workPoints.push_back(currentIndex);
439 currentIndex = ensureIndexInImage(currentIndex[0] - 1, currentIndex[1] - 1);
441 if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == m_FillColor) == mode)
442 workPoints.push_back(currentIndex);
444 currentIndex = ensureIndexInImage(currentIndex[0], currentIndex[1] + 2);
445 if (pic->GetLargestPossibleRegion().IsInside(currentIndex) && (pic->GetPixel(currentIndex) == m_FillColor) == mode)
446 workPoints.push_back(currentIndex);
449 return numberOfPixel;
452 void mitk::CorrectorAlgorithm::OverwriteImage(
456 typedef itk::Image<mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2> ItkImageType;
457 typedef itk::ImageRegionIterator<ItkImageType> ImageIteratorType;
459 ImageIteratorType sourceIter(source, source->GetLargestPossibleRegion());
460 ImageIteratorType targetIter(target, target->GetLargestPossibleRegion());
461 while (!sourceIter.IsAtEnd())
463 targetIter.Set(sourceIter.Get());
474 ItkImagePointerType firstSideImage = CloneImage(pic);
475 ColorSegment(segment, firstSideImage);
476 ItkImagePointerType secondSideImage = CloneImage(firstSideImage);
478 std::vector<itk::Index<2>> seedPoints = FindSeedPoints(segment, firstSideImage);
479 if (seedPoints.size() < 1)
481 int firstSidePixel = FillRegion(seedPoints, firstSideImage);
483 std::vector<itk::Index<2>> secondSeedPoints = FindSeedPoints(segment, firstSideImage);
484 if (secondSeedPoints.size() < 1)
486 int secondSidePixel = FillRegion(secondSeedPoints, secondSideImage);
488 if (firstSidePixel < secondSidePixel)
490 OverwriteImage(firstSideImage, pic);
494 OverwriteImage(secondSideImage, pic);
itk::SmartPointer< Self > Pointer
mitk::ContourElement::VertexIterator VertexIterator
void ConvertBackToCorrectPixelType(itk::Image< TPixel, VDimensions > *reference, mitk::Image::Pointer target, itk::Image< mitk::CorrectorAlgorithm::DefaultSegmentationDataType, 2 >::Pointer segmentationPixelTypeImage)
#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)
itk::Image< double, 3 > InputImageType
An object of this class represents an exception of MITK. Please don't instantiate exceptions manually...
Calculated difference image.
Image class for storing images.
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.
Superclass of all classes having one or more Images as input and generating Images as output...
InputImageType * GetInput(void)
virtual ~CorrectorAlgorithm()
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
virtual void GenerateData() override
A version of GenerateData() specific for image processing filters.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.