+
+
+//--------------------------------------------------------------------
+template<class ImageType>
+typename ImageType::Pointer
+clitk::Dilate(typename ImageType::Pointer image,
+ double radiusInMM,
+ typename ImageType::PixelType BG,
+ typename ImageType::PixelType FG,
+ bool extendSupport)
+{
+ typename ImageType::SizeType r;
+ for(uint i=0; i<ImageType::ImageDimension; i++)
+ r[i] = (uint)lrint(radiusInMM/image->GetSpacing()[i]);
+ return clitk::Dilate<ImageType>(image, r, BG, FG, extendSupport);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ImageType>
+typename ImageType::Pointer
+clitk::Dilate(typename ImageType::Pointer image,
+ typename ImageType::PointType radiusInMM,
+ typename ImageType::PixelType BG,
+ typename ImageType::PixelType FG,
+ bool extendSupport)
+{
+ typename ImageType::SizeType r;
+ for(uint i=0; i<ImageType::ImageDimension; i++)
+ r[i] = (uint)lrint(radiusInMM[i]/image->GetSpacing()[i]);
+ return clitk::Dilate<ImageType>(image, r, BG, FG, extendSupport);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ImageType>
+typename ImageType::Pointer
+clitk::Dilate(typename ImageType::Pointer image,
+ typename ImageType::SizeType radius,
+ typename ImageType::PixelType BG,
+ typename ImageType::PixelType FG,
+ bool extendSupport)
+{
+ // Create kernel for dilatation
+ typedef itk::BinaryBallStructuringElement<typename ImageType::PixelType,
+ ImageType::ImageDimension> KernelType;
+ KernelType structuringElement;
+ structuringElement.SetRadius(radius);
+ structuringElement.CreateStructuringElement();
+
+ if (extendSupport) {
+ typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadFilterType;
+ typename PadFilterType::Pointer padFilter = PadFilterType::New();
+ padFilter->SetInput(image);
+ typename ImageType::SizeType lower;
+ typename ImageType::SizeType upper;
+ for(uint i=0; i<3; i++) {
+ lower[i] = upper[i] = 2*(radius[i]+1);
+ }
+ padFilter->SetPadLowerBound(lower);
+ padFilter->SetPadUpperBound(upper);
+ padFilter->Update();
+ image = padFilter->GetOutput();
+ }
+
+ // Dilate filter
+ typedef itk::BinaryDilateImageFilter<ImageType, ImageType , KernelType> DilateFilterType;
+ typename DilateFilterType::Pointer dilateFilter = DilateFilterType::New();
+ dilateFilter->SetBackgroundValue(BG);
+ dilateFilter->SetForegroundValue(FG);
+ dilateFilter->SetBoundaryToForeground(false);
+ dilateFilter->SetKernel(structuringElement);
+ dilateFilter->SetInput(image);
+ dilateFilter->Update();
+ return image = dilateFilter->GetOutput();
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ValueType, class VectorType>
+void clitk::ConvertOption(std::string optionName, uint given,
+ ValueType * values, VectorType & p,
+ uint dim, bool required)
+{
+ if (required && (given == 0)) {
+ clitkExceptionMacro("The option --" << optionName << " must be set and have 1 or "
+ << dim << " values.");
+ }
+ if (given == 1) {
+ for(uint i=0; i<dim; i++) p[i] = values[0];
+ return;
+ }
+ if (given == dim) {
+ for(uint i=0; i<dim; i++) p[i] = values[i];
+ return;
+ }
+ if (given == 0) return;
+ clitkExceptionMacro("The option --" << optionName << " must have 1 or "
+ << dim << " values.");
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+/*
+ 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<class ImageType>
+void
+clitk::SliceBySliceSetBackgroundFromLineSeparation(typename ImageType::Pointer input,
+ std::vector<typename ImageType::PointType> & lA,
+ std::vector<typename ImageType::PointType> & lB,
+ typename ImageType::PixelType BG,
+ int mainDirection,
+ double offsetToKeep)
+{
+
+ typedef itk::ImageSliceIteratorWithIndex<ImageType> SliceIteratorType;
+ SliceIteratorType siter = SliceIteratorType(input,
+ input->GetLargestPossibleRegion());
+ siter.SetFirstDirection(0);
+ siter.SetSecondDirection(1);
+ siter.GoToBegin();
+ uint i=0;
+ typename ImageType::PointType A;
+ typename ImageType::PointType B;
+ typename ImageType::PointType C;
+ assert(lA.size() == B.size());
+ // DD(lA.size());
+ //DD(input->GetLargestPossibleRegion().GetSize());
+ while ((i<lA.size()) && (!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();
+ }
+}
+//--------------------------------------------------------------------