X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=itk%2FclitkSegmentationUtils.txx;h=c8f976e69449f2d95456e1a9c1a3a1c6d4e77064;hb=c91bc7359270b60e51abdc42dddf0a35c11ea604;hp=94e915431c72a78b082515d1002f802398ed4397;hpb=11b92682c7b52e3920c733aeb2c97721359898e3;p=clitk.git diff --git a/itk/clitkSegmentationUtils.txx b/itk/clitkSegmentationUtils.txx index 94e9154..c8f976e 100644 --- a/itk/clitkSegmentationUtils.txx +++ b/itk/clitkSegmentationUtils.txx @@ -31,6 +31,7 @@ #include #include #include +#include //-------------------------------------------------------------------- template @@ -191,6 +192,53 @@ clitk::Labelize(const ImageType * input, relabelFilter->SetMinimumObjectSize(minimalComponentSize); relabelFilter->Update(); + // DD(relabelFilter->GetNumberOfObjects()); + // DD(relabelFilter->GetOriginalNumberOfObjects()); + // DD(relabelFilter->GetSizeOfObjectsInPhysicalUnits()[0]); + + // Return result + typename ImageType::Pointer output = relabelFilter->GetOutput(); + return output; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +/* + Warning : in this cas, we consider outputType like inputType, not + InternalImageType. Be sure it fits. + */ +template +typename ImageType::Pointer +clitk::LabelizeAndCountNumberOfObjects(const ImageType * input, + typename ImageType::PixelType BG, + bool isFullyConnected, + int minimalComponentSize, + int & nb) { + // InternalImageType for storing large number of component + typedef itk::Image InternalImageType; + + // Connected Component label + typedef itk::ConnectedComponentImageFilter ConnectFilterType; + typename ConnectFilterType::Pointer connectFilter = ConnectFilterType::New(); + // connectFilter->ReleaseDataFlagOn(); + connectFilter->SetInput(input); + connectFilter->SetBackgroundValue(BG); + connectFilter->SetFullyConnected(isFullyConnected); + + // Sort by size and remove too small area. + typedef itk::RelabelComponentImageFilter RelabelFilterType; + typename RelabelFilterType::Pointer relabelFilter = RelabelFilterType::New(); + // relabelFilter->ReleaseDataFlagOn(); // if yes, fail when ExplosionControlledThresholdConnectedImageFilter ??? + relabelFilter->SetInput(connectFilter->GetOutput()); + relabelFilter->SetMinimumObjectSize(minimalComponentSize); + relabelFilter->Update(); + + nb = relabelFilter->GetNumberOfObjects(); + // DD(relabelFilter->GetNumberOfObjects()); + // DD(relabelFilter->GetOriginalNumberOfObjects()); + // DD(relabelFilter->GetSizeOfObjectsInPhysicalUnits()[0]); + // Return result typename ImageType::Pointer output = relabelFilter->GetOutput(); return output; @@ -198,6 +246,7 @@ clitk::Labelize(const ImageType * input, //-------------------------------------------------------------------- + //-------------------------------------------------------------------- template typename ImageType::Pointer @@ -669,3 +718,73 @@ void clitk::ConvertOption(std::string optionName, uint given, //-------------------------------------------------------------------- +//-------------------------------------------------------------------- +/* + http://www.gamedev.net/community/forums/topic.asp?topic_id=542870 + Assuming the points are (Ax,Ay) (Bx,By) and (Cx,Cy), you need to compute: + (Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax) + This will equal zero if the point C is on the line formed by + points A and B, and will have a different sign depending on the + side. Which side this is depends on the orientation of your (x,y) + coordinates, but you can plug test values for A,B and C into this + formula to determine whether negative values are to the left or to + the right. + => to accelerate, start with formula, when change sign -> stop and fill +*/ +template +void +clitk::SliceBySliceSetBackgroundFromLineSeparation(typename ImageType::Pointer input, + std::vector & lA, + std::vector & lB, + typename ImageType::PixelType BG, + int mainDirection, + double offsetToKeep) +{ + + typedef itk::ImageSliceIteratorWithIndex SliceIteratorType; + SliceIteratorType siter = SliceIteratorType(input, + input->GetLargestPossibleRegion()); + siter.SetFirstDirection(0); + siter.SetSecondDirection(1); + siter.GoToBegin(); + int i=0; + typename ImageType::PointType A; + typename ImageType::PointType B; + typename ImageType::PointType C; + while (!siter.IsAtEnd()) { + // Check that the current slice correspond to the current point + input->TransformIndexToPhysicalPoint(siter.GetIndex(), C); + if (C[2] != lA[i][2]) { + // DD(C); + // DD(lA[i]); + } + else { + // Define A,B,C points + A = lA[i]; + B = lB[i]; + C = A; + C[mainDirection] += offsetToKeep; // I know I must keep this point + double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]); + bool isPositive = s<0; + while (!siter.IsAtEndOfSlice()) { + while (!siter.IsAtEndOfLine()) { + // Very slow, I know ... but image should be very small + input->TransformIndexToPhysicalPoint(siter.GetIndex(), C); + double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]); + if (s == 0) siter.Set(BG); // on the line, we decide to remove + if (isPositive) { + if (s > 0) siter.Set(BG); + } + else { + if (s < 0) siter.Set(BG); + } + ++siter; + } + siter.NextLine(); + } + ++i; + } + siter.NextSlice(); + } +} +//--------------------------------------------------------------------