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_;
};
|