36 #ifndef VIGRA_SLIC_HXX 
   37 #define VIGRA_SLIC_HXX 
   39 #include "multi_array.hxx" 
   40 #include "multi_convolution.hxx" 
   41 #include "multi_labeling.hxx" 
   42 #include "numerictraits.hxx" 
   43 #include "accumulator.hxx" 
   44 #include "array_vector.hxx" 
  112 template <
unsigned int N, 
class T, 
class S1,
 
  113                           class Label, 
class S2>
 
  116                   MultiArrayView<N, Label, S2>     seeds,
 
  117                   unsigned int                     seedDist,
 
  118                   unsigned int                     searchRadius = 1)
 
  120     typedef typename MultiArrayShape<N>::type   Shape;
 
  123     Shape shape(boundaryIndicatorImage.shape()),
 
  124           seedShape(
floor(shape / 
double(seedDist))),
 
  125           offset((shape - (seedShape - Shape(1))*seedDist) / 2);
 
  127     unsigned int label = 0;
 
  128     MultiCoordinateIterator<N> iter(seedShape),
 
  129                                end = iter.getEndIterator();
 
  130     for(; iter != end; ++iter)
 
  133         Shape center = (*iter)*seedDist + offset;
 
  134         Shape startCoord = max(Shape(0), center-Shape(searchRadius));
 
  135         Shape endCoord   = min(center+Shape(searchRadius+1), shape);
 
  139         AccumulatorChain<CoupledArrays<N, T>,
 
  140                          Select<WeightArg<1>, Coord<ArgMinWeight> > > a;
 
  141         extractFeatures(boundaryIndicatorImage.subarray(startCoord, endCoord), a);
 
  144         Shape minCoord = get<Coord<ArgMinWeight> >(a) + startCoord;
 
  145         if(seeds[minCoord] == 0)
 
  146             seeds[minCoord] = ++label;
 
  191     unsigned int sizeLimit;
 
  196 template <
unsigned int N, 
class T, 
class Label>
 
  201     typedef MultiArrayView<N, T>                    DataImageType;
 
  202     typedef MultiArrayView<N, Label>                LabelImageType;
 
  204     typedef typename PromoteTraits<
 
  205                    typename NormTraits<T>::NormType,
 
  206                    typename NormTraits<MultiArrayIndex>::NormType
 
  207              >::Promote                             DistanceType;
 
  209     Slic(DataImageType dataImage,
 
  211          DistanceType intensityScaling,
 
  213          SlicOptions 
const & options = SlicOptions());
 
  215     unsigned int execute();
 
  218     void updateAssigments();
 
  219     unsigned int postProcessing();
 
  221     typedef MultiArray<N,DistanceType>  DistanceImageType;
 
  224     DataImageType                   dataImage_;
 
  225     LabelImageType                  labelImage_;
 
  226     DistanceImageType               distance_;
 
  228     DistanceType                    normalization_;
 
  229     SlicOptions                     options_;
 
  232     typedef acc::AccumulatorChainArray<CoupledArrays<N, T, Label>, Statistics> RegionFeatures;
 
  233     RegionFeatures clusters_;
 
  238 template <
unsigned int N, 
class T, 
class Label>
 
  239 Slic<N, T, Label>::Slic(
 
  240     DataImageType         dataImage,
 
  242     DistanceType          intensityScaling,
 
  244     SlicOptions 
const &   options)
 
  245 :   shape_(dataImage.shape()),
 
  246     dataImage_(dataImage),
 
  247     labelImage_(labelImage),
 
  249     max_radius_(maxRadius),
 
  250     normalization_(
sq(intensityScaling) / 
sq(max_radius_)),
 
  253     clusters_.ignoreLabel(0);
 
  256 template <
unsigned int N, 
class T, 
class Label>
 
  257 unsigned int Slic<N, T, Label>::execute()
 
  260     for(
size_t i=0; i<options_.iter; ++i)
 
  270     return postProcessing();
 
  273 template <
unsigned int N, 
class T, 
class Label>
 
  275 Slic<N, T, Label>::updateAssigments()
 
  278     distance_.init(NumericTraits<DistanceType>::max());
 
  279     for(
unsigned int c=1; c<=clusters_.maxRegionLabel(); ++c)
 
  281         if(get<Count>(clusters_, c) == 0) 
 
  284         typedef typename LookupTag<RegionCenter, RegionFeatures>::value_type CenterType;
 
  285         CenterType center = get<RegionCenter>(clusters_, c);
 
  288         ShapeType pixelCenter(
round(center)),
 
  289                   startCoord(max(ShapeType(0), pixelCenter - ShapeType(max_radius_))),
 
  290                   endCoord(min(shape_, pixelCenter + ShapeType(max_radius_+1)));
 
  291         center -= startCoord; 
 
  294         typedef typename CoupledArrays<N, T, Label, DistanceType>::IteratorType Iterator;
 
  295         Iterator iter = createCoupledIterator(dataImage_, labelImage_, distance_).
 
  296                             restrictToSubarray(startCoord, endCoord),
 
  297                  end = iter.getEndIterator();
 
  300         for(; iter != end; ++iter)
 
  303             DistanceType spatialDist   = 
