├── LICENSE ├── README.md ├── egs.m └── result_egs_detail.txt /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Shijie Lin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ## Autofocus for Event Cameras 5 | 6 | This contains the implementation of the paper [Autofocus for Event Cameras](https://arxiv.org/abs/2109.01750). 7 | Please refer to the [project webpage](https://eleboss.github.io/eaf_webpage/) for more information. 8 | 9 | ### Install the environment 10 | Install the [Matlab](https://www.mathworks.com/products/matlab.html) for your system. 11 | 12 | 13 | ### Download the dataset 14 | [https://doi.org/10.25442/hku.19407884.v1] 15 | 16 | ### Usage 17 | We provide the Matlab code of this work. Simply run the `egs.m` you can get the results. Please follow below steps: 18 | 1. download the EAD dataset provided on the project page 19 | 2. change the `start_path="..\EAD"` to your EAD path 20 | 3. uncomment the `% spliter = ":";` if you use Linux 21 | 4. run the code 22 | 23 | 24 | ### BibTex 25 | Please cite our work if you use the data or our code. 26 | ``` 27 | @inproceedings{lin2022autofocus, 28 | title={Autofocus for Event Cameras}, 29 | author={Shijie, Lin and Yinqiang, Zhang and Lei, Yu and Bin, Zhou and Xiaowei, Luo and Jia, Pan}, 30 | booktitle={The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)}, 31 | year={2022}, 32 | } 33 | ``` 34 | ### License 35 | 36 | MIT 37 | -------------------------------------------------------------------------------- /egs.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This code is an unoptimized version with square complexity. But it is still quite fast. We will release the optimized version with linear complexity once we have done the preparation. 3 | % Author: Shijie Lin 4 | % Email: lsj2048@connect.hku.hk 5 | % License: MIT 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | clc;clear;close all; 8 | format longG 9 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10 | timescale = 1e6; 11 | image_height = 260; 12 | image_width = 346; 13 | start_path = "..\EAD"; % your path to the EAD 14 | spliter = ";"; % for win 15 | % spliter = ":" % for linux 16 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17 | gt_path = fullfile(start_path, "gt_focus_points.txt"); 18 | fileID_score = fopen('result_egs_detail.txt','w'); % resutlt txt 19 | allSubFolders = genpath(start_path); 20 | % Parse into a cell array. 21 | remain = allSubFolders; 22 | listOfFolderNames = {}; 23 | while true 24 | [singleSubFolder, remain] = strtok(remain, spliter); 25 | if isempty(singleSubFolder) 26 | break; 27 | end 28 | listOfFolderNames = [listOfFolderNames singleSubFolder]; 29 | end 30 | numberOfFolders = length(listOfFolderNames); 31 | % Process all image files in those folders. 32 | for k = 1 : numberOfFolders 33 | % Get this folder and print it out. 34 | thisFolder = listOfFolderNames{k}; 35 | % Get MAT files. 36 | filePattern = sprintf('%s/*.mat', thisFolder); 37 | baseFileNames = dir(filePattern); 38 | numberOfImageFiles = length(baseFileNames); 39 | % Now we have a list of all files in this folder. 40 | if numberOfImageFiles >= 1 41 | thisFolder_sep=regexp(thisFolder,filesep,'split'); 42 | sequence_name = thisFolder_sep{end}; 43 | % Go through all those mat files. 44 | for f = 1 : numberOfImageFiles 45 | fullFileName = fullfile(thisFolder, baseFileNames(f).name); 46 | load(fullFileName); 47 | % load the focus position 48 | focus_position_file = fullfile(thisFolder, "focus_position.txt"); 49 | fileID = fopen(focus_position_file); 50 | focus_position_ts_list = textscan(fileID, '%f %f'); 51 | fclose(fileID); 52 | focus_position_list = focus_position_ts_list{2}; 53 | focus_timestamp_list = focus_position_ts_list{1}./ timescale; 54 | % load event data 55 | y_o = double(aedat.data.polarity.y); 56 | x_o = double(aedat.data.polarity.x); 57 | pol_o = double(aedat.data.polarity.polarity); 58 | focus_o = double(aedat.data.polarity.focusPosition); 59 | pol_o(pol_o==0) = -1; 60 | t_o = double(aedat.data.polarity.timeStamp) ./ timescale; 61 | t_o = t_o - t_o(1); 62 | % load Groundtruth 63 | gt_focus_file = gt_path; 64 | gt_focus_fileID = fopen(gt_focus_file); 65 | gt_focus = textscan(gt_focus_fileID, '%s %f'); 66 | gt_focus_seq_name_list = gt_focus{1}; 67 | find_return = strfind(gt_focus_seq_name_list, sequence_name); 68 | index_gt_foc = 0; 69 | for i=1:length(find_return) 70 | if find_return{i} == 1 71 | index_gt_foc = i; 72 | end 73 | end 74 | gt_focus_pos_list = gt_focus{2}; 75 | gt_focus_pos = gt_focus_pos_list(index_gt_foc); 76 | fclose(gt_focus_fileID); 77 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 78 | optimal_focus_time = realmax; 79 | optimal_focus_pos = realmax; 80 | prev_optimal_focus_time = 0; 81 | uptaded_focus_moving_step = realmax; 82 | stopping_threshold = 0.001; 83 | eventstart_time = t_o(1); 84 | eventend_time = t_o(end); 85 | golden_search_range = t_o(end) - t_o(1); 86 | while golden_search_range > stopping_threshold 87 | % -------------------------------------------- % 88 | % load data in a smaller subset 89 | % -------------------------------------------- % 90 | x = x_o; y = y_o; pol = pol_o; t = t_o; focus = focus_o; 91 | idx = (t>=eventstart_time)&(t<=eventend_time); 92 | y(idx~=1)=[]; 93 | x(idx~=1)=[]; 94 | pol(idx~=1)=[]; 95 | t(idx~=1)=[]; 96 | focus(idx~=1)=[]; 97 | % -------------------------------------------- % 98 | % computer ER to determine next best interval 99 | % -------------------------------------------- % 100 | event_rate = 0; 101 | event_rate_sec = 0; 102 | event_rate_list = []; 103 | event_rate_ts_list = []; 104 | time_range = t(end) - t(1); 105 | golden_search_range = time_range; 106 | delta_time = time_range * 0.618; 107 | event_size = length(t); 108 | fst_start_time = t(1); 109 | second_start_time = t(1) + time_range * 0.381; 110 | CAPTURE = true; 111 | CAPTURE_SEC = true; 112 | EV_FLAG = true; 113 | EV_FLAG_SEC = true; 114 | corres_focus_pos_list = []; 115 | for i = 1:event_size 116 | ev_t = t(i); 117 | ev_x = x(i) + 1; 118 | ev_y = y(i) + 1; 119 | ev_p = pol(i); 120 | ev_focus = focus(i); 121 | % -------------------------------------------- % 122 | % the first interval 123 | % -------------------------------------------- % 124 | if ev_t > fst_start_time && ev_t <= (fst_start_time + delta_time) && EV_FLAG 125 | event_rate = event_rate + 1; 126 | elseif ev_t > fst_start_time + delta_time && EV_FLAG 127 | event_rate = event_rate / delta_time; 128 | event_rate_list = [event_rate_list, event_rate]; 129 | event_rate_ts_list = [event_rate_ts_list, ev_t]; 130 | event_rate = 0; 131 | fst_start_time = ev_t; 132 | EV_FLAG = false; 133 | end 134 | if ev_t >= (fst_start_time + delta_time/2) && CAPTURE 135 | CAPTURE = false; 136 | corres_focus_pos_list(end+1) = ev_focus; 137 | end 138 | % -------------------------------------------- % 139 | % the second interval 140 | % -------------------------------------------- % 141 | if ev_t > second_start_time && ev_t <= (second_start_time + delta_time) && EV_FLAG_SEC 142 | event_rate_sec = event_rate_sec + 1; 143 | elseif ev_t > second_start_time + delta_time && EV_FLAG_SEC 144 | event_rate_sec = event_rate_sec / delta_time; 145 | event_rate_list = [event_rate_list, event_rate_sec]; 146 | event_rate_ts_list = [event_rate_ts_list, ev_t]; 147 | event_rate_sec = 0; 148 | second_start_time = ev_t; 149 | EV_FLAG_SEC = false; 150 | end 151 | if ev_t >= (second_start_time + delta_time/2) && CAPTURE_SEC 152 | CAPTURE_SEC = false; 153 | corres_focus_pos_list(end+1) = ev_focus; 154 | end 155 | end 156 | % find the optimal focus point 157 | [max_ev_rate, max_ev_rate_index] = max(event_rate_list); 158 | optimal_focus_time = event_rate_ts_list(max_ev_rate_index); 159 | optimal_focus_pos = corres_focus_pos_list(max_ev_rate_index); 160 | uptaded_focus_moving_step = abs(optimal_focus_time - prev_optimal_focus_time); 161 | prev_optimal_focus_time = optimal_focus_time; 162 | % give next best event interval 163 | eventstart_time = optimal_focus_time - delta_time; 164 | eventend_time = optimal_focus_time; 165 | end 166 | error_cal = (optimal_focus_pos - gt_focus_pos); 167 | % print the error and step size 168 | fprintf(' Processing mat file %s\n', fullFileName); 169 | disp(["optimal_f_pos:", optimal_focus_pos, "steps:", uptaded_focus_moving_step , "e_cal:", error_cal]) 170 | % record results in the text file 171 | fprintf(fileID_score,'%s & %.1f\n',sequence_name, error_cal); 172 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 173 | clearvars aedat 174 | end 175 | end 176 | end 177 | fclose(fileID_score); -------------------------------------------------------------------------------- /result_egs_detail.txt: -------------------------------------------------------------------------------- 1 | bottle_drone_dark_shake & 66.0 2 | bottle_drone_dark_static & -83.0 3 | bottle_drone_light_shake & -17.0 4 | bottle_drone_light_static & -86.0 5 | cactus_dark_shake & -236.0 6 | cactus_dark_static & -19.0 7 | cactus_light_shake & 45.0 8 | cactus_light_static & -137.0 9 | camel_dark_shake & 39.0 10 | camel_dark_static & -155.0 11 | camel_light_shake & 52.0 12 | camel_light_static & -12.0 13 | chinese_light_shake & -1.0 14 | chinese_light_static & -191.0 15 | construction_dark_shake & 18.0 16 | construction_dark_static & -44.0 17 | construction_light_shake & -41.0 18 | construction_light_static & 9.0 19 | crossroad_dark_shake & 32.0 20 | crossroad_dark_static & -44.0 21 | crossroad_light_shake & -23.0 22 | crossroad_light_static & 50.0 23 | focus_board_dark_shake & -14.0 24 | focus_board_dark_static & 6.0 25 | focus_board_light_shake & 24.0 26 | focus_board_light_static & -56.0 27 | piles_dark_shake & 49.0 28 | piles_dark_static & -28.0 29 | --------------------------------------------------------------------------------