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 {};
31template <
typename Container,
typename =
void>
32struct has_clear_ : std::false_type {};
33template <
typename Container>
34struct has_clear_<Container, std::void_t<decltype(std::declval<Container &>().clear())>> : std::true_type {};
48template <
typename Container>
50 static_assert(has_push_back_<Container>::value || has_push_<Container>::value,
"ev::Grid_: the container must offer push_back() or push().");
54 using T =
typename EventType::value_type;
62 template <
typename... Args>
63 explicit Grid_(
const cv::Size sensor,
const cv::Size cells, Args &&...args) : sensor_{sensor}, shape_{cells}, prototype_(std::forward<Args>(args)...) {
64 if(sensor.width <= 0 || sensor.height <= 0) {
65 CV_Error(cv::Error::StsBadArg,
"ev::Grid_: the sensor size must be positive.");
67 if(cells.width <= 0 || cells.height <= 0 || cells.width > sensor.width || cells.height > sensor.height) {
68 CV_Error(cv::Error::StsBadArg,
"ev::Grid_: the number of cells must be positive and not exceed the sensor size.");
70 cell_ = cv::Size((sensor.width + cells.width - 1) / cells.width, (sensor.height + cells.height - 1) / cells.height);
71 cells_.assign(
static_cast<std::size_t
>(cells.width) *
static_cast<std::size_t
>(cells.height), prototype_);
80 const cv::Point c =
cell(e);
84 push_(cells_[index_(c)], e);
96 if constexpr(std::is_floating_point_v<T>) {
100 x =
static_cast<int>(e.x);
101 y =
static_cast<int>(e.y);
103 if(x < 0 || y < 0 || x >= sensor_.width || y >= sensor_.height) {
106 return {x / cell_.width, y / cell_.height};
115 [[nodiscard]]
inline Container &
operator()(
const int row,
const int col) {
116 return cells_[index_({col, row})];
125 [[nodiscard]]
inline const Container &
operator()(
const int row,
const int col)
const {
126 return cells_[index_({col, row})];
134 [[nodiscard]]
inline Container &
operator()(
const cv::Point c) {
135 return cells_[index_(c)];
143 [[nodiscard]]
inline const Container &
operator()(
const cv::Point c)
const {
144 return cells_[index_(c)];
151 if constexpr(has_clear_<Container>::value) {
152 for(Container &
cell : cells_) {
156 cells_.assign(cells_.size(), prototype_);
164 [[nodiscard]]
inline int rows()
const {
165 return shape_.height;
172 [[nodiscard]]
inline int cols()
const {
180 [[nodiscard]]
inline cv::Size
size()
const {
201 [[nodiscard]]
inline auto begin() {
202 return cells_.begin();
205 [[nodiscard]]
inline auto end() {
209 [[nodiscard]]
inline auto begin()
const {
210 return cells_.begin();
213 [[nodiscard]]
inline auto end()
const {
222 Container prototype_;
223 std::vector<Container> cells_;
225 [[nodiscard]]
inline std::size_t index_(
const cv::Point c)
const {
226 return (
static_cast<std::size_t
>(c.y) *
static_cast<std::size_t
>(shape_.width)) +
static_cast<std::size_t
>(c.x);
229 static inline void push_(Container &container,
const EventType &e) {
230 if constexpr(has_push_<Container>::value) {
233 container.push_back(e);
const Container & operator()(const int row, const int col) const
Access a cell.
Definition grid.hpp:125
cv::Point cell(const EventType &e) const
Cell an event falls into.
Definition grid.hpp:93
bool insert(const EventType &e)
Insert an event into the cell its coordinates fall into.
Definition grid.hpp:79
cv::Size cellSize() const
Size of each cell in pixels.
Definition grid.hpp:188
cv::Size sensorSize() const
Size of the sensor in pixels.
Definition grid.hpp:196
Container & operator()(const int row, const int col)
Access a cell.
Definition grid.hpp:115
Grid_(const cv::Size sensor, const cv::Size cells, Args &&...args)
Construct a grid of cells covering the sensor.
Definition grid.hpp:63
typename Container::value_type EventType
Definition grid.hpp:53
void clear()
Empty every cell.
Definition grid.hpp:150
const Container & operator()(const cv::Point c) const
Access a cell.
Definition grid.hpp:143
typename EventType::value_type T
Definition grid.hpp:54
cv::Size size() const
Number of cells: width columns and height rows.
Definition grid.hpp:180
int rows() const
Number of rows of the grid.
Definition grid.hpp:164
Container & operator()(const cv::Point c)
Access a cell.
Definition grid.hpp:134
int cols() const
Number of columns of the grid.
Definition grid.hpp:172
Basic event-based vision structures based on OpenCV components.