OpenEV
Extending OpenCV to event-based vision
Loading...
Searching...
No Matches
matrices.hpp
Go to the documentation of this file.
1
6#ifndef OPENEV_CORE_MATRICES_HPP
7#define OPENEV_CORE_MATRICES_HPP
8
10#include <cmath>
11#include <cstring>
12#include <limits>
13#include <opencv2/core/hal/interface.h>
14#include <opencv2/core/mat.hpp>
15#include <opencv2/core/mat.inl.hpp>
16#include <opencv2/core/traits.hpp>
17#include <ostream>
18#include <type_traits>
19
20namespace ev {
21constexpr bool USING_MATRICES_HPP = true;
22
24template <typename T>
25class Event_;
27
28namespace Mat {
29template <typename T>
30class Mat_ : public cv::Mat_<T> {
31 static_assert(std::is_arithmetic_v<T>, "ev::Mat_: the pixel type must be arithmetic.");
32
33public:
34 using cv::Mat_<T>::Mat_;
35
37 Mat_() = default;
38 Mat_(const int rows, const int cols) : cv::Mat_<T>(rows, cols, static_cast<T>(0)) {}
39 explicit Mat_(const cv::Size size) : cv::Mat_<T>(size, static_cast<T>(0)) {}
41
46 void updateStats(const Event &e) {
47 if(count_ == 0) {
48 first_ = e.t;
49 }
50 last_ = e.t;
51 count_++;
52 }
53
58 CounterType count() const {
59 return count_;
60 }
61
66 TimeType duration() const {
67 return last_ - first_;
68 }
69
73 inline void resetStats() {
74 first_ = 0;
75 last_ = 0;
76 count_ = 0;
77 }
78
82 inline void clear() {
83 if(cv::Mat_<T>::empty()) {
84 return;
85 }
86 if(cv::Mat_<T>::isContinuous()) {
87 std::memset(cv::Mat_<T>::data, 0, cv::Mat_<T>::total() * cv::Mat_<T>::elemSize());
88 return;
89 }
90 cv::Mat_<T>::setTo(0);
91 }
92
93private:
94 TimeType first_{0};
95 TimeType last_{0};
96 CounterType count_{0};
97};
98
109template <typename Tb>
110class Binary_ : public Mat_<Tb> {
111 static_assert(std::is_integral_v<Tb>, "ev::Binary_: the pixel type must be integral.");
112
113public:
114 using Mat_<Tb>::Mat_;
115
121 template <typename T>
122 inline Tb insert(const Event_<T> &e) {
123 return set(e.x, e.y);
124 }
125
132 template <typename T>
133 inline Tb emplace(const T x, const T y) {
134 return set(x, y);
135 }
136
137 static constexpr Tb ON = std::numeric_limits<Tb>::max();
138 static constexpr Tb OFF = static_cast<Tb>(0);
139
140 friend std::ostream &operator<<(std::ostream &os, const Binary_ &binary) {
141 os << "Binary " << binary.cols << "x" << binary.rows;
142 return os;
143 }
144
145private:
146 template <typename T>
147 inline Tb set(const T x, const T y) {
148 if constexpr(std::is_floating_point_v<T>) {
149 return *(this->template ptr<Tb>(std::lround(y)) + std::lround(x)) = ON;
150 } else {
151 return *(this->template ptr<Tb>(y) + x) = ON;
152 }
153 }
154};
155using Binary = Binary_<uchar>;
156
168template <typename Tb>
169class Ternary_ : public Mat_<Tb> {
170 static_assert(std::is_integral_v<Tb> && std::is_signed_v<Tb>, "ev::Ternary_: the pixel type must be signed, otherwise NEGATIVE and ZERO are both zero.");
171
172public:
173 using Mat_<Tb>::Mat_;
174
180 template <typename T>
181 inline Tb insert(const Event_<T> &e) {
182 return set(e.x, e.y, e.p);
183 }
184
192 template <typename T>
193 inline Tb emplace(const T x, const T y, const bool p) {
194 return set(x, y, p);
195 }
196
197 static constexpr Tb POSITIVE = std::numeric_limits<Tb>::max();
198 static constexpr Tb ZERO = static_cast<Tb>(0);
199 static constexpr Tb NEGATIVE = std::numeric_limits<Tb>::min();
200
201 friend std::ostream &operator<<(std::ostream &os, const Ternary_ &ternary) {
202 os << "Ternary " << ternary.cols << "x" << ternary.rows;
203 return os;
204 }
205
206private:
207 static constexpr Tb VALUE[2]{NEGATIVE, POSITIVE};
208
209 template <typename T>
210 inline Tb set(const T x, const T y, const bool p) {
211 if constexpr(std::is_floating_point_v<T>) {
212 return *(this->template ptr<Tb>(std::lround(y)) + std::lround(x)) = VALUE[p];
213 } else {
214 return *(this->template ptr<Tb>(y) + x) = VALUE[p];
215 }
216 }
217};
218using Ternary = Ternary_<signed char>;
219
226class Time : public Mat_<TimeType> {
227public:
228 using Mat_<TimeType>::Mat_;
229
235 template <typename T>
236 inline TimeType insert(const Event_<T> &e) {
237 return set(e.x, e.y, e.t);
238 }
239
247 template <typename T>
248 inline TimeType emplace(const T x, const T y, const TimeType t) {
249 return set(x, y, t);
250 }
251
252 friend std::ostream &operator<<(std::ostream &os, const Time &time) {
253 os << "Time " << time.cols << "x" << time.rows;
254 return os;
255 }
256
257private:
258 template <typename T>
259 inline TimeType set(const T x, const T y, const TimeType t) {
260 if constexpr(std::is_floating_point_v<T>) {
261 return *(this->ptr<TimeType>(std::lround(y)) + std::lround(x)) = t;
262 } else {
263 return *(this->ptr<TimeType>(y) + x) = t;
264 }
265 }
266};
267
274class Polarity : public Mat_<PolarityType> {
275public:
276 using Mat_<PolarityType>::Mat_;
277
283 template <typename T>
284 inline PolarityType insert(const Event_<T> &e) {
285 return set(e.x, e.y, e.p);
286 }
287
295 template <typename T>
296 inline PolarityType emplace(const T x, const T y, const PolarityType p) {
297 return set(x, y, p);
298 }
299
300 friend std::ostream &operator<<(std::ostream &os, const Polarity &polarity) {
301 os << "Polarity " << polarity.cols << "x" << polarity.rows;
302 return os;
303 }
304
305private:
306 template <typename T>
307 inline PolarityType set(const T x, const T y, const PolarityType p) {
308 if constexpr(std::is_floating_point_v<T>) {
309 return *(this->ptr<PolarityType>(std::lround(y)) + std::lround(x)) = p;
310 } else {
311 return *(this->ptr<PolarityType>(y) + x) = p;
312 }
313 }
314};
315
322class Counter : public Mat_<CounterType> {
323public:
324 using Mat_<CounterType>::Mat_;
325
331 template <typename T>
332 inline CounterType insert(const Event_<T> &e) {
333 return set(e.x, e.y, e.p);
334 }
335
343 template <typename T>
344 inline CounterType emplace(const T x, const T y, const bool p) {
345 return set(x, y, p);
346 }
347
348 friend std::ostream &operator<<(std::ostream &os, const Counter &counter) {
349 os << "Counter " << counter.cols << "x" << counter.rows;
350 return os;
351 }
352
353private:
354 static constexpr CounterType INCREMENT[2]{-1, +1};
355
356 template <typename T>
357 inline CounterType set(const T x, const T y, const bool p) {
358 if constexpr(std::is_floating_point_v<T>) {
359 return *(this->ptr<CounterType>(std::lround(y)) + std::lround(x)) += INCREMENT[p];
360 } else {
361 return *(this->ptr<CounterType>(y) + x) += INCREMENT[p];
362 }
363 }
364};
365} // namespace Mat
366} // namespace ev
367
368#endif // OPENEV_CORE_MATRICES_HPP
This class extends cv::Point_<T> for event data. For more information, please refer here.
Definition types.hpp:78
PolarityType p
Definition types.hpp:83
TimeType t
Definition types.hpp:82
Spatial map marking whether any event has occurred at each pixel.
Definition matrices.hpp:110
Tb insert(const Event_< T > &e)
Insert an event, setting the pixel at (e.x, e.y) to ON.
Definition matrices.hpp:122
Tb emplace(const T x, const T y)
Set the pixel at (x, y) to ON without constructing an Event_.
Definition matrices.hpp:133
static constexpr uchar ON
Definition matrices.hpp:137
static constexpr uchar OFF
Definition matrices.hpp:138
Spatial map accumulating signed event counts per pixel.
Definition matrices.hpp:322
CounterType insert(const Event_< T > &e)
Insert an event, incrementing (p=true) or decrementing (p=false) the counter at (e....
Definition matrices.hpp:332
CounterType emplace(const T x, const T y, const bool p)
Increment or decrement the counter at (x, y) without constructing an Event_.
Definition matrices.hpp:344
Definition matrices.hpp:30
CounterType count() const
Number of events accounted for by updateStats() since the last resetStats().
Definition matrices.hpp:58
TimeType duration() const
Time elapsed between the first and the last event accounted for by updateStats().
Definition matrices.hpp:66
void clear()
Reset all pixels.
Definition matrices.hpp:82
void resetStats()
Reset statistics (count, first timestamp, last timestamp).
Definition matrices.hpp:73
void updateStats(const Event &e)
Account for an event in the statistics reported by count() and duration().
Definition matrices.hpp:46
Spatial map storing the polarity of the most recent event at each pixel.
Definition matrices.hpp:274
PolarityType emplace(const T x, const T y, const PolarityType p)
Store polarity p at (x, y) without constructing an Event_.
Definition matrices.hpp:296
PolarityType insert(const Event_< T > &e)
Insert an event, storing e.p at pixel (e.x, e.y).
Definition matrices.hpp:284
Spatial map encoding event polarity at each pixel.
Definition matrices.hpp:169
Tb insert(const Event_< T > &e)
Insert an event, writing POSITIVE or NEGATIVE at (e.x, e.y) based on e.p.
Definition matrices.hpp:181
static constexpr signed char ZERO
Definition matrices.hpp:198
Tb emplace(const T x, const T y, const bool p)
Write polarity p at (x, y) without constructing an Event_.
Definition matrices.hpp:193
static constexpr signed char NEGATIVE
Definition matrices.hpp:199
static constexpr signed char POSITIVE
Definition matrices.hpp:197
Spatial map storing the timestamp of the most recent event at each pixel.
Definition matrices.hpp:226
TimeType insert(const Event_< T > &e)
Insert an event, storing e.t at pixel (e.x, e.y).
Definition matrices.hpp:236
TimeType emplace(const T x, const T y, const TimeType t)
Store timestamp t at (x, y) without constructing an Event_.
Definition matrices.hpp:248
Basic event-based vision structures based on OpenCV components.
constexpr PolarityType POSITIVE
Definition types.hpp:30
Eventi Event
Definition types.hpp:254
constexpr PolarityType NEGATIVE
Definition types.hpp:31