File: itkApproximateSignedDistanceMapImageFilter.hxx

package info (click to toggle)
insighttoolkit4 4.13.3withdata-dfsg2-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 491,256 kB
  • sloc: cpp: 557,600; ansic: 180,546; fortran: 34,788; python: 16,572; sh: 2,187; lisp: 2,070; tcl: 993; java: 362; perl: 200; makefile: 133; csh: 81; pascal: 69; xml: 19; ruby: 10
file content (141 lines) | stat: -rw-r--r-- 5,363 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkApproximateSignedDistanceMapImageFilter_hxx
#define itkApproximateSignedDistanceMapImageFilter_hxx

#include "itkApproximateSignedDistanceMapImageFilter.h"

#include "itkNumericTraits.h"
#include "itkImageScanlineIterator.h"
#include "itkProgressAccumulator.h"

namespace itk
{

template< typename TInputImage, typename TOutputImage >
ApproximateSignedDistanceMapImageFilter< TInputImage, TOutputImage >
::ApproximateSignedDistanceMapImageFilter():
  m_IsoContourFilter( IsoContourType::New() ),
  m_ChamferFilter( ChamferType::New() ),
  m_InsideValue( NumericTraits< InputPixelType >::min() ),
  m_OutsideValue( NumericTraits< InputPixelType >::max() )
{
}

template< typename TInputImage, typename TOutputImage >
void
ApproximateSignedDistanceMapImageFilter< TInputImage, TOutputImage >
::GenerateData()
{
  ThreadIdType numberOfThreads = this->GetNumberOfThreads();

  OutputImagePointer output = this->GetOutput();

  typedef typename OutputImageType::RegionType OutputRegionType;
  OutputRegionType oRegion = output->GetRequestedRegion();

  // Calculate the largest possible distance in the output image.
  // this maximum is the distance from one corner of the image to the other.
  OutputSizeType      outputSize = oRegion.GetSize();
  OutputSizeValueType maximumDistance = 0;

  for( unsigned int i = 0; i < InputImageDimension; i++ )
    {
    maximumDistance += outputSize[i] * outputSize[i];
    }

  // Cast to double and back because there's no sqrt defined for unsigned long,
  // which is the general SizeValueType.
  maximumDistance =
    static_cast< OutputSizeValueType >( std::sqrt( static_cast< double >( maximumDistance ) ) );

  // Allocate the output
  this->AllocateOutputs();

  // Create a process accumulator for tracking the progress of this minipipeline
  ProgressAccumulator::Pointer progress = ProgressAccumulator::New();
  progress->SetMiniPipelineFilter(this);
  progress->RegisterInternalFilter(m_IsoContourFilter, 0.5f);
  progress->RegisterInternalFilter(m_ChamferFilter, 0.5f);

  // Set up the isocontour filter
  m_IsoContourFilter->SetInput( this->GetInput() );
  m_IsoContourFilter->SetFarValue(maximumDistance + 1);
  m_IsoContourFilter->SetNumberOfThreads( numberOfThreads );
  typename IsoContourType::PixelRealType levelSetValue =
    (static_cast<typename IsoContourType::PixelRealType>( m_InsideValue )
    + static_cast<typename IsoContourType::PixelRealType>(m_OutsideValue) ) / 2.0;
  m_IsoContourFilter->SetLevelSetValue(levelSetValue);

  // Set up the chamfer filter
  m_ChamferFilter->SetInput( m_IsoContourFilter->GetOutput() );
  m_ChamferFilter->SetMaximumDistance(maximumDistance);
  m_ChamferFilter->SetNumberOfThreads( numberOfThreads );

  // Graft our output to the chamfer filter to force the proper regions
  // to be generated
  m_ChamferFilter->GraftOutput( output );

  // Create the distance map
  m_ChamferFilter->Update();

  // Graft the output of the chamfer filter back onto this filter's
  // output. this is needed to get the appropriate regions passed
  // back.
  this->GraftOutput( m_ChamferFilter->GetOutput() );

  // Recall that we set the isocontour value to halfway between the inside and
  // outside value. The above filters assume that regions "inside" objects are
  // those with values *less* than the isocontour. This assumption is violated
  // if the "inside" intensity value is greater than the "outside" value.
  // (E.g. in the case that we're computing the distance from a mask where the
  // background is zero and the objects are colored 255.)
  // In this case, the distance will be calculated negative, so we need to
  // flip the sign of the output image.
  if( m_InsideValue > m_OutsideValue )
    {
    ImageScanlineIterator< OutputImageType > ot( output, oRegion );
    while( !ot.IsAtEnd() )
      {
      while( !ot.IsAtEndOfLine() )
        {
        ot.Set(ot.Get() * -1);
        ++ot;
        }
      ot.NextLine();
      }
    }
}

template< typename TInputImage, typename TOutputImage >
void
ApproximateSignedDistanceMapImageFilter< TInputImage, TOutputImage >
::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);

  os << indent << "Inside intensity value: " << m_InsideValue << std::endl;
  os << indent << "Outside intensity value: " << m_OutsideValue << std::endl;
  os << indent << "IsoContourDistanceImageFilter (used internally): "
     << m_IsoContourFilter << std::endl;
  os << indent << "FastChamferDistanceImageFilter (used internally): "
     << m_ChamferFilter << std::endl;
}
} // end of namespace itk

#endif