squaredNorm(center-iter.point());
 
  304             DistanceType colorDist     = 
squaredNorm(get<Mean>(clusters_, c)-iter.template get<1>());
 
  305             DistanceType dist =  colorDist + normalization_*spatialDist;
 
  307             if(dist < iter.template get<3>())
 
  309                 iter.template get<2>() = static_cast<Label>(c);
 
  310                 iter.template get<3>() = dist;
 
  316 template <
unsigned int N, 
class T, 
class Label>
 
  318 Slic<N, T, Label>::postProcessing()
 
  321     MultiArray<N,Label> tmpLabelImage(labelImage_);
 
  324     unsigned int sizeLimit = options_.sizeLimit == 0
 
  325                                  ? (
unsigned int)(0.25 * labelImage_.size() / maxLabel)
 
  326                                  : options_.sizeLimit;
 
  332     AccumulatorChainArray<CoupledArrays<N, Label>, Select<LabelArg<1>, 
Count> > sizes;
 
  335     typedef GridGraph<N, undirected_tag> Graph;
 
  338     typedef typename Graph::NodeIt        graph_scanner;
 
  339     typedef typename Graph::OutBackArcIt  neighbor_iterator;
 
  341     vigra::UnionFindArray<Label>  regions(maxLabel+1);
 
  342     ArrayVector<unsigned char>    done(maxLabel+1, 
false);
 
  345     for (graph_scanner node(graph); node != lemon::INVALID; ++node)
 
  347         Label label = labelImage_[*node];
 
  352         if(get<Count>(sizes, label) < sizeLimit)
 
  355             for (neighbor_iterator arc(graph, node); arc != lemon::INVALID; ++arc)
 
  357                 Label other = labelImage_[graph.target(*arc)];
 
  360                     regions.makeUnion(label, other);
 
  373     Label newMaxLabel = regions.makeContiguous();
 
  374     for (graph_scanner node(graph); node != lemon::INVALID; ++node)
 
  376         labelImage_[*node] = regions.findLabel(labelImage_[*node]);
 
  379     return (
unsigned int)newMaxLabel;
 
  460 template <
unsigned int N, 
class T, 
class S1,
 
  461                           class Label, 
class S2,
 
  465                 MultiArrayView<N, Label, S2>      labels,
 
  466                 DistanceType                      intensityScaling,
 
  467                 unsigned int                      seedDistance,
 
  468                 SlicOptions 
const &               options = SlicOptions())
 
  472         typedef typename NormTraits<T>::NormType TmpType;
 
  473         MultiArray<N, TmpType> grad(src.shape());
 
  477     return detail::Slic<N, T, Label>(src, labels, intensityScaling, seedDistance, options).execute();
 
  484 #endif // VIGRA_SLIC_HXX 
unsigned int generateSlicSeeds(...)
Generate seeds for SLIC superpixel computation in arbitrary dimensions. 
PowerSum< 0 > Count
Alias. Count. 
Definition: accumulator-grammar.hxx:157
MultiArrayShape< actual_dimension >::type difference_type
Definition: multi_array.hxx:739
unsigned int labelImage(...)
Find the connected components of a segmented image. 
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude) 
Definition: fftw3.hxx:1044
int round(FixedPoint< IntBits, FracBits > v)
rounding to the nearest integer. 
Definition: fixedpoint.hxx:683
unsigned int slicSuperpixels(...)
Compute SLIC superpixels in arbitrary dimensions. 
SlicOptions()
Create options object with default settings. 
Definition: slic.hxx:163
NumericTraits< T >::Promote sq(T t)
The square function. 
Definition: mathutil.hxx:382
DivideByCount< Sum > Mean
Alias. Mean. 
Definition: accumulator-grammar.hxx:173
Coord< Mean > RegionCenter
Alias. Region center. 
Definition: accumulator-grammar.hxx:223
void extractFeatures(...)
void gaussianGradientMagnitude(...)
Calculate the gradient magnitude by means of a 1st derivatives of Gaussian filter. 
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays. 
Options object for slicSuperpixels(). 
Definition: slic.hxx:157
int floor(FixedPoint< IntBits, FracBits > v)
rounding down. 
Definition: fixedpoint.hxx:667
use only direct neighbors 
Definition: multi_fwd.hxx:187
unsigned int labelMultiArray(...)
Find the connected components of a MultiArray with arbitrary many dimensions. 
SlicOptions & iterations(unsigned int i)
Number of iterations. 
Definition: slic.hxx:172
SlicOptions & minSize(unsigned int s)
Minimum superpixel size. 
Definition: slic.hxx:184