├── .vscode └── settings.json ├── README.MD ├── camera_response_function └── crf.txt ├── dv-module └── fast-edi │ ├── .gitignore │ ├── .vscode │ └── settings.json │ ├── CMakeLists.txt │ └── FEDI.cpp └── img └── layout.png /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "array": "cpp", 4 | "string_view": "cpp", 5 | "cctype": "cpp", 6 | "clocale": "cpp", 7 | "cmath": "cpp", 8 | "cstdarg": "cpp", 9 | "cstddef": "cpp", 10 | "cstdio": "cpp", 11 | "cstdlib": "cpp", 12 | "cstring": "cpp", 13 | "ctime": "cpp", 14 | "cwchar": "cpp", 15 | "cwctype": "cpp", 16 | "atomic": "cpp", 17 | "strstream": "cpp", 18 | "bit": "cpp", 19 | "*.tcc": "cpp", 20 | "bitset": "cpp", 21 | "cinttypes": "cpp", 22 | "compare": "cpp", 23 | "concepts": "cpp", 24 | "cstdint": "cpp", 25 | "set": "cpp", 26 | "unordered_map": "cpp", 27 | "vector": "cpp", 28 | "exception": "cpp", 29 | "algorithm": "cpp", 30 | "functional": "cpp", 31 | "iterator": "cpp", 32 | "memory": "cpp", 33 | "memory_resource": "cpp", 34 | "numeric": "cpp", 35 | "optional": "cpp", 36 | "random": "cpp", 37 | "string": "cpp", 38 | "system_error": "cpp", 39 | "tuple": "cpp", 40 | "type_traits": "cpp", 41 | "utility": "cpp", 42 | "initializer_list": "cpp", 43 | "iomanip": "cpp", 44 | "iosfwd": "cpp", 45 | "iostream": "cpp", 46 | "istream": "cpp", 47 | "limits": "cpp", 48 | "new": "cpp", 49 | "ostream": "cpp", 50 | "ranges": "cpp", 51 | "sstream": "cpp", 52 | "stdexcept": "cpp", 53 | "streambuf": "cpp", 54 | "typeinfo": "cpp", 55 | "__bit_reference": "cpp", 56 | "__config": "cpp", 57 | "__debug": "cpp", 58 | "__functional_base": "cpp", 59 | "__hash_table": "cpp", 60 | "__locale": "cpp", 61 | "__nullptr": "cpp", 62 | "__split_buffer": "cpp", 63 | "__string": "cpp", 64 | "__tree": "cpp", 65 | "__tuple": "cpp", 66 | "ios": "cpp", 67 | "locale": "cpp", 68 | "chrono": "cpp" 69 | } 70 | } -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Fast Event-based Double Integral for Real-time Robotics (Academic Use Only) 4 | ## [Paper](https://arxiv.org/abs/2305.05925) | [Video: Youtube](https://www.youtube.com/watch?v=xzrHNA97wls) | [Video: Bilibili](https://www.bilibili.com/video/BV1qL411X7hc/?share_source=copy_web&vd_source=2483c9488f1bd3f3478cf69bfca4d49e) 5 | 6 | 7 | Motion deblurring is a critical ill-posed problem that is important in many vision-based robotics applications. The recently proposed event-based double integral (EDI) provides a theoretical framework for solving the deblurring problem with the event camera and generating clear images at high frame-rate. However, the original EDI is mainly designed for offline computation and does not support real-time requirement in many robotics applications. In this paper, we propose the fast EDI, an efficient implementation of EDI that can achieve real-time online computation on single-core CPU devices, which is common for physical robotic platforms used in practice. In experiments, our method can handle event rates at as high as 13 million event per second in a wide variety of challenging lighting conditions. Its benefit has been demonstrated on multiple downstream real-time applications, including localization, visual tag detection, and feature matching. 8 | 9 | 10 | 11 | 12 | ## Understanding the hardware bias of event camera 13 | [Tutorial of the bias](https://gitlab.com/inivation/inivation-docs/blob/master/Advanced%20configurations/User_guide_-_Biasing.md) 14 | ## Checking the hardware bias using the jAER 15 | One can use the jAER project to get a roughly estimated contrast from the bias currents that are estimated to be generated by the on-chip bias generator bias current ratios: [jAER homepage](https://github.com/SensorsINI/jaer) 16 | 17 | 18 | Discussion regarding the bias estimation: [discussion](https://groups.google.com/g/davis-users/c/68gp0zxTMUk/m/SpweyJKrDgAJ) 19 | 20 | 21 | and the physical model that build to estimate the threshold: [Paper](https://ieeexplore.ieee.org/document/7962235/) 22 | 23 | 24 | ## Usage 25 | Test env: 26 | ``` 27 | ubuntu 18.04 28 | dv-runtime 1.6.1 29 | dv-gui 1.6.0 30 | ``` 31 | 32 | 1. download the DV and install it following the tutorial [DV install guide](https://inivation.gitlab.io/dv/dv-docs/docs/getting-started.html) 33 | 2. download the fast EDI code 34 | ``` 35 | git clone https://github.com/eleboss/fast_EDI 36 | ``` 37 | 3. compile the fast EDI module 38 | ``` 39 | cd ./dv-module/fast-edi 40 | cmake ./ 41 | make 42 | ``` 43 | then you will see the `fedi_FEDI.so`, this is the file you need to add to the dv-gui. 44 | 45 | 4. configure the DV-GUI search path 46 | ``` 47 | dv-gui 48 | ``` 49 | find the `structure - add modules - modify module search path - add path` (this path leads to `fedi_FEDI.so`, for me is `/home/eleboss/Documents/fast_EDI/dv-module/fast-edi`). Then you can add the fast edi modules to the dv-gui and wires it in this way: 50 | ![layout](./img/layout.png) 51 | 52 | 5. download the test data [dataset](https://figshare.com/s/bfa74d5793a4af962b49), and play it. 53 | 54 | Performance tips: You can tune the contrast or use the jAER to estimate, or use EDI to optimize an accurate contrast. 55 | 56 | I have already calibrated the camera response function for DAVIS346, you should load this file before launching the fast-edi module, the camera response function gives a slightly more accurate log mapping, which improves the reconstuction performance. You can also delete it and use the log mapping, which makes it identical to the original paper of EDI. 57 | ## Citation 58 | ``` 59 | @article{lin2023fast, 60 | title={Fast Event-based Double Integral for Real-time Robotics}, 61 | author={Lin, Shijie and Zhang, Yingqiang and Huang, Dongyue and Zhou, Bin and Luo, Xiaowei and Pan, Jia}, 62 | booktitle={international conference on robotics and automation (ICRA)}, 63 | year={2023}, 64 | organization={IEEE} 65 | } 66 | ``` 67 | -------------------------------------------------------------------------------- /camera_response_function/crf.txt: -------------------------------------------------------------------------------- 1 | -2.874582 2 | -2.790881 3 | -2.707180 4 | -2.625109 5 | -2.545483 6 | -2.468953 7 | -2.396010 8 | -2.326496 9 | -2.260470 10 | -2.197684 11 | -2.137819 12 | -2.080908 13 | -2.026740 14 | -1.975217 15 | -1.926164 16 | -1.879497 17 | -1.835124 18 | -1.792643 19 | -1.751809 20 | -1.712408 21 | -1.674361 22 | -1.637537 23 | -1.601916 24 | -1.567420 25 | -1.533991 26 | -1.501475 27 | -1.469870 28 | -1.439243 29 | -1.409518 30 | -1.380648 31 | -1.352526 32 | -1.325119 33 | -1.298371 34 | -1.272192 35 | -1.246648 36 | -1.221755 37 | -1.197509 38 | -1.173850 39 | -1.150610 40 | -1.127717 41 | -1.105186 42 | -1.083062 43 | -1.061363 44 | -1.040074 45 | -1.019232 46 | -0.998823 47 | -0.978865 48 | -0.959372 49 | -0.940344 50 | -0.921689 51 | -0.903325 52 | -0.885267 53 | -0.867572 54 | -0.850186 55 | -0.833039 56 | -0.816136 57 | -0.799475 58 | -0.782992 59 | -0.766640 60 | -0.750423 61 | -0.734423 62 | -0.718722 63 | -0.703357 64 | -0.688343 65 | -0.673632 66 | -0.659150 67 | -0.644888 68 | -0.630809 69 | -0.616881 70 | -0.603071 71 | -0.589369 72 | -0.575820 73 | -0.562412 74 | -0.549169 75 | -0.536146 76 | -0.523345 77 | -0.510784 78 | -0.498444 79 | -0.486300 80 | -0.474304 81 | -0.462424 82 | -0.450615 83 | -0.438897 84 | -0.427267 85 | -0.415689 86 | -0.404170 87 | -0.392739 88 | -0.381393 89 | -0.370177 90 | -0.359113 91 | -0.348220 92 | -0.337477 93 | -0.326847 94 | -0.316282 95 | -0.305746 96 | -0.295243 97 | -0.284807 98 | -0.274479 99 | -0.264315 100 | -0.254367 101 | -0.244637 102 | -0.235113 103 | -0.225755 104 | -0.216499 105 | -0.207245 106 | -0.197987 107 | -0.188719 108 | -0.179484 109 | -0.170297 110 | -0.161126 111 | -0.151967 112 | -0.142806 113 | -0.133714 114 | -0.124761 115 | -0.115973 116 | -0.107314 117 | -0.098782 118 | -0.090357 119 | -0.082001 120 | -0.073712 121 | -0.065494 122 | -0.057329 123 | -0.049173 124 | -0.040994 125 | -0.032772 126 | -0.024527 127 | -0.016313 128 | -0.008144 129 | -0.000000 130 | 0.008158 131 | 0.016312 132 | 0.024468 133 | 0.032559 134 | 0.040512 135 | 0.048304 136 | 0.055914 137 | 0.063403 138 | 0.070761 139 | 0.078006 140 | 0.085145 141 | 0.092171 142 | 0.099085 143 | 0.105833 144 | 0.112398 145 | 0.118826 146 | 0.125146 147 | 0.131368 148 | 0.137538 149 | 0.143655 150 | 0.149720 151 | 0.155766 152 | 0.161877 153 | 0.168030 154 | 0.174201 155 | 0.180344 156 | 0.186374 157 | 0.192274 158 | 0.198062 159 | 0.203697 160 | 0.209081 161 | 0.214089 162 | 0.218674 163 | 0.222887 164 | 0.226814 165 | 0.230500 166 | 0.233959 167 | 0.237384 168 | 0.241004 169 | 0.244897 170 | 0.249169 171 | 0.253782 172 | 0.258729 173 | 0.263957 174 | 0.269574 175 | 0.275599 176 | 0.282051 177 | 0.288989 178 | 0.296364 179 | 0.304061 180 | 0.312042 181 | 0.320199 182 | 0.328418 183 | 0.336661 184 | 0.344941 185 | 0.353216 186 | 0.361560 187 | 0.369921 188 | 0.378312 189 | 0.386725 190 | 0.395120 191 | 0.403412 192 | 0.411700 193 | 0.419966 194 | 0.428304 195 | 0.436603 196 | 0.444734 197 | 0.452665 198 | 0.460565 199 | 0.468446 200 | 0.476222 201 | 0.483860 202 | 0.491250 203 | 0.498244 204 | 0.504708 205 | 0.510610 206 | 0.515834 207 | 0.520365 208 | 0.524113 209 | 0.527170 210 | 0.529667 211 | 0.531819 212 | 0.533966 213 | 0.536276 214 | 0.538997 215 | 0.542347 216 | 0.546325 217 | 0.550838 218 | 0.555753 219 | 0.560943 220 | 0.566482 221 | 0.572383 222 | 0.578595 223 | 0.584997 224 | 0.591581 225 | 0.598007 226 | 0.603953 227 | 0.609072 228 | 0.613229 229 | 0.616600 230 | 0.619453 231 | 0.621973 232 | 0.624322 233 | 0.626685 234 | 0.629328 235 | 0.632320 236 | 0.635567 237 | 0.639560 238 | 0.645378 239 | 0.654259 240 | 0.668391 241 | 0.689650 242 | 0.718518 243 | 0.754098 244 | 0.794689 245 | 0.838049 246 | 0.882577 247 | 0.928158 248 | 0.974237 249 | 1.020763 250 | 1.067188 251 | 1.112999 252 | 1.158271 253 | 1.203217 254 | 1.248465 255 | 1.293622 256 | 1.338778 -------------------------------------------------------------------------------- /dv-module/fast-edi/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | .config 3 | 4 | # VS Code 5 | *.user 6 | 7 | # Code blocks 8 | *.cbp 9 | 10 | # CLion 11 | .idea/**/workspace.xml 12 | .idea/**/tasks.xml 13 | .idea/**/usage.statistics.xml 14 | .idea/**/dictionaries 15 | .idea/**/shelf 16 | .idea/**/contentModel.xml 17 | .idea/**/dataSources/ 18 | .idea/**/dataSources.ids 19 | .idea/**/dataSources.local.xml 20 | .idea/**/sqlDataSources.xml 21 | .idea/**/dynamic.xml 22 | .idea/**/uiDesigner.xml 23 | .idea/**/dbnavigator.xml 24 | 25 | # CMake generated 26 | cmake-build-* 27 | CMakeFiles 28 | CMakeCache.txt 29 | Makefile 30 | cmake_install.cmake 31 | install_manifest.txt 32 | 33 | # dynamic libraries 34 | *.so 35 | *.dylib 36 | 37 | -------------------------------------------------------------------------------- /dv-module/fast-edi/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "complex": "cpp" 4 | } 5 | } -------------------------------------------------------------------------------- /dv-module/fast-edi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Init CMake (require at least version 3.10.0) 2 | CMAKE_MINIMUM_REQUIRED(VERSION 3.10.0) 3 | 4 | 5 | # Project name and version 6 | PROJECT(fast-edi 7 | VERSION 1.0.0 8 | LANGUAGES C CXX) 9 | 10 | # Define installation paths 11 | INCLUDE(GNUInstallDirs) 12 | # find_package(Boost REQUIRED COMPONENTS filesystem) 13 | FIND_PACKAGE(dv-processing 1.7.2 REQUIRED) 14 | FIND_PACKAGE(dv 1.6.2 REQUIRED) 15 | 16 | 17 | # Compile this module (standard C++ file, no additional dependencies) 18 | ADD_LIBRARY(FEDI SHARED FEDI.cpp) 19 | 20 | SET_TARGET_PROPERTIES(FEDI 21 | PROPERTIES 22 | PREFIX "fedi_" 23 | ) 24 | 25 | TARGET_LINK_LIBRARIES(FEDI PRIVATE dv::sdk) 26 | 27 | INSTALL(TARGETS FEDI DESTINATION ${DV_MODULES_DIR}) 28 | -------------------------------------------------------------------------------- /dv-module/fast-edi/FEDI.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define DAVIS346_IMAGE_HEIGHT 260 10 | #define DAVIS346_IMAGE_WIDTH 346 11 | #define DAVIS346_IMAGE_PIXNUM (DAVIS346_IMAGE_HEIGHT * DAVIS346_IMAGE_WIDTH) 12 | #define TIME_SCALE 1e6 13 | #define MAX_SIZE 700 14 | typedef std::numeric_limits< double > dbl; 15 | 16 | class FastEDI : public dv::ModuleBase { 17 | 18 | private: 19 | bool frameReceiveFlag_ = false; 20 | bool pushbackFlag_ = false; 21 | double frame_ts_expStart = INT64_MAX; 22 | double frame_ts_expEnd = INT64_MAX; 23 | double frame_ts = 0; 24 | 25 | cv::Mat input_img; 26 | long int nonuni_counter = 0; 27 | 28 | long long total_events_decode = 0; 29 | long long total_runtime_decode = 0; 30 | 31 | 32 | std::vector crf_exposure; 33 | std::vector crf_irr; 34 | std::vector aps_irr_log = std::vector(DAVIS346_IMAGE_PIXNUM, 0); 35 | std::vector deblur_exp = std::vector(DAVIS346_IMAGE_PIXNUM, 1); 36 | 37 | double dvs_c_pos_; 38 | double dvs_c_neg_; 39 | bool loadOnceFlag_ = true; 40 | std::string crf_addr; 41 | 42 | // variable for event runtime processing 43 | std::vector ev_irr_runtime_log = std::vector(DAVIS346_IMAGE_PIXNUM, 0); 44 | std::vector stacked_ev_irr_runtime_exp = std::vector(DAVIS346_IMAGE_PIXNUM, 1); 45 | double stacked_runtime_counter_nonuni = 0; 46 | 47 | 48 | std::vector dynamic_runtime_counter = std::vector(DAVIS346_IMAGE_PIXNUM, 0); 49 | 50 | std::array, MAX_SIZE * DAVIS346_IMAGE_PIXNUM> stacked_runtime_counter_nonuni_list; 51 | 52 | std::array,MAX_SIZE>,DAVIS346_IMAGE_PIXNUM> ev_irr_exp_runtime_list; 53 | 54 | // variable for irrdiance estimation 55 | std::vector est_ev_irr_exp_nonuni = std::vector(DAVIS346_IMAGE_PIXNUM, 0); 56 | std::vector est_ev_pixcount_uni = std::vector(DAVIS346_IMAGE_PIXNUM, 1); 57 | 58 | std::vector runtime_list; 59 | 60 | 61 | double est_ev_pixcount_nonuni = 0; 62 | 63 | // variable for irrdiance estimation, aps side 64 | std::vector aps_irr_deblur_log = std::vector(DAVIS346_IMAGE_PIXNUM, 0); 65 | 66 | 67 | public: 68 | FastEDI() { 69 | outputs.getFrameOutput("image").setup(DAVIS346_IMAGE_WIDTH, DAVIS346_IMAGE_HEIGHT, "deblur result for vis, x*y"); 70 | 71 | } 72 | std::vector loading_vec_from_file(std::string file_path) 73 | { 74 | char sep = ' '; 75 | std::string line; 76 | std::vector vec; 77 | double vec_value; 78 | std::ifstream myfile (file_path); 79 | int count; 80 | if (myfile.is_open()) 81 | { 82 | while (getline(myfile, line)) 83 | { 84 | count = 0; 85 | for(size_t p=0, q=0; p!=line.npos; p=q) 86 | { 87 | std::string::size_type sz; // alias of size_t 88 | if(count == 0) 89 | { 90 | vec_value = stold(line.substr(p+(p!=0), (q=line.find(sep, p+1))-p-(p!=0)),&sz); 91 | } 92 | count += 1; 93 | } 94 | vec.push_back(vec_value); 95 | } 96 | myfile.close(); 97 | } 98 | return vec; 99 | } 100 | static void initInputs(dv::InputDefinitionList &in) { 101 | in.addFrameInput("frames"); 102 | in.addEventInput("events"); 103 | } 104 | static void initOutputs(dv::OutputDefinitionList &out) { 105 | out.addFrameOutput("image"); 106 | } 107 | 108 | static const char *initDescription() { 109 | return ("The fast EDI pipeline"); 110 | } 111 | 112 | static void initConfigOptions(dv::RuntimeConfig &config) { 113 | config.add("dvs_c_pos", 114 | dv::ConfigOption::doubleOption( 115 | "DVS contrast positive.", 0.2609, 0, 10)); 116 | config.add("dvs_c_neg", 117 | dv::ConfigOption::doubleOption( 118 | "DVS contrast negative.", -0.2415, -10, 0)); 119 | config.add("crf_address", 120 | dv::ConfigOption::stringOption( 121 | "location of the camera response function", "/home/eleboss/Documents/fast_EDI/camera_response_function/crf.txt")); 122 | 123 | } 124 | void configUpdate() override { 125 | // get parameter 126 | dvs_c_pos_ = config.getDouble("dvs_c_pos"); 127 | dvs_c_neg_ = config.getDouble("dvs_c_neg"); 128 | crf_addr = config.getString("crf_address"); 129 | 130 | if(loadOnceFlag_) 131 | { 132 | loadOnceFlag_ = false; 133 | crf_exposure = loading_vec_from_file(crf_addr); 134 | } 135 | 136 | } 137 | 138 | void run() override 139 | { 140 | double exposure_time = 0; 141 | // get data 142 | const auto frame = inputs.getFrameInput("frames").frame(); 143 | 144 | if(frame && !frameReceiveFlag_) 145 | { 146 | 147 | input_img = *frame.getMatPointer(); 148 | 149 | frame_ts = double(frame.timestamp())/TIME_SCALE; 150 | frame_ts_expStart = double(frame.timestampStartOfExposure())/TIME_SCALE; 151 | frame_ts_expEnd = double(frame.timestampEndOfExposure())/TIME_SCALE; 152 | 153 | exposure_time = frame_ts_expEnd - frame_ts_expStart; 154 | 155 | crf_irr = crf_exposure; 156 | double log_exposure_time = std::log(exposure_time); 157 | transform(crf_irr.begin(), crf_irr.end(), crf_irr.begin(), bind2nd(std::minus(), log_exposure_time)); 158 | 159 | std::fill(aps_irr_log.begin(), aps_irr_log.end(), 0); 160 | // crf mapping 161 | for(int j = 0; j < DAVIS346_IMAGE_PIXNUM; j++) 162 | { 163 | uint8_t pix_dn = input_img.at(j); 164 | // log.info< frame_ts_expEnd && frameReceiveFlag_) 199 | { 200 | 201 | auto start = std::chrono::high_resolution_clock::now(); 202 | 203 | frameReceiveFlag_ = false; 204 | pushbackFlag_ = false; 205 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 206 | // locate nonuni init 207 | double stacked_counter_nonuni_mark_in = 0; 208 | double stacked_counter_nonuni_mark_out = 1; // no event, no change, no count, set to 0 for good debug 209 | for(int i = nonuni_counter-1; i > 1; i--) 210 | { 211 | if(stacked_runtime_counter_nonuni_list[i][0] <= frame_ts_expStart) 212 | { 213 | stacked_counter_nonuni_mark_in = stacked_runtime_counter_nonuni_list[i][1]; 214 | break; 215 | } 216 | if(stacked_runtime_counter_nonuni_list[i][0] <= frame_ts_expEnd && (stacked_counter_nonuni_mark_out==1)) 217 | { 218 | stacked_counter_nonuni_mark_out = stacked_runtime_counter_nonuni_list[i][1]; 219 | } 220 | } 221 | est_ev_pixcount_nonuni = stacked_counter_nonuni_mark_out - stacked_counter_nonuni_mark_in; 222 | /////////////////// 223 | for(int i = 0; i < DAVIS346_IMAGE_PIXNUM; i++) 224 | { 225 | bool minTsFlag_ = false; 226 | bool maxTsFlag_ = false; 227 | int ev_ts_in = 0; 228 | int ev_ts_out = 0; 229 | int ev_ts_before_in = 0; 230 | // int ev_ts_after_out = 0; 231 | double est_ev_irr_exp_in = 0; 232 | double est_ev_pixcount_uni_in = 0; 233 | double est_ev_pixcount_uni_out = 0; 234 | double est_ev_irr_exp_out = 0; 235 | for(int ev = 1; ev < dynamic_runtime_counter[i]; ev++) 236 | { 237 | const double ev_t = ev_irr_exp_runtime_list[i][ev][0]; 238 | if(!minTsFlag_ && ev_t >= frame_ts_expStart && ev_t < frame_ts_expEnd) 239 | { 240 | minTsFlag_ = true; 241 | ev_ts_in = ev; 242 | ev_ts_out = ev; 243 | } 244 | if(!maxTsFlag_ && minTsFlag_ && ev_t == frame_ts_expEnd) 245 | { 246 | maxTsFlag_ = true; 247 | ev_ts_out = ev; 248 | } 249 | else if (!maxTsFlag_ && minTsFlag_ && ev_t > frame_ts_expEnd) 250 | { 251 | maxTsFlag_ = true; 252 | ev_ts_out = ev-1; 253 | 254 | } 255 | if(minTsFlag_ && !maxTsFlag_ && ev == dynamic_runtime_counter[i]-1) 256 | { 257 | ev_ts_out = ev; 258 | } 259 | 260 | if(ev_t < frame_ts_expStart) 261 | { 262 | ev_ts_before_in = ev; 263 | } 264 | } 265 | 266 | if(ev_ts_in > 1) 267 | { 268 | double event_irr_exp_init_mark = ev_irr_exp_runtime_list[i][ev_ts_in-1][1]; 269 | for(int j = ev_ts_in; j < ev_ts_out; j++) 270 | { 271 | // (j+1 - j) * j 272 | double event_irr_exp_mid = ev_irr_exp_runtime_list[i][j][1] / event_irr_exp_init_mark; 273 | double nui_c_front = ev_irr_exp_runtime_list[i][j][2] - stacked_counter_nonuni_mark_in; 274 | double nui_c_end = ev_irr_exp_runtime_list[i][j+1][2] - stacked_counter_nonuni_mark_in; 275 | est_ev_irr_exp_nonuni[i] = est_ev_irr_exp_nonuni[i] + (nui_c_end - nui_c_front) * event_irr_exp_mid; 276 | } 277 | double event_irr_exp_end = ev_irr_exp_runtime_list[i][ev_ts_out][1] / event_irr_exp_init_mark; 278 | double event_counter_nonuni_end = ev_irr_exp_runtime_list[i][ev_ts_out][2] - stacked_counter_nonuni_mark_in; 279 | double event_counter_nonuni_start = ev_irr_exp_runtime_list[i][ev_ts_in][2] - stacked_counter_nonuni_mark_in; 280 | est_ev_irr_exp_nonuni[i] = est_ev_irr_exp_nonuni[i] 281 | + (est_ev_pixcount_nonuni - event_counter_nonuni_end) * event_irr_exp_end 282 | + event_counter_nonuni_start; 283 | } 284 | else if(ev_ts_in == 1) 285 | { 286 | for(int j = ev_ts_in; j < ev_ts_out; j++) 287 | { 288 | // (j+1 - j) * j 289 | double event_irr_exp_mid = ev_irr_exp_runtime_list[i][j][1]; 290 | double nui_c_front = ev_irr_exp_runtime_list[i][j][2] - stacked_counter_nonuni_mark_in; 291 | double nui_c_end = ev_irr_exp_runtime_list[i][j+1][2] - stacked_counter_nonuni_mark_in; 292 | est_ev_irr_exp_nonuni[i] = est_ev_irr_exp_nonuni[i] 293 | + (nui_c_end - nui_c_front) * event_irr_exp_mid; 294 | } 295 | double event_irr_exp_end = ev_irr_exp_runtime_list[i][ev_ts_out][1]; 296 | double event_counter_nonuni_end = ev_irr_exp_runtime_list[i][ev_ts_out][2] - stacked_counter_nonuni_mark_in; 297 | double event_counter_nonuni_start = ev_irr_exp_runtime_list[i][ev_ts_in][2] - stacked_counter_nonuni_mark_in; 298 | est_ev_irr_exp_nonuni[i] = est_ev_irr_exp_nonuni[i] 299 | + (est_ev_pixcount_nonuni - event_counter_nonuni_end) * event_irr_exp_end 300 | + event_counter_nonuni_start; 301 | } 302 | else if(ev_ts_in == 0) 303 | { 304 | est_ev_irr_exp_nonuni[i] = est_ev_pixcount_nonuni; 305 | } 306 | // the hot pixel will set irr_exp too small, make it meansless, thus just set it to 1. 307 | if(std::isnan(est_ev_irr_exp_nonuni[i])) 308 | est_ev_irr_exp_nonuni[i] = est_ev_pixcount_nonuni; 309 | // --------------------------- nonuni nor 310 | est_ev_irr_exp_nonuni[i] = est_ev_irr_exp_nonuni[i] / est_ev_pixcount_nonuni; 311 | // --------------------------- 312 | //////////////////////////////////// pixcheck and deblur 313 | aps_irr_deblur_log[i] = aps_irr_log[i] - std::log(est_ev_irr_exp_nonuni[i]); 314 | } 315 | 316 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 317 | // clear parts of the container 318 | stacked_runtime_counter_nonuni = 0; 319 | std::fill(ev_irr_runtime_log.begin(), ev_irr_runtime_log.end(), 0); 320 | std::fill(stacked_ev_irr_runtime_exp.begin(), stacked_ev_irr_runtime_exp.end(), 1); 321 | nonuni_counter = 0; 322 | dynamic_runtime_counter = std::vector(DAVIS346_IMAGE_PIXNUM, 0); 323 | 324 | ////////////////////////////////////////// output as image 325 | for (int i = 0; i < DAVIS346_IMAGE_PIXNUM; i++) 326 | { 327 | for (uint8_t j = 0; j < 255; j++) 328 | { 329 | if(aps_irr_deblur_log[i] >= crf_irr[j]) 330 | deblur_exp[i] = j; 331 | else 332 | break; 333 | } 334 | } 335 | //load to mat 336 | cv::Mat deblur_exp_mat(1, deblur_exp.size(), CV_8UC1, deblur_exp.data()); 337 | deblur_exp_mat = deblur_exp_mat.reshape(1,DAVIS346_IMAGE_HEIGHT); 338 | 339 | // send it for exposure estimation 340 | auto outFrame_deblur = outputs.getFrameOutput("image").frame(); 341 | outFrame_deblur.setTimestamp(frame_ts * TIME_SCALE); 342 | outFrame_deblur.setMat(deblur_exp_mat); 343 | outFrame_deblur.commit(); 344 | } 345 | } 346 | } 347 | }; 348 | 349 | registerModuleClass(FastEDI) 350 | -------------------------------------------------------------------------------- /img/layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleboss/fast_EDI/d8731e668d1732ac11b7151632652e424f11424b/img/layout.png --------------------------------------------------------------------------------