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
10#include <array>
11#include <cstddef>
12#include <limits>
13#include <memory>
14#include <opencv2/core/hal/interface.h>
15#include <opencv2/core/mat.hpp>
16#include <opencv2/core/mat.inl.hpp>
17#include <opencv2/core/matx.hpp>
18#include <opencv2/core/traits.hpp>
19#include <opencv2/core/utils/logger.hpp>
20#include <opencv2/imgproc.hpp>
21#include <opencv2/viz/types.hpp>
22#include <stdint.h>
23#include <type_traits>
24
25namespace ev {
27template <typename T, std::size_t N>
28class Array_;
29template <typename T>
30class Event_;
31template <typename T>
32class Queue_;
33template <typename T>
34class Vector_;
36
37enum RepresentationOptions : uint8_t {
38 NONE = 0b00000000,
39 IGNORE_POLARITY = 0b00000001,
40 ONLY_IF_POSITIVE = 0b00000010,
41 ONLY_IF_NEGATIVE = 0b00000100
42};
43constexpr bool REPRESENTATION_OPTION_CHECK(const uint8_t a, const RepresentationOptions b) {
44 return static_cast<bool>(a & static_cast<uint8_t>(b));
45}
46
48template <typename T, typename = void>
49struct DataTypeTrait {
50 using type = T;
51};
52
53template <typename T>
54struct DataTypeTrait<T, std::void_t<typename T::value_type>> {
55 using type = typename T::value_type;
56};
57
58template <typename T>
59class TypeHelper {
60public:
61 using Type = T;
62 using TypeArray = std::array<T, 3>;
63 using PrimitiveDataType = typename DataTypeTrait<T>::type;
64 using FloatingPointType = typename std::conditional<std::is_same<T, double>::value, double, float>::type;
65 using ChannelType = typename cv::Mat_<PrimitiveDataType>;
66 static constexpr int NumChannels = cv::DataType<T>::channels;
67
68 static constexpr TypeArray initialize() {
69 if constexpr(std::is_floating_point_v<PrimitiveDataType>) {
70 return TypeArray{repeat(1.0), repeat(-1.0), repeat(0.0)};
71 } else {
72 if constexpr(NumChannels == 1) {
73 constexpr Type white = 255;
74 constexpr Type black = 0;
75 constexpr Type gray = 128;
76 return TypeArray{white, black, gray};
77 } else {
78 return TypeArray{Type(255, 0, 0), Type(0, 0, 255), Type(0, 0, 0)};
79 }
80 }
81 }
82
83 static constexpr Type repeat(const double &value) {
84 if constexpr(NumChannels == 1) {
85 return static_cast<Type>(value);
86 } else {
87 Type ret;
88 for(int i = 0; i < NumChannels; i++) {
89 ret[i] = value;
90 }
91 return ret;
92 }
93 }
94
95 static constexpr Type convert(const cv::viz::Color &color) {
96 if constexpr(NumChannels == 1) {
97 return color[0];
98 } else {
99 Type ret;
100 for(int i = 0; i < NumChannels; i++) {
101 ret[i] = color[i];
102 }
103 return ret;
104 }
105 }
106
107 static cv::viz::Color convert(const Type &noncolor) {
108 if constexpr(NumChannels == 1) {
109 return cv::viz::Color(noncolor);
110 } else {
111 cv::viz::Color ret;
112 for(int i = 0; i < NumChannels; i++) {
113 ret[i] = noncolor[i];
114 }
115 return ret;
116 }
117 }
118};
120
124template <typename T, const RepresentationOptions Options = RepresentationOptions::NONE, typename E = int>
126 static_assert(TypeHelper<T>::NumChannels == 1 || TypeHelper<T>::NumChannels == 3, "ev::AbstractRepresentation_: only 1- and 3-channel representations are supported.");
127 static_assert(std::is_arithmetic_v<E>, "ev::AbstractRepresentation_: the event coordinate type must be arithmetic.");
128
129public:
130 using Type = typename TypeHelper<T>::Type;
131
133 AbstractRepresentation_() = default;
134 virtual ~AbstractRepresentation_() = default;
137 AbstractRepresentation_ &operator=(const AbstractRepresentation_ &) = delete;
138 AbstractRepresentation_ &operator=(AbstractRepresentation_ &&) noexcept = delete;
140
145 [[nodiscard]] inline std::size_t count() const { return count_; }
146
151 [[nodiscard]] inline TimeType duration() const {
152 if(tLimits_[MIN] == std::numeric_limits<TimeType>::max() || tLimits_[MAX] == std::numeric_limits<TimeType>::min()) {
153 return -1;
154 }
155 return tLimits_[MAX] - tLimits_[MIN];
156 }
157
162 [[nodiscard]] inline TimeType midTime() const {
163 if(tLimits_[MIN] == std::numeric_limits<TimeType>::max() || tLimits_[MAX] == std::numeric_limits<TimeType>::min()) {
164 return -1;
165 }
166 return 0.5 * (tLimits_[MAX] + tLimits_[MIN]);
167 }
168
173 void clear();
174
180 void clear(const cv::Mat &background, const cv::Point &origin = {0, 0});
181
188 bool insert(const Event_<E> &e);
189
195 template <std::size_t N>
196 bool insert(const Array_<E, N> &array);
197
203 bool insert(const Vector_<E> &vector);
204
211 bool insert(Queue_<E> &queue, const bool keep_events_in_queue = false);
212
218 void setTimeOffset(const Event_<E> &e) {
219 timeOffset_ = -e.t;
220 }
221
227 inline void setValue(const bool polarity, const Type &value) {
228 if(polarity) {
229 V_ON = value;
230 } else {
231 V_OFF = value;
232 }
233 colormap_ = nullptr;
234 this->clear();
235 }
236
241 inline void setValue(const Type &value) {
242 V_RESET = value;
243 colormap_ = nullptr;
244 this->clear();
245 }
246
253 inline void setValues(const Type &positive, const Type &negative, const Type &reset) {
254 V_ON = positive;
255 V_OFF = negative;
256 V_RESET = reset;
257 colormap_ = nullptr;
258 this->clear();
259 }
260
267 inline void setColor(const bool polarity, const cv::viz::Color &color) {
268 setValue(polarity, TypeHelper<T>::convert(color));
269 }
270
276 inline void setColor(const cv::viz::Color &color) {
277 setValue(TypeHelper<T>::convert(color));
278 }
279
287 inline void setColors(const cv::viz::Color &positive, const cv::viz::Color &negative, const cv::viz::Color &reset) {
288 setValues(TypeHelper<T>::convert(positive), TypeHelper<T>::convert(negative), TypeHelper<T>::convert(reset));
289 }
290
296 inline void setColormap(const cv::ColormapTypes cm) {
297 static_assert(TypeHelper<T>::NumChannels == 3, "ev::AbstractRepresentation_::setColormap: a colormap can only be used with 3-channel representations.");
298 colormap_ = std::make_unique<cv::ColormapTypes>(cm);
299
300 constexpr std::array<uchar, 3> aux1_data = {0, 128, 255};
301 cv::Mat aux1(1, 3, CV_8UC1, const_cast<uchar *>(aux1_data.data()));
302 cv::Mat aux3;
303 cv::applyColorMap(aux1, aux3, *colormap_);
304
305 if constexpr(REPRESENTATION_OPTION_CHECK(Options, RepresentationOptions::IGNORE_POLARITY)) {
306 V_ON = aux3.at<cv::Vec3b>(0, 2);
307 V_RESET = aux3.at<cv::Vec3b>(0, 0);
308 } else {
309 V_ON = aux3.at<cv::Vec3b>(0, 2);
310 V_OFF = aux3.at<cv::Vec3b>(0, 0);
311 V_RESET = aux3.at<cv::Vec3b>(0, 1);
312 }
313 this->clear();
314 }
315
316protected:
318 enum : uint8_t { MIN,
319 MAX };
320
321 Type V_ON = TypeHelper<T>::initialize()[0];
322 Type V_OFF = TypeHelper<T>::initialize()[1];
323 Type V_RESET = TypeHelper<T>::initialize()[2];
324
325 TimeType timeOffset_{0};
326 std::array<TimeType, 2> tLimits_{std::numeric_limits<TimeType>::max(), std::numeric_limits<TimeType>::min()};
327 std::size_t count_{0};
328 std::unique_ptr<cv::ColormapTypes> colormap_;
329 cv::Mat background_;
330
331 [[nodiscard]] virtual cv::Size frameSize_() const = 0;
332 virtual void clear_() = 0;
333 virtual void clear_(const cv::Mat &background) = 0;
334 virtual bool insert_(const Event_<E> &e) = 0;
336};
337
338} // namespace ev
339
341#include "openev/representations/abstract-representation.tpp"
343
344#endif // OPENEV_REPRESENTATIONS_ABSTRACT_REPRESENTATION_HPP
This is an auxiliary class. This class cannot be instanced.
Definition abstract-representation.hpp:125
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:287
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:276
typename TypeHelper< T >::Type Type
Definition abstract-representation.hpp:130
TimeType midTime() const
Calculate the midpoint time between the oldest and the newest event.
Definition abstract-representation.hpp:162
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:267
void setColormap(const cv::ColormapTypes cm)
Set colormap for the representation.
Definition abstract-representation.hpp:296
std::size_t count() const
Number of events integrated in the representation.
Definition abstract-representation.hpp:145
void setValue(const bool polarity, const Type &value)
Set values for ON and OFF pixels.
Definition abstract-representation.hpp:227
TimeType duration() const
Time difference between the oldest and the newest event integrated in the representation.
Definition abstract-representation.hpp:151
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:253
void clear(const cv::Mat &background, const cv::Point &origin={0, 0})
Remove all events from the representation and add a background image.
void setTimeOffset(const Event_< E > &e)
Set time offset.
Definition abstract-representation.hpp:218
void setValue(const Type &value)
Set value for non-activated pixels (background).
Definition abstract-representation.hpp:241
This class extends std::array to implement event arrays. For more information, please refer here.
Definition array.hpp:24
This class extends cv::Point_<T> for event data. For more information, please refer here.
Definition types.hpp:78
TimeType t
Definition types.hpp:82
This class extends std::queue to implement event queues. For more information, please refer here.
Definition queue.hpp:32
This class extends std::vector to implement event vectors. For more information, please refer here.
Definition vector.hpp:23
Basic event-based vision structures based on OpenCV components.