X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=itk%2FclitkSegmentationUtils.txx;h=75e5ef35f982b2d7e33fff174af5ae7b77c8ad40;hb=a523f5be1e221995c0d4d29a0077b5e8b984c96d;hp=b432188aec93aa8e34a21f1047ea3d22991a2c25;hpb=8ba83e36419fdc652818505bc9061135aa31e2d6;p=clitk.git diff --git a/itk/clitkSegmentationUtils.txx b/itk/clitkSegmentationUtils.txx index b432188..75e5ef3 100644 --- a/itk/clitkSegmentationUtils.txx +++ b/itk/clitkSegmentationUtils.txx @@ -34,92 +34,10 @@ #include #include #include +#include namespace clitk { - //-------------------------------------------------------------------- - template - void ComputeBBFromImageRegion(const ImageType * image, - typename ImageType::RegionType region, - typename itk::BoundingBox::Pointer bb) { - typedef typename ImageType::IndexType IndexType; - IndexType firstIndex; - IndexType lastIndex; - for(unsigned int i=0; iGetImageDimension(); i++) { - firstIndex[i] = region.GetIndex()[i]; - lastIndex[i] = firstIndex[i]+region.GetSize()[i]; - } - - typedef itk::BoundingBox BBType; - typedef typename BBType::PointType PointType; - PointType lastPoint; - PointType firstPoint; - image->TransformIndexToPhysicalPoint(firstIndex, firstPoint); - image->TransformIndexToPhysicalPoint(lastIndex, lastPoint); - - bb->SetMaximum(lastPoint); - bb->SetMinimum(firstPoint); - } - //-------------------------------------------------------------------- - - - //-------------------------------------------------------------------- - template - void ComputeBBIntersection(typename itk::BoundingBox::Pointer bbo, - typename itk::BoundingBox::Pointer bbi1, - typename itk::BoundingBox::Pointer bbi2) { - - typedef itk::BoundingBox BBType; - typedef typename BBType::PointType PointType; - PointType lastPoint; - PointType firstPoint; - - for(unsigned int i=0; iGetMinimum()[i], - bbi2->GetMinimum()[i]); - lastPoint[i] = std::min(bbi1->GetMaximum()[i], - bbi2->GetMaximum()[i]); - } - - bbo->SetMaximum(lastPoint); - bbo->SetMinimum(firstPoint); - } - //-------------------------------------------------------------------- - - - //-------------------------------------------------------------------- - template - void ComputeRegionFromBB(const ImageType * image, - const typename itk::BoundingBox::Pointer bb, - typename ImageType::RegionType & region) { - // Types - typedef typename ImageType::IndexType IndexType; - typedef typename ImageType::PointType PointType; - typedef typename ImageType::RegionType RegionType; - typedef typename ImageType::SizeType SizeType; - - // Region starting point - IndexType regionStart; - PointType start = bb->GetMinimum(); - image->TransformPhysicalPointToIndex(start, regionStart); - - // Region size - SizeType regionSize; - PointType maxs = bb->GetMaximum(); - PointType mins = bb->GetMinimum(); - for(unsigned int i=0; iGetSpacing()[i]); - } - - // Create region - region.SetIndex(regionStart); - region.SetSize(regionSize); - } - //-------------------------------------------------------------------- - //-------------------------------------------------------------------- template typename ImageType::Pointer @@ -312,19 +230,37 @@ namespace clitk { //-------------------------------------------------------------------- - template - typename ImageType::Pointer - ResizeImageLike(const ImageType * input, - const itk::ImageBase * like, - typename ImageType::PixelType backgroundValue) + template + typename MaskImageType::Pointer + SliceBySliceRelativePosition(const MaskImageType * input, + const MaskImageType * object, + int direction, + double threshold, + std::string orientation, + bool uniqueConnectedComponent, + double spacing, + bool autocropFlag, + bool singleObjectCCL) { - typedef CropLikeImageFilter CropFilterType; - typename CropFilterType::Pointer cropFilter = CropFilterType::New(); - cropFilter->SetInput(input); - cropFilter->SetCropLikeImage(like); - cropFilter->SetBackgroundValue(backgroundValue); - cropFilter->Update(); - return cropFilter->GetOutput(); + typedef clitk::SliceBySliceRelativePositionFilter SliceRelPosFilterType; + typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New(); + sliceRelPosFilter->VerboseStepFlagOff(); + sliceRelPosFilter->WriteStepFlagOff(); + sliceRelPosFilter->SetInput(input); + sliceRelPosFilter->SetInputObject(object); + sliceRelPosFilter->SetDirection(direction); + sliceRelPosFilter->SetFuzzyThreshold(threshold); + sliceRelPosFilter->AddOrientationTypeString(orientation); + sliceRelPosFilter->SetIntermediateSpacingFlag((spacing != -1)); + sliceRelPosFilter->SetIntermediateSpacing(spacing); + sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(uniqueConnectedComponent); + sliceRelPosFilter->ObjectCCLSelectionFlagOff(); + sliceRelPosFilter->SetUseTheLargestObjectCCLFlag(singleObjectCCL); + // sliceRelPosFilter->SetInverseOrientationFlag(inverseflag); + sliceRelPosFilter->SetAutoCropFlag(autocropFlag); + sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); + sliceRelPosFilter->Update(); + return sliceRelPosFilter->GetOutput(); } //-------------------------------------------------------------------- @@ -336,13 +272,14 @@ namespace clitk { const MaskImageType * object, int direction, double threshold, - std::string orientation, + double angle, + bool inverseflag, bool uniqueConnectedComponent, double spacing, bool autocropFlag, bool singleObjectCCL) { - typedef SliceBySliceRelativePositionFilter SliceRelPosFilterType; + typedef clitk::SliceBySliceRelativePositionFilter SliceRelPosFilterType; typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New(); sliceRelPosFilter->VerboseStepFlagOff(); sliceRelPosFilter->WriteStepFlagOff(); @@ -350,12 +287,14 @@ namespace clitk { sliceRelPosFilter->SetInputObject(object); sliceRelPosFilter->SetDirection(direction); sliceRelPosFilter->SetFuzzyThreshold(threshold); - sliceRelPosFilter->AddOrientationTypeString(orientation); + // sliceRelPosFilter->AddOrientationTypeString(orientation); + sliceRelPosFilter->AddAnglesInRad(angle, 0.0); sliceRelPosFilter->SetIntermediateSpacingFlag((spacing != -1)); sliceRelPosFilter->SetIntermediateSpacing(spacing); - sliceRelPosFilter->SetUniqueConnectedComponentBySlice(uniqueConnectedComponent); - sliceRelPosFilter->SetUseASingleObjectConnectedComponentBySliceFlag(singleObjectCCL); - // sliceRelPosFilter->SetInverseOrientationFlag(inverseflag); + sliceRelPosFilter->SetUniqueConnectedComponentBySliceFlag(uniqueConnectedComponent); + sliceRelPosFilter->ObjectCCLSelectionFlagOff(); + sliceRelPosFilter->SetUseTheLargestObjectCCLFlag(singleObjectCCL); + sliceRelPosFilter->SetInverseOrientationFlag(inverseflag); sliceRelPosFilter->SetAutoCropFlag(autocropFlag); sliceRelPosFilter->IgnoreEmptySliceObjectFlagOn(); sliceRelPosFilter->Update(); @@ -363,6 +302,7 @@ namespace clitk { } //-------------------------------------------------------------------- + //-------------------------------------------------------------------- template bool @@ -377,6 +317,7 @@ namespace clitk { } //-------------------------------------------------------------------- + //-------------------------------------------------------------------- template bool @@ -413,7 +354,7 @@ namespace clitk { ++iter; } if (!found) return false; - input->TransformIndexToPhysicalPoint(max, point); + input->TransformIndexToPhysicalPoint(max, point); // half of the pixel return true; } //-------------------------------------------------------------------- @@ -441,9 +382,11 @@ namespace clitk { int dim, double max, bool autoCrop, typename ImageType::PixelType BG) { - typename ImageType::PointType p; + typename ImageType::PointType p; + image->TransformIndexToPhysicalPoint(image->GetLargestPossibleRegion().GetIndex()+ image->GetLargestPossibleRegion().GetSize(), p); + return CropImageAlongOneAxis(image, dim, max, p[dim], autoCrop, BG); } //-------------------------------------------------------------------- @@ -459,14 +402,24 @@ namespace clitk { // Compute region size typename ImageType::RegionType region; typename ImageType::SizeType size = image->GetLargestPossibleRegion().GetSize(); - typename ImageType::PointType p = image->GetOrigin(); - p[dim] = min; + + // Starting index + typename ImageType::PointType p = image->GetOrigin(); // not at pixel center ! + if (min > p[dim]) p[dim] = min; // Check if not outside the image typename ImageType::IndexType start; image->TransformPhysicalPointToIndex(p, start); - p[dim] = max; + + // Size of the region + // -1 because last point is size -1 + double m = image->GetOrigin()[dim] + (size[dim]-1)*image->GetSpacing()[dim]; + if (max > m) p[dim] = m; // Check if not outside the image + else p[dim] = max; + typename ImageType::IndexType end; image->TransformPhysicalPointToIndex(p, end); - size[dim] = abs(end[dim]-start[dim]); + size[dim] = abs(end[dim]-start[dim])+1;// +1 because we want to include the point. + + // Set region region.SetIndex(start); region.SetSize(size); @@ -729,7 +682,8 @@ namespace clitk { dilateFilter->SetForegroundValue(FG); dilateFilter->SetBoundaryToForeground(false); dilateFilter->SetKernel(structuringElement); - dilateFilter->SetInput(output); + if (extendSupport) dilateFilter->SetInput(output); + else dilateFilter->SetInput(image); dilateFilter->Update(); return dilateFilter->GetOutput(); } @@ -814,11 +768,26 @@ namespace clitk { std::vector & lB, typename ImageType::PixelType BG, int mainDirection, - double offsetToKeep) + double offsetToKeep, + bool keepIfEqual) + { + assert((mainDirection==0) || (mainDirection==1)); + typename ImageType::PointType offset; + offset[0] = offset[1] = offset[2] = 0.0; + offset[mainDirection] = offsetToKeep; + SliceBySliceSetBackgroundFromLineSeparation_pt(input, lA, lB, BG, offset, keepIfEqual); + } + template + void + SliceBySliceSetBackgroundFromLineSeparation_pt(ImageType * input, + std::vector & lA, + std::vector & lB, + typename ImageType::PixelType BG, + typename ImageType::PointType offsetToKeep, + bool keepIfEqual) { typedef itk::ImageSliceIteratorWithIndex SliceIteratorType; - SliceIteratorType siter = SliceIteratorType(input, - input->GetLargestPossibleRegion()); + SliceIteratorType siter = SliceIteratorType(input, input->GetLargestPossibleRegion()); siter.SetFirstDirection(0); siter.SetSecondDirection(1); siter.GoToBegin(); @@ -830,38 +799,40 @@ namespace clitk { while ((iTransformIndexToPhysicalPoint(siter.GetIndex(), C); - // DD(C); - // DD(i); - // DD(lA[i]); if ((fabs(C[2] - lA[i][2]))>0.01) { // is !equal with a tolerance of 0.01 mm + // FIXME : if not the same slices, should advance i or slice (not done yet) + // clitkExceptionMacro("Error list of point and slice do not start at the same location"); } else { // Define A,B,C points A = lA[i]; B = lB[i]; C = A; - // DD(A); - // DD(B); - // DD(C); - // Check that the line is not a point (A=B) bool p = (A[0] == B[0]) && (A[1] == B[1]); if (!p) { - C[mainDirection] += offsetToKeep; // I know I must keep this point + //C[mainDirection] += offsetToKeep; // I know I must keep this point + C[0] += offsetToKeep[0]; + C[1] += offsetToKeep[1]; + //C[2] += offsetToKeep[2]; 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); + if (siter.Get() != BG) { // do only if not BG + // 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) { + if (!keepIfEqual) 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; } @@ -876,6 +847,7 @@ namespace clitk { } //-------------------------------------------------------------------- + //-------------------------------------------------------------------- template void @@ -904,6 +876,62 @@ namespace clitk { //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + template + void + And(ImageType * input, + const ImageType * object, + typename ImageType::PixelType BG) + { + typename ImageType::Pointer o; + bool resized=false; + if (!clitk::HaveSameSizeAndSpacing(input, object)) { + o = clitk::ResizeImageLike(object, input, BG); + resized = true; + } + + typedef clitk::BooleanOperatorLabelImageFilter BoolFilterType; + typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); + boolFilter->InPlaceOn(); + boolFilter->SetInput1(input); + if (resized) boolFilter->SetInput2(o); + else boolFilter->SetInput2(object); + boolFilter->SetBackgroundValue1(BG); + boolFilter->SetBackgroundValue2(BG); + boolFilter->SetOperationType(BoolFilterType::And); + boolFilter->Update(); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + template + void + Or(ImageType * input, + const ImageType * object, + typename ImageType::PixelType BG) + { + typename ImageType::Pointer o; + bool resized=false; + if (!clitk::HaveSameSizeAndSpacing(input, object)) { + o = clitk::ResizeImageLike(object, input, BG); + resized = true; + } + + typedef clitk::BooleanOperatorLabelImageFilter BoolFilterType; + typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); + boolFilter->InPlaceOn(); + boolFilter->SetInput1(input); + if (resized) boolFilter->SetInput2(o); + else boolFilter->SetInput2(object); + boolFilter->SetBackgroundValue1(BG); + boolFilter->SetBackgroundValue2(BG); + boolFilter->SetOperationType(BoolFilterType::Or); + boolFilter->Update(); + } + //-------------------------------------------------------------------- + + //-------------------------------------------------------------------- template typename ImageType::Pointer @@ -1033,7 +1061,7 @@ namespace clitk { extremaDirection, extremaOppositeFlag, p); if (found) { position2D[i] = p; - } + } } // Convert 2D points in slice into 3D points @@ -1046,8 +1074,8 @@ namespace clitk { p[lineDirection] += 10; B.push_back(p); // Margins ? - A[i][1] += margin; - B[i][1] += margin; + A[i][extremaDirection] += margin; + B[i][extremaDirection] += margin; } } @@ -1095,5 +1123,330 @@ namespace clitk { //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + /* Consider an input object, start at A, for each slice (dim1): + - compute the intersection between the AB line and the current slice + - remove what is at lower or greater according to dim2 of this point + - stop at B + */ + template + typename ImageType::Pointer + SliceBySliceSetBackgroundFromSingleLine(const ImageType * input, + typename ImageType::PixelType BG, + typename ImageType::PointType & A, + typename ImageType::PointType & B, + int dim1, int dim2, bool removeLowerPartFlag) + + { + // Extract slices + typedef typename itk::Image SliceType; + typedef typename SliceType::Pointer SlicePointer; + std::vector slices; + clitk::ExtractSlices(input, dim1, slices); + + // Start at slice that contains A, and stop at B + typename ImageType::IndexType Ap; + typename ImageType::IndexType Bp; + input->TransformPhysicalPointToIndex(A, Ap); + input->TransformPhysicalPointToIndex(B, Bp); + + // Determine slice largest region + typename SliceType::RegionType region = slices[0]->GetLargestPossibleRegion(); + typename SliceType::SizeType size = region.GetSize(); + typename SliceType::IndexType index = region.GetIndex(); + + // Line slope + double a = (Bp[dim2]-Ap[dim2])/(Bp[dim1]-Ap[dim1]); + double b = Ap[dim2]; + + // Loop from slice A to slice B + for(uint i=0; i<(Bp[dim1]-Ap[dim1]); i++) { + // Compute intersection between line AB and current slice for the dim2 + double p = a*i+b; + // Change region (lower than dim2) + if (removeLowerPartFlag) { + size[dim2] = p-Ap[dim2]; + } + else { + size[dim2] = slices[0]->GetLargestPossibleRegion().GetSize()[dim2]-p; + index[dim2] = p; + } + region.SetSize(size); + region.SetIndex(index); + // Fill region with BG (simple region iterator) + FillRegionWithValue(slices[i+Ap[dim1]], BG, region); + /* + typedef itk::ImageRegionIterator IteratorType; + IteratorType iter(slices[i+Ap[dim1]], region); + iter.GoToBegin(); + while (!iter.IsAtEnd()) { + iter.Set(BG); + ++iter; + } + */ + // Loop + } + + // Merge slices + typename ImageType::Pointer output; + output = clitk::JoinSlices(slices, input, dim1); + return output; + } + //-------------------------------------------------------------------- + + //-------------------------------------------------------------------- + /* Consider an input object, slice by slice, use the point A and set + pixel to BG according to their position relatively to A + */ + template + typename ImageType::Pointer + SliceBySliceSetBackgroundFromPoints(const ImageType * input, + typename ImageType::PixelType BG, + int sliceDim, + std::vector & A, + bool removeGreaterThanXFlag, + bool removeGreaterThanYFlag) + + { + // Extract slices + typedef typename itk::Image SliceType; + typedef typename SliceType::Pointer SlicePointer; + std::vector slices; + clitk::ExtractSlices(input, sliceDim, slices); + + // Start at slice that contains A + typename ImageType::IndexType Ap; + + // Determine slice largest region + typename SliceType::RegionType region = slices[0]->GetLargestPossibleRegion(); + typename SliceType::SizeType size = region.GetSize(); + typename SliceType::IndexType index = region.GetIndex(); + + // Loop from slice A to slice B + for(uint i=0; iTransformPhysicalPointToIndex(A[i], Ap); + uint sliceIndex = Ap[2] - input->GetLargestPossibleRegion().GetIndex()[2]; + if ((sliceIndex < 0) || (sliceIndex >= slices.size())) { + continue; // do not consider this slice + } + + // Compute region for BG + if (removeGreaterThanXFlag) { + index[0] = Ap[0]; + size[0] = region.GetSize()[0]-(index[0]-region.GetIndex()[0]); + } + else { + index[0] = region.GetIndex()[0]; + size[0] = Ap[0] - index[0]; + } + + if (removeGreaterThanYFlag) { + index[1] = Ap[1]; + size[1] = region.GetSize()[1]-(index[1]-region.GetIndex()[1]); + } + else { + index[1] = region.GetIndex()[1]; + size[1] = Ap[1] - index[1]; + } + + // Set region + region.SetSize(size); + region.SetIndex(index); + + // Fill region with BG (simple region iterator) + FillRegionWithValue(slices[sliceIndex], BG, region); + // Loop + } + + // Merge slices + typename ImageType::Pointer output; + output = clitk::JoinSlices(slices, input, sliceDim); + return output; + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + template + void + FillRegionWithValue(ImageType * input, typename ImageType::PixelType value, typename ImageType::RegionType & region) + { + typedef itk::ImageRegionIterator IteratorType; + IteratorType iter(input, region); + iter.GoToBegin(); + while (!iter.IsAtEnd()) { + iter.Set(value); + ++iter; + } + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + template + void + GetMinMaxBoundary(ImageType * input, typename ImageType::PointType & min, + typename ImageType::PointType & max) + { + typedef typename ImageType::PointType PointType; + typedef typename ImageType::IndexType IndexType; + IndexType min_i, max_i; + min_i = input->GetLargestPossibleRegion().GetIndex(); + for(uint i=0; iGetLargestPossibleRegion().GetSize()[i] + min_i[i]; + input->TransformIndexToPhysicalPoint(min_i, min); + input->TransformIndexToPhysicalPoint(max_i, max); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + template + typename itk::Image::Pointer + DistanceMap(const ImageType * input, typename ImageType::PixelType BG)//, + // typename itk::Image::Pointer dmap) + { + typedef itk::Image FloatImageType; + typedef itk::SignedMaurerDistanceMapImageFilter DistanceMapFilterType; + typename DistanceMapFilterType::Pointer filter = DistanceMapFilterType::New(); + filter->SetInput(input); + filter->SetUseImageSpacing(true); + filter->SquaredDistanceOff(); + filter->SetBackgroundValue(BG); + filter->Update(); + return filter->GetOutput(); + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + template + void + SliceBySliceBuildLineSegmentAccordingToMinimalDistanceBetweenStructures(const ImageType * S1, + const ImageType * S2, + typename ImageType::PixelType BG, + int sliceDimension, + std::vector & A, + std::vector & B) + { + // Extract slices + typedef typename itk::Image SliceType; + typedef typename SliceType::Pointer SlicePointer; + std::vector slices_s1; + std::vector slices_s2; + clitk::ExtractSlices(S1, sliceDimension, slices_s1); + clitk::ExtractSlices(S2, sliceDimension, slices_s2); + + assert(slices_s1.size() == slices_s2.size()); + + // Prepare dmap + typedef itk::Image FloatImageType; + typedef itk::SignedMaurerDistanceMapImageFilter DistanceMapFilterType; + std::vector dmaps1; + std::vector dmaps2; + typename FloatImageType::Pointer dmap; + + // loop on slices + for(uint i=0; i(slices_s1[i], BG); + dmaps1.push_back(dmap); + //writeImage(dmap, "dmap1.mha"); + // Compute dmap for S2 + dmap = clitk::DistanceMap(slices_s2[i], BG); + dmaps2.push_back(dmap); + //writeImage(dmap, "dmap2.mha"); + + // Look in S2 for the point the closest to S1 + typename SliceType::PointType p = ComputeClosestPoint(slices_s1[i], dmaps2[i], BG); + typename ImageType::PointType p3D; + clitk::PointsUtils::Convert2DTo3D(p, S1, i, p3D); + A.push_back(p3D); + + // Look in S2 for the point the closest to S1 + p = ComputeClosestPoint(slices_s2[i], dmaps1[i], BG); + clitk::PointsUtils::Convert2DTo3D(p, S2, i, p3D); + B.push_back(p3D); + + } + + /* + // Debug dmap + typedef itk::Image FT; + FT::Pointer f = FT::New(); + typename FT::Pointer d1 = clitk::JoinSlices(dmaps1, S1, 2); + typename FT::Pointer d2 = clitk::JoinSlices(dmaps2, S2, 2); + writeImage(d1, "d1.mha"); + writeImage(d2, "d2.mha"); + */ + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + template + typename ImageType::PointType + ComputeClosestPoint(const ImageType * input, + const itk::Image * dmap, + typename ImageType::PixelType & BG) + { + // Loop dmap + S2, if FG, get min + typedef itk::Image FloatImageType; + typedef itk::ImageRegionConstIteratorWithIndex ImageIteratorType; + typedef itk::ImageRegionConstIterator DMapIteratorType; + ImageIteratorType iter1(input, input->GetLargestPossibleRegion()); + DMapIteratorType iter2(dmap, dmap->GetLargestPossibleRegion()); + + iter1.GoToBegin(); + iter2.GoToBegin(); + double dmin = 100000.0; + typename ImageType::IndexType indexmin; + indexmin.Fill(0); + while (!iter1.IsAtEnd()) { + if (iter1.Get() != BG) { + double d = iter2.Get(); + if (dTransformIndexToPhysicalPoint(indexmin, p); + return p; + } + //-------------------------------------------------------------------- + + + //-------------------------------------------------------------------- + template + typename ImageType::Pointer + RemoveNegativeIndexFromRegion(ImageType * input) { + typedef itk::ChangeInformationImageFilter< ImageType > InfoFilterType; + typename InfoFilterType::Pointer indexChangeFilter = InfoFilterType::New(); + indexChangeFilter->ChangeRegionOn(); + // The next line is commented because not exist in itk 3 + // typename InfoFilterType::OutputImageOffsetValueType indexShift[3]; + long indexShift[3]; + typename ImageType::IndexType index = input->GetLargestPossibleRegion().GetIndex(); + for(uint i=0;iGetOrigin()[i] - indexShift[i]*input->GetSpacing()[i]; + indexChangeFilter->SetOutputOffset( indexShift ); + indexChangeFilter->SetInput(input); + indexChangeFilter->SetOutputOrigin(origin); + indexChangeFilter->ChangeOriginOn(); + indexChangeFilter->Update(); + return indexChangeFilter->GetOutput(); + } + //-------------------------------------------------------------------- + + } // end of namespace