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