26 #include <itkNeighborhoodIterator.h>
27 #include <itkImageRegionIterator.h>
33 #define XRAND_MAX (RAND_MAX*(RAND_MAX + 2))
36 return rand () * (RAND_MAX + 1) + rand ();
40 template <
typename TPixel,
unsigned int VImageDimension>
46 template <
typename TPixel,
unsigned int VImageDimension>
49 m_NumberNodes = numberNodes;
52 template <
typename TPixel,
unsigned int VImageDimension>
55 m_GivenSizeOfSmallestRegion = givenSizeOfSmallestRegion;
56 m_DesiredNumberOfParcels = desiredNumberOfParcels;
57 m_GivenSizeOfSmallestRegionBeginning = givenSizeOfSmallestRegionBeginning;
60 template <
typename TPixel,
unsigned int VImageDimension>
63 m_MergingWithNumberParcels = mergingWithNumberParcels;
64 m_MergingWithSmallestParcel = mergingWithSmallestParcel;
65 m_JustMergeSmallParcels = justMergeSmallParcels;
71 template <
typename TPixel,
unsigned int VImageDimension>
76 typedef itk::Image< TPixel, VImageDimension >
ImageType;
77 int currentSizeOfRegion (0);
78 std::vector<typename ImageType::IndexType> indexVoxel;
79 std::vector<double> centerOfMass;
84 for (it_region.GoToBegin(); !it_region.IsAtEnd(); ++it_region)
86 if(it_region.Value() == valueOfRegion)
88 indexVoxel.push_back(it_region.GetIndex());
89 currentSizeOfRegion++;
93 if (getSizeOfRegions ==
true)
95 m_SizeOfRegions.push_back(currentSizeOfRegion);
102 for (
int i = 0; i < currentSizeOfRegion; i++)
104 xValue += indexVoxel[i][0];
105 yValue += indexVoxel[i][1];
106 zValue += indexVoxel[i][2];
109 centerOfMass.push_back(xValue/currentSizeOfRegion);
110 centerOfMass.push_back(yValue/currentSizeOfRegion);
111 centerOfMass.push_back(zValue/currentSizeOfRegion);
116 template <
typename TPixel,
unsigned int VImageDimension>
119 double distancetemp(0);
121 for (
int i = 0; i < 3; i++)
123 distancetemp += (centerOfMass[i] - indexNewVoxel[i])*(centerOfMass[i] - indexNewVoxel[i]);
125 return sqrt(distancetemp);
128 template <
typename TPixel,
unsigned int VImageDimension>
131 double distancetemp(0);
133 for (
int i = 0; i < 3; i++)
135 distancetemp += (centerOfMass[i] - indexNewVoxel[i])*(centerOfMass[i] - indexNewVoxel[i]);
137 return sqrt(distancetemp);
141 template <
typename TPixel,
unsigned int VImageDimension >
145 distancemin = distance[0];
147 for (
int i = 1; i < distance.size(); i++)
149 if (distance[i] < distancemin)
151 distancemin = distance[i];
157 template <
typename TPixel,
unsigned int VImageDimension >
161 distancemin = distance[0];
163 for (
int i = 1; i < distance.size(); i++)
165 if (distance[i] < distancemin)
167 distancemin = distance[i];
173 template <
typename TPixel,
unsigned int VImageDimension >
176 typedef itk::Image< TPixel, VImageDimension > TemplateImageType;
178 itk::ImageRegionIterator<TemplateImageType> it_image(m_Image, m_Image->GetLargestPossibleRegion());
180 TPixel minimumValue, maximumValue;
182 it_image.GoToBegin();
183 maximumValue = minimumValue = it_image.Value();
185 for(it_image.GoToBegin(); !it_image.IsAtEnd(); ++it_image)
187 if ( it_image.Value() < minimumValue )
189 minimumValue = it_image.Value();
193 if ( it_image.Value() > maximumValue )
195 maximumValue = it_image.Value();
200 int range = int ( maximumValue - minimumValue );
201 int offset = int ( minimumValue );
208 std::vector< unsigned int > histogram;
209 histogram.resize( range + 1, 0 );
211 for(it_image.GoToBegin(); !it_image.IsAtEnd(); ++it_image)
213 histogram[ int ( it_image.Value() ) - offset ] += 1;
219 std::vector< TPixel > subtractionStorage;
220 subtractionStorage.resize( range + 1, 0 );
222 for(
int index = 0; index <= range; index++ )
224 if( histogram[ index ] == 0 )
230 subtractionStorage[ index ] = TPixel ( gapCounter );
235 for(it_image.GoToBegin(); !it_image.IsAtEnd(); ++it_image)
237 it_image.Value() = it_image.Value() - subtractionStorage[ int ( it_image.Value() ) ];
243 template <
typename TPixel,
unsigned int VImageDimension >
246 itk::Size<3> size = chosenRegion.GetSize();
248 std::vector<int> greatestValues;
249 std::vector<int> smallestValues;
251 for(
int i = 0; i < 3; i++)
253 greatestValues.push_back(start[i] + size[i]);
254 smallestValues.push_back(start[i]);
257 for(
int i = 0; i < 3; i++)
259 if (indexChosenVoxel[i] == greatestValues[i])
263 if (indexChosenVoxel[i] == smallestValues[i] - 1)
270 chosenRegion.SetSize(size);
271 chosenRegion.SetIndex(start);
276 template <
typename TPixel,
unsigned int VImageDimension >
279 itk::Size<3> sizeChosenRegion = chosenRegion.GetSize();
281 itk::Size<3> sizeSmallestRegion = smallestRegion.GetSize();
282 itk::Index<3> startSmallestRegion = smallestRegion.GetIndex();
289 for (
int i = 0; i < 3; i++)
292 if ((startChosenRegion[i] + sizeChosenRegion[i] > startSmallestRegion[i]) &&
293 (startChosenRegion[i] <= startSmallestRegion[i]))
296 if (startSmallestRegion[i] + sizeSmallestRegion[i] > startChosenRegion[i] + sizeChosenRegion[i])
298 size[i] = abs(startSmallestRegion[i] - startChosenRegion[i]) + sizeSmallestRegion[i];
303 size[i] =
std::max(sizeChosenRegion[i], sizeSmallestRegion[i]);
308 if ((startSmallestRegion[i] + sizeSmallestRegion[i] > startChosenRegion[i]) &&
309 (startChosenRegion[i] >= startSmallestRegion[i]))
312 if (startChosenRegion[i] + sizeChosenRegion[i] > startSmallestRegion[i] + sizeSmallestRegion[i])
314 size[i] = abs(startSmallestRegion[i] - startChosenRegion[i]) + sizeChosenRegion[i];
319 size[i] =
std::max(sizeChosenRegion[i], sizeSmallestRegion[i]);
324 if ((startChosenRegion[i] + sizeChosenRegion[i] == startSmallestRegion[i]) ||
325 (startSmallestRegion[i] + sizeSmallestRegion[i] == startChosenRegion[i]))
327 size[i] = sizeChosenRegion[i] + sizeSmallestRegion[i];
331 if ((startChosenRegion[i] + sizeChosenRegion[i] < startSmallestRegion[i]) ||
332 (startSmallestRegion[i] + sizeSmallestRegion[i] < startChosenRegion[i]))
334 if(startChosenRegion[i] + sizeChosenRegion[i] < startSmallestRegion[i])
336 size[i] = abs(startChosenRegion[i] - startSmallestRegion[i]) +1;
338 if(startSmallestRegion[i] + sizeSmallestRegion[i] < startChosenRegion[i])
340 size[i] = abs(startChosenRegion[i] - startSmallestRegion[i]) + sizeChosenRegion[i];
346 for (
int i = 0; i < 3; i++)
348 start[i] =
std::min(startChosenRegion[i], startSmallestRegion[i]);
351 chosenRegion.SetSize(size);
352 chosenRegion.SetIndex(start);
358 template <
typename TPixel,
unsigned int VImageDimension >
361 for (
int i = 0; i < vec.size(); i++)
363 if (vec[i] == number)
371 template <
typename TPixel,
unsigned int VImageDimension >
374 typedef itk::Image< TPixel, VImageDimension >
ImageType;
378 counter.
SetRegion(m_Image->GetLargestPossibleRegion());
384 std::vector<int> randomvector;
388 for (
int j = 0; j < m_NumberNodes; j++)
391 randomnumber =
xrand() % numberVoxels +1;
394 if (this->IsUnique(randomnumber, randomvector))
396 randomvector.push_back(randomnumber);
405 sort (randomvector.begin(), randomvector.end());
409 itk::Size<3> originalSize;
410 originalSize.Fill(1);
412 typename ImageType::IndexType currentIndex;
416 typename ImageType::RegionType tempRegion;
417 itk::ImageRegionIterator<ImageType> it_image(m_Image, m_Image->GetLargestPossibleRegion());
420 for (it_image.GoToBegin(); !it_image.IsAtEnd(), regionNumber < m_NumberNodes; ++it_image)
422 if (it_image.Value() >= 1)
425 if (valueCounter == randomvector[regionNumber])
427 it_image.Value() = regionNumber+3;
430 currentIndex = it_image.GetIndex();
431 originalStart[0] = currentIndex[0];
432 originalStart[1] = currentIndex[1];
433 originalStart[2] = currentIndex[2];
435 tempRegion.SetSize(originalSize);
436 tempRegion.SetIndex(originalStart);
437 std::pair<RegionType, int> tempPair (tempRegion, regionNumber+3);
438 m_OddRegions.push_back(tempPair);
445 template <
typename TPixel,
unsigned int VImageDimension >
448 typedef itk::Image< int, VImageDimension > IntegerImageType;
449 typedef itk::NeighborhoodIterator< IntegerImageType > NeighborhoodIteratorType;
450 typename NeighborhoodIteratorType::RadiusType radius;
453 std::pair<RegionType, int> chosenRegion;
455 typename IntegerImageType::IndexType indexChosenVoxel;
456 std::vector<double> distance;
457 std::vector<int> possibleNeighbor;
459 std::vector<double> centerOfMass;
460 typename IntegerImageType::IndexType indexNewVoxel;
461 std::vector<typename IntegerImageType::IndexType> indexNewVoxelVector;
462 int numberAvailableVoxels(0);
463 bool validVoxelNotYetFound;
464 bool checkRegionsOfOddSize(
true);
465 std::vector<std::pair<RegionType,int> > * possibleRegions;
470 while(m_OddRegions.size() != 0 || m_EvenRegions.size() != 0)
473 if (m_OddRegions.size() == 0)
475 checkRegionsOfOddSize =
false;
476 possibleRegions = &m_EvenRegions;
479 if (m_EvenRegions.size() == 0)
481 checkRegionsOfOddSize =
true;
482 possibleRegions = &m_OddRegions;
487 thisRegion =
xrand() % possibleRegions->size();
488 chosenRegion = (*possibleRegions)[thisRegion];
491 centerOfMass.clear();
492 itk::ImageRegionIterator<IntegerImageType> it_region(m_Image, chosenRegion.first);
493 centerOfMass = this->GetCenterOfMass(it_region, chosenRegion.second,
false);
495 numberAvailableVoxels = 0;
496 NeighborhoodIteratorType it_neighborhood(radius, m_Image, chosenRegion.first);
500 for (it_neighborhood.GoToBegin(); !it_neighborhood.IsAtEnd(); ++it_neighborhood)
502 if (it_neighborhood.GetCenterPixel() == chosenRegion.second)
507 for (
int k = 0; k <27; k++)
509 if (it_neighborhood.GetPixel(k) == 1 && (k == 4 || k == 10 || k == 12 || k == 14 || k == 16 || k == 22) )
512 indexNewVoxel = it_neighborhood.GetIndex(k);
513 indexNewVoxelVector.push_back(indexNewVoxel);
515 distance.push_back(this->GetDistance(centerOfMass, indexNewVoxel));
517 numberAvailableVoxels++;
523 if (numberAvailableVoxels > 0)
525 validVoxelNotYetFound =
true;
526 while (validVoxelNotYetFound && distance.size() > 0)
528 possibleNeighbor.clear();
531 for (
int i = 0; i < distance.size(); i++)
533 if (distance[i] == this->SmallestValue(distance))
535 possibleNeighbor.push_back(i);
541 thisNeighbor =
xrand() % possibleNeighbor.size();
542 indexChosenVoxel = indexNewVoxelVector[possibleNeighbor[thisNeighbor]];
545 std::pair<RegionType, int> chosenRegionChanged;
546 chosenRegionChanged.first = this->ExtendedRegion(chosenRegion.first, indexChosenVoxel);
547 chosenRegionChanged.second = chosenRegion.second;
553 costCalculator.
SetRegion(chosenRegionChanged);
559 validVoxelNotYetFound =
false;
560 chosenRegion = chosenRegionChanged;
564 validVoxelNotYetFound =
true;
565 distance.erase(distance.begin() + possibleNeighbor[thisNeighbor]);
566 indexNewVoxelVector.erase(indexNewVoxelVector.begin() + possibleNeighbor[thisNeighbor]);
568 if (distance.size() == 0)
570 if (checkRegionsOfOddSize ==
true)
572 m_InvalidRegions.push_back(chosenRegion);
573 m_OddRegions.erase(m_OddRegions.begin() + thisRegion);
577 m_InvalidRegions.push_back(chosenRegion);
578 m_EvenRegions.erase(m_EvenRegions.begin() + thisRegion);
585 if (distance.size() > 0)
588 itk::ImageRegionIterator<IntegerImageType> it_region(m_Image, m_Image->GetLargestPossibleRegion());
589 it_region.SetIndex(indexChosenVoxel);
590 it_region.Value() = chosenRegion.second;
593 if (checkRegionsOfOddSize ==
true)
595 m_EvenRegions.push_back(chosenRegion);
596 m_OddRegions.erase(m_OddRegions.begin() + thisRegion);
600 m_OddRegions.push_back(chosenRegion);
601 m_EvenRegions.erase(m_EvenRegions.begin() + thisRegion);
605 indexNewVoxelVector.clear();
611 m_InvalidRegions.push_back((*possibleRegions)[thisRegion]);
612 possibleRegions->erase(possibleRegions->begin() + thisRegion);
617 template <
typename TPixel,
unsigned int VImageDimension >
620 typedef itk::Image< int, VImageDimension > IntegerImageType;
621 typedef itk::NeighborhoodIterator< IntegerImageType > NeighborhoodIteratorType;
622 typename NeighborhoodIteratorType::RadiusType radius;
624 NeighborhoodIteratorType it_neighborhood(radius, m_Image, m_Image->GetLargestPossibleRegion());
626 std::vector<int> valueOfRegions;
627 std::vector<int> sizeOfPossibleRegions;
628 std::vector<int> valueOfPossibleRegions;
629 std::vector<int> indexInvalidRegions;
630 std::vector<int> indexOfPossibleInvalidRegions;
631 std::vector<double> distance;
632 std::vector<int> possibleNeighbor;
633 typename IntegerImageType::IndexType indexNewVoxel;
634 std::vector<double> centerOfMass;
636 std::pair<RegionType, int> chosenRegion;
637 typename IntegerImageType::IndexType indexChosenVoxel;
640 wholeImageCounter.
SetImage(m_Image);
641 wholeImageCounter.
SetRegion(m_Image->GetLargestPossibleRegion());
644 if (voxelsWithValueOne > 0)
646 std::stringstream message;
647 message <<
"Edge " << voxelsWithValueOne << endl;
649 for (it_neighborhood.GoToBegin(); !it_neighborhood.IsAtEnd(); ++it_neighborhood)
651 if (it_neighborhood.GetCenterPixel() == 1)
653 m_SizeOfRegions.clear();
655 valueOfRegions.clear();
656 possibleNeighbor.clear();
657 indexInvalidRegions.clear();
658 indexOfPossibleInvalidRegions.clear();
659 indexNewVoxel = it_neighborhood.GetIndex();
663 for (
int k = 0; k <27; k++)
665 if (it_neighborhood.GetPixel(k) > 2)
667 for (
int i = 0; i < m_InvalidRegions.size(); i++)
669 if (it_neighborhood.GetPixel(k) == m_InvalidRegions[i].second)
671 valueOfRegions.push_back(m_InvalidRegions[i].second);
672 itk::ImageRegionIterator<IntegerImageType> it_region(m_Image, m_InvalidRegions[i].first);
675 centerOfMass = this->GetCenterOfMass(it_region, m_InvalidRegions[i].second,
true);
676 distance.push_back(this->GetDistance(centerOfMass, indexNewVoxel));
677 indexInvalidRegions.push_back(i);
684 if (distance.size() != 0)
686 for (
int i = 0; i < distance.size(); i++)
688 if (distance[i] == this->SmallestValue(distance))
690 possibleNeighbor.push_back(i);
697 for (
int i = 0; i < possibleNeighbor.size(); i++)
699 sizeOfPossibleRegions.push_back(m_SizeOfRegions[possibleNeighbor[i]]);
700 valueOfPossibleRegions.push_back(valueOfRegions[possibleNeighbor[i]]);
701 indexOfPossibleInvalidRegions.push_back(indexInvalidRegions[possibleNeighbor[i]]);
703 possibleNeighbor.clear();
704 indexInvalidRegions.clear();
706 for (
int i = 0; i < sizeOfPossibleRegions.size(); i++)
708 if (sizeOfPossibleRegions[i] == this->SmallestValue(sizeOfPossibleRegions))
710 possibleNeighbor.push_back(i);
713 sizeOfPossibleRegions.clear();
715 thisNeighbor =
xrand() % possibleNeighbor.size();
717 it_neighborhood.SetCenterPixel(valueOfPossibleRegions[thisNeighbor]);
718 valueOfPossibleRegions.clear();
722 chosenRegion = m_InvalidRegions[indexOfPossibleInvalidRegions[thisNeighbor]];
723 indexChosenVoxel = it_neighborhood.GetIndex();
725 m_InvalidRegions[indexOfPossibleInvalidRegions[thisNeighbor]].first = this->ExtendedRegion(chosenRegion.first, indexChosenVoxel);
727 indexOfPossibleInvalidRegions.clear();
735 template <
typename TPixel,
unsigned int VImageDimension >
738 typedef itk::Image< int, VImageDimension > IntegerImageType;
740 std::vector<int> valueOfRegions;
741 std::vector<int> sizeOfPossibleRegions;
742 std::vector<int> valueOfPossibleRegions;
743 std::vector<int> indexInvalidRegions;
744 std::vector<int> indexOfPossibleInvalidRegions;
745 std::vector<double> distance;
746 std::vector<int> possibleNeighbor;
747 typename IntegerImageType::IndexType indexNewVoxel;
748 std::vector<double> centerOfMass;
750 std::pair<RegionType, int> chosenRegion;
751 typename IntegerImageType::IndexType indexChosenVoxel;
754 wholeImageCounter.
SetImage(m_Image);
755 wholeImageCounter.
SetRegion(m_Image->GetLargestPossibleRegion());
758 if (voxelsWithValueOne > 0)
760 std::stringstream message;
761 message <<
"Isolated " << voxelsWithValueOne << endl;
763 std::vector<std::vector<double> > comOfRegions;
764 m_SizeOfRegions.clear();
767 for (
int i = 0; i < m_InvalidRegions.size(); i++)
769 valueOfRegions.push_back(m_InvalidRegions[i].second);
770 itk::ImageRegionIterator<IntegerImageType> it_region(m_Image, m_InvalidRegions[i].first);
772 centerOfMass = this->GetCenterOfMass(it_region, m_InvalidRegions[i].second,
true);
773 comOfRegions.push_back(centerOfMass);
776 itk::ImageRegionIterator<IntegerImageType> it_region(m_Image, m_Image->GetLargestPossibleRegion());
778 for (it_region.GoToBegin(); !it_region.IsAtEnd(); ++it_region)
780 if (it_region.Value() == 1)
782 indexNewVoxel = it_region.GetIndex();
785 for (
int j = 0; j < m_InvalidRegions.size(); j++)
787 distance.push_back(this->GetDistance(comOfRegions[j], indexNewVoxel));
788 indexInvalidRegions.push_back(j);
793 if (distance.size() != 0)
795 for (
int i = 0; i < distance.size(); i++)
797 if (distance[i] == this->SmallestValue(distance))
799 possibleNeighbor.push_back(i);
806 for (
int i = 0; i < possibleNeighbor.size(); i++)
808 sizeOfPossibleRegions.push_back(m_SizeOfRegions[possibleNeighbor[i]]);
809 valueOfPossibleRegions.push_back(valueOfRegions[possibleNeighbor[i]]);
810 indexOfPossibleInvalidRegions.push_back(indexInvalidRegions[possibleNeighbor[i]]);
812 possibleNeighbor.clear();
813 indexInvalidRegions.clear();
815 for (
int i = 0; i < sizeOfPossibleRegions.size(); i++)
817 if (sizeOfPossibleRegions[i] == this->SmallestValue(sizeOfPossibleRegions))
819 possibleNeighbor.push_back(i);
822 sizeOfPossibleRegions.clear();
824 thisNeighbor =
xrand() % possibleNeighbor.size();
826 it_region.Value() = valueOfPossibleRegions[thisNeighbor];
827 valueOfPossibleRegions.clear();
828 possibleNeighbor.clear();
832 chosenRegion = m_InvalidRegions[indexOfPossibleInvalidRegions[thisNeighbor]];
833 indexChosenVoxel = it_region.GetIndex();
835 voxelRegion.SetIndex(indexChosenVoxel);
836 itk::Size<3> voxelSize;
838 voxelRegion.SetSize(voxelSize);
840 m_InvalidRegions[indexOfPossibleInvalidRegions[thisNeighbor]].first = this->ExtendedRegionNotNeighbor(chosenRegion.first, voxelRegion);
842 indexOfPossibleInvalidRegions.clear();
849 template <
typename TPixel,
unsigned int VImageDimension >
852 typedef itk::Image< int, VImageDimension > IntegerImageType;
853 typedef itk::NeighborhoodIterator< IntegerImageType > NeighborhoodIteratorType;
854 typename NeighborhoodIteratorType::RadiusType radius;
858 this->GetSizeOfRegions();
860 int sizeOfSmallestRegion = this->SmallestValue(m_SizeOfRegions);
862 std::vector<int> smallRegions;
863 std::vector<int> indexSmallRegions;
866 bool mergingStillPossible(
true);
867 std::vector<int> smallDistances;
868 std::vector<double> centerOfMassPossibleRegion;
869 std::vector<std::vector<double> > comOfRegions;
870 std::vector<int> sizeSmallRegions;
871 std::vector<int> smallestRegions;
872 bool tooManyParcels(
true);
873 int currentNumberOfParcels = m_NumberNodes;
875 std::vector<double> costFunctionValue;
876 std::vector<double> smallestCostFunctionValues;
877 std::vector<int> valueOfPossibleRegions;
878 std::vector<double> distance;
879 std::pair<RegionType, int> chosenRegion;
880 std::vector<double> centerOfMass;
881 bool smallRegionFound(
false);
882 bool hasNeighbors(
false);
884 while (sizeOfSmallestRegion < m_GivenSizeOfSmallestRegion && mergingStillPossible && tooManyParcels)
886 smallRegions.clear();
887 sizeSmallRegions.clear();
888 smallestRegions.clear();
891 for (
int i = 0; i < m_SizeOfRegions.size(); i++)
893 if (m_SizeOfRegions[i] < m_GivenSizeOfSmallestRegion)
895 smallRegions.push_back(i);
896 sizeSmallRegions.push_back(m_SizeOfRegions[i]);
901 for (
int i = 0; i < sizeSmallRegions.size(); i++)
903 if (sizeSmallRegions[i] == this->SmallestValue(sizeSmallRegions))
905 smallestRegions.push_back(smallRegions[i]);
909 if (smallestRegions.size() > 0 && this->SmallestValue(sizeSmallRegions) < m_GivenSizeOfSmallestRegionBeginning)
911 thisSmallRegion = rand() % smallestRegions.size();
915 NeighborhoodIteratorType it_neighborhood(radius, m_Image, m_InvalidRegions[smallestRegions[thisSmallRegion]].first);
916 valueOfPossibleRegions.clear();
917 smallRegionFound =
false;
918 hasNeighbors =
false;
920 for (it_neighborhood.GoToBegin(); !it_neighborhood.IsAtEnd(); ++it_neighborhood)
922 for (
int k = 0; k <27; k++)
924 if ((k == 4 || k == 10 || k == 12 || k == 14 || k == 16 || k == 22) &&
925 it_neighborhood.GetPixel(k) > 2
926 && it_neighborhood.GetPixel(k) != m_InvalidRegions[smallestRegions[thisSmallRegion]].second)
929 for (
int i = 0; i < smallRegions.size(); i++)
931 if (it_neighborhood.GetPixel(k) == m_InvalidRegions[smallRegions[i]].second)
933 valueOfPossibleRegions.push_back(it_neighborhood.GetPixel(k));
934 smallRegionFound =
true;
942 if (hasNeighbors ==
true)
944 if (smallRegionFound ==
true)
947 std::sort(valueOfPossibleRegions.begin(), valueOfPossibleRegions.end());
948 valueOfPossibleRegions.erase(std::unique(valueOfPossibleRegions.begin(), valueOfPossibleRegions.end()), valueOfPossibleRegions.end());
950 indexSmallRegions.clear();
953 for (
int i = 0; i < valueOfPossibleRegions.size() ; i++)
955 for (
int j = 0; j < m_InvalidRegions.size(); j++)
957 if (valueOfPossibleRegions[i] == m_InvalidRegions[j].second)
959 indexSmallRegions.push_back(j);
969 itk::ImageRegionIterator<IntegerImageType> it_regionSmallest(m_Image, m_InvalidRegions[smallestRegions[thisSmallRegion]].first);
970 std::vector<double> centerOfMassCurrentRegion = this->GetCenterOfMass(it_regionSmallest, m_InvalidRegions[smallestRegions[thisSmallRegion]].second,
false);
974 for (
int i = 0; i < indexSmallRegions.size(); i++)
976 itk::ImageRegionIterator<IntegerImageType> it_region(m_Image, m_InvalidRegions[indexSmallRegions[i]].first);
977 centerOfMassPossibleRegion = this->GetCenterOfMass(it_region, m_InvalidRegions[indexSmallRegions[i]].second,
false);
978 distance.push_back(this->GetDistanceVector(centerOfMassCurrentRegion, centerOfMassPossibleRegion));
980 smallDistances.clear();
982 if (m_MergingWithSmallestParcel && m_JustMergeSmallParcels)
985 for (
int i = 0; i < distance.size(); i++)
987 if (distance[i] == this->SmallestValue(distance))
989 smallDistances.push_back(indexSmallRegions[i]);
992 thisIndex = smallDistances[rand() % smallDistances.size()];
997 if (m_MergingWithNumberParcels || (m_MergingWithSmallestParcel && !m_JustMergeSmallParcels))
999 costFunctionValue.clear();
1001 for (
int i = 0; i < indexSmallRegions.size(); i++)
1003 if (distance[i] == 0)
1007 sizeNewParcel = (m_SizeOfRegions[smallestRegions[thisSmallRegion]] + m_SizeOfRegions[indexSmallRegions[i]]);
1009 costFunctionValue.push_back(-(1.0/distance[i]) - (1.0/sizeNewParcel));
1011 smallestCostFunctionValues.clear();
1013 for (
int i = 0; i < indexSmallRegions.size(); i++)
1015 if (costFunctionValue[i] == this->SmallestValue(costFunctionValue))
1017 smallestCostFunctionValues.push_back(indexSmallRegions[i]);
1020 thisIndex = smallestCostFunctionValues[rand() % smallestCostFunctionValues.size()];
1026 for (it_regionSmallest.GoToBegin(); !it_regionSmallest.IsAtEnd(); ++it_regionSmallest)
1028 if (it_regionSmallest.Value() == m_InvalidRegions[smallestRegions[thisSmallRegion]].second)
1030 it_regionSmallest.Value() = m_InvalidRegions[thisIndex].second;
1036 chosenRegion = m_InvalidRegions[thisIndex];
1037 chosenRegion.first = this->ExtendedRegionNotNeighbor(chosenRegion.first, m_InvalidRegions[smallestRegions[thisSmallRegion]].first);
1038 m_InvalidRegions[thisIndex] = chosenRegion;
1041 m_InvalidRegions.erase(m_InvalidRegions.begin() + smallestRegions[thisSmallRegion]);
1042 currentNumberOfParcels--;
1044 if (currentNumberOfParcels <= m_DesiredNumberOfParcels)
1046 tooManyParcels =
false;
1050 this->GetSizeOfRegions();
1055 m_InvalidRegions.erase(m_InvalidRegions.begin() + smallestRegions[thisSmallRegion]);
1056 currentNumberOfParcels--;
1057 m_SizeOfFinishedRegions.push_back(m_SizeOfRegions[smallestRegions[thisSmallRegion]]);
1058 m_SizeOfRegions.erase(m_SizeOfRegions.begin() + smallestRegions[thisSmallRegion]);
1060 if (currentNumberOfParcels <= m_DesiredNumberOfParcels)
1062 tooManyParcels =
false;
1068 comOfRegions.clear();
1070 for (
int i = 0; i < smallRegions.size(); i++)
1072 itk::ImageRegionIterator<IntegerImageType> it_region(m_Image, m_InvalidRegions[smallRegions[i]].first);
1074 centerOfMass = this->GetCenterOfMass(it_region, m_InvalidRegions[smallRegions[i]].second,
false);
1075 comOfRegions.push_back(centerOfMass);
1079 itk::ImageRegionIterator<IntegerImageType> it_regionSmallest(m_Image, m_InvalidRegions[smallestRegions[thisSmallRegion]].first);
1080 std::vector<double> centerOfMassCurrentRegion = this->GetCenterOfMass(it_regionSmallest, m_InvalidRegions[smallestRegions[thisSmallRegion]].second,
false);
1084 for (
int i = 0; i < smallRegions.size(); i++)
1086 itk::ImageRegionIterator<IntegerImageType> it_region(m_Image, m_InvalidRegions[smallRegions[i]].first);
1087 centerOfMassPossibleRegion = this->GetCenterOfMass(it_region, m_InvalidRegions[smallRegions[i]].second,
false);
1088 distance.push_back(this->GetDistanceVector(centerOfMassCurrentRegion, centerOfMassPossibleRegion));
1090 smallDistances.clear();
1091 std::vector<double> distanceWithoutZero = distance;
1092 for (
int i = 0; i < distanceWithoutZero.size(); i++)
1094 if (distanceWithoutZero[i] == 0)
1096 distanceWithoutZero.erase(distanceWithoutZero.begin() + i);
1101 if (distanceWithoutZero.size() > 0)
1104 for (
int i = 0; i < distance.size(); i++)
1106 if (distance[i] == this->SmallestValue(distanceWithoutZero))
1108 smallDistances.push_back(smallRegions[i]);
1112 thisIndex = smallDistances[rand() % smallDistances.size()];
1115 for (it_regionSmallest.GoToBegin(); !it_regionSmallest.IsAtEnd(); ++it_regionSmallest)
1117 if (it_regionSmallest.Value() == m_InvalidRegions[smallestRegions[thisSmallRegion]].second)
1119 it_regionSmallest.Value() = m_InvalidRegions[thisIndex].second;
1124 chosenRegion = m_InvalidRegions[thisIndex];
1125 chosenRegion.first = this->ExtendedRegionNotNeighbor(chosenRegion.first , m_InvalidRegions[smallestRegions[thisSmallRegion]].first);
1126 m_InvalidRegions[thisIndex] = chosenRegion;
1129 m_InvalidRegions.erase(m_InvalidRegions.begin() + smallestRegions[thisSmallRegion]);
1130 currentNumberOfParcels--;
1132 if (currentNumberOfParcels <= m_DesiredNumberOfParcels)
1134 tooManyParcels =
false;
1138 this->GetSizeOfRegions();
1143 m_InvalidRegions.erase(m_InvalidRegions.begin() + smallestRegions[thisSmallRegion]);
1144 currentNumberOfParcels--;
1145 m_SizeOfFinishedRegions.push_back(m_SizeOfRegions[smallestRegions[thisSmallRegion]]);
1146 m_SizeOfRegions.erase(m_SizeOfRegions.begin() + smallestRegions[thisSmallRegion]);
1148 if (currentNumberOfParcels <= m_DesiredNumberOfParcels)
1150 tooManyParcels =
false;
1157 mergingStillPossible =
false;
1160 return (m_SizeOfFinishedRegions.size() + m_SizeOfRegions.size());
1163 template <
typename TPixel,
unsigned int VImageDimension >
1166 m_SizeOfRegions.clear();
1169 for (
int i = 0; i < m_InvalidRegions.size(); i++)
1171 voxelCounter.
SetRegion(m_InvalidRegions[i].first);
1172 m_SizeOfRegions.push_back(voxelCounter.
VoxelWithValue(m_InvalidRegions[i].second));
1176 template <
typename TPixel,
unsigned int VImageDimension >
1181 std::stringstream message;
1182 for (
int i = 0; i < m_InvalidRegions.size(); i++)
1184 voxelCounter.
SetRegion(m_InvalidRegions[i].first);
1185 m_SizeOfRegions.push_back(voxelCounter.
VoxelWithValue(m_InvalidRegions[i].second));
1186 message << voxelCounter.
VoxelWithValue(m_InvalidRegions[i].second) <<
" , ";
void SetImage(itk::Image< TPixel, VImageDimension > *)
void SetRegion(std::pair< RegionType, int >)
void SetImage(itk::Image< TPixel, VImageDimension > *)
int MergeParcels()
Merge parcels according to a cost function Looks for the parcel with the smallest number of voxels...
itk::Image< unsigned char, 3 > ImageType
bool IsUnique(int number, std::vector< int > vec)
Checks if a number is an element of the vector already.
itk::ImageRegion< 3 > RegionType
double GetDistance(std::vector< double > centerOfMass, typename ImageType::IndexType indexNewVoxel)
Calculates the distance between two voxels, the position of the first one is given by an index and th...
int CalculateCost()
Checks if the functions RegionIsFullEnough, SidesAreNotTooLong and COMLiesWithinParcel all return val...
int MaximalValue()
Calculates the maximal possible value of the cost function.
void SetImage(itk::Image< TPixel, VImageDimension > *)
void ShowSizeOfRegions()
Calculates and shows the size (number of voxels) of all regions on the console.
void SetRegion(typename ImageType::RegionType)
void SetBoolsForMerging(bool mergingWithNumberParcels, bool mergingWithSmallestParcel, bool justMergeSmallParcels)
void SetVariablesForMerging(int givenSizeOfSmallestRegion, int desiredNumberOfParcels, int givenSizeOfSmallestRegionBeginning)
std::vector< double > GetCenterOfMass(itk::ImageRegionIterator< ImageType > it_region, int valueOfRegion, bool getSizeOfRegions)
Gives back the center of mass and -if wanted- the size (number of voxels) of a parcel.
int VoxelWithValue(int value)
Counts all voxels with the chosen value in the set region.
void GetSizeOfRegions()
Calculates the size (number of voxels) of all regions.
void SetAppropriateValues()
Changes the values of the nodes, such that no gaps exist and it starts with value 1...
int SmallestValue(std::vector< int > distance)
Gives back the smallest value of an int-vector.
ImageType::RegionType ExtendedRegion(typename ImageType::RegionType chosenRegion, typename ImageType::IndexType indexChosenVoxel)
Extends the region if the chosen voxel lies outside.
void GetRandomSeedVoxels()
Sets randomly chosen seed voxels (1x1x1 regions) on the segmented image This is done by creating a ve...
double GetDistanceVector(std::vector< double > centerOfMass, std::vector< double > indexNewVoxel)
Calculates the distance between two voxels, both positions are given by vectors.
void AllocateIsolatedVoxels()
Add voxels of the segmented part to an appropriate region (no neighbors necessary) Checks which voxel...
ImageType::RegionType ExtendedRegionNotNeighbor(typename ImageType::RegionType chosenRegion, typename ImageType::RegionType smallestRegion)
Extends the region of a parcel such that the second region lies within.
void SetNumberNodes(int inputNumberNodes)
void FillOverEdgeOrVertex()
Add voxels of the segmented part to an appropriate region (26-connected neighborhood) Checks which vo...
void ParcelGrowthOverFaces()
Add appropriate voxels of the segmented part to a region (just 6-connected neighborhood) A voxel is a...