--- /dev/null
+<cpPlugins_Workspace>
+ <filter category="ImageFilters" class="CastImageFilter" name="cast" ViewX="-1098" ViewY="-242">
+ <parameter name="CastType" value="char#short#int#long#uchar#ushort#uint#ulong#float#double@double" type="Choices"/>
+ </filter>
+ <filter category="fpaImageAlgorithmFunctors" class="InvertCostFunction" name="cost" ViewX="-951" ViewY="-428">
+ <parameter name="Alpha" value="1" type="Real"/>
+ <parameter name="Beta" value="1" type="Real"/>
+ <parameter name="ScalarType" value="float#double@float" type="Choices"/>
+ </filter>
+ <filter category="fpaImageAlgorithm" class="ImageDijkstra" name="dijkstra" ViewX="-735" ViewY="-176">
+ <parameter name="FillNodeQueue" value="1" type="Bool"/>
+ <parameter name="NeighborhoodOrder" value="1#2@1" type="Choices"/>
+ <parameter name="StopAtOneFront" value="0" type="Bool"/>
+ <parameter name="VisualDebug" value="1" type="Bool"/>
+ </filter>
+ <filter category="ImageFilters" class="SignedMaurerDistanceMapImageFilter" name="dmap" ViewX="-1093" ViewY="-379">
+ <parameter name="BackgroundValue" value="0" type="Real"/>
+ <parameter name="InsideIsPositive" value="1" type="Bool"/>
+ <parameter name="OutputResolution" value="float#double@float" type="Choices"/>
+ <parameter name="SquaredDistance" value="0" type="Bool"/>
+ <parameter name="UseImageSpacing" value="1" type="Bool"/>
+ </filter>
+ <filter category="fpaImageAlgorithm" class="ExtractEndPointsAndBifurcationsFromMinimumSpanningTree" name="eb" ViewX="-491" ViewY="-267">
+ <parameter name="SquaredDistanceMap" value="0" type="Bool"/>
+ </filter>
+ <filter category="IO" class="ImageReader" name="reader" ViewX="-1366" ViewY="-264">
+ <parameter name="FileNames" value="" type="OpenFileNameList"/>
+ </filter>
+ <filter category="Widgets" class="NoInteractiveSeedWidget" name="seed" ViewX="-1116" ViewY="-124">
+ <parameter name="Text" value="" type="String"/>
+ </filter>
+ <connection>
+ <origin filter="cost" name="Output"/>
+ <destination filter="dijkstra" name="CostFunctor"/>
+ </connection>
+ <connection>
+ <origin filter="dijkstra" name="Output"/>
+ <destination filter="eb" name="CostsImage"/>
+ </connection>
+ <connection>
+ <origin filter="dijkstra" name="MST"/>
+ <destination filter="eb" name="MST"/>
+ </connection>
+ <connection>
+ <origin filter="dmap" name="Output"/>
+ <destination filter="dijkstra" name="Input"/>
+ </connection>
+ <connection>
+ <origin filter="dmap" name="Output"/>
+ <destination filter="eb" name="DistanceMap"/>
+ </connection>
+ <connection>
+ <origin filter="reader" name="Output"/>
+ <destination filter="cast" name="Input"/>
+ </connection>
+ <connection>
+ <origin filter="reader" name="Output"/>
+ <destination filter="dmap" name="Input"/>
+ </connection>
+ <connection>
+ <origin filter="reader" name="Output"/>
+ <destination filter="seed" name="ReferenceImage"/>
+ </connection>
+ <connection>
+ <origin filter="seed" name="Output"/>
+ <destination filter="dijkstra" name="Seeds"/>
+ </connection>
+ <exposed_output_port port_name="bifurcations" filter="eb" filter_port_name="Bifurcations"/>
+ <exposed_output_port port_name="endpoints" filter="eb" filter_port_name="EndPoints"/>
+ <exposed_output_port port_name="input_image_casted" filter="CastImageFilter" filter_port_name="Output"/>
+ <exposed_output_port port_name="input_image_dmap" filter="dmap" filter_port_name="Output"/>
+ <exposed_output_port port_name="skeleton" filter="eb" filter_port_name="Skeleton"/>
+</cpPlugins_Workspace>
#include <queue>
#include <itkImageRegionConstIteratorWithIndex.h>
+#include <itkImageRegionIteratorWithIndex.h>
// -------------------------------------------------------------------------
#define fpa_Image_SkeletonFilter_InputMacro( i_n, i_t, i_i ) \
// 2. Detect end-points
this->_EndPoints( dmap, cmap, mst, ep->Get( ) );
+ std::cout << "endpoints" << std::endl;
// 3. Build skeleton and keep track of bifurcations
this->_Skeleton( dmap, cmap, mst, ep->Get( ), bi->Get( ), sk );
typedef itk::ImageRegionConstIteratorWithIndex< _TCostMap > _TCostMapIt;
typedef std::multimap< double, TIndex, std::greater< double > > _TQueue;
typedef typename _TQueue::value_type _TQueueValue;
- typedef itk::Image< unsigned char, _TCostMap::ImageDimension > _TMarks;
+ typedef itk::ImageRegionIteratorWithIndex< TMarks > _TMarksIt;
+
+ static const double _eps = std::sqrt( double( TMarks::ImageDimension + 1 ) );
// Some values
- // typename _TMarks::Pointer marks = _TMarks::New( );
auto marks = this->GetMarks( );
marks->SetLargestPossibleRegion( dmap->GetLargestPossibleRegion( ) );
marks->SetRequestedRegion( dmap->GetRequestedRegion( ) );
for( ; !dIt.IsAtEnd( ) && !cIt.IsAtEnd( ); ++dIt, ++cIt )
{
double d = double( dIt.Get( ) );
- if( d > 0 )
+ if( d > double( 0 ) )
{
double v = double( cIt.Get( ) ) / ( d * d );
queue.insert( _TQueueValue( v, dIt.GetIndex( ) ) );
queue.erase( nIt );
unsigned char m = marks->GetPixel( n.second );
- // if( ( m & 0x01 ) == 0x01 )
- if( m != 0 || ( n.first / init_v ) < double( 1e-1 ) )
+ if( m != 0 )
continue;
+ std::cout << queue.size( ) << std::endl;
+
// Mark it and update end-points
m |= 0x01;
marks->SetPixel( n.second, m );
end_points.insert( n.second );
- // Get path
+ // Mark path
+ auto spac = marks->GetSpacing( );
typename TMST::TPath::Pointer path;
mst->GetPath( path, n.second );
for( unsigned long i = 0; i < path->GetSize( ); ++i )
TIndex idx = path->GetVertex( i );
typename _TCostMap::PointType cnt;
cmap->TransformIndexToPhysicalPoint( idx, cnt );
- double d = double( 2 ) * double( dmap->GetPixel( idx ) );
+ double r = double( dmap->GetPixel( idx ) ) * _eps;
+
+ TIndex i0, i1;
+ for( unsigned int d = 0; d < TMarks::ImageDimension; ++d )
+ {
+ long off = long( std::ceil( r / double( spac[ d ] ) ) );
+ if( off == 0 )
+ off = 1;
+ i0[ d ] = idx[ d ] - off;
+ i1[ d ] = idx[ d ] + off;
+
+ if( i0[ d ] < region.GetIndex( )[ d ] )
+ i0[ d ] = region.GetIndex( )[ d ];
- // Mark sphere
- std::queue< TIndex > q;
- q.push( idx );
- while( q.size( ) > 0 )
+ if( i1[ d ] >= region.GetIndex( )[ d ] + region.GetSize( )[ d ] )
+ i1[ d ] = region.GetIndex( )[ d ] + region.GetSize( )[ d ] - 1;
+
+ } // rof
+
+ typename TMarks::SizeType size;
+ for( unsigned int d = 0; d < TMarks::ImageDimension; ++d )
+ size[ d ] = i1[ d ] - i0[ d ] + 1;
+
+ typename TMarks::RegionType neighRegion;
+ neighRegion.SetIndex( i0 );
+ neighRegion.SetSize( size );
+
+ _TMarksIt mIt( marks, neighRegion );
+ for( mIt.GoToBegin( ); !mIt.IsAtEnd( ); ++mIt )
{
- TIndex v = q.front( );
- q.pop( );
- unsigned char m = marks->GetPixel( v );
- if( ( m & 0x02 ) == 0x02 )
- continue;
- m |= 0x02;
- marks->SetPixel( v, m );
-
- for( unsigned int x = 0; x < _TCostMap::ImageDimension; ++x )
- {
- for( int y = -1; y <= 1; y += 2 )
- {
- TIndex w = v;
- w[ x ] += y;
- if( region.IsInside( w ) )
- {
- typename _TCostMap::PointType p;
- cmap->TransformIndexToPhysicalPoint( w, p );
- if( cnt.EuclideanDistanceTo( p ) <= d )
- q.push( w );
-
- } // fi
-
- } // rof
-
- } // rof
-
- } // elihw
+ TIndex w = mIt.GetIndex( );
+ typename _TCostMap::PointType p;
+ marks->TransformIndexToPhysicalPoint( w, p );
+ if( cnt.EuclideanDistanceTo( p ) <= r )
+ mIt.Set( mIt.Get( ) | 0x02 );
+
+ } // rof
} // rof