#include <itkImageSliceIteratorWithIndex.h>
#include <itkBinaryMorphologicalOpeningImageFilter.h>
#include <itkImageDuplicator.h>
+#include <itkSignedMaurerDistanceMapImageFilter.h>
namespace clitk {
- //--------------------------------------------------------------------
- template<class ImageType>
- void ComputeBBFromImageRegion(const ImageType * image,
- typename ImageType::RegionType region,
- typename itk::BoundingBox<unsigned long,
- ImageType::ImageDimension>::Pointer bb) {
- typedef typename ImageType::IndexType IndexType;
- IndexType firstIndex;
- IndexType lastIndex;
- for(unsigned int i=0; i<image->GetImageDimension(); i++) {
- firstIndex[i] = region.GetIndex()[i];
- lastIndex[i] = firstIndex[i]+region.GetSize()[i];
- }
-
- typedef itk::BoundingBox<unsigned long,
- ImageType::ImageDimension> 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<int Dimension>
- void ComputeBBIntersection(typename itk::BoundingBox<unsigned long, Dimension>::Pointer bbo,
- typename itk::BoundingBox<unsigned long, Dimension>::Pointer bbi1,
- typename itk::BoundingBox<unsigned long, Dimension>::Pointer bbi2) {
-
- typedef itk::BoundingBox<unsigned long, Dimension> BBType;
- typedef typename BBType::PointType PointType;
- PointType lastPoint;
- PointType firstPoint;
-
- for(unsigned int i=0; i<Dimension; i++) {
- firstPoint[i] = std::max(bbi1->GetMinimum()[i],
- bbi2->GetMinimum()[i]);
- lastPoint[i] = std::min(bbi1->GetMaximum()[i],
- bbi2->GetMaximum()[i]);
- }
-
- bbo->SetMaximum(lastPoint);
- bbo->SetMinimum(firstPoint);
- }
- //--------------------------------------------------------------------
-
-
- //--------------------------------------------------------------------
- template<class ImageType>
- void ComputeRegionFromBB(const ImageType * image,
- const typename itk::BoundingBox<unsigned long,
- ImageType::ImageDimension>::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; i<ImageType::ImageDimension; i++) {
- regionSize[i] = lrint((maxs[i] - mins[i])/image->GetSpacing()[i]);
- }
-
- // Create region
- region.SetIndex(regionStart);
- region.SetSize(regionSize);
- }
- //--------------------------------------------------------------------
-
//--------------------------------------------------------------------
template<class ImageType, class TMaskImageType>
typename ImageType::Pointer
//--------------------------------------------------------------------
- template<class ImageType>
- typename ImageType::Pointer
- ResizeImageLike(const ImageType * input,
- const itk::ImageBase<ImageType::ImageDimension> * like,
- typename ImageType::PixelType backgroundValue)
+ template<class MaskImageType>
+ 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<ImageType> CropFilterType;
- typename CropFilterType::Pointer cropFilter = CropFilterType::New();
- cropFilter->SetInput(input);
- cropFilter->SetCropLikeImage(like);
- cropFilter->SetBackgroundValue(backgroundValue);
- cropFilter->Update();
- return cropFilter->GetOutput();
+ typedef clitk::SliceBySliceRelativePositionFilter<MaskImageType> 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();
}
//--------------------------------------------------------------------
const MaskImageType * object,
int direction,
double threshold,
- std::string orientation,
+ double angle,
+ bool inverseflag,
bool uniqueConnectedComponent,
double spacing,
bool autocropFlag,
bool singleObjectCCL)
{
- typedef SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
+ typedef clitk::SliceBySliceRelativePositionFilter<MaskImageType> SliceRelPosFilterType;
typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New();
sliceRelPosFilter->VerboseStepFlagOff();
sliceRelPosFilter->WriteStepFlagOff();
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();
}
//--------------------------------------------------------------------
+
//--------------------------------------------------------------------
template<class ImageType>
bool
}
//--------------------------------------------------------------------
+
//--------------------------------------------------------------------
template<class ImageType>
bool
typename ImageType::PointType p;
image->TransformIndexToPhysicalPoint(image->GetLargestPossibleRegion().GetIndex()+
image->GetLargestPossibleRegion().GetSize(), p);
- return CropImageAlongOneAxis<ImageType>(image, dim, max, p[dim], autoCrop, BG);
+ // Add GetSpacing because remove Lower or equal than
+ // DD(max);
+ // DD(p);
+ // DD(max+image->GetSpacing()[dim]);
+ return CropImageAlongOneAxis<ImageType>(image, dim, max+image->GetSpacing()[dim], p[dim], autoCrop, BG);
}
//--------------------------------------------------------------------
typename ImageType::RegionType region;
typename ImageType::SizeType size = image->GetLargestPossibleRegion().GetSize();
typename ImageType::PointType p = image->GetOrigin();
- p[dim] = min;
+ if (min > p[dim]) p[dim] = min; // Check if not outside the image
typename ImageType::IndexType start;
image->TransformPhysicalPointToIndex(p, start);
- p[dim] = max;
+ double m = image->GetOrigin()[dim] + size[dim]*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] = fabs(end[dim]-start[dim]);
+ size[dim] = abs(end[dim]-start[dim]);
region.SetIndex(start);
region.SetSize(size);
//--------------------------------------------------------------------
- //--------------------------------------------------------------------
- template<class ImageType>
- void
- ExtractSlices(const ImageType * image, int direction,
- std::vector<typename itk::Image<typename ImageType::PixelType,
- ImageType::ImageDimension-1>::Pointer > & slices)
- {
- typedef ExtractSliceFilter<ImageType> ExtractSliceFilterType;
- typedef typename ExtractSliceFilterType::SliceType SliceType;
- typename ExtractSliceFilterType::Pointer
- extractSliceFilter = ExtractSliceFilterType::New();
- extractSliceFilter->SetInput(image);
- extractSliceFilter->SetDirection(direction);
- extractSliceFilter->Update();
- extractSliceFilter->GetOutputSlices(slices);
- }
- //--------------------------------------------------------------------
-
-
//--------------------------------------------------------------------
template<class ImageType>
void
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();
}
int mainDirection,
double offsetToKeep)
{
+ assert((mainDirection==0) || (mainDirection==1));
typedef itk::ImageSliceIteratorWithIndex<ImageType> SliceIteratorType;
- SliceIteratorType siter = SliceIteratorType(input,
- input->GetLargestPossibleRegion());
+ SliceIteratorType siter = SliceIteratorType(input, input->GetLargestPossibleRegion());
siter.SetFirstDirection(0);
siter.SetSecondDirection(1);
siter.GoToBegin();
while ((i<lA.size()) && (!siter.IsAtEnd())) {
// Check that the current slice correspond to the current point
input->TransformIndexToPhysicalPoint(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
}
else {
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]);
}
//--------------------------------------------------------------------
+
//--------------------------------------------------------------------
template<class ImageType>
void
//--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ void
+ And(ImageType * input,
+ const ImageType * object,
+ typename ImageType::PixelType BG)
+ {
+ typename ImageType::Pointer o;
+ bool resized=false;
+ if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(input, object)) {
+ o = clitk::ResizeImageLike<ImageType>(object, input, BG);
+ resized = true;
+ }
+
+ typedef clitk::BooleanOperatorLabelImageFilter<ImageType> 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<class ImageType>
+ void
+ Or(ImageType * input,
+ const ImageType * object,
+ typename ImageType::PixelType BG)
+ {
+ typename ImageType::Pointer o;
+ bool resized=false;
+ if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(input, object)) {
+ o = clitk::ResizeImageLike<ImageType>(object, input, BG);
+ resized = true;
+ }
+
+ typedef clitk::BooleanOperatorLabelImageFilter<ImageType> 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<class ImageType>
typename ImageType::Pointer
extremaDirection, extremaOppositeFlag, p);
if (found) {
position2D[i] = p;
- }
+ }
}
// Convert 2D points in slice into 3D points
p[lineDirection] += 10;
B.push_back(p);
// Margins ?
- A[i][1] += margin;
- B[i][1] += margin;
+ A[i][extremaDirection] += margin;
+ B[i][extremaDirection] += margin;
}
}
//--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ /* 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<class ImageType>
+ 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<typename ImageType::PixelType, ImageType::ImageDimension-1> SliceType;
+ typedef typename SliceType::Pointer SlicePointer;
+ std::vector<SlicePointer> slices;
+ clitk::ExtractSlices<ImageType>(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<SliceType>(slices[i+Ap[dim1]], BG, region);
+ /*
+ typedef itk::ImageRegionIterator<SliceType> 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<ImageType>(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<class ImageType>
+ typename ImageType::Pointer
+ SliceBySliceSetBackgroundFromPoints(const ImageType * input,
+ typename ImageType::PixelType BG,
+ int sliceDim,
+ std::vector<typename ImageType::PointType> & A,
+ bool removeGreaterThanXFlag,
+ bool removeGreaterThanYFlag)
+
+ {
+ // Extract slices
+ typedef typename itk::Image<typename ImageType::PixelType, ImageType::ImageDimension-1> SliceType;
+ typedef typename SliceType::Pointer SlicePointer;
+ std::vector<SlicePointer> slices;
+ clitk::ExtractSlices<ImageType>(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; i<A.size(); i++) {
+ input->TransformPhysicalPointToIndex(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<SliceType>(slices[sliceIndex], BG, region);
+ // Loop
+ }
+
+ // Merge slices
+ typename ImageType::Pointer output;
+ output = clitk::JoinSlices<ImageType>(slices, input, sliceDim);
+ return output;
+ }
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ void
+ FillRegionWithValue(ImageType * input, typename ImageType::PixelType value, typename ImageType::RegionType & region)
+ {
+ typedef itk::ImageRegionIterator<ImageType> IteratorType;
+ IteratorType iter(input, region);
+ iter.GoToBegin();
+ while (!iter.IsAtEnd()) {
+ iter.Set(value);
+ ++iter;
+ }
+ }
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ 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; i<ImageType::ImageDimension; i++)
+ max_i[i] = input->GetLargestPossibleRegion().GetSize()[i] + min_i[i];
+ input->TransformIndexToPhysicalPoint(min_i, min);
+ input->TransformIndexToPhysicalPoint(max_i, max);
+ }
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename itk::Image<float, ImageType::ImageDimension>::Pointer
+ DistanceMap(const ImageType * input, typename ImageType::PixelType BG)//,
+ // typename itk::Image<float, ImageType::ImageDimension>::Pointer dmap)
+ {
+ typedef itk::Image<float,ImageType::ImageDimension> FloatImageType;
+ typedef itk::SignedMaurerDistanceMapImageFilter<ImageType, FloatImageType> DistanceMapFilterType;
+ typename DistanceMapFilterType::Pointer filter = DistanceMapFilterType::New();
+ filter->SetInput(input);
+ filter->SetUseImageSpacing(true);
+ filter->SquaredDistanceOff();
+ filter->SetBackgroundValue(BG);
+ filter->Update();
+ return filter->GetOutput();
+ }
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ void
+ SliceBySliceBuildLineSegmentAccordingToMinimalDistanceBetweenStructures(const ImageType * S1,
+ const ImageType * S2,
+ typename ImageType::PixelType BG,
+ int sliceDimension,
+ std::vector<typename ImageType::PointType> & A,
+ std::vector<typename ImageType::PointType> & B)
+ {
+ // Extract slices
+ typedef typename itk::Image<typename ImageType::PixelType, 2> SliceType;
+ typedef typename SliceType::Pointer SlicePointer;
+ std::vector<SlicePointer> slices_s1;
+ std::vector<SlicePointer> slices_s2;
+ clitk::ExtractSlices<ImageType>(S1, sliceDimension, slices_s1);
+ clitk::ExtractSlices<ImageType>(S2, sliceDimension, slices_s2);
+
+ assert(slices_s1.size() == slices_s2.size());
+
+ // Prepare dmap
+ typedef itk::Image<float,2> FloatImageType;
+ typedef itk::SignedMaurerDistanceMapImageFilter<SliceType, FloatImageType> DistanceMapFilterType;
+ std::vector<typename FloatImageType::Pointer> dmaps1;
+ std::vector<typename FloatImageType::Pointer> dmaps2;
+ typename FloatImageType::Pointer dmap;
+
+ // loop on slices
+ for(uint i=0; i<slices_s1.size(); i++) {
+ // Compute dmap for S1 *TO PUT IN FONCTION*
+ dmap = clitk::DistanceMap<SliceType>(slices_s1[i], BG);
+ dmaps1.push_back(dmap);
+ writeImage<FloatImageType>(dmap, "dmap1.mha");
+ // Compute dmap for S2
+ dmap = clitk::DistanceMap<SliceType>(slices_s2[i], BG);
+ dmaps2.push_back(dmap);
+ writeImage<FloatImageType>(dmap, "dmap2.mha");
+
+ // Look in S2 for the point the closest to S1
+ typename SliceType::PointType p = ComputeClosestPoint<SliceType>(slices_s1[i], dmaps2[i], BG);
+ typename ImageType::PointType p3D;
+ clitk::PointsUtils<ImageType>::Convert2DTo3D(p, S1, i, p3D);
+ A.push_back(p3D);
+
+ // Look in S2 for the point the closest to S1
+ p = ComputeClosestPoint<SliceType>(slices_s2[i], dmaps1[i], BG);
+ clitk::PointsUtils<ImageType>::Convert2DTo3D(p, S2, i, p3D);
+ B.push_back(p3D);
+
+ }
+
+ // Debug dmap
+ /*
+ typedef itk::Image<float,3> FT;
+ FT::Pointer f = FT::New();
+ typename FT::Pointer d1 = clitk::JoinSlices<FT>(dmaps1, S1, 2);
+ typename FT::Pointer d2 = clitk::JoinSlices<FT>(dmaps2, S2, 2);
+ writeImage<FT>(d1, "d1.mha");
+ writeImage<FT>(d2, "d2.mha");
+ */
+ }
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename ImageType::PointType
+ ComputeClosestPoint(const ImageType * input,
+ const itk::Image<float, ImageType::ImageDimension> * dmap,
+ typename ImageType::PixelType & BG)
+ {
+ // Loop dmap + S2, if FG, get min
+ typedef itk::Image<float,ImageType::ImageDimension> FloatImageType;
+ typedef itk::ImageRegionConstIteratorWithIndex<ImageType> ImageIteratorType;
+ typedef itk::ImageRegionConstIterator<FloatImageType> 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 (d<dmin) {
+ indexmin = iter1.GetIndex();
+ dmin = d;
+ }
+ }
+ ++iter1;
+ ++iter2;
+ }
+
+ // Convert in Point
+ typename ImageType::PointType p;
+ input->TransformIndexToPhysicalPoint(indexmin, p);
+ return p;
+ }
+ //--------------------------------------------------------------------
+
+
+
+
} // end of namespace