6#ifndef OPENEV_CONTAINERS_GRID_HPP
7#define OPENEV_CONTAINERS_GRID_HPP
11#include <opencv2/core/base.hpp>
12#include <opencv2/core/types.hpp>
18[[maybe_unused]]
constexpr bool USING_GRID_HPP =
true;
21template <
typename Container,
typename =
void>
22struct has_push_back_ : std::false_type {};
23template <
typename Container>
24struct has_push_back_<Container, std::void_t<decltype(std::declval<Container &>().push_back(std::declval<const typename Container::value_type &>()))>> : std::true_type {};
26template <
typename Container,
typename =
void>
27struct has_push_ : std::false_type {};
28template <
typename Container>
29struct has_push_<Container, std::void_t<decltype(std::declval<Container &>().push(std::declval<const typename Container::value_type &>()))>> : std::true_type {};
43template <
typename Container>
45 static_assert(has_push_back_<Container>::value || has_push_<Container>::value,
"ev::Grid_: the container must offer push_back() or push().");
49 using T =
typename EventType::value_type;
57 template <
typename... Args>
58 explicit Grid_(
const cv::Size sensor,
const cv::Size cells, Args &&...args) : sensor_{sensor}, shape_{cells}, prototype_(std::forward<Args>(args)...) {
59 if(sensor.width <= 0 || sensor.height <= 0) {
60 CV_Error(cv::Error::StsBadArg,
"ev::Grid_: the sensor size must be positive.");
62 if(cells.width <= 0 || cells.height <= 0 || cells.width > sensor.width || cells.height > sensor.height) {
63 CV_Error(cv::Error::StsBadArg,
"ev::Grid_: the number of cells must be positive and not exceed the sensor size.");
65 cell_ = cv::Size((sensor.width + cells.width - 1) / cells.width, (sensor.height + cells.height - 1) / cells.height);
66 cells_.assign(
static_cast<std::size_t
>(cells.width) *
static_cast<std::size_t
>(cells.height), prototype_);
75 const cv::Point c =
cell(e);
79 push_(cells_[index_(c)], e);
91 if constexpr(std::is_floating_point_v<T>) {
95 x =
static_cast<int>(e.x);
96 y =
static_cast<int>(e.y);
98 if(x < 0 || y < 0 || x >= sensor_.width || y >= sensor_.height) {
101 return {x / cell_.width, y / cell_.height};
110 [[nodiscard]]
inline Container &
operator()(
const int row,
const int col) {
111 return cells_[index_({col, row})];
120 [[nodiscard]]
inline const Container &
operator()(
const int row,
const int col)
const {
121 return cells_[index_({col, row})];
129 [[nodiscard]]
inline Container &
operator()(
const cv::Point c) {
130 return cells_[index_(c)];
138 [[nodiscard]]
inline const Container &
operator()(
const cv::Point c)
const {
139 return cells_[index_(c)];
146 cells_.assign(cells_.size(), prototype_);
153 [[nodiscard]]
inline int rows()
const {
154 return shape_.height;
161 [[nodiscard]]
inline int cols()
const {
169 [[nodiscard]]
inline cv::Size
size()
const {
190 [[nodiscard]]
inline auto begin() {
191 return cells_.begin();
194 [[nodiscard]]
inline auto end() {
198 [[nodiscard]]
inline auto begin()
const {
199 return cells_.begin();
202 [[nodiscard]]
inline auto end()
const {
211 Container prototype_;
212 std::vector<Container> cells_;
214 [[nodiscard]]
inline std::size_t index_(
const cv::Point c)
const {
215 return (
static_cast<std::size_t
>(c.y) *
static_cast<std::size_t
>(shape_.width)) +
static_cast<std::size_t
>(c.x);
218 static inline void push_(Container &container,
const EventType &e) {
219 if constexpr(has_push_<Container>::value) {
222 container.push_back(e);
const Container & operator()(const int row, const int col) const
Access a cell.
Definition grid.hpp:120
cv::Point cell(const EventType &e) const
Cell an event falls into.
Definition grid.hpp:88
bool insert(const EventType &e)
Insert an event into the cell its coordinates fall into.
Definition grid.hpp:74
cv::Size cellSize() const
Size of each cell in pixels.
Definition grid.hpp:177
cv::Size sensorSize() const
Size of the sensor in pixels.
Definition grid.hpp:185
Container & operator()(const int row, const int col)
Access a cell.
Definition grid.hpp:110
Grid_(const cv::Size sensor, const cv::Size cells, Args &&...args)
Construct a grid of cells covering the sensor.
Definition grid.hpp:58
typename Container::value_type EventType
Definition grid.hpp:48
void clear()
Reset every cell to its freshly constructed state.
Definition grid.hpp:145
const Container & operator()(const cv::Point c) const
Access a cell.
Definition grid.hpp:138
typename EventType::value_type T
Definition grid.hpp:49
cv::Size size() const
Number of cells: width columns and height rows.
Definition grid.hpp:169
int rows() const
Number of rows of the grid.
Definition grid.hpp:153
Container & operator()(const cv::Point c)
Access a cell.
Definition grid.hpp:129
int cols() const
Number of columns of the grid.
Definition grid.hpp:161
Basic event-based vision structures based on OpenCV components.