File size: 3,695 Bytes
e6c4101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#pragma once

#include <vector>

#include <boost/filesystem.hpp>
#include <Eigen/Core>
#include <opencv2/core/core.hpp>

#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;

struct Event
{
  Event(int x, int y, double t, int polarity)
  : x_(x), y_(y), t_(t), polarity_(polarity)
  {}

  bool operator<(Event& other)
  {
    return t_ < other.t_;
  }

  int x_, y_;
  double t_;
  int polarity_;
};

/*
 * The EventSimulator takes as input a sequence of stamped images,
 * assumed to be sampled at a "sufficiently high" framerate,
 * and simulates the principle of operation of an idea event camera
 * with a constant contrast threshold C.
 * Pixel-wise intensity values are linearly interpolated in time.
 *
 * The pixel-wise voltages are reset with the values from the first image
 * which is passed to the simulator.
 */
class EventSimulator
{
public:
  EventSimulator(float contrast_threshold_pos, 
                 float contrast_threshold_neg, 
                 float refractory_period, 
                 float log_eps,
                 bool use_log_img);

  Eigen::MatrixXd generateFromFolder(std::string image_folder, std::string timestamps_file_path);
  Eigen::MatrixXd generateFromVideo(std::string video_path, std::string timestamps_file_path);
  Eigen::MatrixXd generateFromStampedImageSequence(std::vector<std::string> image_paths, std::vector<double> timestamps);
  
  Eigen::MatrixXd generateEventFromCVImage(py::array_t<float> input_array, double time);
  void initialise(py::array_t<float> input_array, double time);

  void setParameters(float contrast_threshold_pos, 
                     float contrast_threshold_neg,
                     float refractory_period,
                     float log_eps,
                     bool use_log_img)
  {
    contrast_threshold_pos_ = contrast_threshold_pos;
    contrast_threshold_neg_ = contrast_threshold_neg;
    refractory_period_ = refractory_period;
    log_eps_ = log_eps;
    use_log_img_ = use_log_img;
  }

  cv::Mat pyArrayToCvMat(py::array_t<float> input_array) {
    // Accessing the NumPy array data
    py::buffer_info buf_info = input_array.request();
    float* ptr = static_cast<float*>(buf_info.ptr);

    // Assuming a 3-channel image, you may need to adjust channels and sizes accordingly
    return cv::Mat(buf_info.shape[0], buf_info.shape[1], CV_32F, ptr).clone();
}


private:
  void init(const cv::Mat &img, double time);  
  Eigen::MatrixXd vec_to_eigen_matrix(std::vector<Event>& events_vec)
  {
    Eigen::MatrixXd events(events_vec.size(), 4);
    for (int i=0; i<events_vec.size(); i++)
    {
        Event& event = events_vec[i]; 
        events(i,0) = event.x_;
        events(i,1) = event.y_;
        events(i,2) = event.t_;
        events(i,3) = event.polarity_;
    }
    return events;
  }

  void imageCallback(const cv::Mat& img, double time, std::vector<Event>& events);
   
  void read_directory_from_path(const std::string& name, std::vector<std::string>& v)
  {
      boost::filesystem::path p(name);
      boost::filesystem::directory_iterator start(p);
      boost::filesystem::directory_iterator end;

      auto path_leaf_string = [](const boost::filesystem::directory_entry& entry) -> std::string {return entry.path().string();};

      std::transform(start, end, std::back_inserter(v), path_leaf_string);

      std::sort(v.begin(), v.end());
  }  

  float contrast_threshold_pos_; 
  float contrast_threshold_neg_;
  float refractory_period_;
  float log_eps_;
  bool use_log_img_;

  bool is_initialized_;
  double current_time_;
  cv::Mat ref_values_;
  cv::Mat last_img_;
  cv::Mat last_event_timestamp_;
  int image_height_;
  int image_width_;
};