8#ifndef META_OCEAN_GEOMETRY_SPATIAL_DISTRIBUTION_H
9#define META_OCEAN_GEOMETRY_SPATIAL_DISTRIBUTION_H
36 class OCEAN_GEOMETRY_EXPORT
Array
44 inline Scalar left()
const;
56 inline Scalar width()
const;
62 inline Scalar height()
const;
68 inline unsigned int horizontalBins()
const;
74 inline unsigned int verticalBins()
const;
80 inline unsigned int bins()
const;
89 inline unsigned int index(
const Scalar x,
const Scalar y)
const;
98 inline int horizontalBin(
const Scalar x)
const;
107 inline int verticalBin(
const Scalar y)
const;
116 inline int clampedHorizontalBin(
const Scalar x)
const;
125 inline int clampedVerticalBin(
const Scalar y)
const;
135 template <
unsigned int tRadius>
136 inline unsigned int beginBinHorizontal(
const unsigned int centerBinX)
const;
146 template <
unsigned int tRadius>
147 inline unsigned int endBinHorizontal(
const unsigned int centerBinX)
const;
157 template <
unsigned int tRadius>
158 inline unsigned int beginBinVertical(
const unsigned int centerBinY)
const;
168 template <
unsigned int tRadius>
169 inline unsigned int endBinVertical(
const unsigned int centerBinY)
const;
175 inline bool isValid()
const;
182 inline bool operator==(
const Array& right)
const;
189 inline bool operator!=(
const Array& right)
const;
195 explicit inline operator bool()
const;
225 inline Array(
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int horizontalBins,
const unsigned int verticalBins);
239 inline Array& operator=(
Array&&
object)
noexcept;
256 unsigned int horizontalBins_ = 0u;
259 unsigned int verticalBins_ = 0u;
335 inline bool hasCopiedNeighborhood8()
const;
348 inline const Indices32& operator()(
const unsigned int horizontal,
const unsigned int vertical)
const;
356 inline Indices32& operator()(
const unsigned int horizontal,
const unsigned int vertical);
364 inline const Indices32& operator[](
const unsigned int index)
const;
372 inline Indices32& operator[](
const unsigned int index);
407 bool hasCopiedNeighborhood8_ =
false;
441 inline OccupancyArray(
const Box2& boundingBox,
const unsigned int horizontalBins,
const unsigned int verticalBins,
const bool allFree =
true);
453 inline OccupancyArray(
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int horizontalBins,
const unsigned int verticalBins,
const bool allFree =
true);
461 inline bool isOccupiedNeighborhood9(
const unsigned int horizontal,
const unsigned int vertical)
const;
468 inline bool isOccupiedNeighborhood9(
const Vector2& point)
const;
476 inline bool isNotOccupiedNeighborhood9(
const unsigned int horizontal,
const unsigned int vertical)
const;
483 inline bool isNotOccupiedNeighborhood9(
const Vector2& point)
const;
491 inline unsigned int countOccupiedNeighborhood9(
const unsigned int horizontal,
const unsigned int vertical)
const;
497 inline unsigned int occupiedBins()
const;
503 inline unsigned int freeBins()
const;
511 inline bool addPoint(
const Vector2& point);
522 inline bool addPointWithCounter(
const Vector2& point,
const unsigned int maximalOccupancyCounter);
531 inline bool removePoint(
const Vector2& point);
559 inline bool operator()(
const unsigned int horizontal,
const unsigned int vertical)
const;
566 inline bool operator()(
const Vector2& point)
const;
574 inline unsigned int& operator()(
const unsigned int horizontal,
const unsigned int vertical);
581 inline bool operator[](
const unsigned int index)
const;
588 inline unsigned int& operator[](
const unsigned int index);
609 inline bool operator==(
const OccupancyArray& occupancyArray)
const;
616 inline bool operator!=(
const OccupancyArray& occupancyArray)
const;
637 inline DistanceElement(
const unsigned int index,
const unsigned int candidateIndex,
const Scalar distance);
643 inline unsigned int index()
const;
649 inline unsigned int candidateIndex()
const;
655 inline Scalar distance()
const;
682 unsigned int index_ = 0u;
685 unsigned int candidateIndex_ = 0u;
709 static void idealBins(
const unsigned int width,
const unsigned int height,
const size_t numberBins,
unsigned int& horizontalBins,
unsigned int& verticalBins,
const unsigned int minimalHorizontalBins = 2u,
const unsigned int minimalVerticalBins = 2u);
724 static void idealBinsNeighborhood9(
const unsigned int width,
const unsigned int height,
const Scalar distance,
unsigned int& horizontalBins,
unsigned int& verticalBins,
const unsigned int minimalHorizontalBins = 2u,
const unsigned int minimalVerticalBins = 2u,
const unsigned int maximalHorizontalBins = 20u,
const unsigned int maximalVerticalBins = 20u);
744 static inline DistributionArray distributeToArray(
const Vector2* imagePoints,
const size_t number,
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int averagePointsPerBin,
const unsigned int maxHorizontalBins,
const unsigned int maxVerticalBins,
unsigned int& horizontalBins,
unsigned int& verticalBins);
776 template <
typename T, const Vector2& (*tFunction)(const T&)>
777 static DistributionArray distributeToArray(
const T* elements,
const size_t number,
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int horizontalBins,
const unsigned int verticalBins);
793 template <
unsigned int tMaximalBins>
836 static void filterCandidatePoint(
const Vector2* imagePoints,
const size_t numberImagePoints,
const Vector2* candidatePoints,
const size_t numberCandidatePoints,
const unsigned int width,
const unsigned int height,
const Scalar filterDistance,
const unsigned int filterSize,
Indices32* filteredIndices =
nullptr,
Vectors2* filteredCandidates =
nullptr);
900 static void determineMinimalSqrDistances(
const Vector2* imagePoints,
const size_t numberImagePoints,
const Vector2* candidates,
const size_t numberCandidates,
const unsigned int width,
const unsigned int height,
const unsigned int bins,
Scalar* sqrDistances);
928 static void determineMinimalSqrDistances(
const Vector2* imagePoints,
const size_t numberImagePoints,
const unsigned int* interestIndices,
const size_t numberInterestIndices,
const unsigned int width,
const unsigned int height,
const unsigned int bins,
Scalar* sqrDistances);
965 static inline Vectors2 distributeAndFilter(
const Vector2* imagePoints,
const size_t numberImagePoints,
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int horizontalBins,
const unsigned int verticalBins);
996 template <
typename TIndex>
997 static inline std::vector<TIndex> distributeAndFilterIndices(
const Vector2* imagePoints,
const size_t numberImagePoints,
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int horizontalBins,
const unsigned int verticalBins);
1013 template <
typename T, Vector2 (*tFunction)(const T&)>
1014 static std::vector<T> distributeAndFilter(
const T* elements,
const size_t numberElements,
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int horizontalBins,
const unsigned int verticalBins);
1035 template <
typename T, Vector2 (*tFunction)(const T&)>
1036 static std::vector<T> distributeAndFilter(
const T* elements,
const size_t numberElements,
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int horizontalBins,
const unsigned int verticalBins,
const size_t numberDesiredFilteredElements,
Indices32 *indices =
nullptr);
1054 template <
typename T,
typename TIndex, Vector2 (*tFunction)(const T&)>
1055 static std::vector<TIndex> distributeAndFilterIndices(
const T* elements,
const size_t numberElements,
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int horizontalBins,
const unsigned int verticalBins);
1065 template <
typename T>
1066 static inline T identity(
const T& value);
1070 areaLeft_(
object.areaLeft_),
1071 areaTop_(
object.areaTop_),
1072 areaWidth_(
object.areaWidth_),
1073 areaHeight_(
object.areaHeight_),
1074 horizontalBins_(
object.horizontalBins_),
1075 verticalBins_(
object.verticalBins_),
1076 horizontalPoint2Bin_(
object.horizontalPoint2Bin_),
1077 verticalPoint2Bin_(
object.verticalPoint2Bin_)
1079 object.areaLeft_ =
Scalar(0);
1080 object.areaTop_ =
Scalar(0);
1081 object.areaWidth_ =
Scalar(0);
1082 object.areaHeight_ =
Scalar(0);
1083 object.horizontalBins_ = 0u;
1084 object.verticalBins_ = 0u;
1085 object.horizontalPoint2Bin_ =
Scalar(0);
1086 object.verticalPoint2Bin_ =
Scalar(0);
1093 areaHeight_(height),
1094 horizontalBins_(horizontalBins),
1095 verticalBins_(verticalBins),
1124 return horizontalBins_;
1129 return verticalBins_;
1134 return horizontalBins_ * verticalBins_;
1139 const int xBin = horizontalBin(x);
1140 const int yBin = verticalBin(y);
1142 ocean_assert(xBin >= 0 && xBin <
int(horizontalBins_));
1143 ocean_assert(yBin >= 0 && yBin <
int(verticalBins_));
1145 return yBin * horizontalBins_ + xBin;
1151 return int(
Numeric::floor((x - areaLeft_) * horizontalPoint2Bin_));
1162 ocean_assert(isValid());
1163 return minmax<int>(0, horizontalBin(x), horizontalBins_ - 1);
1168 ocean_assert(isValid());
1169 return minmax<int>(0, verticalBin(y), verticalBins_ - 1);
1172template <
unsigned int tRadius>
1175 static_assert(tRadius >= 1u,
"Invalid radius");
1177 ocean_assert(centerBinX < horizontalBins_);
1179 return centerBinX >= tRadius ? centerBinX - tRadius : 0u;
1182template <
unsigned int tRadius>
1185 static_assert(tRadius >= 1u,
"Invalid radius");
1187 ocean_assert(centerBinX < horizontalBins_);
1189 return std::min(centerBinX + tRadius + 1u, horizontalBins_);
1192template <
unsigned int tRadius>
1195 static_assert(tRadius >= 1u,
"Invalid radius");
1197 ocean_assert(centerBinY < verticalBins_);
1199 return centerBinY >= tRadius ? centerBinY - tRadius : 0u;
1202template <
unsigned int tRadius>
1205 static_assert(tRadius >= 1u,
"Invalid radius");
1207 ocean_assert(centerBinY < verticalBins_);
1209 return std::min(centerBinY + tRadius + 1u, verticalBins_);
1214 return horizontalBins_ != 0u && verticalBins_ != 0u;
1231 return !(*
this == right);
1234inline SpatialDistribution::Array::operator bool()
const
1241 if (
this != &
object)
1244 areaTop_ =
object.areaTop_;
1245 areaWidth_ =
object.areaWidth_;
1246 areaHeight_ =
object.areaHeight_;
1247 horizontalBins_ =
object.horizontalBins_;
1248 verticalBins_ =
object.verticalBins_;
1249 horizontalPoint2Bin_ =
object.horizontalPoint2Bin_;
1250 verticalPoint2Bin_ =
object.verticalPoint2Bin_;
1258 if (
this != &
object)
1261 areaTop_ =
object.areaTop_;
1262 areaWidth_ =
object.areaWidth_;
1263 areaHeight_ =
object.areaHeight_;
1264 horizontalBins_ =
object.horizontalBins_;
1265 verticalBins_ =
object.verticalBins_;
1266 horizontalPoint2Bin_ =
object.horizontalPoint2Bin_;
1267 verticalPoint2Bin_ =
object.verticalPoint2Bin_;
1269 object.areaLeft_ =
Scalar(0);
1270 object.areaTop_ =
Scalar(0);
1271 object.areaWidth_ =
Scalar(0);
1272 object.areaHeight_ =
Scalar(0);
1273 object.horizontalBins_ = 0u;
1274 object.verticalBins_ = 0u;
1275 object.horizontalPoint2Bin_ =
Scalar(0);
1276 object.verticalPoint2Bin_ =
Scalar(0);
1284 indexGroups_(std::move(
object.indexGroups_)),
1285 hasCopiedNeighborhood8_(
object.hasCopiedNeighborhood8_)
1291 Array(left, top, width, height, horizontalBins, verticalBins),
1292 indexGroups_(horizontalBins * verticalBins),
1293 hasCopiedNeighborhood8_(false)
1300 return hasCopiedNeighborhood8_;
1305 ocean_assert(horizontal < horizontalBins_);
1306 ocean_assert(vertical < verticalBins_);
1308 return indexGroups_[vertical * horizontalBins_ + horizontal];
1313 ocean_assert(horizontal < horizontalBins_);
1314 ocean_assert(vertical < verticalBins_);
1316 return indexGroups_[vertical * horizontalBins_ + horizontal];
1321 ocean_assert(index < horizontalBins_ * verticalBins_);
1322 return indexGroups_[index];
1327 ocean_assert(index < horizontalBins_ * verticalBins_);
1328 return indexGroups_[index];
1334 indexGroups_ =
object.indexGroups_;
1335 hasCopiedNeighborhood8_ =
object.hasCopiedNeighborhood8_;
1342 if (
this != &
object)
1345 indexGroups_ = std::move(
object.indexGroups_);
1346 hasCopiedNeighborhood8_ =
object.hasCopiedNeighborhood8_;
1348 object.hasCopiedNeighborhood8_ =
false;
1356 if (!Array::operator==(distributionArray))
1366 return !(*
this == distributionArray);
1371 occupancy_(std::move(
object.occupancy_))
1377 Array(boundingBox.left(), boundingBox.top(), boundingBox.width(), boundingBox.height(), horizontalBins, verticalBins),
1378 occupancy_(horizontalBins * verticalBins, allFree ? 0u : 1u)
1384 Array(left, top, width, height, horizontalBins, verticalBins),
1385 occupancy_(horizontalBins * verticalBins, allFree ? 0u : 1u)
1392 ocean_assert(horizontal < horizontalBins_);
1393 ocean_assert(vertical < verticalBins_);
1395 unsigned int number = 0u;
1397 for (
unsigned int y = max(0,
int(vertical) - 1); y < min(vertical + 2u, verticalBins_); ++y)
1399 for (
unsigned int x = max(0,
int(horizontal) - 1); x < min(horizontal + 2u, horizontalBins_); ++x)
1413 ocean_assert(horizontal < horizontalBins_);
1414 ocean_assert(vertical < verticalBins_);
1416 for (
unsigned int y = max(0,
int(vertical) - 1); y < min(vertical + 2u, verticalBins_); ++y)
1418 for (
unsigned int x = max(0,
int(horizontal) - 1); x < min(horizontal + 2u, horizontalBins_); ++x)
1432 const unsigned int horizontal = horizontalBin(point.
x());
1433 const unsigned int vertical = verticalBin(point.
y());
1435 if (horizontal < horizontalBins_ && vertical < verticalBins_)
1437 for (
unsigned int y = max(0,
int(vertical) - 1); y < min(vertical + 2u, verticalBins_); ++y)
1439 for (
unsigned int x = max(0,
int(horizontal) - 1); x < min(horizontal + 2u, horizontalBins_); ++x)
1454 ocean_assert(horizontal < horizontalBins_);
1455 ocean_assert(vertical < verticalBins_);
1457 for (
unsigned int y = max(0,
int(vertical) - 1); y < min(vertical + 2u, verticalBins_); ++y)
1459 for (
unsigned int x = max(0,
int(horizontal) - 1); x < min(horizontal + 2u, horizontalBins_); ++x)
1473 const unsigned int horizontal = horizontalBin(point.
x());
1474 const unsigned int vertical = verticalBin(point.
y());
1476 if (horizontal < horizontalBins_ && vertical < verticalBins_)
1478 for (
unsigned int y = max(0,
int(vertical) - 1); y < min(vertical + 2u, verticalBins_); ++y)
1480 for (
unsigned int x = max(0,
int(horizontal) - 1); x < min(horizontal + 2u, horizontalBins_); ++x)
1495 unsigned int count = 0u;
1497 for (
const Index32& bin : occupancy_)
1510 unsigned int count = 0u;
1512 for (
const Index32& bin : occupancy_)
1525 const unsigned int horizontal = (
unsigned int)(horizontalBin(point.
x()));
1526 const unsigned int vertical = (
unsigned int)(verticalBin(point.
y()));
1528 if (horizontal < horizontalBins_ && vertical < verticalBins_)
1530 const unsigned int index = vertical * horizontalBins_ + horizontal;
1532 if (!occupancy_[index])
1534 occupancy_[index] = 1u;
1544 const unsigned int horizontal = (
unsigned int)(horizontalBin(point.
x()));
1545 const unsigned int vertical = (
unsigned int)(verticalBin(point.
y()));
1547 if (horizontal < horizontalBins_ && vertical < verticalBins_)
1549 const unsigned int index = vertical * horizontalBins_ + horizontal;
1551 if (occupancy_[index] <= maximalOccupancyCounter)
1553 occupancy_[index]++;
1563 const unsigned int horizontal = (
unsigned int)(horizontalBin(point.
x()));
1564 const unsigned int vertical = (
unsigned int)(verticalBin(point.
y()));
1566 if (horizontal < horizontalBins_ && vertical < verticalBins_)
1568 const unsigned int index = vertical * horizontalBins_ + horizontal;
1570 if (occupancy_[index])
1572 occupancy_[index] = 0u;
1582 std::fill(occupancy_.begin(), occupancy_.end(), 0u);
1587 const unsigned int horizontal = (
unsigned int)(horizontalBin(point.
x()));
1588 const unsigned int vertical = (
unsigned int)(verticalBin(point.
y()));
1590 if (horizontal < horizontalBins_ && vertical < verticalBins_)
1592 occupancy_[vertical * horizontalBins_ + horizontal] = 1u;
1600 const unsigned int horizontal = (
unsigned int)(horizontalBin(point.
x()));
1601 const unsigned int vertical = (
unsigned int)(verticalBin(point.
y()));
1603 if (horizontal < horizontalBins_ && vertical < verticalBins_)
1605 occupancy_[vertical * horizontalBins_ + horizontal] = 0u;
1613 ocean_assert(horizontal < horizontalBins_);
1614 ocean_assert(vertical < verticalBins_);
1616 return occupancy_[vertical * horizontalBins_ + horizontal] != 0u;
1621 ocean_assert(horizontal < horizontalBins_);
1622 ocean_assert(vertical < verticalBins_);
1624 return occupancy_[vertical * horizontalBins_ + horizontal];
1629 const unsigned int xBin = horizontalBin(point.
x());
1630 const unsigned int yBin = verticalBin(point.
y());
1632 return xBin < horizontalBins_ && yBin < verticalBins_ && occupancy_[yBin * horizontalBins_ + xBin] != 0u;
1637 ocean_assert(index < horizontalBins_ * verticalBins_);
1638 return occupancy_[index] != 0u;
1643 ocean_assert(index < horizontalBins_ * verticalBins_);
1644 return occupancy_[index];
1650 occupancy_ =
object.occupancy_;
1657 if (
this != &
object)
1660 occupancy_ = std::move(
object.occupancy_);
1668 if (!Array::operator==(occupancyArray))
1673 return occupancy_ == occupancyArray.
occupancy_;
1678 return !(*
this == occupancyArray);
1683 candidateIndex_(candidateIndex),
1696 return candidateIndex_;
1721template <
unsigned int tMaximalBins>
1724 static_assert(tMaximalBins > 0u,
"Invalid maximal bin parameter!");
1726 const unsigned int horizontalBins = min(tMaximalBins, (
unsigned int)
Numeric::ceil(width / max(searchDistance,
Scalar(2))));
1727 const unsigned int verticalBins = min(tMaximalBins, (
unsigned int)
Numeric::ceil(height / max(searchDistance,
Scalar(2))));
1729 return distributeToArray(imagePoints, number, left, top, width, height, horizontalBins, verticalBins);
1732template <
typename T, const Vector2& (*tFunction)(const T&)>
1735 ocean_assert(elements);
1736 ocean_assert(width > 0 && height > 0);
1738 ocean_assert(horizontalBins > 0);
1739 ocean_assert(verticalBins > 0);
1741 ocean_assert(
Scalar(horizontalBins) <= width);
1742 ocean_assert(
Scalar(verticalBins) <= height);
1745 DistributionArray indexArray(left, top, width, height, horizontalBins, verticalBins);
1747 for (
size_t n = 0; n < number; ++n)
1749 const Vector2& point = tFunction(*elements);
1751 const unsigned int horizontal = (
unsigned int)(indexArray.
horizontalBin(point.
x()));
1752 const unsigned int vertical = (
unsigned int)(indexArray.
verticalBin(point.
y()));
1757 indexArray(horizontal, vertical).push_back((
unsigned int)n);
1766inline SpatialDistribution::DistributionArray SpatialDistribution::distributeToArray(
const Vector2* imagePoints,
const size_t number,
const Scalar left,
const Scalar top,
const Scalar width,
const Scalar height,
const unsigned int averagePointsPerBin,
const unsigned int maxHorizontalBins,
const unsigned int maxVerticalBins,
unsigned int& horizontalBins,
unsigned int& verticalBins)
1768 ocean_assert(imagePoints || number == 0);
1770 ocean_assert(width > 0 && height > 0);
1771 ocean_assert(averagePointsPerBin > 0);
1773 ocean_assert(maxHorizontalBins >= 1u);
1774 ocean_assert(maxVerticalBins >= 1u);
1778 return DistributionArray(left, top, width, height, horizontalBins, verticalBins);
1788 horizontalBins = min(maxHorizontalBins, max(1u, (
unsigned int)(
Numeric::sqrt(
sqr))));
1789 verticalBins = min(maxVerticalBins, max(1u, (
unsigned int)(
Scalar(horizontalBins) * height / width)));
1791 return distributeToArray(imagePoints, number, left, top, width, height, horizontalBins, verticalBins);
1796 return distributeAndFilter<Vector2, &SpatialDistribution::identity>(imagePoints, numberImagePoints, left, top, width, height, horizontalBins, verticalBins);
1799template <
typename TIndex>
1802 return distributeAndFilterIndices<Vector2, TIndex, &SpatialDistribution::identity>(imagePoints, numberImagePoints, left, top, width, height, horizontalBins, verticalBins);
1805template <
typename T, Vector2 (*tFunction)(const T&)>
1808 ocean_assert(elements || numberElements == 0);
1809 ocean_assert(width >= 0 && height >= 0);
1810 ocean_assert(horizontalBins >= 1u && verticalBins >= 1u);
1812 if (numberElements == 0)
1814 return std::vector<T>();
1817 OccupancyArray occupancyArray(left, top, width, height, horizontalBins, verticalBins);
1819 const size_t bins = occupancyArray.
bins();
1821 std::vector<T> result;
1822 result.reserve(bins);
1824 for (
size_t n = 0; n < numberElements && result.size() < bins; ++n)
1826 if (occupancyArray.
addPoint(tFunction(elements[n])))
1828 result.push_back(elements[n]);
1835template <
typename T, Vector2 (*tFunction)(const T&)>
1838 ocean_assert(elements !=
nullptr || numberElements == 0);
1839 ocean_assert(width >= 0 && height >= 0);
1840 ocean_assert(horizontalBins >= 1u && verticalBins >= 1u);
1841 ocean_assert(numberDesiredFilteredElements <= numberElements);
1843 if (numberElements == 0 || numberDesiredFilteredElements == 0)
1845 return std::vector<T>();
1848 OccupancyArray occupancyArray(left, top, width, height, horizontalBins, verticalBins);
1850 std::vector<unsigned char> usedElements(numberElements, 0u);
1852 const size_t bins = occupancyArray.
bins();
1854 std::vector<T> result;
1855 result.reserve(bins);
1857 unsigned int filterIteration = 0u;
1859 while (result.size() < numberDesiredFilteredElements && filterIteration < (
unsigned int)numberDesiredFilteredElements)
1861 for (
size_t n = 0; n < numberElements && result.size() < numberDesiredFilteredElements; ++n)
1863 if (usedElements[n] == 0u && occupancyArray.
addPointWithCounter(tFunction(elements[n]), filterIteration))
1865 result.push_back(elements[n]);
1866 usedElements[n] = 1u;
1875 for (
size_t n = 0; n < numberElements; ++n)
1879 indices->push_back(
Index32(n));
1887template <
typename T,
typename TIndex, Vector2 (*tFunction)(const T&)>
1890 ocean_assert(elements || numberElements == 0);
1891 ocean_assert(width >= 0 && height >= 0);
1892 ocean_assert(horizontalBins >= 1u && verticalBins >= 1u);
1894 if (numberElements == 0)
1896 return std::vector<TIndex>();
1901 OccupancyArray occupancyArray(left, top, width, height, horizontalBins, verticalBins);
1903 const size_t bins = occupancyArray.
bins();
1905 std::vector<TIndex> result;
1906 result.reserve(bins);
1908 for (
size_t n = 0; n < numberElements && result.size() < bins; ++n)
1910 if (occupancyArray.
addPoint(tFunction(elements[n])))
1912 result.push_back(TIndex(n));
1919template <
typename T>
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:1122
Scalar width() const
Returns the width of the distribution area.
Definition SpatialDistribution.h:1112
int horizontalBin(const Scalar x) const
Returns the horizontal bin of a given horizontal position.
Definition SpatialDistribution.h:1148
int verticalBin(const Scalar y) const
Returns the vertical bin of a given vertical position.
Definition SpatialDistribution.h:1154
Scalar horizontalPoint2Bin_
Horizontal position to bin factor.
Definition SpatialDistribution.h:262
unsigned int endBinHorizontal(const unsigned int centerBinX) const
Returns the (exclusive) end bin in horizontal direction for a neighborhood search.
Definition SpatialDistribution.h:1183
Array & operator=(const Array &object)
Assign operator.
Definition SpatialDistribution.h:1239
Scalar areaTop_
Top position of the distribution area.
Definition SpatialDistribution.h:247
Scalar top() const
Returns the top position of the distribution area.
Definition SpatialDistribution.h:1107
unsigned int verticalBins() const
Returns the number of vertical distribution bins.
Definition SpatialDistribution.h:1127
unsigned int beginBinHorizontal(const unsigned int centerBinX) const
Returns the (inclusive) begin bin in horizontal direction for a neighborhood search.
Definition SpatialDistribution.h:1173
int clampedVerticalBin(const Scalar y) const
Returns the vertical bin of a given vertical position.
Definition SpatialDistribution.h:1166
Scalar areaLeft_
Left position of the distribution area.
Definition SpatialDistribution.h:244
Scalar areaHeight_
Height of the distribution area.
Definition SpatialDistribution.h:253
Array()=default
Creates an empty array object.
int clampedHorizontalBin(const Scalar x) const
Returns the horizontal bin of a given horizontal position.
Definition SpatialDistribution.h:1160
bool isValid() const
Returns whether this object holds a valid distribution.
Definition SpatialDistribution.h:1212
Scalar height() const
Returns the height of the distribution area.
Definition SpatialDistribution.h:1117
Scalar verticalPoint2Bin_
Vertical position to bin factor.
Definition SpatialDistribution.h:265
bool operator==(const Array &right) const
Returns whether two Array objects are identical.
Definition SpatialDistribution.h:1217
unsigned int beginBinVertical(const unsigned int centerBinY) const
Returns the (inclusive) begin bin in vertical direction for a neighborhood search.
Definition SpatialDistribution.h:1193
bool operator!=(const Array &right) const
Returns whether two Array objects are not identical.
Definition SpatialDistribution.h:1229
Scalar areaWidth_
Width of the distribution area.
Definition SpatialDistribution.h:250
unsigned int verticalBins_
Number of vertical distribution bins.
Definition SpatialDistribution.h:259
Array(const Array &object)=default
Copy constructor.
unsigned int endBinVertical(const unsigned int centerBinY) const
Returns the (exclusive) end bin in vertical direction for a neighborhood search.
Definition SpatialDistribution.h:1203
unsigned int horizontalBins_
Number of horizontal distribution bins.
Definition SpatialDistribution.h:256
Scalar left() const
Returns the left position of the distribution area.
Definition SpatialDistribution.h:1102
unsigned int index(const Scalar x, const Scalar y) const
Returns the bin index for a given position.
Definition SpatialDistribution.h:1137
unsigned int bins() const
Returns the number of bins this distribution holds.
Definition SpatialDistribution.h:1132
Definition of a class holding an index and a distance.
Definition SpatialDistribution.h:628
Scalar distance_
Distance value.
Definition SpatialDistribution.h:688
unsigned int candidateIndex() const
Returns the candidate index of this element.
Definition SpatialDistribution.h:1694
static bool compareLeftSmaller(const DistanceElement &left, const DistanceElement &right)
Compares two distance elements.
Definition SpatialDistribution.h:1704
unsigned int index() const
Returns the interest index of this element.
Definition SpatialDistribution.h:1689
static bool compareLeftHigher(const DistanceElement &left, const DistanceElement &right)
Compares two distance elements.
Definition SpatialDistribution.h:1709
DistanceElement(const unsigned int index, const unsigned int candidateIndex, const Scalar distance)
Creates a new distance element.
Definition SpatialDistribution.h:1681
bool operator<(const DistanceElement &element) const
Returns whether the left element holds a higher distance than the right one.
Definition SpatialDistribution.h:1714
Scalar distance() const
Returns the distance of this element.
Definition SpatialDistribution.h:1699
This class implements a distribution array.
Definition SpatialDistribution.h:272
DistributionArray()=default
Creates an empty distribution array object.
bool hasCopiedNeighborhood8() const
Returns whether this distribution array contains copies of indices within the 8-neighborhood of each ...
Definition SpatialDistribution.h:1298
DistributionArray & operator=(const DistributionArray &object)
Assign operator.
Definition SpatialDistribution.h:1331
bool hasCopiedNeighborhood8_
True, if the array contains copies of indices within the 8-neighborhood of each individual bin; False...
Definition SpatialDistribution.h:407
void clear()
Removes all elements form this array.
DistributionArray(const DistributionArray &object)=default
Copy constructor.
const Indices32 & operator()(const unsigned int horizontal, const unsigned int vertical) const
Returns the distribution indices of a specified bin.
Definition SpatialDistribution.h:1303
IndexGroups32 indexGroups_
Distribution array with point indices.
Definition SpatialDistribution.h:404
const Indices32 & operator[](const unsigned int index) const
Returns the distribution indices of a specified bin.
Definition SpatialDistribution.h:1319
DistributionArray(const DistributionArray &distributionArray, const bool copyNeighborhood8)
Copies a given distribution array and optional copies the indices from the 8-neighborhood of each ind...
bool operator!=(const DistributionArray &distributionArray) const
Returns whether two DistributionArray objects are not identical.
Definition SpatialDistribution.h:1364
bool operator==(const DistributionArray &distributionArray) const
Returns whether two DistributionArray objects are identical.
Definition SpatialDistribution.h:1354
void indicesNeighborhood9(const unsigned int horizontal, const unsigned int vertical, Indices32 &indices) const
Returns the indices of the 8-neighborhood and the specified bin itself.
Indices32 indicesNeighborhood9(const unsigned int horizontal, const unsigned int vertical) const
Returns the indices of the 8-neighborhood and the specified bin itself.
This class implements an occupancy array.
Definition SpatialDistribution.h:414
OccupancyArray & operator+=(const Vector2 &point)
Adds an image point to this occupancy array.
Definition SpatialDistribution.h:1585
bool operator!=(const OccupancyArray &occupancyArray) const
Returns whether two OccupancyArray objects are not identical.
Definition SpatialDistribution.h:1676
unsigned int freeBins() const
Returns the number of free bins.
Definition SpatialDistribution.h:1508
bool isNotOccupiedNeighborhood9(const unsigned int horizontal, const unsigned int vertical) const
Returns whether at least one bin in the 8-neighborhood or the specified bin itself is not occupied.
Definition SpatialDistribution.h:1452
OccupancyArray & operator-=(const Vector2 &point)
Removes an image point from this occupancy array.
Definition SpatialDistribution.h:1598
unsigned int occupiedBins() const
Returns the number of occupied bins.
Definition SpatialDistribution.h:1493
unsigned int countOccupiedNeighborhood9(const unsigned int horizontal, const unsigned int vertical) const
Returns the number of occupied bins in the 9-neighborhood (so the specified bin is included).
Definition SpatialDistribution.h:1390
OccupancyArray()=default
Creates an empty distribution array object.
OccupancyArray & operator=(const OccupancyArray &object)
Assign operator.
Definition SpatialDistribution.h:1647
bool isOccupiedNeighborhood9(const unsigned int horizontal, const unsigned int vertical) const
Returns whether at least one bin in the 8-neighborhood or the specified bin itself is occupied.
Definition SpatialDistribution.h:1411
void reset()
Resets all occupied bins so that all bins a free afterwards.
Definition SpatialDistribution.h:1580
bool removePoint(const Vector2 &point)
Removes an image point and returns whether the corresponding bin was occupied before.
Definition SpatialDistribution.h:1561
bool addPointWithCounter(const Vector2 &point, const unsigned int maximalOccupancyCounter)
Adds an image point and returns whether the occupancy counter of the corresponding bin was equal or b...
Definition SpatialDistribution.h:1542
bool addPoint(const Vector2 &point)
Adds an image point and returns whether the corresponding bin was not occupied before (was free befor...
Definition SpatialDistribution.h:1523
OccupancyArray(const OccupancyArray &object)=default
Copy constructor.
bool operator()(const unsigned int horizontal, const unsigned int vertical) const
Returns whether a specified bin is occupied.
Definition SpatialDistribution.h:1611
bool operator==(const OccupancyArray &occupancyArray) const
Returns whether two OccupancyArray objects are identical.
Definition SpatialDistribution.h:1666
Indices32 occupancy_
Occupancy array.
Definition SpatialDistribution.h:621
bool operator[](const unsigned int index) const
Returns whether a specified bin is occupied.
Definition SpatialDistribution.h:1635
This class implements spatial distribution function for 2D geometric data.
Definition SpatialDistribution.h:30
static Indices32 determineNeighbors(const Vector2 &imagePoint, const Vector2 *candidatePoints, const size_t numberCandidatePoints, const Scalar radius, const DistributionArray &distributionCandidatePoints)
Determines all candidate points for a given image point (interest point) lying inside a specified cir...
static void determineMinimalSqrDistances(const Vector2 *imagePoints, const size_t numberImagePoints, const Vector2 *candidates, const size_t numberCandidates, const DistributionArray &distributionCandidates, Scalar *sqrDistances, unsigned int *candidateIndices=nullptr)
Determines the minimal square distances for each given image point to another given set of image poin...
static Vectors2 distributeAndFilter(const Vector2 *imagePoints, const size_t numberImagePoints, const Scalar left, const Scalar top, const Scalar width, const Scalar height, const unsigned int horizontalBins, const unsigned int verticalBins)
Distributes the given image points into an array of specified size and returns (at most) one point fr...
Definition SpatialDistribution.h:1794
static Vectors2 distributeAndFilter(const Vector2 *imagePoints, const size_t numberImagePoints, const Scalar left, const Scalar top, const Scalar width, const Scalar height, const unsigned int horizontalBins, const unsigned int verticalBins, const size_t size)
Distributes the given image points into an array of specified size and returns as much points as requ...
static std::vector< TIndex > distributeAndFilterIndices(const Vector2 *imagePoints, const size_t numberImagePoints, const Scalar left, const Scalar top, const Scalar width, const Scalar height, const unsigned int horizontalBins, const unsigned int verticalBins)
Distributes the given image points into an array of specified size and returns (at most) one point in...
Definition SpatialDistribution.h:1800
static DistributionArray distributeToArray(const Vector2 *imagePoints, const size_t number, const Scalar left, const Scalar top, const Scalar width, const Scalar height, const unsigned int horizontalBins, const unsigned int verticalBins)
Distributes a set of given 2D image points into a spatial array.
static Scalar determineMinimalSqrDistance(const Vector2 *imagePoints, const size_t numberImagePoints, const unsigned int index, const DistributionArray &distributionImagePoints)
Determines the minimal square distance for one given 2D image point to all other points in the same s...
static void determineMinimalSqrDistances(const Vector2 *imagePoints, const size_t numberImagePoints, const unsigned int width, const unsigned int height, const unsigned int bins, Scalar *sqrDistances)
Determines the minimal square distances for each given 2D image point to all other points in the same...
static void idealBins(const unsigned int width, const unsigned int height, const size_t numberBins, unsigned int &horizontalBins, unsigned int &verticalBins, const unsigned int minimalHorizontalBins=2u, const unsigned int minimalVerticalBins=2u)
Calculates the ideal number of horizontal and vertical bins for an array if the overall number of bin...
std::vector< DistanceElement > DistanceElements
Definition of a vector holding distance elements.
Definition SpatialDistribution.h:694
static Index32 determineNearestNeighbor(const Vector2 &interestPoint, const Vector2 *imagePoints, const size_t numberImagePoints, const Scalar radius, const DistributionArray &distributionImagePoints, Scalar *sqrDistance=nullptr)
Determines the nearest image point between an interest point and a set of given image point lying ins...
static void determineMinimalSqrDistances(const Vector2 *imagePoints, const size_t numberImagePoints, const unsigned int *interestIndices, const size_t numberInterestIndices, const unsigned int width, const unsigned int height, const unsigned int bins, Scalar *sqrDistances)
Determines the minimal square distances for each specified image point inside their neighborhood.
static Indices32 filterAccordingDistance(const Vector2 *imagePoints, const size_t number, const unsigned int width, const unsigned int height, const Scalar distance)
Filters the given 2D image points according to their distance to neighboring image points.
static DistanceElements sortAccordingDistance(const Vector2 *imagePoints, const size_t number, const bool minimalDistanceFirst)
Sorts the given 2D image points according to their minimal distance to neighboring image points.
static DistributionArray distributeToArray(const Vector2 *imagePoints, const size_t number, const Scalar left, const Scalar top, const Scalar width, const Scalar height, const unsigned int averagePointsPerBin, const unsigned int maxHorizontalBins, const unsigned int maxVerticalBins, unsigned int &horizontalBins, unsigned int &verticalBins)
Distributes the given 2D image points into a spatial array.
Definition SpatialDistribution.h:1766
static OccupancyArray createOccupancyArray(const Vector2 *imagePoints, const size_t number, const Scalar left, const Scalar top, const Scalar width, const Scalar height, const unsigned int horizontalBins, const unsigned int verticalBins)
Distributes the given 2D image points into a spatial array.
static DistanceElements sortAccordingDistance(const Vector2 *imagePoints, const size_t number, const unsigned int width, const unsigned int height, const unsigned int bins, const bool minimalDistanceFirst)
Sorts the given 2D image points according to their minimal distance to neighboring image points.
static void idealBinsNeighborhood9(const unsigned int width, const unsigned int height, const Scalar distance, unsigned int &horizontalBins, unsigned int &verticalBins, const unsigned int minimalHorizontalBins=2u, const unsigned int minimalVerticalBins=2u, const unsigned int maximalHorizontalBins=20u, const unsigned int maximalVerticalBins=20u)
Calculates the ideal number of horizontal and vertical bins for an array if bin elements within a cer...
static void determineMinimalSqrDistances(const Vector2 *imagePoints, const size_t numberImagePoints, const Vector2 *candidates, const size_t numberCandidates, const unsigned int width, const unsigned int height, const unsigned int bins, Scalar *sqrDistances)
Determines the minimal square distances for each given 2D image point to another given set of 2D imag...
static T identity(const T &value)
This function simply returns the given object (actually a copy of the object).
Definition SpatialDistribution.h:1920
static void filterCandidatePoint(const Vector2 *imagePoints, const size_t numberImagePoints, const Vector2 *candidatePoints, const size_t numberCandidatePoints, const unsigned int width, const unsigned int height, const Scalar filterDistance, const unsigned int filterSize, Indices32 *filteredIndices=nullptr, Vectors2 *filteredCandidates=nullptr)
Filters the given 2D candidate points according to the distance to the given image points.
This class provides basic numeric functionalities.
Definition Numeric.h:57
static T sqrt(const T value)
Returns the square root of a given value.
Definition Numeric.h:1537
static constexpr T eps()
Returns a small epsilon.
static T floor(const T value)
Returns the largest integer value that is not greater than the given value.
Definition Numeric.h:2035
static T ceil(const T value)
Returns the smallest integer value that is not less than the given value.
Definition Numeric.h:1997
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
std::vector< Indices32 > IndexGroups32
Definition of a vector holding 32 bit indices, so we have groups of indices.
Definition Base.h:102
uint32_t Index32
Definition of a 32 bit index value.
Definition Base.h:84
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition base/Utilities.h:1099
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
float Scalar
Definition of a scalar type.
Definition Math.h:129
The namespace covering the entire Ocean framework.
Definition Accessor.h:15