OpenEV
Extending OpenCV to event-based vision
 
Loading...
Searching...
No Matches
abstract-representation.hpp
Go to the documentation of this file.
1
6#ifndef OPENEV_REPRESENTATIONS_ABSTRACT_REPRESENTATION_HPP
7#define OPENEV_REPRESENTATIONS_ABSTRACT_REPRESENTATION_HPP
8
9#include "openev/containers/array.hpp"
11#include "openev/containers/vector.hpp"
12#include "openev/core/types.hpp"
13#include "openev/options.hpp"
15#include <array>
16#include <cstddef>
17#include <float.h>
18#include <memory>
19#include <opencv2/core/hal/interface.h>
20#include <opencv2/core/mat.hpp>
21#include <opencv2/core/mat.inl.hpp>
22#include <opencv2/core/matx.hpp>
23#include <opencv2/core/traits.hpp>
24#include <opencv2/imgproc.hpp>
25#include <opencv2/viz/types.hpp>
26#include <stdint.h>
27#include <type_traits>
28
29namespace ev {
30template <typename T, std::size_t N>
31class Array_;
32template <typename T>
33class Event_;
34template <typename T>
35class Queue_;
36template <typename T>
37class Vector_;
38
39enum RepresentationOptions : uint8_t {
40 NONE = 0b00000000,
41 IGNORE_POLARITY = 0b00000001,
42 ONLY_IF_POSITIVE = 0b00000010,
43 ONLY_IF_NEGATIVE = 0b00000100
44};
45constexpr bool REPRESENTATION_OPTION_CHECK(const uint8_t a, const RepresentationOptions b) {
46 return static_cast<bool>(a & static_cast<uint8_t>(b));
47}
48
50template <typename T, typename = void>
51struct DataTypeTrait {
52 using type = T;
53};
54
55template <typename T>
56struct DataTypeTrait<T, std::void_t<typename T::value_type>> {
57 using type = typename T::value_type;
58};
59
60template <typename T>
61class TypeHelper {
62public:
63 using Type = T;
64 using TypeArray = std::array<T, 3>;
65 using PrimitiveDataType = typename DataTypeTrait<T>::type;
66 using FloatingPointType = typename std::conditional<std::is_same<T, double>::value, double, float>::type;
67 using ChannelType = typename cv::Mat_<PrimitiveDataType>;
68 static constexpr int NumChannels = cv::DataType<T>::channels;
69
70 static constexpr TypeArray initialize() {
71 if constexpr(std::is_floating_point_v<PrimitiveDataType>) {
72 return TypeArray{repeat(1.0), repeat(-1.0), repeat(0.0)};
73 } else {
74 if constexpr(NumChannels == 1) {
75 constexpr Type white = 255;
76 constexpr Type black = 0;
77 constexpr Type gray = 128;
78 return TypeArray{white, black, gray};
79 } else {
80 return TypeArray{Type(255, 0, 0), Type(0, 0, 255), Type(0, 0, 0)};
81 }
82 }
83 }
84
85 static constexpr Type repeat(const double &value) {
86 if constexpr(NumChannels == 1) {
87 return static_cast<Type>(value);
88 } else {
89 Type ret;
90 for(int i = 0; i < NumChannels; i++) {
91 ret[i] = value;
92 }
93 return ret;
94 }
95 }
96
97 static constexpr Type convert(const cv::viz::Color &color) {
98 if constexpr(NumChannels == 1) {
99 return color[0];
100 } else {
101 Type ret;
102 for(int i = 0; i < NumChannels; i++) {
103 ret[i] = color[i];
104 }
105 return ret;
106 }
107 }
108
109 static cv::viz::Color convert(const Type &noncolor) {
110 if constexpr(NumChannels == 1) {
111 return cv::viz::Color(noncolor);
112 } else {
113 cv::viz::Color ret;
114 for(int i = 0; i < NumChannels; i++) {
115 ret[i] = noncolor[i];
116 }
117 return ret;
118 }
119 }
120};
122
126template <typename T, const RepresentationOptions Options = RepresentationOptions::NONE, typename E = int>
128public:
129 using Type = typename TypeHelper<T>::Type;
130
135 [[nodiscard]] inline std::size_t count() const { return count_; }
136
141 [[nodiscard]] inline double duration() const {
142 if(tLimits_[MIN] == DBL_MAX || tLimits_[MAX] == DBL_MIN) {
143 return -1;
144 }
145 return tLimits_[MAX] - tLimits_[MIN];
146 }
147
152 [[nodiscard]] inline double midTime() const {
153 if(tLimits_[MIN] == DBL_MAX || tLimits_[MAX] == DBL_MIN) {
154 return -1;
155 }
156 return 0.5 * (tLimits_[MAX] + tLimits_[MIN]);
157 }
158
163 void clear();
164
169 void clear(const cv::Mat &background);
170
177 bool insert(const Event_<E> &e);
178
184 template <std::size_t N>
185 bool insert(const Array_<E, N> &array);
186
192 bool insert(const Vector_<E> &vector);
193
200 bool insert(Queue_<E> &queue, const bool keep_events_in_queue = false);
201
207 void setTimeOffset(const Event_<E> &e) {
208 timeOffset_ = -e.t;
209 }
210
216 inline void setValue(const bool polarity, const Type &value) {
217 if(polarity) {
218 V_ON = value;
219 } else {
220 V_OFF = value;
221 }
222 colormap_ = nullptr;
223 this->clear();
224 }
225
230 inline void setValue(const Type &value) {
231 V_RESET = value;
232 colormap_ = nullptr;
233 this->clear();
234 }
235
242 inline void setValues(const Type &positive, const Type &negative, const Type &reset) {
243 V_ON = positive;
244 V_OFF = negative;
245 V_RESET = reset;
246 colormap_ = nullptr;
247 this->clear();
248 }
249
256 inline void setColor(const bool polarity, const cv::viz::Color &color) {
257 setValue(polarity, TypeHelper<T>::convert(color));
258 }
259
265 inline void setColor(const cv::viz::Color &color) {
266 setValue(TypeHelper<T>::convert(color));
267 }
268
276 inline void setColors(const cv::viz::Color &positive, const cv::viz::Color &negative, const cv::viz::Color &reset) {
277 setValues(TypeHelper<T>::convert(positive), TypeHelper<T>::convert(negative), TypeHelper<T>::convert(reset));
278 }
279
285 inline void setColormap(const cv::ColormapTypes cm) {
286 if constexpr(TypeHelper<T>::NumChannels == 1) {
287 ev::logger::error("setColorMap: Colormap can only be used with 3-channel representations");
288 } else {
289 colormap_ = std::make_unique<cv::ColormapTypes>(cm);
290
291 constexpr std::array<uchar, 3> aux1_data = {0, 128, 255};
292 cv::Mat aux1(1, 3, CV_8UC1, const_cast<uchar *>(aux1_data.data()));
293 cv::Mat aux3;
294 cv::applyColorMap(aux1, aux3, *colormap_);
295
296 if constexpr(REPRESENTATION_OPTION_CHECK(Options, RepresentationOptions::IGNORE_POLARITY)) {
297 V_ON = aux3.at<cv::Vec3b>(0, 2);
298 V_RESET = aux3.at<cv::Vec3b>(0, 0);
299 } else {
300 V_ON = aux3.at<cv::Vec3b>(0, 2);
301 V_OFF = aux3.at<cv::Vec3b>(0, 0);
302 V_RESET = aux3.at<cv::Vec3b>(0, 1);
303 }
304 this->clear();
305 }
306 }
307
308protected:
310 enum : uint8_t { MIN,
311 MAX };
312
313 Type V_ON = TypeHelper<T>::initialize()[0];
314 Type V_OFF = TypeHelper<T>::initialize()[1];
315 Type V_RESET = TypeHelper<T>::initialize()[2];
316
317 double timeOffset_{0};
318 std::array<double, 2> tLimits_{DBL_MAX, DBL_MIN};
319 std::size_t count_{0};
320 std::unique_ptr<cv::ColormapTypes> colormap_;
321
322 virtual void clear_() = 0;
323 virtual void clear_(const cv::Mat &background) = 0;
324 virtual bool insert_(const Event_<E> &e) = 0;
326};
327
328} // namespace ev
329
331#include "openev/representations/abstract-representation.tpp"
333
334#endif // OPENEV_REPRESENTATIONS_ABSTRACT_REPRESENTATION_HPP
This is an auxiliary class. This class cannot be instanced.
Definition abstract-representation.hpp:127
double midTime() const
Calculate the midpoint time between the oldest and the newest event.
Definition abstract-representation.hpp:152
void setColors(const cv::viz::Color &positive, const cv::viz::Color &negative, const cv::viz::Color &reset)
Set colors for ON, OFF, and non-activated pixels. For more information, please refer here.
Definition abstract-representation.hpp:276
void clear()
Remove all events from the representation.
bool insert(const Vector_< E > &vector)
Insert a vector of events in the representation.
void setColor(const cv::viz::Color &color)
Set colors for non-activated pixels (background). For more information, please refer here.
Definition abstract-representation.hpp:265
typename TypeHelper< T >::Type Type
Definition abstract-representation.hpp:129
bool insert(const Event_< E > &e)
Insert one event in the representation.
void setColor(const bool polarity, const cv::viz::Color &color)
Set colors for ON and OFF pixels. For more information, please refer here.
Definition abstract-representation.hpp:256
void setColormap(const cv::ColormapTypes cm)
Set colormap for the representation.
Definition abstract-representation.hpp:285
double duration() const
Time difference between the oldest and the newest event integrated in the representation.
Definition abstract-representation.hpp:141
std::size_t count() const
Number of events integrated in the representation.
Definition abstract-representation.hpp:135
void setValue(const bool polarity, const Type &value)
Set values for ON and OFF pixels.
Definition abstract-representation.hpp:216
bool insert(const Array_< E, N > &array)
Insert an array of events in the representation.
bool insert(Queue_< E > &queue, const bool keep_events_in_queue=false)
Insert a queue of events in the representation.
void setValues(const Type &positive, const Type &negative, const Type &reset)
Set values for ON, OFF, and non-activated pixels.
Definition abstract-representation.hpp:242
void setTimeOffset(const Event_< E > &e)
Set time offset.
Definition abstract-representation.hpp:207
void clear(const cv::Mat &background)
Remove all events from the representation and add a background image.
void setValue(const Type &value)
Set value for non-activated pixels (background).
Definition abstract-representation.hpp:230
This class extends std::array to implement event arrays. For more information, please refer here.
Definition array.hpp:22
This class extends cv::Point_<T> for event data. For more information, please refer here.
Definition types.hpp:62
double t
Definition types.hpp:64
This class extends std::queue to implement event queues. For more information, please refer here.
Definition queue.hpp:36
This class extends std::vector to implement event vectors. For more information, please refer here.
Definition vector.hpp:36
Logger utility.
void error(const char *message, const bool assert_condition=false)
Log message at error level.
Definition logger.hpp:39
OpenEV compilation options.
Queue container for basic event structures.
Basic event-based vision structures based on OpenCV components.