Ocean
Loading...
Searching...
No Matches
OccupancyArray.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_TRACKING_SLAM_OCCUPANCY_ARRAY_H
9#define META_OCEAN_TRACKING_SLAM_OCCUPANCY_ARRAY_H
10
12
14
15namespace Ocean
16{
17
18namespace Tracking
19{
20
21namespace SLAM
22{
23
24/**
25 * This class implements an occupancy array allowing to keep track of occupied and unoccupied bins in a camera image.
26 * The bins are sized to work with a configurable neighborhood - when checking if a bin is empty, the neighboring bins are also checked.
27 * The neighborhood size can be 1 (only the center bin), 3 (3x3 neighborhood), 5 (5x5 neighborhood), etc.
28 * Use SpatialDistribution::idealBinsNeighborhood9() to calculate the optimal bin count for a 3x3 neighborhood with a given distance threshold.
29 * @ingroup trackingslam
30 */
31class OCEAN_TRACKING_SLAM_EXPORT OccupancyArray : public Geometry::SpatialDistribution::Array
32{
33 public:
34
35 /**
36 * Default constructor to create an invalid array.
37 */
38 OccupancyArray() = default;
39
40 /**
41 * Creates a new occupancy array.
42 * The bins should be sized appropriately for the specified neighborhood size.
43 * For a 3x3 neighborhood, use SpatialDistribution::idealBinsNeighborhood9().
44 * @param left The left position of the distribution area, with range (-infinity, infinity)
45 * @param top The top position of the distribution area, with range (-infinity, infinity)
46 * @param width The width of the distribution area in pixels, with range [1, infinity)
47 * @param height The height of the distribution area in pixels, with range [1, infinity)
48 * @param horizontalBins The number of horizontal distribution bins, with range [1, infinity)
49 * @param verticalBins The number of vertical distribution bins, with range [1, infinity)
50 * @param neighborhoodSize The size of the neighborhood to check (must be odd), e.g., 1 for single bin, 3 for 3x3, 5 for 5x5, with range [1, infinity), must be odd
51 * @param minCoverageThreshold The minimal coverage threshold (fraction of bins that should be occupied, normalized by neighborhood size), with range [0, 1]
52 */
53 OccupancyArray(const Scalar left, const Scalar top, const unsigned int width, const unsigned int height, const unsigned int horizontalBins, const unsigned int verticalBins, const unsigned int neighborhoodSize = 3u, const float minCoverageThreshold = 0.8f);
54
55 /**
56 * Adds a new point.
57 * @param imagePoint The image point to be added
58 */
59 inline void addPoint(const Vector2& imagePoint);
60
61 /**
62 * Adds a new point.
63 * @param xBin The horizontal bin in which the point is located, with range [0, horizontalBins() - 1]
64 * @param yBin The vertical bin in which the point is located, with range [0, verticalBins() - 1]
65 */
66 void addPoint(const unsigned int xBin, const unsigned int yBin);
67
68 /**
69 * Adds a new point only if the neighborhood around the bin is empty (not yet occupied).
70 * The neighborhood size is determined by the constructor parameter.
71 * @param imagePoint The image point to be added
72 * @return True, if the neighborhood was empty and if the point was added
73 */
74 inline bool addPointIfEmpty(const Vector2& imagePoint);
75
76 /**
77 * Adds a new point only if the neighborhood will not exceed the specified number of points after adding the point.
78 * The neighborhood size is determined by the constructor parameter.
79 * @param imagePoint The image point to be added
80 * @param maxPoints The maximum number of points that the neighborhood may contain after adding the point, with range [1, infinity)
81 * @return True if the neighborhood contained fewer than maxPoints before adding, and the point was added
82 */
83 inline bool addPointIfWithinLimit(const Vector2& imagePoint, const unsigned int maxPoints);
84
85 /**
86 * Adds a new point only if the neighborhood around the bin is empty (not yet occupied).
87 * The neighborhood size is determined by the constructor parameter.
88 * @param xBin The horizontal bin in which the point is located, with range [0, horizontalBins() - 1]
89 * @param yBin The vertical bin in which the point is located, with range [0, verticalBins() - 1]
90 * @return True, if the neighborhood was empty and if the point was added
91 */
92 bool addPointIfEmpty(const unsigned int xBin, const unsigned int yBin);
93
94 /**
95 * Adds a new point only if the neighborhood will not exceed the specified number of points after adding the point.
96 * The neighborhood size is determined by the constructor parameter.
97 * @param xBin The horizontal bin in which the point is located, with range [0, horizontalBins() - 1]
98 * @param yBin The vertical bin in which the point is located, with range [0, verticalBins() - 1]
99 * @param maxPoints The maximum number of points that the neighborhood may contain after adding the point, with range [1, infinity)
100 * @return True if the neighborhood contained fewer than maxPoints before adding, and the point was added
101 */
102 bool addPointIfWithinLimit(const unsigned int xBin, const unsigned int yBin, const unsigned int maxPoints);
103
104 /**
105 * Returns whether the neighborhood around the given image point is empty (not yet occupied).
106 * The neighborhood size is determined by the constructor parameter.
107 * @param imagePoint The image point to check
108 * @return True if the neighborhood is empty
109 */
110 inline bool isEmpty(const Vector2& imagePoint) const;
111
112 /**
113 * Returns whether the neighborhood around the given bin is empty (not yet occupied).
114 * The neighborhood size is determined by the constructor parameter.
115 * @param xBin The horizontal bin to check, with range [0, horizontalBins() - 1]
116 * @param yBin The vertical bin to check, with range [0, verticalBins() - 1]
117 * @return True if the neighborhood is empty
118 */
119 bool isEmpty(const unsigned int xBin, const unsigned int yBin) const;
120
121 /**
122 * Removes all points from the occupancy array.
123 */
124 inline void removePoints();
125
126 /**
127 * Returns whether more points are needed to ensure a good distribution of the points in the image.
128 * This compares the current coverage against the minimum coverage threshold specified in the constructor.
129 * @return True, if so
130 */
131 inline bool needMorePoints() const;
132
133 /**
134 * Returns whether this array is valid.
135 * @return True, if valid
136 */
137 inline bool isValid() const;
138
139 /**
140 * Returns the width of the distribution area.
141 * @return The width in pixels
142 */
143 inline unsigned int width() const;
144
145 /**
146 * Returns the height of the distribution area.
147 * @return The height in pixels
148 */
149 inline unsigned int height() const;
150
151 /**
152 * Returns the fraction of bins that are occupied, normalized by neighborhood size.
153 * This value accounts for the fact that each point effectively covers a neighborhood of bins.
154 * @return Coverage ratio, with range [0, infinity), typically in range [0, 1] but can exceed 1 with overlapping neighborhoods
155 */
156 inline float coverage() const;
157
158 protected:
159
160 /// The vector holding occupancy counters for all bins.
162
163 /// The number of points added to the occupancy array.
164 size_t numberPoints_ = 0;
165
166 /// The coverage threshold to determine if more points are needed.
167 float coverageThreshold_ = -1.0f;
168
169 /// The neighborhood radius (offset from center bin), e.g., 1 for 3x3 neighborhood, 2 for 5x5, etc.
170 unsigned int neighborhoodRadius_ = 0u;
171};
172
173inline void OccupancyArray::addPoint(const Vector2& imagePoint)
174{
175 const unsigned int xBin = horizontalBin(imagePoint.x());
176 const unsigned int yBin = verticalBin(imagePoint.y());
177
178 ocean_assert(xBin < horizontalBins());
179 ocean_assert(yBin < verticalBins());
180
181 addPoint(xBin, yBin);
182}
183
184inline bool OccupancyArray::addPointIfEmpty(const Vector2& imagePoint)
185{
186 const unsigned int xBin = horizontalBin(imagePoint.x());
187 const unsigned int yBin = verticalBin(imagePoint.y());
188
189 ocean_assert(xBin < horizontalBins());
190 ocean_assert(yBin < verticalBins());
191
192 return addPointIfEmpty(xBin, yBin);
193}
194
195inline bool OccupancyArray::addPointIfWithinLimit(const Vector2& imagePoint, const unsigned int maxPoints)
196{
197 const unsigned int xBin = horizontalBin(imagePoint.x());
198 const unsigned int yBin = verticalBin(imagePoint.y());
199
200 ocean_assert(xBin < horizontalBins());
201 ocean_assert(yBin < verticalBins());
202
203 return addPointIfWithinLimit(xBin, yBin, maxPoints);
204}
205
206inline bool OccupancyArray::isEmpty(const Vector2& imagePoint) const
207{
208 const unsigned int xBin = horizontalBin(imagePoint.x());
209 const unsigned int yBin = verticalBin(imagePoint.y());
210
211 ocean_assert(xBin < horizontalBins());
212 ocean_assert(yBin < verticalBins());
213
214 return isEmpty(xBin, yBin);
215}
216
218{
219 std::fill(bins_.begin(), bins_.end(), 0u);
220
221 numberPoints_ = 0;
222}
223
225{
226 return coverage() < coverageThreshold_;
227}
228
229inline bool OccupancyArray::isValid() const
230{
231 return Array::isValid() && coverageThreshold_ >= 0.0f && coverageThreshold_ <= 1.0f;
232}
233
234inline unsigned int OccupancyArray::width() const
235{
236 return (unsigned int)(Array::width());
237}
238
239inline unsigned int OccupancyArray::height() const
240{
241 return (unsigned int)(Array::height());
242}
243
244inline float OccupancyArray::coverage() const
245{
246 const unsigned int neighborhoodSize = neighborhoodRadius_ * 2u + 1u;
247
248 return float(numberPoints_ * neighborhoodSize * neighborhoodSize) / float(bins());
249}
250
251}
252
253}
254
255}
256
257#endif // META_OCEAN_TRACKING_SLAM_OCCUPANCY_ARRAY_H
This class implements a base class for data arrays.
Definition SpatialDistribution.h:37
unsigned int horizontalBins() const
Returns the number of horizontal distribution bins.
Definition SpatialDistribution.h:1078
int horizontalBin(const Scalar x) const
Returns the horizontal bin of a given horizontal position.
Definition SpatialDistribution.h:1104
int verticalBin(const Scalar y) const
Returns the vertical bin of a given vertical position.
Definition SpatialDistribution.h:1110
unsigned int verticalBins() const
Returns the number of vertical distribution bins.
Definition SpatialDistribution.h:1083
unsigned int bins() const
Returns the number of bins this distribution holds.
Definition SpatialDistribution.h:1088
This class implements an occupancy array allowing to keep track of occupied and unoccupied bins in a ...
Definition OccupancyArray.h:32
void removePoints()
Removes all points from the occupancy array.
Definition OccupancyArray.h:217
OccupancyArray(const Scalar left, const Scalar top, const unsigned int width, const unsigned int height, const unsigned int horizontalBins, const unsigned int verticalBins, const unsigned int neighborhoodSize=3u, const float minCoverageThreshold=0.8f)
Creates a new occupancy array.
void addPoint(const Vector2 &imagePoint)
Adds a new point.
Definition OccupancyArray.h:173
bool addPointIfEmpty(const Vector2 &imagePoint)
Adds a new point only if the neighborhood around the bin is empty (not yet occupied).
Definition OccupancyArray.h:184
bool addPointIfWithinLimit(const Vector2 &imagePoint, const unsigned int maxPoints)
Adds a new point only if the neighborhood will not exceed the specified number of points after adding...
Definition OccupancyArray.h:195
Indices32 bins_
The vector holding occupancy counters for all bins.
Definition OccupancyArray.h:161
OccupancyArray()=default
Default constructor to create an invalid array.
unsigned int height() const
Returns the height of the distribution area.
Definition OccupancyArray.h:239
float coverage() const
Returns the fraction of bins that are occupied, normalized by neighborhood size.
Definition OccupancyArray.h:244
float coverageThreshold_
The coverage threshold to determine if more points are needed.
Definition OccupancyArray.h:167
bool isEmpty(const Vector2 &imagePoint) const
Returns whether the neighborhood around the given image point is empty (not yet occupied).
Definition OccupancyArray.h:206
bool addPointIfWithinLimit(const unsigned int xBin, const unsigned int yBin, const unsigned int maxPoints)
Adds a new point only if the neighborhood will not exceed the specified number of points after adding...
size_t numberPoints_
The number of points added to the occupancy array.
Definition OccupancyArray.h:164
unsigned int width() const
Returns the width of the distribution area.
Definition OccupancyArray.h:234
bool needMorePoints() const
Returns whether more points are needed to ensure a good distribution of the points in the image.
Definition OccupancyArray.h:224
void addPoint(const unsigned int xBin, const unsigned int yBin)
Adds a new point.
bool addPointIfEmpty(const unsigned int xBin, const unsigned int yBin)
Adds a new point only if the neighborhood around the bin is empty (not yet occupied).
bool isValid() const
Returns whether this array is valid.
Definition OccupancyArray.h:229
unsigned int neighborhoodRadius_
The neighborhood radius (offset from center bin), e.g., 1 for 3x3 neighborhood, 2 for 5x5,...
Definition OccupancyArray.h:170
bool isEmpty(const unsigned int xBin, const unsigned int yBin) const
Returns whether the neighborhood around the given bin is empty (not yet occupied).
const T & x() const noexcept
Returns the x value.
Definition Vector2.h:710
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:722
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition Base.h:96
float Scalar
Definition of a scalar type.
Definition Math.h:129
The namespace covering the entire Ocean framework.
Definition Accessor.h:15