LSSTApplications  11.0-13-gbb96280,12.1+18,12.1+7,12.1-1-g14f38d3+72,12.1-1-g16c0db7+5,12.1-1-g5961e7a+84,12.1-1-ge22e12b+23,12.1-11-g06625e2+4,12.1-11-g0d7f63b+4,12.1-19-gd507bfc,12.1-2-g7dda0ab+38,12.1-2-gc0bc6ab+81,12.1-21-g6ffe579+2,12.1-21-gbdb6c2a+4,12.1-24-g941c398+5,12.1-3-g57f6835+7,12.1-3-gf0736f3,12.1-37-g3ddd237,12.1-4-gf46015e+5,12.1-5-g06c326c+20,12.1-5-g648ee80+3,12.1-5-gc2189d7+4,12.1-6-ga608fc0+1,12.1-7-g3349e2a+5,12.1-7-gfd75620+9,12.1-9-g577b946+5,12.1-9-gc4df26a+10
LSSTDataManagementBasePackage
SpanSet.h
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008-2016 AURA/LSST.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <https://www.lsstcorp.org/LegalNotices/>.
23  */
24 
25 #ifndef LSST_AFW_GEOM_SPANSET_H
26 #define LSST_AFW_GEOM_SPANSET_H
27 /*
28  Implements a compact representation of a collection of pixels
29  */
30 
31 #include <vector>
32 #include <algorithm>
33 #include <functional>
34 #include <memory>
35 #include <utility>
36 #include "lsst/pex/exceptions.h"
37 #include "lsst/afw/geom/Span.h"
38 #include "lsst/afw/geom/Box.h"
39 #include "lsst/afw/image/Mask.h"
42 
43 namespace lsst { namespace afw { namespace geom { namespace details {
44  /* Functor object to be used with maskToSpanSet function
45  */
46  template <typename T>
48  public:
49  bool operator()(T const & pixelValue) {
50  return pixelValue !=0;
51  }
52  };
53 
54 }}}} // end lsst::afw::geom::details
55 
56 
57 
58 namespace lsst { namespace afw { namespace geom {
59 
66 enum class Stencil { CIRCLE, BOX, MANHATTAN };
67 
68 // Forward declaration of the SpanSet class
69 class SpanSet;
70 
87 template <typename T, typename UnaryPredicate = details::AnyBitSetFunctor<T>>
88 std::shared_ptr<geom::SpanSet> maskToSpanSet(image::Mask<T> const & mask,
89  UnaryPredicate p = details::AnyBitSetFunctor<T>() ) {
90  std::vector<Span> tempVec;
91  std::size_t startValue{0};
92  bool started{false};
93  auto const & maskArray = mask.getArray();
94  auto dimensions = maskArray.getShape();
95  for (size_t y = 0; y < dimensions[0]; ++y) {
96  startValue = 0;
97  started = false;
98  for (size_t x = 0; x < dimensions[1]; ++x) {
99  // If a new span has not been started, and a given x matches the functor condition
100  // start a new span
101  if (p(maskArray[y][x]) && !started) {
102  started = true;
103  startValue = x;
104  }
105  // If a span has been started, and the functor condition is false, that means the
106  // Span being created should be stopped, and appended to the Span vector
107  else if (started && !p(maskArray[y][x])) {
108  tempVec.push_back(Span(y, startValue, x-1));
109  started = false;
110  }
111  // If this is the last value in the Span's x range, and started is still true
112  // that means the last value does not evaluate false in the functor and should be
113  // included in the Span under construction. The Span should be completed and added
114  // to the Span Vector before the next span is concidered.
115  if (started && x == dimensions[1]) {
116  tempVec.push_back(Span(y, startValue, x));
117  }
118  }
119  }
120 
121  // construct a SpanSet from the spans determined above
122  return std::make_shared<SpanSet>(std::move(tempVec));
123 }
124 
134 class SpanSet : public afw::table::io::PersistableFacade<lsst::afw::geom::SpanSet>,
136  public:
137  typedef std::vector<Span>::const_iterator const_iterator;
138  typedef std::vector<Span>::size_type size_type;
139  typedef Span value_type;
140  typedef value_type const & const_reference;
141  const_iterator begin() const;
142  const_iterator end() const;
143  const_iterator cbegin() const;
144  const_iterator cend() const;
145  const_reference front() const;
146  const_reference back() const;
147  size_type size() const;
148  bool empty() const;
149 
154  SpanSet();
155 
160  explicit SpanSet(Box2I const & box);
161 
175  template <typename iter>
176  SpanSet(iter begin, iter end, bool normalize = true):_spanVector(begin, end) {
177  // Return a null SpanSet if spanVector is 0
178  if (_spanVector.size() == 0) {
179  _bBox = geom::Box2I();
180  _area = 0;
181  } else {
182  if (normalize) {
183  _runNormalize();
184  }
185  _initialize();
186  }
187  }
188 
200  explicit SpanSet(const std::vector<Span> & vec, bool normalize = true);
201 
202 
214  explicit SpanSet(std::vector<Span> && vec, bool normalize = true);
215 
216  // Explicitly delete copy and move constructors
217  SpanSet(const SpanSet & other) = delete;
218  SpanSet(SpanSet && other) = delete;
219 
220  // Define class methods
223  size_type getArea() const;
224 
228  Box2I getBBox() const;
229 
237  bool isContiguous() const;
238 
244  std::shared_ptr<SpanSet> shiftedBy(int x, int y) const;
249  std::shared_ptr<SpanSet> shiftedBy(Extent2I const & offset) const;
250 
255  std::shared_ptr<SpanSet> clippedTo(Box2I const & box) const;
256 
262  std::shared_ptr<SpanSet> transformedBy(LinearTransform const & t) const;
263 
269  std::shared_ptr<SpanSet> transformedBy(AffineTransform const & t) const;
270 
276  std::shared_ptr<SpanSet> transformedBy(XYTransform const & t) const;
277 
282  bool overlaps(SpanSet const & other) const;
283 
288  bool contains(SpanSet const & other) const;
289 
294  bool contains(Point2I const & point) const;
295 
298  Point2D computeCentroid() const;
299 
303 
312  std::shared_ptr<SpanSet> dilate(int r, Stencil s = Stencil::CIRCLE) const;
313 
320  std::shared_ptr<SpanSet> dilate(SpanSet const & other) const;
321 
330  std::shared_ptr<SpanSet> erode(int r, Stencil s = Stencil::CIRCLE) const;
331 
338  std::shared_ptr<SpanSet> erode(SpanSet const & other) const;
339 
350  template <typename Pixel, int inC>
351  ndarray::Array<Pixel, 1, 1> flatten(ndarray::Array<Pixel, 2, inC> & input,
352  Point2I const & xy0 = Point2I()) const {
353  // Populate a one dimensional array with the values from input taken at the points of SpanSet
354  ndarray::Array<Pixel, 1, 1> outputArray = ndarray::allocate(ndarray::makeVector(getArea()));
355  outputArray.deep() = 0;
356  flatten(outputArray, input, xy0);
357  return outputArray;
358  }
359 
374  template <typename Pixel, int outC, int inC>
375  void flatten(
376  ndarray::Array<Pixel, 1, outC> const & output,
377  ndarray::Array<Pixel, 2, inC> const & input,
378  Point2I const & xy0 = Point2I()) const {
379  auto ndAssigner = []
380  (Point2I const & point,
383  {out = in;};
384  // Populate array output with values from input at positions given by SpanSet
385  applyFunctor(ndAssigner, ndarray::ndFlat(output), ndarray::ndImage(input, xy0));
386  }
387 
398  template <typename Pixel, int inC>
399  ndarray::Array<Pixel, 2, 2> unflatten(ndarray::Array<Pixel, 1, inC> & input) const {
400  // Create a two dimensional array the size of the bounding box. Populate values from input, placed at
401  // locations corresponding to SpanSet, offset by the lower corner of the bounding box
402  ndarray::Array<Pixel, 2, 2> outputArray = ndarray::allocate(_bBox.getHeight(), _bBox.getWidth());
403  outputArray.deep() = 0;
404  unflatten(outputArray, input, Point2I(_bBox.getMinX(), _bBox.getMinY()));
405  return outputArray;
406  }
407 
423  template <typename Pixel, int outC, int inC>
424  void unflatten(ndarray::Array<Pixel, 2, outC> & output,
425  ndarray::Array<Pixel, 1, inC> & input,
426  Point2I const & xy0 = Point2I()) const {
427  // Populate 2D ndarray output with values from input, at locations defined by SpanSet, optionally
428  // offset by xy0
429  auto ndAssigner = []
430  (Point2I const & point,
433  {out = in;};
434  applyFunctor(ndAssigner, ndarray::ndImage(output, xy0), ndarray::ndFlat(input));
435  }
436 
473  template <typename Functor, typename...Args>
474  // Normally std::forward would be used with a universal reference, however
475  // this function does not use one because without std::forward the
476  // compiler is forced to keep any r-value references alive for the
477  // duration of the function call
478  void applyFunctor(Functor && func, Args && ...args) const {
479  /* Use a variadic template to take a functor object, and an arbitrary number
480  of parameters. For each of the arguments, construct a Getter class using
481  a function (makeGetter) which is overloaded to all the types applyFunctorImpl
482  supports: Images, MaskedImages, Exposures, ndarrays, numeric values, and
483  iterators. The functor and the getters are then passed to the implementation of
484  applyFunctor where the values of the input arguments are intelligently
485  generated at each point in SpanSet, and passed to the functor object for evaluation.
486  */
488  }
489 
497  template <typename T>
498  void setMask(lsst::afw::image::Mask<T> & target, T bitmask) const {
499  // Use a lambda to set bits in a mask at the locations given by SpanSet
500  auto targetArray = target.getArray();
501  auto maskFunctor = []
502  (Point2I const & point,
504  T bitmask)
505  {maskVal |= bitmask;};
506  applyFunctor(maskFunctor, ndarray::ndImage(targetArray), bitmask);
507  }
508 
516  template <typename T>
517  void clearMask(lsst::afw::image::Mask<T> & target, T bitmask) const {
518  // Use a lambda to clear bits in a mask at the locations given by SpanSet
519  auto targetArray = target.getArray();
520  auto clearMaskFunctor = []
521  (Point2I const & point,
523  T bitmask)
524  {maskVal &= ~bitmask;};
525  applyFunctor(clearMaskFunctor, ndarray::ndImage(targetArray), bitmask);
526  }
527 
528  // SpanSet functions
533  std::shared_ptr<SpanSet> intersect(SpanSet const & other) const;
534 
542  template <typename T>
543  std::shared_ptr<SpanSet> intersect(image::Mask<T> const & other, T const & bitmask) const {
544  auto comparator = [bitmask]
545  (T pixelValue)
546  {return (pixelValue & bitmask) == bitmask;};
547  auto spanSetFromMask = geom::maskToSpanSet(other, comparator);
548  return intersect(*spanSetFromMask);
549  }
550 
556  std::shared_ptr<SpanSet> intersectNot(SpanSet const & other) const;
557 
566  template <typename T>
567  std::shared_ptr<SpanSet> intersectNot(image::Mask<T> const & other, T const & bitmask) const {
568  auto comparator = [bitmask]
569  (T pixelValue)
570  {return (pixelValue & bitmask) == bitmask;};
571  auto spanSetFromMask = geom::maskToSpanSet(other, comparator);
572  return intersectNot(*spanSetFromMask);
573  }
574 
579  std::shared_ptr<SpanSet> union_(SpanSet const & other) const;
580 
581 
589  template <typename T>
590  std::shared_ptr<SpanSet> union_(image::Mask<T> const & other, T const & bitmask) const {
591  auto comparator = [bitmask]
592  (T pixelValue)
593  {return (pixelValue & bitmask) == bitmask;};
594  auto spanSetFromMask = geom::maskToSpanSet(other, comparator);
595  return union_(*spanSetFromMask);
596  }
597 
598  // Comparison Operators
603  bool operator==(SpanSet const & other) const;
604 
605  /* @brief Compute inequality between two SpanSets
606  *
607  * @param other - The SpanSet for which inequality will be computed
608  */
609  bool operator!=(SpanSet const & other) const;
610 
617  static std::shared_ptr<geom::SpanSet> spanSetFromShape(int r, Stencil s = Stencil::CIRCLE);
618 
621  std::vector<std::shared_ptr<geom::SpanSet>> split() const;
622 
623  bool isPersistable() const { return true; }
624 
625 private:
626  /* Returns the name used by the persistence layer to identify the SpanSet class
627  */
628  std::string getPersistenceName() const override;
629 
630  /* Return a string corresponding to the python module that SpanSets lives in
631  */
632  inline std::string getPythonModule() const override { return "lsst.afw.geom"; }
633 
634  /* Writes the representation of the class out to an output archive
635  */
636  void write(OutputArchiveHandle & handle) const override;
637 
638  /* A class which is used by the persistence layer to restore SpanSets from an archive
639  */
640  friend class SpansSetFactory;
641 
642  /* A function to combine overlapping Spans in a SpanSet into a single Span
643  */
644  void _runNormalize();
645 
646  /* Initializes the SpanSet class. Contains code that is common to multiple constructors
647  */
648  void _initialize();
649 
650  /* Label Spans according to contiguous group. If the SpanSet is contiguous, all Spans will be labeled 1.
651  * If there is more than one group each group will receive a label one higher than the previous.
652  */
653  void _label(geom::Span const & spn, std::vector<std::size_t> & labelVector, std::size_t currentLabel) const;
654  std::pair<std::vector<std::size_t>, std::size_t> _makeLabels() const;
655 
656  /* Determine if two spans overlap
657  *
658  * a - First Span in comparison
659  * b - Second Span in comparison
660  * compareY - a boolean to control if the comparison takes into account the y position of the spans
661  */
662  inline bool spansOverlap(Span const & a, Span const & b, bool compareY = true) const {
663  bool yTruth(true);
664  if (compareY) {
665  yTruth = a.getY() == b.getY();
666  }
667  return (yTruth && ((a.getMaxX() >= b.getMinX() && a.getMinX() <= b.getMinX()) ||
668  (b.getMaxX() >= a.getMinX() && b.getMinX() <= a.getMinX())))
669  ? true : false;
670  }
671 
672 
673  /* Determine if two spans are contiguous, that is they can overlap or the end of one span is
674  * one pixel before the beginning of the next
675  *
676  * a - First Span in comparison
677  * b - Second Span in comparison
678  * compareY - a boolean to control if the comparison takes into account the y position of the spans
679  */
680  inline bool spansContiguous(Span const & a, Span const & b, bool compareY = true) const {
681  bool yTruth(true);
682  if (compareY) {
683  yTruth = a.getY() == b.getY();
684  }
685  return (yTruth && ((a.getMaxX()+1 >= b.getMinX() && a.getMinX() <= b.getMinX()) ||
686  (b.getMaxX()+1 >= a.getMinX() && b.getMinX() <= a. getMinX())))
687  ? true: false;
688  }
689  std::shared_ptr<SpanSet> makeShift(int x, int y) const;
690 
691  template <typename F, typename ...T>
692  void applyFunctorImpl(F f, T... args) const {
693  /* Implementation for applying functors, loop over each of the spans, and then
694  * each point. Use the get method in the getters to fetch the value and pass
695  * the point, and the values to the functor
696  */
697  // make sure that the SpanSet is within the bounds of functor arguments
699  for (auto const & spn : _spanVector) {
700  // Set the current span in the getter, useful for optimizing value lookups
702  for (auto point : spn) {
703  f(point, args.get()...);
705  }
706  }
707  }
708 
709  // Vector to hold the Spans contained in the SpanSet
710  std::vector<Span> _spanVector;
711 
712  // Box that is large enough to bound all pixels in the SpanSet
714 
715  // Number of pixels in the SpanSet
716  std::size_t _area;
717 };
718 
719  }}} // Close namespace lsst::afw::geom
720 
721 #endif // LSST_AFW_GEOM_SPANSET_H
int y
int iter
int getMinX() const
Minimum x-value.
Definition: Span.h:84
static std::shared_ptr< geom::SpanSet > spanSetFromShape(int r, Stencil s=Stencil::CIRCLE)
Factory function for creating SpanSets from a Stencil.
size_type size() const
An ellipse core with quadrupole moments as parameters.
Definition: Quadrupole.h:45
void variadicSpanSetter(Span const spn, T &x)
Stencil
An enumeration class which describes the shapes.
Definition: SpanSet.h:66
std::pair< std::vector< std::size_t >, std::size_t > _makeLabels() const
std::shared_ptr< SpanSet > makeShift(int x, int y) const
typename ndarray::Array< T, N, C >::Reference::Reference Reference
int getMinY() const
Definition: Box.h:125
Point2D computeCentroid() const
Compute the point about which the SpanSet is symmetrically distributed.
std::shared_ptr< SpanSet > union_(SpanSet const &other) const
Create a new SpanSet that contains all points from two SpanSets.
const_iterator end() const
A compact representation of a collection of pixels.
Definition: SpanSet.h:134
Include files required for standard LSST Exception handling.
A range of pixels within one row of an Image.
Definition: Span.h:54
const_reference back() const
Box2I getBBox() const
Return a new integer box which is the minimum size to contain the pixels.
bool operator==(SpanSet const &other) const
Compute equality between two SpanSets.
void clearMask(lsst::afw::image::Mask< T > &target, T bitmask) const
Unset a Maks at pixels defined by the SpanSet.
Definition: SpanSet.h:517
std::shared_ptr< SpanSet > intersect(image::Mask< T > const &other, T const &bitmask) const
Determine the common points between a SpanSet and a Mask with a given bit pattern.
Definition: SpanSet.h:543
const_iterator cbegin() const
io::OutputArchiveHandle OutputArchiveHandle
Definition: Persistable.h:112
details::FlatNdGetter< T > ndFlat(ndarray::Array< T, inA, inB > const &array)
Marks a ndarray to be interpreted as a 1D vector when applying a functor from a SpanSet.
void applyFunctorImpl(F f, T...args) const
Definition: SpanSet.h:692
int getY() const
Return the y-value.
Definition: Span.h:81
const_reference front() const
bool operator()(T const &pixelValue)
Definition: SpanSet.h:49
SpanSet()
Default constructor.
Point< int, 2 > Point2I
Definition: Point.h:285
void unflatten(ndarray::Array< Pixel, 2, outC > &output, ndarray::Array< Pixel, 1, inC > &input, Point2I const &xy0=Point2I()) const
Populate 2d array at points given by SpanSet.
Definition: SpanSet.h:424
std::size_t _area
Definition: SpanSet.h:716
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
bool spansContiguous(Span const &a, Span const &b, bool compareY=true) const
Definition: SpanSet.h:680
std::vector< Span >::size_type size_type
Definition: SpanSet.h:138
bool spansOverlap(Span const &a, Span const &b, bool compareY=true) const
Definition: SpanSet.h:662
An integer coordinate rectangle.
Definition: Box.h:53
int getMinX() const
Definition: Box.h:124
int getMaxX() const
Maximum x-value.
Definition: Span.h:85
A base class for objects that can be persisted via afw::table::io Archive classes.
Definition: Persistable.h:72
void flatten(ndarray::Array< Pixel, 1, outC > const &output, ndarray::Array< Pixel, 2, inC > const &input, Point2I const &xy0=Point2I()) const
Populate 1d array at points given by SpanSet.
Definition: SpanSet.h:375
A 2D linear coordinate transformation.
afw::table::PointKey< int > dimensions
Definition: GaussianPsf.cc:42
bool overlaps(SpanSet const &other) const
Specifies if this SpanSet overlaps with another SpanSet.
int getWidth() const
Definition: Box.h:154
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
Definition: SpanSet.h:632
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:92
An affine coordinate transformation consisting of a linear transformation and an offset.
friend class SpansSetFactory
Definition: SpanSet.h:640
bool isPersistable() const
Return true if this particular object can be persisted using afw::table::io.
Definition: SpanSet.h:623
SpanSet(iter begin, iter end, bool normalize=true)
Construct a SpanSet from an iterator.
Definition: SpanSet.h:176
bool isContiguous() const
Defines if the SpanSet is simply contiguous.
std::shared_ptr< SpanSet > intersect(SpanSet const &other) const
Determine the common points between two SpanSets, and create a new SpanSet.
double x
const_iterator begin() const
ndarray::Array< Pixel, 1, 1 > flatten(ndarray::Array< Pixel, 2, inC > &input, Point2I const &xy0=Point2I()) const
Create 1d array at points given by SpanSet.
Definition: SpanSet.h:351
void variadicBoundChecker(Box2I const box, int area, T const &x)
details::ImageNdGetter< T, inA, inB > ndImage(ndarray::Array< T, inA, inB > const &array, afwGeom::Point2I xy0=afwGeom::Point2I())
Marks a ndarray to be interpreted as an image when applying a functor from a SpanSet.
LSST bitmasks.
std::shared_ptr< SpanSet > intersectNot(image::Mask< T > const &other, T const &bitmask) const
Determine the common points between a SpanSet and the logical inverse of a Mask for a given bit patte...
Definition: SpanSet.h:567
ndarray::Array< Pixel, 2, 2 > unflatten(ndarray::Array< Pixel, 1, inC > &input) const
Create 2d array at pionts given by SpanSet.
Definition: SpanSet.h:399
void applyFunctor(Functor &&func, Args &&...args) const
Apply functor on individual elements from the supplied parameters.
Definition: SpanSet.h:478
value_type const & const_reference
Definition: SpanSet.h:140
std::vector< Span >::const_iterator const_iterator
Definition: SpanSet.h:137
std::shared_ptr< SpanSet > shiftedBy(int x, int y) const
Return a new SpanSet shifted by specified amount.
std::vector< std::shared_ptr< geom::SpanSet > > split() const
Split a discontinuous SpanSet into multiple SpanSets which are contiguous.
void setMask(lsst::afw::image::Mask< T > &target, T bitmask) const
Set a Mask at pixels defined by the SpanSet.
Definition: SpanSet.h:498
int getHeight() const
Definition: Box.h:155
std::shared_ptr< SpanSet > clippedTo(Box2I const &box) const
Return a new SpanSet which has all pixel values inside specified box.
Virtual base class for 2D transforms.
Definition: XYTransform.h:48
std::shared_ptr< SpanSet > transformedBy(LinearTransform const &t) const
Return a new SpanSet who&#39;s pixels are the product of applying the specified transformation.
typename ndarray::Array< T, 1, 1 >::Reference Reference
bool operator!=(SpanSet const &other) const
std::shared_ptr< SpanSet > dilate(int r, Stencil s=Stencil::CIRCLE) const
Perform a set dilation operation, and return a new object.
afw::table::Key< double > b
metadata input
std::shared_ptr< SpanSet > union_(image::Mask< T > const &other, T const &bitmask) const
Determine the union between a SpanSet and a Mask for a given bit pattern.
Definition: SpanSet.h:590
FlatNdGetter< T > makeGetter(FlatNdGetter< T > &getter)
ellipses::Quadrupole computeShape() const
Compute the shape parameters for the distribution of points in the SpanSet.
Abstract base class for function objects.
Definition: Functor.h:49
size_type getArea() const
Return the number of pixels in the SpanSet.
std::shared_ptr< SpanSet > intersectNot(SpanSet const &other) const
Determine the common points between a SpanSet and the logical inverse of a second SpanSet and return ...
bool contains(SpanSet const &other) const
Check if a SpanSet instance entirely contains another SpanSet.
A CRTP facade class for subclasses of Persistable.
Definition: Persistable.h:180
std::shared_ptr< SpanSet > erode(int r, Stencil s=Stencil::CIRCLE) const
Perform a set erosion, and return a new object.
std::shared_ptr< geom::SpanSet > maskToSpanSet(image::Mask< T > const &mask, UnaryPredicate p=details::AnyBitSetFunctor< T >())
Create a SpanSet from a mask.
Definition: SpanSet.h:88
const_iterator cend() const
std::vector< Span > _spanVector
Definition: SpanSet.h:710
void _label(geom::Span const &spn, std::vector< std::size_t > &labelVector, std::size_t currentLabel) const