├── .gitignore ├── CMakeLists.txt ├── EcoTrackerExtern.cc ├── EcoTrackerExtern.hpp ├── LICENSE ├── README.md ├── cvgputest.cc ├── cvgputest.png ├── debug.hpp ├── eco.cc ├── eco.hpp ├── eco_unittest.cc ├── feature_extractor.cc ├── feature_extractor.hpp ├── feature_operator.cc ├── feature_operator.hpp ├── ffttools.cc ├── ffttools.hpp ├── fhog.cc ├── fhog.hpp ├── gradient.cpp ├── gradient.hpp ├── interpolator.cc ├── interpolator.hpp ├── look_tables ├── CNnorm.txt ├── intensityChannelNorm11.txt ├── intensityChannelNorm16.txt └── intensityChannelNorm6.txt ├── metrics.cc ├── metrics.hpp ├── model ├── VGG_mean.binaryproto ├── imagenet-vgg-m-2048.prototxt └── imagenet-vgg-m-2048.prototxt.origin ├── optimize_scores.cc ├── optimize_scores.hpp ├── parameters.hpp ├── recttools.hpp ├── regularization_filter.cc ├── regularization_filter.hpp ├── sample_update.cc ├── sample_update.hpp ├── scale_filter.cc ├── scale_filter.hpp ├── sse.hpp ├── sse2neon.h ├── training.cc ├── training.hpp ├── vot.h ├── vot_eco.cpp └── wrappers.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | /Properties/launchSettings.json 2 | 3 | ## Ignore Visual Studio temporary files, build results, and 4 | ## files generated by popular Visual Studio add-ons. 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | AppData/ 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Dd]ebugPublic/ 20 | [Rr]elease/ 21 | [Rr]eleases/ 22 | x64/ 23 | x86/ 24 | build/ 25 | bld/ 26 | bin/ 27 | Bin/ 28 | obj/ 29 | Obj/ 30 | 31 | # Visual Studio 2015 cache/options directory 32 | .vs/ 33 | .vscode/ 34 | /wwwroot/dist/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | *_i.c 50 | *_p.c 51 | *_i.h 52 | *.ilk 53 | *.meta 54 | *.obj 55 | *.pch 56 | *.pdb 57 | *.pgc 58 | *.pgd 59 | *.rsp 60 | *.sbr 61 | *.tlb 62 | *.tli 63 | *.tlh 64 | *.tmp 65 | *.tmp_proj 66 | *.log 67 | *.vspscc 68 | *.vssscc 69 | .builds 70 | *.pidb 71 | *.svclog 72 | *.scc 73 | 74 | # Chutzpah Test files 75 | _Chutzpah* 76 | 77 | # Visual C++ cache files 78 | ipch/ 79 | *.aps 80 | *.ncb 81 | *.opendb 82 | *.opensdf 83 | *.sdf 84 | *.cachefile 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # NuGet Packages 149 | *.nupkg 150 | # The packages folder can be ignored because of Package Restore 151 | **/packages/* 152 | # except build/, which is used as an MSBuild target. 153 | !**/packages/build/ 154 | # Uncomment if necessary however generally it will be regenerated when needed 155 | #!**/packages/repositories.config 156 | 157 | # Microsoft Azure Build Output 158 | csx/ 159 | *.build.csdef 160 | 161 | # Microsoft Azure Emulator 162 | ecf/ 163 | rcf/ 164 | 165 | # Microsoft Azure ApplicationInsights config file 166 | ApplicationInsights.config 167 | 168 | # Windows Store app package directory 169 | AppPackages/ 170 | BundleArtifacts/ 171 | 172 | # Visual Studio cache files 173 | # files ending in .cache can be ignored 174 | *.[Cc]ache 175 | # but keep track of directories ending in .cache 176 | !*.[Cc]ache/ 177 | 178 | # Others 179 | ClientBin/ 180 | ~$* 181 | *~ 182 | *.dbmdl 183 | *.dbproj.schemaview 184 | *.pfx 185 | *.publishsettings 186 | orleans.codegen.cs 187 | 188 | /node_modules 189 | 190 | # RIA/Silverlight projects 191 | Generated_Code/ 192 | 193 | # Backup & report files from converting an old project file 194 | # to a newer Visual Studio version. Backup files are not needed, 195 | # because we have git ;-) 196 | _UpgradeReport_Files/ 197 | Backup*/ 198 | UpgradeLog*.XML 199 | UpgradeLog*.htm 200 | 201 | # SQL Server files 202 | *.mdf 203 | *.ldf 204 | 205 | # Business Intelligence projects 206 | *.rdl.data 207 | *.bim.layout 208 | *.bim_*.settings 209 | 210 | # Microsoft Fakes 211 | FakesAssemblies/ 212 | 213 | # GhostDoc plugin setting file 214 | *.GhostDoc.xml 215 | 216 | # Node.js Tools for Visual Studio 217 | .ntvs_analysis.dat 218 | 219 | # Visual Studio 6 build log 220 | *.plg 221 | 222 | # Visual Studio 6 workspace options file 223 | *.opt 224 | 225 | # Visual Studio LightSwitch build output 226 | **/*.HTMLClient/GeneratedArtifacts 227 | **/*.DesktopClient/GeneratedArtifacts 228 | **/*.DesktopClient/ModelManifest.xml 229 | **/*.Server/GeneratedArtifacts 230 | **/*.Server/ModelManifest.xml 231 | _Pvt_Extensions 232 | 233 | # Paket dependency manager 234 | .paket/paket.exe 235 | 236 | # FAKE - F# Make 237 | .fake/ 238 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(EcoTracker) 3 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_LIST_DIR}) 4 | include_directories(${CMAKE_CURRENT_LIST_DIR}) 5 | 6 | SET(CMAKE_CXX_STANDARD 11) 7 | SET(CMAKE_CXX_FLAGS "-O2 -lm") 8 | 9 | find_package(OpenCV REQUIRED) 10 | include_directories(${OpenCV_DIRS}) 11 | 12 | file(GLOB eco_srcs 13 | ${CMAKE_CURRENT_LIST_DIR}/*.hpp 14 | ${CMAKE_CURRENT_LIST_DIR}/*.h 15 | ${CMAKE_CURRENT_LIST_DIR}/eco.cc 16 | ${CMAKE_CURRENT_LIST_DIR}/feature_extractor.cc 17 | ${CMAKE_CURRENT_LIST_DIR}/feature_operator.cc 18 | ${CMAKE_CURRENT_LIST_DIR}/ffttools.cc 19 | ${CMAKE_CURRENT_LIST_DIR}/fhog.cc 20 | ${CMAKE_CURRENT_LIST_DIR}/interpolator.cc 21 | ${CMAKE_CURRENT_LIST_DIR}/metrics.cc 22 | ${CMAKE_CURRENT_LIST_DIR}/optimize_scores.cc 23 | ${CMAKE_CURRENT_LIST_DIR}/regularization_filter.cc 24 | ${CMAKE_CURRENT_LIST_DIR}/sample_update.cc 25 | ${CMAKE_CURRENT_LIST_DIR}/scale_filter.cc 26 | ${CMAKE_CURRENT_LIST_DIR}/training.cc 27 | ${CMAKE_CURRENT_LIST_DIR}/EcoTrackerExtern.cc) 28 | 29 | if(SIMD GREATER 0) 30 | set(eco_srcs ${eco_srcs} ${CMAKE_CURRENT_LIST_DIR}/gradient.cpp) 31 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_SIMD -msse4") 32 | endif() 33 | 34 | if(MULTI_THREAD GREATER 0) 35 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_MULTI_THREAD -pthread") 36 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lpthread") 37 | endif() 38 | 39 | #compile eco library 40 | add_library(ecotracker SHARED ${eco_srcs}) 41 | target_link_libraries(ecotracker ${OpenCV_LIBS}) 42 | 43 | install(TARGETS ecotracker 44 | RUNTIME DESTINATION bin 45 | LIBRARY DESTINATION lib 46 | ARCHIVE DESTINATION lib/static 47 | ) 48 | -------------------------------------------------------------------------------- /EcoTrackerExtern.cc: -------------------------------------------------------------------------------- 1 | #include "EcoTrackerExtern.hpp" 2 | 3 | eco::ECO* create() 4 | { 5 | eco::ECO *tracker = new eco::ECO(); 6 | return tracker; 7 | } 8 | 9 | void init(eco::ECO *tracker, cv::Mat *im, const cv::Rect2f *rect) 10 | { 11 | eco::EcoParameters parameters; 12 | (*tracker).init(*im, *rect, parameters); 13 | } 14 | 15 | bool update(eco::ECO *tracker, const cv::Mat *frame, cv::Rect2f *roi) 16 | { 17 | return (*tracker).update(*frame, *roi); 18 | } 19 | 20 | void dispose(eco::ECO *tracker) 21 | { 22 | delete tracker; 23 | } -------------------------------------------------------------------------------- /EcoTrackerExtern.hpp: -------------------------------------------------------------------------------- 1 | #include "eco.hpp" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | #ifdef _WIN32 7 | __declspec(dllexport) 8 | #endif 9 | eco::ECO* create(); 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | #ifdef _WIN32 18 | __declspec(dllexport) 19 | #endif 20 | void init(eco::ECO* tracker, cv::Mat* im, const cv::Rect2f* rect); 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | #ifdef _WIN32 29 | __declspec(dllexport) 30 | #endif 31 | bool update(eco::ECO* tracker, const cv::Mat* frame, cv::Rect2f* roi); 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | #ifdef _WIN32 40 | __declspec(dllexport) 41 | #endif 42 | void dispose(eco::ECO* tracker); 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EcoTracker 2 | Object tracker using ECO-HC algorithm 3 | 4 | ## Prerequisties 5 | - opencv 6 | 7 | ## Build 8 | ```bash 9 | git clone https://github.com/hez2010/EcoTracker.git 10 | cd EcoTracker 11 | mkdir build && cd build 12 | cmake .. -DSIMD=1 -DMULTI_THREAD=1 -DCMAKE_BUILD_TYPE=Release 13 | 14 | // for linux 15 | make -j8 16 | sudo make install 17 | 18 | // for Windows + Visual Studio 19 | msbuild EcoTracker.sln /p:Configuration=Release /p:TargetPlatform=x64 /m -verbosity:m 20 | ``` 21 | 22 | ## Note 23 | Please build with **Release** configuration, there're some problems with Debug configuration need to be resolved. 24 | 25 | ## Super quick start 26 | ```cpp 27 | eco::ECO *tracker = new eco::ECO(); 28 | eco::EcoParameters parameters; 29 | Rect2f roi = Rect2f(...); // initial ROI 30 | tracker->init(/* cv::Mat */ frame, /* cv::Rect2f */ roi, /* eco::EcoParameters */ parameters); 31 | 32 | // got an updated ROI on new frame 33 | tracker->update(/* cv::Mat */ frame, /* cv::Rect2f */ roi); 34 | ``` 35 | 36 | Provided C ABI for interop with other languages, see EcoTrackerExtern.hpp 37 | -------------------------------------------------------------------------------- /cvgputest.cc: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifdef USE_CUDA 9 | using namespace std; 10 | #include 11 | #include 12 | 13 | #define debug(a, args...) printf("%s(%s:%d) " a "\n", __func__, __FILE__, __LINE__, ##args) 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | try 18 | { 19 | cv::cuda::printCudaDeviceInfo(0); 20 | 21 | cv::Mat src_host = cv::imread("./cvgputest.png", CV_LOAD_IMAGE_GRAYSCALE); 22 | 23 | // upload to GPU: Mat -> GpuMat 24 | cv::cuda::GpuMat dst, src; 25 | src.upload(src_host); 26 | 27 | double timer = (double)cv::getTickCount(); 28 | float timedft = 0; 29 | 30 | cv::cuda::threshold(src, dst, 100.0, 255.0, CV_THRESH_BINARY); 31 | 32 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 33 | debug("GPU time: %f", timedft); 34 | 35 | // download to CPU: GpuMat -> Mat 36 | cv::Mat result_host; 37 | dst.download(result_host); 38 | 39 | cv::Mat dst_host; 40 | timer = (double)cv::getTickCount(); 41 | 42 | cv::threshold(src_host, dst_host, 100.0, 255.0, CV_THRESH_BINARY); 43 | 44 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 45 | debug("CPU time: %f", timedft); 46 | 47 | 48 | cv::cuda::multiply(dst, dst, dst); 49 | } 50 | catch (const cv::Exception &ex) 51 | { 52 | std::cout << "Error: " << ex.what() << std::endl; 53 | } 54 | return 0; 55 | } 56 | #endif -------------------------------------------------------------------------------- /cvgputest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hez2010/EcoTracker/9258c3a037ae2e7b462a85f5630392aa44f98d6c/cvgputest.png -------------------------------------------------------------------------------- /debug.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_HPP 2 | #define DEBUG_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include "parameters.hpp" 16 | 17 | namespace eco 18 | { 19 | #define debug(a, ...) //printf("%s(%s:%d) " a "\n", __func__, __FILE__, __LINE__, ##args) 20 | #define ddebug(a, ...) //printf("%s(%s:%d) " a "\n", __func__, __FILE__, __LINE__, ##args) 21 | 22 | using namespace std; 23 | 24 | void timerExample(); 25 | inline void timerExample() 26 | { 27 | std::clock_t start; 28 | double duration; 29 | 30 | start = std::clock(); 31 | 32 | /* Your algorithm here */ 33 | 34 | duration = (std::clock() - start) / (double)CLOCKS_PER_SEC; 35 | std::cout << "time: " << duration << '\n'; 36 | } 37 | 38 | void timerExampleCV(); 39 | inline void timerExampleCV() 40 | { 41 | double timer = (double)cv::getTickCount(); 42 | float timedft = 0; 43 | 44 | // your test code here 45 | 46 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 47 | debug("time: %f", timedft); 48 | } 49 | 50 | // Show the type of a Mat 51 | // Using like this: 52 | // string ty = type2str( im.type() ); 53 | // printf("im: %s %d x %d \n", ty.c_str(), im.cols, im.rows ); 54 | void printMat(cv::Mat mat); 55 | inline void printMat(cv::Mat mat) 56 | { 57 | int type = mat.type(); 58 | string r; 59 | 60 | uchar depth = type & CV_MAT_DEPTH_MASK; 61 | uchar chans = 1 + (type >> CV_CN_SHIFT); 62 | 63 | switch (depth) 64 | { 65 | case CV_8U: 66 | r = "8U"; 67 | break; 68 | case CV_8S: 69 | r = "8S"; 70 | break; 71 | case CV_16U: 72 | r = "16U"; 73 | break; 74 | case CV_16S: 75 | r = "16S"; 76 | break; 77 | case CV_32S: 78 | r = "32S"; 79 | break; 80 | case CV_32F: 81 | r = "32F"; 82 | break; 83 | case CV_64F: 84 | r = "64F"; 85 | break; 86 | default: 87 | r = "User"; 88 | break; 89 | } 90 | 91 | r += "C"; 92 | r += (chans + '0'); 93 | 94 | debug("%s %d x %d", r.c_str(), mat.rows, mat.cols); 95 | //return r; 96 | } 97 | 98 | void printECO_FEATS(ECO_FEATS a); 99 | inline void printECO_FEATS(ECO_FEATS a) 100 | { 101 | printMat(a[0][0]); 102 | for (size_t i = 0; i < a.size(); i++) 103 | { 104 | debug("%lu, %lu, %d x %d", i, a[i].size(), a[i][0].rows, a[i][0].cols); 105 | } 106 | } 107 | 108 | void printVector_Mat(std::vector a); 109 | inline void printVector_Mat(std::vector a) 110 | { 111 | printMat(a[0]); 112 | for (size_t i = 0; i < a.size(); i++) 113 | { 114 | debug("%lu, %lu, %d x %d", i, a.size(), a[i].rows, a[i].cols); 115 | } 116 | } 117 | 118 | void printMaxmin(); 119 | inline void printMaxmin(cv::Mat mat) 120 | { 121 | cv::Point p; 122 | double maxValue = -1, minValue = 256; 123 | cv::minMaxLoc(mat, &minValue, &maxValue, NULL, &p); 124 | printf("mat: min: %lf max: %lf loc: %d %d \n", minValue, maxValue, p.x, p.y); 125 | } 126 | 127 | void showmat1channels(cv::Mat mat, int type); 128 | inline void showmat1channels(cv::Mat mat, int type) 129 | { 130 | for (int i = 0; i < mat.rows; i++) 131 | { 132 | for (int j = 0; j < mat.cols; j++) 133 | { 134 | if (type == 0) 135 | { // char 136 | printf("%d ", mat.at(i, j)); 137 | } 138 | else if (type == 1) 139 | { // int 140 | printf("%d ", mat.at(i, j)); 141 | } 142 | else if (type == 2) 143 | { //float 144 | printf("%f ", mat.at(i, j)); 145 | } 146 | else if (type == 3) 147 | { //double 148 | printf("%lf ", mat.at(i, j)); 149 | } 150 | } 151 | printf("\n"); 152 | } 153 | printf("-------------------------End of 1 channel mat\n"); 154 | } 155 | 156 | void showmat2channels(cv::Mat mat, int type); 157 | 158 | inline void showmat2channels(cv::Mat mat, int type) 159 | { 160 | for (int k = 0; k < mat.channels(); k++) 161 | { 162 | printf("\n"); 163 | for (int i = 0; i < mat.rows; i++) 164 | { 165 | for (int j = 0; j < mat.cols; j++) 166 | { 167 | if (type == 0) 168 | { // char 169 | printf("%d ", mat.at(i, j)[k]); 170 | } 171 | else if (type == 1) 172 | { // int 173 | printf("%d ", mat.at(i, j)[k]); 174 | } 175 | else if (type == 2) 176 | { //float 177 | printf("%f ", mat.at(i, j)[k]); 178 | } 179 | else if (type == 3) 180 | { //float 181 | printf("%lf ", mat.at(i, j)[k]); 182 | } 183 | } 184 | printf("\n"); 185 | } 186 | printf("-------------------------"); 187 | } 188 | printf("End of 2 channels mat\n"); 189 | } 190 | 191 | void showmat3channels(cv::Mat mat, int type); 192 | 193 | inline void showmat3channels(cv::Mat mat, int type) 194 | { 195 | for (int k = 0; k < mat.channels(); k++) 196 | { 197 | for (int i = 0; i < mat.rows; i++) 198 | { 199 | for (int j = 0; j < mat.cols; j++) 200 | { 201 | if (type == 0) 202 | { // char 203 | printf("%d ", mat.at(i, j)[k]); 204 | } 205 | else if (type == 1) 206 | { // int 207 | printf("%d ", mat.at(i, j)[k]); 208 | } 209 | else if (type == 2) 210 | { //float 211 | printf("%f ", mat.at(i, j)[k]); 212 | } 213 | else if (type == 3) 214 | { //float 215 | printf("%lf ", mat.at(i, j)[k]); 216 | } 217 | } 218 | printf("\n"); 219 | } 220 | printf("\n\n"); 221 | break; 222 | } 223 | printf("End of 3 channel mat\n"); 224 | } 225 | 226 | void showmat1ch(cv::Mat mat, int type); 227 | inline void showmat1ch(cv::Mat mat, int type) 228 | { 229 | printf("\nFirst row: \n"); 230 | for (int j = 0; j < mat.cols; j++) 231 | { 232 | if (type == 1) 233 | { // int 234 | printf("%d ", mat.at(0, j)); 235 | } 236 | else if (type == 2) 237 | { //float 238 | printf("%f ", mat.at(0, j)); 239 | } 240 | else if (type == 3) 241 | { // first row 242 | printf("%lf ", mat.at(0, j)); 243 | } 244 | } 245 | printf("\nrow %d: \n", mat.cols - 1); 246 | for (int j = 0; j < mat.cols; j++) 247 | { 248 | if (type == 1) 249 | { // last row 250 | printf("%d ", mat.at(mat.cols - 1, j)); 251 | } 252 | else if (type == 2) 253 | { // last row 254 | printf("%f ", mat.at(mat.cols - 1, j)); 255 | } 256 | else if (type == 3) 257 | { // last row 258 | printf("%lf ", mat.at(mat.cols - 1, j)); 259 | } 260 | } 261 | printf("\nFirst col: \n"); 262 | for (int i = 0; i < mat.rows; i++) 263 | { 264 | if (type == 1) 265 | { // first col 266 | printf("%d ", mat.at(i, 0)); 267 | } 268 | else if (type == 2) 269 | { // first col 270 | printf("%f ", mat.at(i, 0)); 271 | } 272 | else if (type == 3) 273 | { // first col 274 | printf("%lf ", mat.at(i, 0)); 275 | } 276 | } 277 | printf("\ncol %d: \n", mat.rows - 1); 278 | for (int i = 0; i < mat.rows; i++) 279 | { 280 | if (type == 1) 281 | { // last col 282 | printf("%d ", mat.at(i, mat.rows - 1)); 283 | } 284 | else if (type == 2) 285 | { // last col 286 | printf("%f ", mat.at(i, mat.rows - 1)); 287 | } 288 | else if (type == 3) 289 | { // last col 290 | printf("%lf ", mat.at(i, mat.rows - 1)); 291 | } 292 | } 293 | printf("\nEnd of 2 channel mat\n"); 294 | } 295 | 296 | void showmat2ch(cv::Mat mat, int type); 297 | inline void showmat2ch(cv::Mat mat, int type) 298 | { 299 | printf("First row: \n"); 300 | for (int k = 0; k < mat.channels(); k++) 301 | { 302 | for (int j = 0; j < mat.cols; j++) 303 | { 304 | if (type == 3) 305 | { // first row 306 | printf("%lf ", mat.at(0, j)[k]); 307 | } 308 | } 309 | printf("\n\n"); 310 | } 311 | printf("\n"); 312 | printf("row %d: \n", mat.cols - 1); 313 | for (int k = 0; k < mat.channels(); k++) 314 | { 315 | for (int j = 0; j < mat.cols; j++) 316 | { 317 | if (type == 3) 318 | { // last row 319 | printf("%lf ", mat.at(mat.cols - 1, j)[k]); 320 | } 321 | } 322 | printf("\n\n"); 323 | } 324 | printf("\n"); 325 | printf("First col: \n"); 326 | for (int k = 0; k < mat.channels(); k++) 327 | { 328 | for (int i = 0; i < mat.rows; i++) 329 | { 330 | if (type == 3) 331 | { // first col 332 | printf("%lf ", mat.at(i, 0)[k]); 333 | } 334 | } 335 | printf("\n\n"); 336 | } 337 | printf("\n"); 338 | printf("col %d: \n", mat.rows - 1); 339 | for (int k = 0; k < mat.channels(); k++) 340 | { 341 | for (int i = 0; i < mat.rows; i++) 342 | { 343 | if (type == 3) 344 | { // last col 345 | printf("%lf ", mat.at(i, mat.rows - 1)[k]); 346 | } 347 | } 348 | printf("\n\n"); 349 | } 350 | printf("End of 2 channel mat\n"); 351 | } 352 | 353 | // Attention!!!! opencv/caffe: BGR, matlab: RGB, different order!!! 354 | void showmat3ch(cv::Mat mat, int type); 355 | inline void showmat3ch(cv::Mat mat, int type) 356 | { 357 | std::vector splitmat; 358 | cv::split(mat, splitmat); 359 | 360 | debug("channels: %lu", splitmat.size()); 361 | 362 | printf("First row of channel 0: \n"); 363 | for (int j = 0; j < mat.cols; j += 1) 364 | { 365 | if (type == 0) 366 | { // 2: means Red, 0 means first row 367 | printf("%d ", splitmat[2].at(0, j)); 368 | } 369 | else if (type == 1) 370 | { 371 | printf("%d ", splitmat[2].at(0, j)); 372 | } 373 | else if (type == 2) 374 | { 375 | printf("%f ", splitmat[2].at(0, j)); 376 | } 377 | else if (type == 3) 378 | { 379 | printf("%lf ", splitmat[2].at(0, j)); 380 | } 381 | } 382 | printf("\n\n"); 383 | 384 | printf("\n"); 385 | printf("First col of channel 0: \n"); 386 | for (int i = 0; i < mat.rows; i += 1) 387 | { 388 | if (type == 0) 389 | { 390 | printf("%d ", splitmat[2].at(i, 0)); 391 | } 392 | else if (type == 1) 393 | { 394 | printf("%d ", splitmat[2].at(i, 0)); 395 | } 396 | else if (type == 2) 397 | { 398 | printf("%f ", splitmat[2].at(i, 0)); 399 | } 400 | else if (type == 3) 401 | { 402 | printf("%lf ", splitmat[2].at(i, 0)); 403 | } 404 | } 405 | printf("\n\n"); 406 | 407 | printf("End of feature mat\n"); 408 | } 409 | 410 | void showmatNch(cv::Mat mat, int type); 411 | inline void showmatNch(cv::Mat mat, int type) 412 | { 413 | std::vector splitmat; 414 | cv::split(mat, splitmat); 415 | 416 | debug("channels: %lu", splitmat.size()); 417 | printf("1th row of channel 0: \n"); 418 | for (int j = 0; j < mat.cols; j += 1) 419 | { 420 | if (type == 0) 421 | { 422 | printf("%d ", splitmat[0].at(1, j)); 423 | } 424 | else if (type == 1) 425 | { // first row 426 | printf("%d ", splitmat[0].at(1, j)); 427 | } 428 | else if (type == 2) 429 | { // first row 430 | printf("%f ", splitmat[0].at(1, j)); 431 | } 432 | else if (type == 3) 433 | { // first row 434 | printf("%lf ", splitmat[0].at(1, j)); 435 | } 436 | } 437 | printf("\n"); 438 | printf("1th col of channel 0: \n"); 439 | for (int i = 0; i < mat.rows; i += 1) 440 | { 441 | if (type == 0) 442 | { // first row 443 | printf("%d ", splitmat[0].at(i, 1)); 444 | } 445 | else if (type == 1) 446 | { // first row 447 | printf("%d ", splitmat[0].at(i, 1)); 448 | } 449 | else if (type == 2) 450 | { // first row 451 | printf("%f ", splitmat[0].at(i, 1)); 452 | } 453 | else if (type == 3) 454 | { // first col 455 | printf("%lf ", splitmat[0].at(i, 1)); 456 | } 457 | } 458 | printf("\n"); 459 | printf("10th row of channel 0: \n"); 460 | for (int j = 0; j < mat.cols; j += 1) 461 | { 462 | if (type == 0) 463 | { 464 | printf("%d ", splitmat[0].at(10, j)); 465 | } 466 | else if (type == 1) 467 | { // first row 468 | printf("%d ", splitmat[0].at(10, j)); 469 | } 470 | else if (type == 2) 471 | { // first row 472 | printf("%f ", splitmat[0].at(10, j)); 473 | } 474 | else if (type == 3) 475 | { // first row 476 | printf("%lf ", splitmat[0].at(10, j)); 477 | } 478 | } 479 | printf("\n"); 480 | printf("20th col of channel 0: \n"); 481 | for (int i = 0; i < mat.rows; i += 1) 482 | { 483 | if (type == 0) 484 | { // first row 485 | printf("%d ", splitmat[0].at(i, 20)); 486 | } 487 | else if (type == 1) 488 | { // first row 489 | printf("%d ", splitmat[0].at(i, 20)); 490 | } 491 | else if (type == 2) 492 | { // first row 493 | printf("%f ", splitmat[0].at(i, 20)); 494 | } 495 | else if (type == 3) 496 | { // first col 497 | printf("%lf ", splitmat[0].at(i, 20)); 498 | } 499 | } 500 | printf("\n"); 501 | printf("24th row of channel -1: \n"); 502 | for (int j = 0; j < mat.cols; j += 1) 503 | { 504 | if (type == 0) 505 | { 506 | printf("%d ", splitmat[splitmat.size()-1].at(24, j)); 507 | } 508 | else if (type == 1) 509 | { // first row 510 | printf("%d ", splitmat[splitmat.size()-1].at(24, j)); 511 | } 512 | else if (type == 2) 513 | { // first row 514 | printf("%f ", splitmat[splitmat.size()-1].at(24, j)); 515 | } 516 | else if (type == 3) 517 | { // first row 518 | printf("%lf ", splitmat[splitmat.size()-1].at(24, j)); 519 | } 520 | } 521 | printf("\n\n"); 522 | printf("End of feature mat\n"); 523 | } 524 | 525 | //TEST========================================================================== 526 | // Simple test of the structure of mat in opencv; channel->x->y; 527 | void opencvTest(); 528 | inline void opencvTest() 529 | { 530 | printf("opencvTest begin=======================================\n"); 531 | float *newdata = (float *)malloc(sizeof(float) * (2 * 3 * 4)); 532 | 533 | for (int i = 0; i < 2 * 3 * 4; i++) 534 | { 535 | newdata[i] = i; 536 | } 537 | 538 | cv::Mat mat = cv::Mat(cv::Size(3, 4), CV_32FC(2), newdata); 539 | 540 | printf("\nInfo of original mat:"); 541 | printMat(mat); 542 | for (int i = 0; i < 2 * 3 * 4; i++) 543 | { 544 | printf("%f ", mat.at(0, i)); 545 | } 546 | printf("\n"); 547 | 548 | std::vector splitmat; 549 | cv::split(mat, splitmat); 550 | 551 | printf("\nInfo of splited mat:"); 552 | printMat(splitmat[0]); 553 | 554 | printf("channel 0:\n"); 555 | for (int j = 0; j < mat.rows; j++) 556 | { 557 | for (int i = 0; i < mat.cols; i++) 558 | { 559 | printf("%f ", splitmat[0].at(j, i)); 560 | } 561 | printf("\n"); 562 | } 563 | printf("\n"); 564 | printf("channel 1:\n"); 565 | for (int j = 0; j < mat.rows; j++) 566 | { 567 | for (int i = 0; i < mat.cols; i++) 568 | { 569 | printf("%f ", splitmat[1].at(j, i)); 570 | } 571 | printf("\n"); 572 | } 573 | printf("\n"); 574 | printf("%p, %p, %p, %p, %p\n", newdata, 575 | &mat.at(0, 0)[0], 576 | &mat.at(0, 0)[1], 577 | &mat.at(0, 1)[0], 578 | &mat.at(1, 0)[0] 579 | ); 580 | 581 | free(newdata); 582 | printf("opencvTest end=======================================\n"); 583 | } 584 | 585 | void absTest(); 586 | inline void absTest() 587 | { 588 | printf("absTest begin=======================================\n"); 589 | std::vector v{0.1, 0.2}; 590 | //sometimes this works: 591 | //``` 592 | //float abs = abs(1.23f); 593 | //``` 594 | //but it use a different liberay from eigen, cause error 595 | //so remember to add `std::` before! 596 | float abs = std::abs(1.23f); 597 | debug("False abs:%f", abs); 598 | 599 | abs = std::abs(1.23f); 600 | debug("True abs:%f", abs); 601 | printf("absTest end=======================================\n"); 602 | } 603 | 604 | void accumulateTest(); 605 | inline void accumulateTest() 606 | { 607 | printf("accumulateTest begin=======================================\n"); 608 | std::vector v{0.1, 0.2}; 609 | float sum = std::accumulate(v.begin(), v.end(), 0); 610 | debug("False sum:%f", sum); 611 | 612 | sum = std::accumulate(v.begin(), v.end(), 0.0f); 613 | debug("True sum:%f", sum); 614 | printf("accumulateTest end=======================================\n"); 615 | } 616 | /* Compare the differences of function copyTo() and clone(): 617 | [0, 0, 0, 0, 0] 618 | [0, 0, 0, 0, 0] 619 | [0, 0, 0, 0, 0] 620 | [1, 1, 1, 1, 1] 621 | */ 622 | void copyTo_clone_Difference(); 623 | inline void copyTo_clone_Difference() 624 | { 625 | // copyTo will not change the address of the destination matrix. 626 | cv::Mat mat1 = cv::Mat::ones(1, 5, CV_32F); 627 | cv::Mat mat2 = mat1; 628 | cv::Mat mat3 = cv::Mat::zeros(1, 5, CV_32F); 629 | mat3.copyTo(mat1); 630 | std::cout << mat1 << std::endl; // it has a old address with new value 631 | std::cout << mat2 << std::endl; // it has a old address with new value 632 | // clone will always allocate a new address for the destination matrix. 633 | mat1 = cv::Mat::ones(1, 5, CV_32F); 634 | mat2 = mat1; 635 | mat3 = cv::Mat::zeros(1, 5, CV_32F); 636 | mat1 = mat3.clone(); 637 | std::cout << mat1 << std::endl; // it has a new address with new value 638 | std::cout << mat2 << std::endl; // it has a old address with old value 639 | } 640 | 641 | void matReferenceTest(); 642 | inline void matReferenceTest() 643 | { 644 | cv::Mat mat; 645 | mat.release(); 646 | debug("%p, %d", mat.data, mat.data==NULL); 647 | mat.create(cv::Size(10, 10), CV_32FC2); 648 | debug("%p, %d", mat.data, mat.data==NULL); 649 | mat.release(); 650 | debug("%p, %d", mat.data, mat.data==NULL); 651 | } 652 | 653 | } 654 | #endif -------------------------------------------------------------------------------- /eco.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ECO_HPP 2 | #define ECO_HPP 3 | 4 | #define _USE_MATH_DEFINES 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifdef USE_CAFFE 14 | #include 15 | #include 16 | #endif 17 | /* 18 | #ifdef USE_CUDA 19 | #include 20 | #include 21 | #endif 22 | */ 23 | #ifdef USE_MULTI_THREAD 24 | #include 25 | #ifdef _WIN32 26 | #define NOMINMAX 27 | #include 28 | #define sleep(x) Sleep(x) 29 | #else 30 | #include 31 | #define sleep(x) usleep(x) 32 | #endif 33 | #endif 34 | 35 | #include "parameters.hpp" 36 | #include "interpolator.hpp" 37 | #include "regularization_filter.hpp" 38 | #include "feature_extractor.hpp" 39 | #include "feature_operator.hpp" 40 | #include "sample_update.hpp" 41 | #include "optimize_scores.hpp" 42 | #include "training.hpp" 43 | #include "ffttools.hpp" 44 | #include "scale_filter.hpp" 45 | #include "debug.hpp" 46 | 47 | namespace eco 48 | { 49 | class ECO 50 | { 51 | public: 52 | ECO() {}; 53 | virtual ~ECO() {} 54 | 55 | void init(cv::Mat &im, const cv::Rect2f &rect, const eco::EcoParameters ¶mters); 56 | 57 | bool update(const cv::Mat &frame, cv::Rect2f &roi); 58 | 59 | void init_parameters(const eco::EcoParameters ¶meters); 60 | 61 | void init_features(); 62 | #ifdef USE_CAFFE 63 | void read_deep_mean(const string &mean_file); 64 | #endif 65 | void yf_gaussian(); // the desired outputs of features, real part of (9) in paper C-COT 66 | 67 | void cos_window(); // construct cosine window of features; 68 | 69 | ECO_FEATS interpolate_dft(const ECO_FEATS &xlf, 70 | vector &interp1_fs, 71 | vector &interp2_fs); 72 | 73 | ECO_FEATS compact_fourier_coeff(const ECO_FEATS &xf); 74 | 75 | ECO_FEATS full_fourier_coeff(const ECO_FEATS &xf); 76 | 77 | vector project_mat_energy(vector proj, 78 | vector yf); 79 | 80 | ECO_FEATS shift_sample(ECO_FEATS &xf, 81 | cv::Point2f shift, 82 | std::vector kx, 83 | std::vector ky); 84 | #ifdef USE_MULTI_THREAD 85 | static void thread_train(void *params); 86 | #endif 87 | 88 | private: 89 | bool is_color_image_; 90 | EcoParameters params_; 91 | cv::Point2f pos_; // final result 92 | size_t frames_since_last_train_; // used for update; 93 | 94 | // The max size of feature and its index, output_sz is T in (9) of C-COT paper 95 | size_t output_size_, output_index_; 96 | 97 | cv::Size2f base_target_size_; // target size without scale 98 | cv::Size2i img_sample_size_; // base_target_sz * sarch_area_scale 99 | cv::Size2i img_support_size_; // the corresponding size in the image 100 | 101 | vector feature_size_, filter_size_; 102 | vector feature_dim_, compressed_dim_; 103 | 104 | ScaleFilter scale_filter_; 105 | int nScales_; // number of scales; 106 | float scale_step_; 107 | vector scale_factors_; 108 | float currentScaleFactor_; // current img scale 109 | 110 | // Compute the Fourier series indices 111 | // kx_, ky_ is the k in (9) of C-COT paper, yf_ is the left part of (9); 112 | vector ky_, kx_, yf_; 113 | vector interp1_fs_, interp2_fs_; 114 | vector cos_window_; 115 | vector projection_matrix_; 116 | 117 | vector reg_filter_; 118 | vector reg_energy_; 119 | 120 | FeatureExtractor feature_extractor_; 121 | 122 | SampleUpdate sample_update_; 123 | ECO_FEATS sample_energy_; 124 | 125 | EcoTrain eco_trainer_; 126 | 127 | ECO_FEATS hf_full_; 128 | 129 | #ifdef USE_MULTI_THREAD 130 | bool thread_flag_train_; 131 | public: 132 | std::thread *thread_train_ = nullptr; 133 | #endif 134 | 135 | }; 136 | 137 | } // namespace eco 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /eco_unittest.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // A sample program demonstrating using Google C++ testing framework. 31 | // 32 | // Author: wan@google.com (Zhanyong Wan) 33 | 34 | #include "gtest/gtest.h" 35 | #include "ffttools.hpp" 36 | #include "debug.hpp" 37 | 38 | #ifdef USE_FFTW 39 | #include 40 | #endif 41 | 42 | namespace 43 | { 44 | TEST(ffttoolsTest, dft_float) 45 | { 46 | int N = 5; 47 | cv::Mat_ mat_float(N, 2*N, CV_32FC1); 48 | for (int j = 0; j < mat_float.rows; j++) 49 | for (int i = 0; i < mat_float.cols; i++) 50 | mat_float.at(j, i) = i + j * mat_float.cols; 51 | //showmat1channels(mat_float, 2); 52 | 53 | double timer = (double)cv::getTickCount(); 54 | float timedft = 0; 55 | 56 | cv::Mat res = eco::dft(mat_float)/(mat_float.rows * mat_float.cols); 57 | //printMat(res); 58 | //showmat2channels(res, 2); 59 | 60 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 61 | debug("dft time: %f", timedft); 62 | timer = (double)cv::getTickCount(); 63 | 64 | res = eco::dft(res, 1); 65 | //showmat2channels(res, 2); 66 | 67 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 68 | debug("dft time: %f", timedft); 69 | } 70 | 71 | TEST(ffttoolsTest, dft_double) 72 | { 73 | int N = 5; 74 | cv::Mat_ mat_double(N, 2*N, CV_64FC1); 75 | for (int j = 0; j < mat_double.rows; j++) 76 | for (int i = 0; i < mat_double.cols; i++) 77 | mat_double.at(j, i) = i + j * mat_double.cols; 78 | //showmat1channels(mat_double, 3); 79 | 80 | double timer = (double)cv::getTickCount(); 81 | float timedft = 0; 82 | 83 | cv::Mat res = eco::dft(mat_double)/(mat_double.rows * mat_double.cols); 84 | //showmat2channels(res, 3); 85 | 86 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 87 | debug("dft_d time: %f", timedft); 88 | timer = (double)cv::getTickCount(); 89 | 90 | res = eco::dft(res, 1); 91 | //showmat2channels(res, 3); 92 | 93 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 94 | debug("dft_d time: %f", timedft); 95 | } 96 | /* 97 | TEST(ffttoolsTest, fftshift) 98 | { 99 | cv::Mat_ mat_float(10, 10, CV_32FC1); 100 | for (int j = 0; j < mat_float.rows; j++) 101 | for (int i = 0; i < mat_float.cols; i++) 102 | mat_float.at(j, i) = i + j * mat_float.cols; 103 | debug("channels: %d", mat_float.channels()); 104 | 105 | showmat1channels(mat_float, 2); 106 | cv::Mat res; 107 | res = eco::fftshift(mat_float); 108 | showmat1channels(res, 2); 109 | 110 | res = eco::dft(mat_float, 1); 111 | showmat2channels(res, 2); 112 | 113 | res = eco::fftshift(res); 114 | showmat2channels(res, 2); 115 | } 116 | 117 | TEST(ffttoolsTest, fftshift) 118 | { 119 | cv::Mat_ mat_double(10, 10, CV_32FC1); 120 | for (int j = 0; j < mat_double.rows; j++) 121 | for (int i = 0; i < mat_double.cols; i++) 122 | mat_double.at(j, i) = i + j * mat_double.cols; 123 | debug("channels: %d", mat_double.channels()); 124 | 125 | showmat1channels(mat_double, 3); 126 | cv::Mat res; 127 | res = eco::fftshift(mat_double); 128 | showmat1channels(res, 3); 129 | 130 | res = eco::dft_d(mat_double, 1); 131 | showmat2channels(res, 3); 132 | 133 | res = eco::fftshift(res); 134 | showmat2channels(res, 3); 135 | } 136 | 137 | TEST(ffttoolsTest, complexDotDivision) 138 | { 139 | cv::Mat mat_float(10, 10, CV_32FC2); 140 | for (int j = 0; j < mat_float.rows; j++) 141 | for (int i = 0; i < mat_float.cols; i++) 142 | { 143 | mat_float.at(j, i)[0] = i + j * mat_float.cols; 144 | mat_float.at(j, i)[1] = i + j * mat_float.cols; 145 | } 146 | debug("channels: %d", mat_float.channels()); 147 | showmat2channels(mat_float, 2); 148 | 149 | cv::Mat mat_float1(10, 10, CV_32FC2); 150 | for (int j = 0; j < mat_float1.rows; j++) 151 | for (int i = 0; i < mat_float1.cols; i++) 152 | { 153 | mat_float1.at(j, i)[0] = i + j * mat_float1.cols; 154 | mat_float1.at(j, i)[1] = -i; 155 | } 156 | debug("channels: %d", mat_float1.channels()); 157 | showmat2channels(mat_float1, 2); 158 | 159 | cv::Mat res; 160 | res = eco::complexDotDivision(mat_float, mat_float1); 161 | showmat2channels(res, 2); 162 | } 163 | 164 | TEST(ffttoolsTest, complexMatrixMultiplication) 165 | { 166 | cv::Mat mat_float(10, 10, CV_32FC2); 167 | for (int j = 0; j < mat_float.rows; j++) 168 | for (int i = 0; i < mat_float.cols; i++) 169 | { 170 | mat_float.at(j, i)[0] = i + j * mat_float.cols; 171 | mat_float.at(j, i)[1] = i + j * mat_float.cols; 172 | } 173 | debug("channels: %d", mat_float.channels()); 174 | showmat2channels(mat_float, 2); 175 | 176 | cv::Mat mat_float1(10, 10, CV_32FC2); 177 | for (int j = 0; j < mat_float1.rows; j++) 178 | for (int i = 0; i < mat_float1.cols; i++) 179 | { 180 | mat_float1.at(j, i)[0] = i + j * mat_float1.cols; 181 | mat_float1.at(j, i)[1] = -i; 182 | } 183 | debug("channels: %d", mat_float1.channels()); 184 | showmat2channels(mat_float1, 2); 185 | 186 | cv::Mat res; 187 | res = eco::complexMatrixMultiplication(mat_float, mat_float1); 188 | showmat2channels(res, 2); 189 | } 190 | 191 | TEST(ffttoolsTest, mat_sum_f) 192 | { 193 | cv::Mat_ mat_float(10, 10, CV_32FC1); 194 | for (int j = 0; j < mat_float.rows; j++) 195 | for (int i = 0; i < mat_float.cols; i++) 196 | mat_float.at(j, i) = i + j * mat_float.cols; 197 | 198 | EXPECT_EQ(4950, eco::mat_sum_f(mat_float)); 199 | } 200 | 201 | TEST(ffttoolsTest, mat_sum_d) 202 | { 203 | cv::Mat_ mat_double(10, 10, CV_64FC1); 204 | for (int j = 0; j < mat_double.rows; j++) 205 | for (int i = 0; i < mat_double.cols; i++) 206 | mat_double.at(j, i) = i + j * mat_double.cols; 207 | 208 | EXPECT_EQ(4950, eco::mat_sum_d(mat_double)); 209 | } 210 | 211 | TEST(ffttoolsTest, rot90) 212 | { 213 | cv::Mat_ mat_float(10, 10, CV_32FC1); 214 | for (int j = 0; j < mat_float.rows; j++) 215 | for (int i = 0; i < mat_float.cols; i++) 216 | mat_float.at(j, i) = i + j * mat_float.cols; 217 | 218 | showmat1channels(mat_float, 2); 219 | debug("=============="); 220 | eco::rot90(mat_float, 1); 221 | showmat1channels(mat_float, 2); 222 | debug("=============="); 223 | eco::rot90(mat_float, 2); 224 | showmat1channels(mat_float, 2); 225 | debug("=============="); 226 | eco::rot90(mat_float, 3); 227 | showmat1channels(mat_float, 2); 228 | } 229 | 230 | TEST(ffttoolsTest, complexConvolution) 231 | { 232 | cv::Mat mat_float(14, 14, CV_32FC2); 233 | for (int j = 0; j < mat_float.rows; j++) 234 | for (int i = 0; i < mat_float.cols; i++) 235 | { 236 | mat_float.at(j, i)[0] = i + j * mat_float.cols; 237 | mat_float.at(j, i)[1] = i + j * mat_float.cols; 238 | } 239 | debug("channels: %d", mat_float.channels()); 240 | showmat2channels(mat_float, 2); 241 | 242 | cv::Mat mat_float1(9, 9, CV_32FC2); 243 | for (int j = 0; j < mat_float1.rows; j++) 244 | for (int i = 0; i < mat_float1.cols; i++) 245 | { 246 | mat_float1.at(j, i)[0] = i + j * mat_float1.cols; 247 | mat_float1.at(j, i)[1] = -i; 248 | } 249 | debug("channels: %d", mat_float1.channels()); 250 | showmat2channels(mat_float1, 2); 251 | 252 | cv::Mat res; 253 | res = eco::complexConvolution(mat_float, mat_float1, 0); 254 | showmat2channels(res, 2); 255 | res = eco::complexConvolution(mat_float, mat_float1, 1); 256 | showmat2channels(res, 2); 257 | } 258 | 259 | TEST(debug, copyTo_clone_Difference) 260 | { 261 | copyTo_clone_Difference(); 262 | } 263 | */ 264 | 265 | TEST(ffttoolsTest, complexDotMultiplication) 266 | { 267 | int N = 5; 268 | cv::Mat mat_float(N, N*2, CV_32FC2); 269 | for (int j = 0; j < mat_float.rows; j++) 270 | for (int i = 0; i < mat_float.cols; i++) 271 | { 272 | mat_float.at(j, i)[0] = i + j * mat_float.cols; 273 | mat_float.at(j, i)[1] = i + j * mat_float.cols; 274 | } 275 | //showmat2channels(mat_float, 2); 276 | 277 | cv::Mat mat_float1(N, N*2, CV_32FC2); 278 | for (int j = 0; j < mat_float1.rows; j++) 279 | for (int i = 0; i < mat_float1.cols; i++) 280 | { 281 | mat_float1.at(j, i)[0] = i + j * mat_float1.cols; 282 | mat_float1.at(j, i)[1] = -i; 283 | } 284 | //showmat2channels(mat_float1, 2); 285 | 286 | // complexDotMultiplicationCPU 287 | cv::Mat res; 288 | res = eco::complexDotMultiplicationCPU(mat_float, mat_float1); 289 | int iter = 70; 290 | double timer = (double)cv::getTickCount(); 291 | float timedft = 0; 292 | while (iter > 0) 293 | { 294 | res = eco::complexDotMultiplicationCPU(mat_float, mat_float1); 295 | iter--; 296 | } 297 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 298 | debug("complexDotMultiplicationCPU time: %f", timedft); 299 | //showmat2channels(res, 2); 300 | 301 | // complexDotMultiplicationSIMD 302 | #ifdef USE_SIMD 303 | res = eco::complexDotMultiplicationSIMD(mat_float, mat_float1); 304 | iter = 70; 305 | timer = (double)cv::getTickCount(); 306 | while (iter > 0) 307 | { 308 | res = eco::complexDotMultiplicationSIMD(mat_float, mat_float1); 309 | iter--; 310 | } 311 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 312 | debug("complexDotMultiplicationSIMD time: %f", timedft); 313 | //showmat2channels(res, 2); 314 | #endif 315 | 316 | /* 317 | #ifdef USE_CUDA 318 | cv::cuda::setDevice(0); 319 | debug("%d", cv::cuda::getDevice()); 320 | //res = eco::complexDotMultiplicationGPU(mat_float, mat_float1); 321 | iter = 1; 322 | timer = (double)cv::getTickCount(); 323 | while (iter > 0) 324 | { 325 | res = eco::complexDotMultiplicationGPU(mat_float, mat_float1); 326 | iter--; 327 | } 328 | timedft = ((double)cv::getTickCount() - timer) / cv::getTickFrequency(); 329 | debug("complexDotMultiplicationGPU time: %f", timedft); 330 | //showmat2channels(res, 2); 331 | #endif 332 | */ 333 | }//TEST 334 | TEST(matReferenceTest, matReferenceTest) 335 | { 336 | eco::matReferenceTest(); 337 | } 338 | } //namespace -------------------------------------------------------------------------------- /feature_extractor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FEATURE_EXTRACTOR_HPP 2 | #define FEATURE_EXTRACTOR_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "parameters.hpp" 14 | #include "ffttools.hpp" 15 | #include "recttools.hpp" 16 | #include "fhog.hpp" 17 | #include "debug.hpp" 18 | 19 | #ifdef USE_SIMD 20 | #include "gradient.hpp" 21 | #endif 22 | 23 | #ifdef USE_CAFFE 24 | #include 25 | #include 26 | #include 27 | #endif 28 | 29 | namespace eco 30 | { 31 | class FeatureExtractor 32 | { 33 | public: 34 | FeatureExtractor() {} 35 | virtual ~FeatureExtractor(){}; 36 | 37 | ECO_FEATS extractor(const cv::Mat image, 38 | const cv::Point2f pos, 39 | const vector scales, 40 | const EcoParameters ¶ms, 41 | const bool &is_color_image); 42 | 43 | cv::Mat sample_patch(const cv::Mat im, 44 | const cv::Point2f pos, 45 | cv::Size2f sample_sz, 46 | cv::Size2f input_sz); 47 | 48 | #ifdef USE_SIMD 49 | vector get_hog_features_simd(const vector ims); 50 | #else 51 | vector get_hog_features(const vector ims); 52 | #endif 53 | vector hog_feature_normalization(vector &hog_feat_maps); 54 | inline vector get_hog_feats() const { return hog_feat_maps_; } 55 | 56 | vector get_cn_features(const vector ims); 57 | vector cn_feature_normalization(vector &cn_feat_maps); 58 | inline vector get_cn_feats() const { return cn_feat_maps_; } 59 | 60 | #ifdef USE_CAFFE 61 | ECO_FEATS get_cnn_layers(vector im, const cv::Mat &deep_mean_mat); 62 | cv::Mat sample_pool(const cv::Mat &im, int smaple_factor, int stride); 63 | void cnn_feature_normalization(ECO_FEATS &feature); 64 | inline ECO_FEATS get_cnn_feats() const { return cnn_feat_maps_; } 65 | #endif 66 | 67 | private: 68 | EcoParameters params_; 69 | 70 | HogFeatures hog_features_; 71 | int hog_feat_ind_ = -1; 72 | vector hog_feat_maps_; 73 | 74 | ColorspaceFeatures colorspace_features_; 75 | int colorspace_feat_ind_ = -1; 76 | vector colorspace_feat_maps_; 77 | 78 | CnFeatures cn_features_; 79 | int cn_feat_ind_ = -1; 80 | vector cn_feat_maps_; 81 | 82 | IcFeatures ic_features_; 83 | int ic_feat_ind_ = -1; 84 | vector ic_feat_maps_; 85 | 86 | #ifdef USE_CAFFE 87 | boost::shared_ptr> net_; 88 | CnnFeatures cnn_features_; 89 | int cnn_feat_ind_ = -1; 90 | ECO_FEATS cnn_feat_maps_; 91 | #endif 92 | }; 93 | } // namespace eco 94 | #endif 95 | -------------------------------------------------------------------------------- /feature_operator.cc: -------------------------------------------------------------------------------- 1 | #include "feature_operator.hpp" 2 | 3 | namespace eco 4 | { 5 | ECO_FEATS do_dft(const ECO_FEATS &xlw) 6 | { 7 | ECO_FEATS xlf; 8 | for (size_t i = 0; i < xlw.size(); i++) 9 | { 10 | std::vector temp; 11 | for (size_t j = 0; j < xlw[i].size(); j++) 12 | { 13 | int size = xlw[i][j].rows; 14 | if (size % 2 == 1) 15 | temp.push_back(fftshift(dft(xlw[i][j]))); 16 | else 17 | { 18 | cv::Mat xf = fftshift(dft(xlw[i][j])); 19 | cv::Mat xf_pad = subwindow(xf, cv::Rect(cv::Point(0, 0), cv::Size(size + 1, size + 1))); 20 | for (size_t k = 0; k < (size_t)xf_pad.rows; k++) 21 | { 22 | xf_pad.at>(size, k) = xf_pad.at>(size - 1, k).conj(); 23 | xf_pad.at>(k, size) = xf_pad.at>(k, size - 1).conj(); 24 | } 25 | temp.push_back(xf_pad); 26 | } 27 | } 28 | 29 | xlf.push_back(temp); 30 | } 31 | return xlf; 32 | } 33 | // Do the element-wise multiplication for the two matrix. 34 | ECO_FEATS do_windows(const ECO_FEATS &xl, vector &cos_win) 35 | { 36 | ECO_FEATS xlw; 37 | for (size_t i = 0; i < xl.size(); i++) // for each feature 38 | { 39 | vector temp; 40 | //debug("xl[%lu]: %lu", i, xl[i].size()); //96, 512, 31 41 | for (size_t j = 0; j < xl[i].size(); j++) // for the dimensions fo the feature 42 | temp.push_back(cos_win[i].mul(xl[i][j])); 43 | xlw.push_back(temp); 44 | } 45 | return xlw; 46 | } 47 | 48 | void FilterSymmetrize(ECO_FEATS &hf) 49 | { 50 | 51 | for (size_t i = 0; i < hf.size(); i++) 52 | { 53 | int dc_ind = (hf[i][0].rows + 1) / 2; 54 | for (size_t j = 0; j < (size_t)hf[i].size(); j++) 55 | { 56 | int c = hf[i][j].cols - 1; 57 | for (size_t r = dc_ind; r < (size_t)hf[i][j].rows; r++) 58 | { 59 | //cout << hf[i][j].at(r, c); 60 | hf[i][j].at(r, c) = hf[i][j].at(2 * dc_ind - r - 2, c).conj(); 61 | } 62 | } 63 | } 64 | } 65 | 66 | vector init_projection_matrix(const ECO_FEATS &init_sample, 67 | const vector &compressed_dim, 68 | const vector &feature_dim) 69 | { 70 | vector result; 71 | for (size_t i = 0; i < init_sample.size(); i++) // for each feature 72 | { 73 | // vectorize mat init_sample 74 | cv::Mat feat_vec(init_sample[i][0].size().area(), feature_dim[i], CV_32FC1); 75 | //cv::Mat mean(init_sample[i][0].size().area(), feature_dim[i], CV_32FC1); 76 | for (unsigned int j = 0; j < init_sample[i].size(); j++) // for each dimension of the feature 77 | { 78 | float mean = cv::mean(init_sample[i][j])[0]; // get the mean value of the mat; 79 | for (size_t r = 0; r < (size_t)init_sample[i][j].rows; r++) 80 | for (size_t c = 0; c < (size_t)init_sample[i][j].cols; c++) 81 | feat_vec.at(c * init_sample[i][j].rows + r, j) = init_sample[i][j].at(r, c) - mean; 82 | } 83 | result.push_back(feat_vec); 84 | } 85 | //printMat(result[0]); // 3844 x 31 86 | 87 | vector proj_mat; 88 | // do SVD and dimension reduction for each feature 89 | for (size_t i = 0; i < result.size(); i++) 90 | { 91 | cv::Mat S, V, D; 92 | cv::SVD::compute(result[i].t() * result[i], S, V, D); 93 | vector V_; 94 | V_.push_back(V); // real part 95 | V_.push_back(cv::Mat::zeros(V.size(), CV_32FC1)); // image part 96 | cv::merge(V_, V); // merge to 2 channel mat, represent a complex 97 | proj_mat.push_back(V.colRange(0, compressed_dim[i])); // get the previous compressed number components 98 | } 99 | 100 | return proj_mat; 101 | } 102 | // Do projection row vector x_mat[i] * projection_matrix[i] 103 | ECO_FEATS FeatureProjection(const ECO_FEATS &x, const std::vector &projection_matrix) 104 | { 105 | ECO_FEATS result; 106 | for (size_t i = 0; i < x.size(); i++) // for each feature 107 | { 108 | // vectorize the mat 109 | cv::Mat x_mat; 110 | for (size_t j = 0; j < x[i].size(); j++) // for each channel of original feature 111 | { 112 | // transform x[i][j]: 113 | // x1 x4 114 | // x2 x5 115 | // x3 x6 116 | // to [x1 x2 x3 x4 x5 x6] 117 | cv::Mat t = x[i][j].t(); 118 | x_mat.push_back(cv::Mat(1, x[i][j].size().area(), CV_32FC2, t.data)); // vectorize each channel map to row vector 119 | } 120 | //debug("x_mat %lu: %d x %d", i, x_mat.rows, x_mat.cols); 121 | x_mat = x_mat.t(); 122 | // do projection by matrix production 123 | cv::Mat res_temp = x_mat * projection_matrix[i]; // each col is a reduced feature 124 | 125 | // transform back to standard formation 126 | std::vector temp; 127 | for (size_t j = 0; j < (size_t)res_temp.cols; j++) // for each channel of reduced feature 128 | { 129 | cv::Mat temp2 = res_temp.col(j); // just a header of the col, no data copied 130 | cv::Mat tt; 131 | temp2.copyTo(tt); // the memory should be continous, prepare for transform back 132 | cv::Mat temp3(x[i][0].cols, x[i][0].rows, CV_32FC2, tt.data); 133 | temp.push_back(temp3.t()); 134 | } 135 | result.push_back(temp); 136 | } 137 | return result; 138 | } 139 | 140 | ECO_FEATS FeatureProjectionMultScale(const ECO_FEATS &x, const std::vector &projection_matrix) 141 | { 142 | ECO_FEATS result; 143 | //vector featsVec = FeatureVectorization(x); 144 | for (size_t i = 0; i < x.size(); i++) 145 | { 146 | int org_dim = projection_matrix[i].rows; 147 | int numScales = x[i].size() / org_dim; 148 | std::vector temp; 149 | 150 | for (size_t s = 0; s < (size_t)numScales; s++) // for every scale 151 | { 152 | cv::Mat x_mat; 153 | for (size_t j = s * org_dim; j < (s + 1) * org_dim; j++) 154 | { 155 | cv::Mat t = x[i][j].t(); 156 | x_mat.push_back(cv::Mat(1, x[i][j].size().area(), CV_32FC1, t.data)); 157 | } 158 | 159 | x_mat = x_mat.t(); 160 | 161 | cv::Mat res_temp = x_mat * real(projection_matrix[i]); 162 | 163 | //**** reconver to standard formation **** 164 | for (size_t j = 0; j < (size_t)res_temp.cols; j++) 165 | { 166 | cv::Mat temp2 = res_temp.col(j); 167 | cv::Mat tt; 168 | temp2.copyTo(tt); // the memory should be continous!!!!!!!!!! 169 | cv::Mat temp3(x[i][0].cols, x[i][0].rows, CV_32FC1, tt.data); //(x[i][0].cols, x[i][0].rows, CV_32FC2, temp2.data) int size[2] = { x[i][0].cols, x[i][0].rows };cv::Mat temp3 = temp2.reshape(2, 2, size) 170 | temp.push_back(temp3.t()); 171 | } 172 | } 173 | result.push_back(temp); 174 | } 175 | return result; 176 | } 177 | // inputs: a+bi, c+di; output: ac+bd; // gpu_implemented 178 | float FeatureComputeInnerProduct(const ECO_FEATS &feat1, const ECO_FEATS &feat2) 179 | { 180 | if (feat1.size() != feat2.size()) 181 | return 0; 182 | 183 | float dist = 0; 184 | for (size_t i = 0; i < feat1.size(); i++) 185 | { 186 | for (size_t j = 0; j < feat1[i].size(); j++) 187 | { 188 | cv::Mat feat2_conj = mat_conj(feat2[i][j]); 189 | dist += mat_sum_f(real(complexDotMultiplication(feat1[i][j], 190 | feat2_conj))); 191 | } 192 | } 193 | return dist; 194 | } 195 | // compute the energy of the feature 196 | // input: a+bi; output: a^2+b^2; // gpu_implemented 197 | float FeatureComputeEnergy(const ECO_FEATS &feat) 198 | { 199 | float res = 0; 200 | if (feat.empty()) 201 | return res; 202 | 203 | res = FeatureComputeInnerProduct(feat, feat); 204 | return res; 205 | } 206 | // compute the conv(feats) .* feats 207 | ECO_FEATS FeautreComputePower2(const ECO_FEATS &feats) 208 | { 209 | ECO_FEATS result; 210 | if (feats.empty()) 211 | { 212 | return feats; 213 | } 214 | 215 | for (size_t i = 0; i < feats.size(); i++) // for each feature 216 | { 217 | std::vector feat_vec; 218 | for (size_t j = 0; j < (size_t)feats[i].size(); j++) // for each dimension 219 | { 220 | cv::Mat temp(feats[i][0].size(), CV_32FC2); 221 | feats[i][j].copyTo(temp); 222 | for (size_t r = 0; r < (size_t)feats[i][j].rows; r++) 223 | { 224 | for (size_t c = 0; c < (size_t)feats[i][j].cols; c++) 225 | { 226 | temp.at(r, c)[0] = 227 | std::pow(temp.at(r, c)[0], 2) + 228 | std::pow(temp.at(r, c)[1], 2); 229 | temp.at(r, c)[1] = 0; 230 | } 231 | } 232 | feat_vec.push_back(temp); 233 | } 234 | result.push_back(feat_vec); 235 | } 236 | return result; 237 | } 238 | // sum up for each feature // gpu_implemented 239 | // DotMultiply for each dimension of each feature and 240 | // sum up all the dimensions for each feature 241 | std::vector FeatureComputeScores(const ECO_FEATS &x, 242 | const ECO_FEATS &f) 243 | { 244 | std::vector res; 245 | ECO_FEATS res_temp = FeatureDotMultiply(x, f); 246 | for (size_t i = 0; i < res_temp.size(); i++) // for each feature 247 | { 248 | cv::Mat temp(cv::Mat::zeros(res_temp[i][0].size(), 249 | res_temp[i][0].type())); 250 | for (size_t j = 0; j < res_temp[i].size(); j++) // for each dimension 251 | { 252 | temp = temp + res_temp[i][j]; 253 | } 254 | res.push_back(temp); 255 | } 256 | return res; 257 | } 258 | // vectorize features 259 | std::vector FeatureVectorization(const ECO_FEATS &x) 260 | { 261 | if (x.empty()) 262 | return std::vector(); 263 | 264 | std::vector res; 265 | for (size_t i = 0; i < x.size(); i++) 266 | { 267 | cv::Mat temp; 268 | for (size_t j = 0; j < x[i].size(); j++) 269 | { 270 | cv::Mat temp2 = x[i][j].t(); 271 | temp.push_back(cv::Mat(1, x[i][j].size().area(), 272 | CV_32FC2, temp2.data)); 273 | } 274 | res.push_back(temp); 275 | } 276 | return res; 277 | } 278 | 279 | ECO_FEATS FeatureVectorMultiply(const ECO_FEATS &x, 280 | const std::vector &y, 281 | const bool _conj) 282 | { 283 | if (x.size() != y.size()) 284 | assert(0 && "Feature and Vector Size Unmatched!"); 285 | 286 | ECO_FEATS res; 287 | for (size_t i = 0; i < x.size(); i++) 288 | { 289 | vector temp; 290 | for (size_t j = 0; j < x[i].size(); j++) 291 | { 292 | if (_conj) 293 | temp.push_back(complexDotMultiplication(mat_conj(x[i][j]), y[i])); 294 | else 295 | temp.push_back(complexDotMultiplication(x[i][j], y[i])); 296 | } 297 | res.push_back(temp); 298 | } 299 | return res; 300 | } 301 | 302 | // features operation 303 | ECO_FEATS FeatureDotMultiply(const ECO_FEATS &a, const ECO_FEATS &b) 304 | { 305 | ECO_FEATS res; 306 | if (a.size() != b.size()) 307 | assert(0 && "Unmatched feature size!"); 308 | 309 | for (size_t i = 0; i < a.size(); i++) 310 | { 311 | std::vector temp; 312 | for (size_t j = 0; j < a[i].size(); j++) 313 | { 314 | temp.push_back(complexDotMultiplication(a[i][j], b[i][j])); 315 | } 316 | res.push_back(temp); 317 | } 318 | return res; 319 | } 320 | ECO_FEATS FeatureDotDivide(const ECO_FEATS &a, const ECO_FEATS &b) 321 | { 322 | ECO_FEATS res; 323 | if (a.size() != b.size()) 324 | assert(0 && "Unmatched feature size!"); 325 | 326 | for (size_t i = 0; i < a.size(); i++) 327 | { 328 | std::vector temp; 329 | for (size_t j = 0; j < a[i].size(); j++) 330 | { 331 | temp.push_back(complexDotDivision(a[i][j], b[i][j])); 332 | } 333 | res.push_back(temp); 334 | } 335 | return res; 336 | } 337 | } // namespace eco -------------------------------------------------------------------------------- /feature_operator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FEATURE_OPERATOR_HPP 2 | #define FEATURE_OPERATOR_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include "parameters.hpp" 8 | #include "ffttools.hpp" 9 | #include "recttools.hpp" 10 | #include "debug.hpp" 11 | 12 | namespace eco 13 | { 14 | template 15 | extern std::vector operator+(const std::vector &a, 16 | const std::vector &b) 17 | { 18 | assert(a.size() == b.size()); 19 | std::vector result; 20 | for (unsigned int i = 0; i < a.size(); ++i) 21 | { 22 | result.push_back(a[i] + b[i]); 23 | } 24 | return result; 25 | } 26 | 27 | template 28 | extern std::vector operator-(const std::vector &a, 29 | const std::vector &b) 30 | { 31 | assert(a.size() == b.size()); 32 | std::vector result; 33 | for (unsigned int i = 0; i < a.size(); ++i) 34 | { 35 | result.push_back(a[i] - b[i]); 36 | } 37 | return result; 38 | } 39 | 40 | template 41 | extern std::vector operator*(const std::vector &a, const float scale) 42 | { 43 | std::vector result; 44 | for (unsigned int i = 0; i < a.size(); ++i) 45 | { 46 | result.push_back(a[i] * scale); 47 | } 48 | return result; 49 | } 50 | 51 | extern ECO_FEATS do_dft(const ECO_FEATS &xlw); 52 | extern ECO_FEATS do_windows(const ECO_FEATS &xl, vector &cos_win); 53 | 54 | extern void FilterSymmetrize(ECO_FEATS &hf); 55 | extern vector init_projection_matrix(const ECO_FEATS &init_sample, 56 | const vector &compressed_dim, 57 | const vector &feature_dim); 58 | extern ECO_FEATS FeatureProjection(const ECO_FEATS &x, 59 | const std::vector &projection_matrix); 60 | extern ECO_FEATS FeatureProjectionMultScale(const ECO_FEATS &x, 61 | const std::vector &projection_matrix); 62 | 63 | extern float FeatureComputeInnerProduct(const ECO_FEATS &feat1, 64 | const ECO_FEATS &feat2); 65 | extern float FeatureComputeEnergy(const ECO_FEATS &feat); 66 | extern ECO_FEATS FeautreComputePower2(const ECO_FEATS &feats); 67 | extern std::vector FeatureComputeScores(const ECO_FEATS &x, 68 | const ECO_FEATS &f); 69 | extern std::vector FeatureVectorization(const ECO_FEATS &x); 70 | 71 | extern ECO_FEATS FeatureVectorMultiply(const ECO_FEATS &x, 72 | const std::vector &y, 73 | const bool _conj = 0); // feature * yf 74 | 75 | extern ECO_FEATS FeatureDotMultiply(const ECO_FEATS &a, const ECO_FEATS &b); 76 | extern ECO_FEATS FeatureDotDivide(const ECO_FEATS &a, const ECO_FEATS &b); 77 | } // namespace eco 78 | 79 | #endif -------------------------------------------------------------------------------- /ffttools.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Author: Christian Bailer 3 | Contact address: Christian.Bailer@dfki.de 4 | Department Augmented Vision DFKI 5 | 6 | License Agreement 7 | For Open Source Computer Vision Library 8 | (3-clause BSD License) 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, 14 | this list of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, 17 | this list of conditions and the following disclaimer in the documentation 18 | and/or other materials provided with the distribution. 19 | 20 | * Neither the names of the copyright holders nor the names of the contributors 21 | may be used to endorse or promote products derived from this software 22 | without specific prior written permission. 23 | 24 | This software is provided by the copyright holders and contributors "as is" and 25 | any express or implied warranties, including, but not limited to, the implied 26 | warranties of merchantability and fitness for a particular purpose are disclaimed. 27 | In no event shall copyright holders or contributors be liable for any direct, 28 | indirect, incidental, special, exemplary, or consequential damages 29 | (including, but not limited to, procurement of substitute goods or services; 30 | loss of use, data, or profits; or business interruption) however caused 31 | and on any theory of liability, whether in contract, strict liability, 32 | or tort (including negligence or otherwise) arising in any way out of 33 | the use of this software, even if advised of the possibility of such damage. 34 | */ 35 | 36 | #ifndef FFTTOOLS_HPP 37 | #define FFTTOOLS_HPP 38 | 39 | #include 40 | #include "debug.hpp" 41 | /* 42 | #ifdef USE_CUDA 43 | #include 44 | #include 45 | #endif 46 | */ 47 | #ifdef USE_SIMD 48 | #include "sse.hpp" 49 | #include "wrappers.hpp" 50 | #endif 51 | 52 | #ifdef USE_FFTW 53 | #include 54 | #endif 55 | 56 | namespace eco 57 | { 58 | cv::Mat dft(const cv::Mat img_org, const bool backwards = false); 59 | cv::Mat fftshift(const cv::Mat img_org, 60 | const bool rowshift = true, 61 | const bool colshift = true, 62 | const bool reverse = 0); 63 | 64 | cv::Mat real(const cv::Mat img); 65 | cv::Mat imag(const cv::Mat img); 66 | cv::Mat magnitude(const cv::Mat img); 67 | cv::Mat complexDotMultiplication(const cv::Mat &a, const cv::Mat &b); 68 | cv::Mat complexDotMultiplicationCPU(const cv::Mat &a, const cv::Mat &b); 69 | #ifdef USE_SIMD 70 | cv::Mat complexDotMultiplicationSIMD(const cv::Mat &a, const cv::Mat &b); 71 | #endif 72 | /* 73 | #ifdef USE_CUDA 74 | cv::Mat complexDotMultiplicationGPU(const cv::Mat &a, const cv::Mat &b); 75 | #endif 76 | */ 77 | cv::Mat complexDotDivision(const cv::Mat a, const cv::Mat b); 78 | cv::Mat complexMatrixMultiplication(const cv::Mat &a, const cv::Mat &b); 79 | cv::Mat complexConvolution(const cv::Mat a_input, 80 | const cv::Mat b_input, 81 | const bool valid = 0); 82 | 83 | cv::Mat real2complex(const cv::Mat &x); 84 | cv::Mat mat_conj(const cv::Mat &org); 85 | float mat_sum_f(const cv::Mat &org); 86 | double mat_sum_d(const cv::Mat &org); 87 | 88 | inline bool SizeCompare(cv::Size &a, cv::Size &b) 89 | { 90 | return a.height < b.height; 91 | } 92 | 93 | inline void rot90(cv::Mat &matImage, int rotflag) 94 | { 95 | if (rotflag == 1) 96 | { 97 | cv::transpose(matImage, matImage); 98 | cv::flip(matImage, matImage, 1); // flip around y-axis 99 | } 100 | else if (rotflag == 2) 101 | { 102 | cv::transpose(matImage, matImage); 103 | cv::flip(matImage, matImage, 0); // flip around x-axis 104 | } 105 | else if (rotflag == 3) 106 | { 107 | cv::flip(matImage, matImage, -1); // flip around both axis 108 | } 109 | else if (rotflag != 0) // 0: keep the same 110 | { 111 | assert(0 && "error: unknown rotation flag!"); 112 | } 113 | } 114 | 115 | } // namespace eco 116 | 117 | #endif -------------------------------------------------------------------------------- /fhog.hpp: -------------------------------------------------------------------------------- 1 | /*M/////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 | // 5 | // By downloading, copying, installing or using the software you agree to this license. 6 | // If you do not agree to this license, do not download, install, 7 | // copy or use the software. 8 | // 9 | // 10 | // License Agreement 11 | // For Open Source Computer Vision Library 12 | // 13 | // Copyright (C) 2010-2013, University of Nizhny Novgorod, all rights reserved. 14 | // Third party copyrights are property of their respective owners. 15 | // 16 | // Redistribution and use in source and binary forms, with or without modification, 17 | // are permitted provided that the following conditions are met: 18 | // 19 | // * Redistribution's of source code must retain the above copyright notice, 20 | // this list of conditions and the following disclaimer. 21 | // 22 | // * Redistribution's in binary form must reproduce the above copyright notice, 23 | // this list of conditions and the following disclaimer in the documentation 24 | // and/or other materials provided with the distribution. 25 | // 26 | // * The name of the copyright holders may not be used to endorse or promote products 27 | // derived from this software without specific prior written permission. 28 | // 29 | // This software is provided by the copyright holders and contributors "as is" and 30 | // any express or implied warranties, including, but not limited to, the implied 31 | // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 | // In no event shall the Intel Corporation or contributors be liable for any direct, 33 | // indirect, incidental, special, exemplary, or consequential damages 34 | // (including, but not limited to, procurement of substitute goods or services; 35 | // loss of use, data, or profits; or business interruption) however caused 36 | // and on any theory of liability, whether in contract, strict liability, 37 | // or tort (including negligence or otherwise) arising in any way out of 38 | // the use of this software, even if advised of the possibility of such damage. 39 | // 40 | //M*/ 41 | 42 | //Modified from latentsvm module's "_lsvmc_latentsvm.h". 43 | 44 | /*****************************************************************************/ 45 | /* Latent SVM prediction API */ 46 | /*****************************************************************************/ 47 | 48 | #ifndef _FHOG_H_ 49 | #define _FHOG_H_ 50 | 51 | #include 52 | 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | namespace eco 60 | { 61 | // DataType: STRUCT featureMap 62 | // FEATURE MAP DESCRIPTION 63 | // Rectangular map (sizeX x sizeY), 64 | // every cell stores feature vector (dimension = numFeatures) 65 | // map - matrix of feature vectors 66 | // to set and get feature vectors (i,j) 67 | // used formula map[(j * sizeX + i) * p + k], where 68 | // k - component of feature vector in cell (i, j) 69 | typedef struct 70 | { 71 | int sizeX; 72 | int sizeY; 73 | int numFeatures; 74 | float *map; 75 | } CvLSVMFeatureMapCaskade; 76 | 77 | #include "float.h" 78 | 79 | #define PI CV_PI 80 | #define EPS 0.000001 81 | #define F_MAX FLT_MAX 82 | #define F_MIN -FLT_MAX 83 | 84 | // The number of elements in bin 85 | // The number of sectors in gradient histogram building 86 | #define NUM_SECTOR 9 87 | 88 | // The number of levels in image resize procedure 89 | // We need Lambda levels to resize image twice 90 | #define LAMBDA 10 91 | 92 | // Block size. Used in feature pyramid building procedure 93 | #define SIDE_LENGTH 8 94 | 95 | #define VAL_OF_TRUNCATE 0.2f 96 | 97 | //modified from "_lsvm_error.h" 98 | #define LATENT_SVM_OK 0 99 | #define LATENT_SVM_MEM_NULL 2 100 | #define DISTANCE_TRANSFORM_OK 1 101 | #define DISTANCE_TRANSFORM_GET_INTERSECTION_ERROR -1 102 | #define DISTANCE_TRANSFORM_ERROR -2 103 | #define DISTANCE_TRANSFORM_EQUAL_POINTS -3 104 | #define LATENT_SVM_GET_FEATURE_PYRAMID_FAILED -4 105 | #define LATENT_SVM_SEARCH_OBJECT_FAILED -5 106 | #define LATENT_SVM_FAILED_SUPERPOSITION -6 107 | #define FILTER_OUT_OF_BOUNDARIES -7 108 | #define LATENT_SVM_TBB_SCHEDULE_CREATION_FAILED -8 109 | #define LATENT_SVM_TBB_NUMTHREADS_NOT_CORRECT -9 110 | #define FFT_OK 2 111 | #define FFT_ERROR -10 112 | #define LSVM_PARSER_FILE_NOT_FOUND -11 113 | 114 | /* 115 | // Getting feature map for the selected subimage 116 | // 117 | // API 118 | // int getFeatureMaps(const IplImage * image, const int k, featureMap **map); 119 | // INPUT 120 | // image - selected subimage 121 | // k - size of cells 122 | // OUTPUT 123 | // map - feature map 124 | // RESULT 125 | // Error status 126 | */ 127 | int getFeatureMaps(const IplImage *image, const int k, 128 | CvLSVMFeatureMapCaskade **map); 129 | 130 | /* 131 | // Feature map Normalization and Truncation 132 | // 133 | // API 134 | // int normalizationAndTruncationFeatureMaps(featureMap *map, const float alfa); 135 | // INPUT 136 | // map - feature map 137 | // alfa - truncation threshold 138 | // OUTPUT 139 | // map - truncated and normalized feature map 140 | // RESULT 141 | // Error status 142 | */ 143 | int normalizeAndTruncate(CvLSVMFeatureMapCaskade *map, const float alfa); 144 | 145 | /* 146 | // Feature map reduction 147 | // In each cell we reduce dimension of the feature vector 148 | // according to original paper special procedure 149 | // 150 | // API 151 | // int PCAFeatureMaps(featureMap *map) 152 | // INPUT 153 | // map - feature map 154 | // OUTPUT 155 | // map - feature map 156 | // RESULT 157 | // Error status 158 | */ 159 | int PCAFeatureMaps(CvLSVMFeatureMapCaskade *map); 160 | 161 | int allocFeatureMapObject(CvLSVMFeatureMapCaskade **obj, 162 | const int sizeX, const int sizeY, const int p); 163 | 164 | int freeFeatureMapObject(CvLSVMFeatureMapCaskade **obj); 165 | } // namespace eco 166 | 167 | #endif 168 | -------------------------------------------------------------------------------- /gradient.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Piotr's Computer Vision Matlab Toolbox Version 3.30 3 | * Copyright 2014 Piotr Dollar & Ron Appel. [pdollar-at-gmail.com] 4 | * Licensed under the Simplified BSD License [see external/bsd.txt] 5 | *******************************************************************************/ 6 | 7 | #include "gradient.hpp" 8 | 9 | #define PI 3.14159265f 10 | 11 | // compute x and y gradients for just one column (uses sse) 12 | void grad1( float *I, float *Gx, float *Gy, int h, int w, int x ) { 13 | int y, y1; float *Ip, *In, r; __m128 *_Ip, *_In, *_G, _r; 14 | // compute column of Gx 15 | Ip=I-h; In=I+h; r=.5f; 16 | if(x==0) { r=1; Ip+=h; } else if(x==w-1) { r=1; In-=h; } 17 | // if h not 4x or address not 16-aligned, calculate normally, 18 | if( h<4 || h%4>0 || (size_t(I)&15) || (size_t(Gx)&15) ) { 19 | for( y=0; yh-1) y1=h-1; 32 | GRADY(1); Ip--; for(y=1; y PI-1e-6f ) a1[i]=PI-1e-6f; 58 | init=true; return a1; 59 | } 60 | 61 | // compute gradient magnitude and orientation at each location (uses sse) 62 | void gradMag( float *I, float *M, float *O, int h, int w, int d, bool full ) { 63 | int x, y, y1, c, h4, s; float *Gx, *Gy, *M2; __m128 *_Gx, *_Gy, *_M2, _m; 64 | float *acost = acosTable(), acMult=10000.0f; 65 | // allocate memory for storing one column of output (padded so h4%4==0) 66 | h4=(h%4==0) ? h : h-(h%4)+4; s=d*h4*sizeof(float); 67 | M2=(float*) alMalloc(s,16); _M2=(__m128*) M2; 68 | Gx=(float*) alMalloc(s,16); _Gx=(__m128*) Gx; 69 | Gy=(float*) alMalloc(s,16); _Gy=(__m128*) Gy; 70 | // compute gradient magnitude and orientation for each column 71 | for( x=0; x=oMax) o0=0; O0[i]=o0; 130 | M0[i]=M[i]*norm; M1[i]=0; O1[i]=0; 131 | } 132 | */ 133 | // speed-up version 134 | // perform the majority of the work with sse 135 | _O0=(__m128i*) O0; _O1=(__m128i*) O1; _M0=(__m128*) M0; _M1=(__m128*) M1; 136 | if( interpolate ) for( i=0; i<=n-4; i+=4 ) { 137 | _o=MUL(LDu(O[i]),_oMult); _o0=CVT(_o); _od=SUB(_o,CVT(_o0)); 138 | _o0=CVT(MUL(CVT(_o0),_nbf)); _o0=AND(CMPGT(_oMax,_o0),_o0); *_O0++=_o0; 139 | _o1=ADD(_o0,_nb); _o1=AND(CMPGT(_oMax,_o1),_o1); *_O1++=_o1; 140 | _m=MUL(LDu(M[i]),_norm); *_M1=MUL(_od,_m); *_M0++=SUB(_m,*_M1); _M1++; 141 | } else for( i=0; i<=n-4; i+=4 ) { 142 | _o=MUL(LDu(O[i]),_oMult); _o0=CVT(ADD(_o,SET(.5f))); 143 | _o0=CVT(MUL(CVT(_o0),_nbf)); _o0=AND(CMPGT(_oMax,_o0),_o0); *_O0++=_o0; 144 | *_M0++=MUL(LDu(M[i]),_norm); *_M1++=SET(0.f); *_O1++=SET(0); 145 | } 146 | // compute trailing locations without sse 147 | if( interpolate ) for(; i=oMax) o0=0; O0[i]=o0; 150 | o1=o0+nb; if(o1==oMax) o1=0; O1[i]=o1; 151 | m=M[i]*norm; M1[i]=od*m; M0[i]=m-M1[i]; 152 | } else for(; i=oMax) o0=0; O0[i]=o0; 155 | M0[i]=M[i]*norm; M1[i]=0; O1[i]=0; 156 | } 157 | } 158 | 159 | // compute nOrients gradient histograms per bin x bin block of pixels 160 | void gradHist( float *M, float *O, float *H, int h, int w, 161 | int bin, int nOrients, int softBin, bool full ) 162 | { 163 | const int hb=h/bin, wb=w/bin, h0=hb*bin, w0=wb*bin, nb=wb*hb; 164 | const float s=(float)bin, sInv=1/s, sInv2=1/s/s; 165 | float *H0, *H1, *M0, *M1; int x, y; int *O0, *O1; float xb, init; 166 | O0=(int*)alMalloc(h*sizeof(int),16); M0=(float*) alMalloc(h*sizeof(float),16); 167 | O1=(int*)alMalloc(h*sizeof(int),16); M1=(float*) alMalloc(h*sizeof(float),16); 168 | // main loop 169 | for( x=0; x=0); 173 | /* 174 | for (int i = 0; i < h; i++) 175 | { 176 | printf("%f ", *(O+i)); 177 | } 178 | printf("\nO end\n"); 179 | for (int i = 0; i < h; i++) 180 | { 181 | printf("%d ",*(O0+i)); 182 | } 183 | printf("\nO0 end\n"); 184 | for (int i = 0; i < h; i++) 185 | { 186 | printf("%f ", *(M0+i)); 187 | } 188 | printf("\nM0 end\n"); 189 | */ 190 | if( softBin<0 && softBin%2==0 ) { // softBin<0 and even 191 | // no interpolation w.r.t. either orienation or spatial bin 192 | H1=H+(x/bin)*hb; 193 | #define GH H1[O0[y]]+=M0[y]; y++; 194 | if( bin==1 ) for(y=0; y=0 and even 201 | // interpolate w.r.t. orientation only, not spatial bin 202 | H1=H+(x/bin)*hb; 203 | #define GH H1[O0[y]]+=M0[y]; H1[O1[y]]+=M1[y]; y++; 204 | if( bin==1 ) for(y=0; y=0; xb0 = hasLf?(int)xb:-1; hasRt = xb0 < wb-1; 216 | xd=xb-xb0; xb+=sInv; yb=init; y=0; 217 | // macros for code conciseness 218 | #define GHinit yd=yb-yb0; yb+=sInv; H0=H+xb0*hb+yb0; xyd=xd*yd; \ 219 | ms[0]=1-xd-yd+xyd; ms[1]=yd-xyd; ms[2]=xd-xyd; ms[3]=xyd; 220 | #define GH(H,ma,mb) H1=H; STRu(*H1,ADD(LDu(*H1),MUL(ma,mb))); 221 | // leading rows, no top bin 222 | for( ; y=hb-1) break; GHinit; 231 | // none speedup version 232 | if(hasLf) { H0[O0[y]+1]+=ms[1]*M0[y]; H0[O0[y]]+=ms[0]*M0[y]; } 233 | if(hasRt) { H0[O0[y]+hb+1]+=ms[3]*M0[y]; H0[O0[y]+hb]+=ms[2]*M0[y]; } 234 | // speedup version, have potential bugs 235 | // _m0=SET(M0[y]); 236 | // if(hasLf) { _m=SET(0,0,ms[1],ms[0]); GH(H0+O0[y],_m,_m0); } 237 | // if(hasRt) { _m=SET(0,0,ms[3],ms[2]); GH(H0+O0[y]+hb,_m,_m0); } 238 | } else for( ; ; y++ ) { //softBin > 0 odd 239 | yb0 = (int) yb; if(yb0>=hb-1) break; GHinit; 240 | // none speedup version 241 | if(hasLf) { 242 | H0[O0[y]+1]+=ms[1]*M0[y]; H0[O1[y]+1]+=ms[1]*M1[y]; 243 | H0[O0[y]]+=ms[0]*M0[y]; H0[O1[y]]+=ms[0]*M1[y]; } 244 | if(hasRt) { 245 | H0[O0[y]+hb+1]+=ms[3]*M0[y]; H0[O1[y]+hb+1]+=ms[3]*M1[y]; 246 | H0[O0[y]+hb]+=ms[2]*M0[y]; H0[O1[y]+hb]+=ms[2]*M1[y]; } 247 | // speedup version, have potential bugs 248 | /* _m0=SET(M0[y]); _m1=SET(M1[y]); 249 | if(hasLf) { _m=SET(0,0,ms[1],ms[0]); 250 | GH(H0+O0[y],_m,_m0); GH(H0+O1[y],_m,_m1); } 251 | if(hasRt) { _m=SET(0,0,ms[3],ms[2]); 252 | GH(H0+O0[y]+hb,_m,_m0); GH(H0+O1[y]+hb,_m,_m1); }*/ 253 | } 254 | // final rows, no bottom bin 255 | for( ; yclip) t=clip; c++; 301 | const float r=.2357f; int o, x, y, c; float t; 302 | const int nb=wb*hb, nbo=nOrients*nb, hb1=hb+1; 303 | for( o=0; o 11 | #include "string.h" 12 | #include "sse.hpp" 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | // compute x and y gradients for just one column (uses sse) 19 | void grad1(float *I, float *Gx, float *Gy, int h, int w, int x); 20 | 21 | // compute x and y gradients at each location (uses sse) 22 | void grad2(float *I, float *Gx, float *Gy, int h, int w, int d); 23 | 24 | // build lookup table a[] s.t. a[x*n]~=acos(x) for x in [-1,1] 25 | float *acosTable(); 26 | 27 | // compute gradient magnitude and orientation at each location (uses sse) 28 | void gradMag(float *I, float *M, float *O, int h, int w, int d, bool full); 29 | 30 | // normalize gradient magnitude at each location (uses sse) 31 | void gradMagNorm(float *M, float *S, int h, int w, float norm); 32 | 33 | // helper for gradHist, quantize O and M into O0, O1 and M0, M1 (uses sse) 34 | void gradQuantize(float *O, float *M, int *O0, int *O1, float *M0, float *M1, 35 | int nb, int n, float norm, int nOrients, bool full, bool interpolate); 36 | 37 | // compute nOrients gradient histograms per bin x bin block of pixels 38 | void gradHist(float *M, float *O, float *H, int h, int w, 39 | int bin, int nOrients, int softBin, bool full); 40 | 41 | /******************************************************************************/ 42 | 43 | // HOG helper: compute 2x2 block normalization values (padded by 1 pixel) 44 | float *hogNormMatrix(float *H, int nOrients, int hb, int wb, int bin); 45 | 46 | // HOG helper: compute HOG or FHOG channels 47 | void hogChannels(float *H, const float *R, const float *N, 48 | int hb, int wb, int nOrients, float clip, int type); 49 | 50 | // compute HOG features 51 | void hog(float *M, float *O, float *H, int h, int w, int binSize, 52 | int nOrients, int softBin, bool full, float clip); 53 | 54 | // compute FHOG features 55 | void fhog(float *M, float *O, float *H, int h, int w, int binSize, 56 | int nOrients, int softBin, float clip); 57 | 58 | #endif -------------------------------------------------------------------------------- /interpolator.cc: -------------------------------------------------------------------------------- 1 | #include "interpolator.hpp" 2 | 3 | namespace eco 4 | { 5 | Interpolator::Interpolator() {} 6 | 7 | Interpolator::~Interpolator() {} 8 | 9 | void Interpolator::get_interp_fourier(cv::Size filter_sz, 10 | cv::Mat &interp1_fs, 11 | cv::Mat &interp2_fs, 12 | float a) 13 | { 14 | cv::Mat temp1(filter_sz.height, 1, CV_32FC1); 15 | cv::Mat temp2(1, filter_sz.width, CV_32FC1); 16 | for (int j = 0; j < temp1.rows; j++) 17 | { 18 | temp1.at(j, 0) = j - temp1.rows / 2; 19 | } 20 | for (int j = 0; j < temp2.cols; j++) 21 | { 22 | temp2.at(0, j) = j - temp2.cols / 2; 23 | } 24 | 25 | interp1_fs = cubic_spline_fourier(temp1 / filter_sz.height, a) / filter_sz.height; 26 | interp2_fs = cubic_spline_fourier(temp2 / filter_sz.width, a) / filter_sz.width; 27 | 28 | // Multiply Fourier coeff with e ^ (-i*pi*k / N):[cos(pi*k/N), -sin(pi*k/N)] 29 | cv::Mat result1(temp1.size(), CV_32FC1), result2(temp1.size(), CV_32FC1); 30 | temp1 = temp1 / filter_sz.height; 31 | temp2 = temp2 / filter_sz.width; 32 | std::transform(temp1.begin(), temp1.end(), result1.begin(), Interpolator::mat_cos1); 33 | std::transform(temp1.begin(), temp1.end(), result2.begin(), Interpolator::mat_sin1); 34 | 35 | //cv::Mat planes1[] = {interp1_fs.mul(result1), -interp1_fs.mul(result2)}; 36 | //cv::merge(planes1, 2, interp1_fs); 37 | //interp2_fs = interp1_fs.t(); 38 | cv::Mat temp = cv::Mat(interp1_fs.size(), CV_32FC2); 39 | cv::Mat tempT = cv::Mat(interp1_fs.cols, interp1_fs.rows, CV_32FC2); 40 | for(int r = 0; r < temp1.rows; r++) 41 | { 42 | for(int c = 0; c < temp1.cols; c++) 43 | { 44 | 45 | temp.at(r, c)[0] = interp1_fs.at(r, c) * result1.at(r, c); 46 | temp.at(r, c)[1] = -interp1_fs.at(r, c) * result2.at(r, c); 47 | tempT.at(c, r)[0] = temp.at(r, c)[0]; 48 | tempT.at(c, r)[1] = temp.at(r, c)[1]; 49 | } 50 | } 51 | interp1_fs = temp; 52 | interp2_fs = tempT; 53 | } 54 | 55 | cv::Mat Interpolator::cubic_spline_fourier(cv::Mat f, float a) 56 | { 57 | if (f.empty()) 58 | { 59 | assert(0 && "error: input mat is empty!"); 60 | } 61 | /* 62 | cv::Mat bf(f.size(), CV_32FC1), 63 | temp_cos2(f.size(), CV_32FC1), 64 | temp_cos4(f.size(), CV_32FC1), 65 | temp_sin2(f.size(), CV_32FC1), 66 | temp_sin4(f.size(), CV_32FC1); 67 | std::transform(f.begin(), f.end(), temp_cos2.begin(), Interpolator::mat_cos2); 68 | std::transform(f.begin(), f.end(), temp_cos4.begin(), Interpolator::mat_cos4); 69 | std::transform(f.begin(), f.end(), temp_sin2.begin(), Interpolator::mat_sin2); 70 | std::transform(f.begin(), f.end(), temp_sin4.begin(), Interpolator::mat_sin4); 71 | 72 | bf = 6 * (cv::Mat::ones(f.size(), CV_32FC1) - temp_cos2) + 3 * a * (cv::Mat::ones(f.size(), CV_32FC1) - temp_cos4) - (6 + a * 8) * CV_PI * f.mul(temp_sin2) - 2 * a * CV_PI * f.mul(temp_sin4); 73 | 74 | cv::Mat L(f.size(), CV_32FC1); 75 | cv::pow(f, 4, L); 76 | cv::divide(bf, 4 * L * cv::pow(CV_PI, 4), bf); 77 | bf.at(bf.rows / 2, bf.cols / 2) = 1; 78 | */ 79 | cv::Mat bf(f.size(), CV_32FC1); 80 | for(int r = 0; r < bf.rows; r++) 81 | { 82 | for(int c = 0; c < bf.cols; c++) 83 | { 84 | bf.at(r, c) = 6.0f * (1 - cos(2.0f * f.at(r, c) * M_PI)) 85 | + 3.0f * a * (1.0f - cos(4 * f.at(r, c) * M_PI)) 86 | - (6.0f + a * 8.0f) * M_PI * f.at(r, c) * sin(2.0f * f.at(r, c) * M_PI) 87 | - 2.0f * a * M_PI * f.at(r, c) * sin(4.0f * f.at(r, c) * M_PI); 88 | float L = 4.0f * pow(f.at(r, c) * M_PI, 4); 89 | bf.at(r, c) /= L; 90 | } 91 | } 92 | bf.at(bf.rows / 2, bf.cols / 2) = 1; 93 | //printMat(bf); 94 | //showmat1channels(bf, 2); 95 | 96 | return bf; 97 | } 98 | } // namespace eco -------------------------------------------------------------------------------- /interpolator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INTERPOLATOR_HPP 2 | #define INTERPOLATOR_HPP 3 | 4 | #define _USE_MATH_DEFINES 5 | #include 6 | #include 7 | #include "debug.hpp" 8 | 9 | namespace eco{ 10 | class Interpolator 11 | { 12 | public: 13 | Interpolator(); 14 | virtual ~Interpolator(); 15 | static inline float mat_cos1(float x) 16 | { 17 | return (cos(x * M_PI)); 18 | } 19 | static inline float mat_sin1(float x) 20 | { 21 | return (sin(x * M_PI)); 22 | } 23 | static inline float mat_cos2(float x) 24 | { 25 | return (cos(2 * x * M_PI)); 26 | } 27 | static inline float mat_sin2(float x) 28 | { 29 | return (sin(2 * x * M_PI)); 30 | } 31 | static inline float mat_cos4(float x) 32 | { 33 | return (cos(4 * x * M_PI)); 34 | } 35 | static inline float mat_sin4(float x) 36 | { 37 | return (sin(4 * x * M_PI)); 38 | } 39 | 40 | static void get_interp_fourier(cv::Size filter_sz, 41 | cv::Mat &interp1_fs, 42 | cv::Mat &interp2_fs, 43 | float a); 44 | 45 | static cv::Mat cubic_spline_fourier(cv::Mat f, float a); 46 | }; 47 | } 48 | 49 | #endif -------------------------------------------------------------------------------- /look_tables/intensityChannelNorm11.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 0 0 0 0.50000000 0 0.35355338 0.18463723 2 | -0.048592184 0.00044041252 0 0 0 0 0.49937716 0 0.35355338 0.18463723 3 | -0.094541892 0.0017616501 0 0 0 0 0.49750865 0 0.35355338 0.18463723 4 | -0.13784912 0.0039637126 0 0 0 0 0.49439445 0 0.35355338 0.18463723 5 | -0.17851388 0.0070466003 0 0 0 0 0.49003461 0 0.35355338 0.18463723 6 | -0.21653616 0.011010313 0 0 0 0 0.48442906 0 0.35355338 0.18463723 7 | -0.25191596 0.015854850 0 0 0 0 0.47757787 0 0.35355338 0.18463723 8 | -0.28465331 0.021580214 0 0 0 0 0.46948096 0 0.35355338 0.18463723 9 | -0.31474817 0.028186401 0 0 0 0 0.46013841 0 0.35355338 0.18463723 10 | -0.34220055 0.035673413 0 0 0 0 0.44955018 0 0.35355338 0.18463723 11 | -0.36701044 0.044041254 0 0 0 0 0.43771628 0 0.35355338 0.18463723 12 | -0.38917786 0.053289916 0 0 0 0 0.42463669 0 0.35355338 0.18463723 13 | -0.40870282 0.063419402 0 0 0 0 0.41031143 0 0.35355338 0.18463723 14 | -0.42558530 0.074429721 0 0 0 0 0.39474049 0 0.35355338 0.18463723 15 | -0.43982533 0.086320855 0 0 0 0 0.37792388 0 0.35355338 0.18463723 16 | -0.45142284 0.099092819 0 0 0 0 0.35986158 0 0.35355338 0.18463723 17 | -0.46037790 0.11274561 0 0 0 0 0.34055364 0 0.35355338 0.18463723 18 | -0.46669048 0.12727922 0 0 0 0 0.31999999 0 0.35355338 0.18463723 19 | -0.47036058 0.14269365 0 0 0 0 0.29820070 0 0.35355338 0.18463723 20 | -0.47138822 0.15898892 0 0 0 0 0.27515572 0 0.35355338 0.18463723 21 | -0.46977335 0.17616501 0 0 0 0 0.25086504 0 0.35355338 0.18463723 22 | -0.46551603 0.19422193 0 0 0 0 0.22532871 0 0.35355338 0.18463723 23 | -0.45861626 0.21315967 0 0 0 0 0.19854671 0 0.35355338 0.18463723 24 | -0.44907397 0.23297822 0 0 0 0 0.17051902 0 0.35355338 0.18463723 25 | -0.43688923 0.25367761 0 0 0 0 0.14124568 0 0.35355338 0.18463723 26 | -0.42206201 0.27525783 0 0 0 0 0.11072665 0 0.35355338 0.18463723 27 | -0.40459231 0.29771888 0 0 0 0 0.078961939 0 0.35355338 0.18463723 28 | -0.38448015 0.32106075 0 0 0 0 0.045951556 0 0.35355338 0.18463723 29 | -0.36172548 0.34528342 0 0 0 0 0.011695501 0 0.35355338 0.18463723 30 | -0.33711132 0.36960399 0 0 0 0 -0.023252595 0 0.35355338 0.18463723 31 | -0.31318223 0.39147779 0 0 0 0 -0.057093427 0 0.35355338 0.18463723 32 | -0.29013398 0.41070914 0 0 0 0 -0.089688584 0 0.35355338 0.18463723 33 | -0.26796657 0.42729801 0 0 0 0 -0.12103806 0 0.35355338 0.18463723 34 | -0.24667995 0.44124442 0 0 0 0 -0.15114187 0 0.35355338 0.18463723 35 | -0.22627416 0.45254833 0 0 0 0 -0.18000001 0 0.35355338 0.18463723 36 | -0.20674922 0.46120977 0 0 0 0 -0.20761245 0 0.35355338 0.18463723 37 | -0.18810509 0.46722877 0 0 0 0 -0.23397924 0 0.35355338 0.18463723 38 | -0.17034177 0.47060525 0 0 0 0 -0.25910035 0 0.35355338 0.18463723 39 | -0.15345930 0.47133929 0 0 0 0 -0.28297579 0 0.35355338 0.18463723 40 | -0.13745764 0.46943083 0 0 0 0 -0.30560553 0 0.35355338 0.18463723 41 | -0.12233681 0.46487990 0 0 0 0 -0.32698962 0 0.35355338 0.18463723 42 | -0.10809681 0.45768648 0 0 0 0 -0.34712803 0 0.35355338 0.18463723 43 | -0.094737627 0.44785061 0 0 0 0 -0.36602077 0 0.35355338 0.18463723 44 | -0.082259275 0.43537226 0 0 0 0 -0.38366783 0 0.35355338 0.18463723 45 | -0.070661746 0.42025143 0 0 0 0 -0.40006921 0 0.35355338 0.18463723 46 | -0.059945039 0.40248811 0 0 0 0 -0.41522491 0 0.35355338 0.18463723 47 | -0.050109159 0.38208234 0 0 0 0 -0.42913494 0 0.35355338 0.18463723 48 | -0.041154105 0.35903409 0 0 0 0 -0.44179931 0 0.35355338 0.18463723 49 | -0.033079874 0.33334336 0 0 0 0 -0.45321798 0 0.35355338 0.18463723 50 | -0.025886470 0.30501014 0 0 0 0 -0.46339101 0 0.35355338 0.18463723 51 | -0.019573890 0.27403447 0 0 0 0 -0.47231835 0 0.35355338 0.18463723 52 | -0.014142135 0.24041630 0 0 0 0 -0.47999999 0 0.35355338 0.18463723 53 | -0.0095912060 0.20415567 0 0 0 0 -0.48643598 0 0.35355338 0.18463723 54 | -0.0059211017 0.16525257 0 0 0 0 -0.49162629 0 0.35355338 0.18463723 55 | -0.0031318225 0.12370699 0 0 0 0 -0.49557093 0 0.35355338 0.18463723 56 | -0.0012233681 0.079518929 0 0 0 0 -0.49826989 0 0.35355338 0.18463723 57 | -0.00019573890 0.032688398 0 0 0 0 -0.49972320 0 0.35355338 0.18463723 58 | 0 -0.016491003 4.8934726e-05 0 0 0 -0.49996540 3.4602075e-05 0.35350445 0.18463723 59 | 0 -0.064202361 0.00078295561 0 0 0 -0.49944636 0.00055363320 0.35277045 0.18463723 60 | 0 -0.10927124 0.0023978015 0 0 0 -0.49830449 0.0016955017 0.35115558 0.18463723 61 | 0 -0.15169765 0.0048934724 0 0 0 -0.49653980 0.0034602077 0.34865993 0.18463723 62 | 0 -0.19148158 0.0082699684 0 0 0 -0.49415225 0.0058477507 0.34528342 0.18463723 63 | 0 -0.22862303 0.012527290 0 0 0 -0.49114186 0.0088581312 0.34102610 0.18463723 64 | 0 -0.26312202 0.017665436 0 0 0 -0.48750865 0.012491349 0.33588797 0.18463723 65 | 0 -0.29497853 0.023684407 0 0 0 -0.48325258 0.016747406 0.32986897 0.18463723 66 | 0 -0.32419255 0.030584203 0 0 0 -0.47837371 0.021626297 0.32296920 0.18463723 67 | 0 -0.35076413 0.038364824 0 0 0 -0.47287196 0.027128028 0.31518856 0.18463723 68 | 0 -0.37469319 0.047026273 0 0 0 -0.46674740 0.033252597 0.30652711 0.18463723 69 | 0 -0.39597979 0.056568541 0 0 0 -0.46000001 0.039999999 0.29698485 0.18463723 70 | 0 -0.41462392 0.066991642 0 0 0 -0.45262975 0.047370244 0.28656176 0.18463723 71 | 0 -0.43062559 0.078295559 0 0 0 -0.44463667 0.055363324 0.27525783 0.18463723 72 | 0 -0.44398478 0.090480305 0 0 0 -0.43602076 0.063979238 0.26307309 0.18463723 73 | 0 -0.45470145 0.10354588 0 0 0 -0.42678201 0.073217995 0.25000751 0.18463723 74 | 0 -0.46277571 0.11749227 0 0 0 -0.41692042 0.083079584 0.23606111 0.18463723 75 | 0 -0.46820745 0.13231950 0 0 0 -0.40643600 0.093564011 0.22123389 0.18463723 76 | 0 -0.47099674 0.14802754 0 0 0 -0.39532873 0.10467128 0.20552585 0.18463723 77 | 0 -0.47114354 0.16461642 0 0 0 -0.38359863 0.11640138 0.18893698 0.18463723 78 | 0 -0.46864787 0.18208611 0 0 0 -0.37124568 0.12875433 0.17146727 0.18463723 79 | 0 -0.46350971 0.20043664 0 0 0 -0.35826990 0.14173010 0.15311676 0.18463723 80 | 0 -0.45572910 0.21966799 0 0 0 -0.34467128 0.15532872 0.13388541 0.18463723 81 | 0 -0.44530600 0.23978016 0 0 0 -0.33044982 0.16955018 0.11377323 0.18463723 82 | 0 -0.43224043 0.26077315 0 0 0 -0.31560555 0.18439446 0.092780240 0.18463723 83 | 0 -0.41653237 0.28264698 0 0 0 -0.30013841 0.19986159 0.070906416 0.18463723 84 | 0 -0.39818186 0.30540162 0 0 0 -0.28404844 0.21595156 0.048151769 0.18463723 85 | 0 -0.37718886 0.32903710 0 0 0 -0.26733565 0.23266436 0.024516298 0.18463723 86 | 0 -0.35355338 0.35355338 0 0 0 -0.25000000 0.25000000 1.3877788e-17 0.18463723 87 | 0 -0.32903710 0.37718886 0 0 0 -0.23266436 0.26733565 -0.024516298 0.18463723 88 | 0 -0.30540162 0.39818186 0 0 0 -0.21595156 0.28404844 -0.048151769 0.18463723 89 | 0 -0.28264698 0.41653237 0 0 0 -0.19986159 0.30013841 -0.070906416 0.18463723 90 | 0 -0.26077315 0.43224043 0 0 0 -0.18439446 0.31560555 -0.092780240 0.18463723 91 | 0 -0.23978016 0.44530600 0 0 0 -0.16955018 0.33044982 -0.11377323 0.18463723 92 | 0 -0.21966799 0.45572910 0 0 0 -0.15532872 0.34467128 -0.13388541 0.18463723 93 | 0 -0.20043664 0.46350971 0 0 0 -0.14173010 0.35826990 -0.15311676 0.18463723 94 | 0 -0.18208611 0.46864787 0 0 0 -0.12875433 0.37124568 -0.17146727 0.18463723 95 | 0 -0.16461642 0.47114354 0 0 0 -0.11640138 0.38359863 -0.18893698 0.18463723 96 | 0 -0.14802754 0.47099674 0 0 0 -0.10467128 0.39532873 -0.20552585 0.18463723 97 | 0 -0.13231950 0.46820745 0 0 0 -0.093564011 0.40643600 -0.22123389 0.18463723 98 | 0 -0.11749227 0.46277571 0 0 0 -0.083079584 0.41692042 -0.23606111 0.18463723 99 | 0 -0.10354588 0.45470145 0 0 0 -0.073217995 0.42678201 -0.25000751 0.18463723 100 | 0 -0.090480305 0.44398478 0 0 0 -0.063979238 0.43602076 -0.26307309 0.18463723 101 | 0 -0.078295559 0.43062559 0 0 0 -0.055363324 0.44463667 -0.27525783 0.18463723 102 | 0 -0.066991642 0.41462392 0 0 0 -0.047370244 0.45262975 -0.28656176 0.18463723 103 | 0 -0.056568541 0.39597979 0 0 0 -0.039999999 0.46000001 -0.29698485 0.18463723 104 | 0 -0.047026273 0.37469319 0 0 0 -0.033252597 0.46674740 -0.30652711 0.18463723 105 | 0 -0.038364824 0.35076413 0 0 0 -0.027128028 0.47287196 -0.31518856 0.18463723 106 | 0 -0.030584203 0.32419255 0 0 0 -0.021626297 0.47837371 -0.32296920 0.18463723 107 | 0 -0.023684407 0.29497853 0 0 0 -0.016747406 0.48325258 -0.32986897 0.18463723 108 | 0 -0.017665436 0.26312202 0 0 0 -0.012491349 0.48750865 -0.33588797 0.18463723 109 | 0 -0.012527290 0.22862303 0 0 0 -0.0088581312 0.49114186 -0.34102610 0.18463723 110 | 0 -0.0082699684 0.19148158 0 0 0 -0.0058477507 0.49415225 -0.34528342 0.18463723 111 | 0 -0.0048934724 0.15169765 0 0 0 -0.0034602077 0.49653980 -0.34865993 0.18463723 112 | 0 -0.0023978015 0.10927124 0 0 0 -0.0016955017 0.49830449 -0.35115558 0.18463723 113 | 0 -0.00078295561 0.064202361 0 0 0 -0.00055363320 0.49944636 -0.35277045 0.18463723 114 | 0 -4.8934726e-05 0.016491003 0 0 0 -3.4602075e-05 0.49996540 -0.35350445 0.18463723 115 | 0 0 -0.032688398 0.00019573890 0 0 0 0.49972320 -0.35355338 0.18463723 116 | 0 0 -0.079518929 0.0012233681 0 0 0 0.49826989 -0.35355338 0.18463723 117 | 0 0 -0.12370699 0.0031318225 0 0 0 0.49557093 -0.35355338 0.18463723 118 | 0 0 -0.16525257 0.0059211017 0 0 0 0.49162629 -0.35355338 0.18463723 119 | 0 0 -0.20415567 0.0095912060 0 0 0 0.48643598 -0.35355338 0.18463723 120 | 0 0 -0.24041630 0.014142135 0 0 0 0.47999999 -0.35355338 0.18463723 121 | 0 0 -0.27403447 0.019573890 0 0 0 0.47231835 -0.35355338 0.18463723 122 | 0 0 -0.30501014 0.025886470 0 0 0 0.46339101 -0.35355338 0.18463723 123 | 0 0 -0.33334336 0.033079874 0 0 0 0.45321798 -0.35355338 0.18463723 124 | 0 0 -0.35903409 0.041154105 0 0 0 0.44179931 -0.35355338 0.18463723 125 | 0 0 -0.38208234 0.050109159 0 0 0 0.42913494 -0.35355338 0.18463723 126 | 0 0 -0.40248811 0.059945039 0 0 0 0.41522491 -0.35355338 0.18463723 127 | 0 0 -0.42025143 0.070661746 0 0 0 0.40006921 -0.35355338 0.18463723 128 | 0 0 -0.43537226 0.082259275 0 0 0 0.38366783 -0.35355338 0.18463723 129 | 0 0 -0.44785061 0.094737627 0 0 0 0.36602077 -0.35355338 0.18463723 130 | 0 0 -0.45768648 0.10809681 0 0 0 0.34712803 -0.35355338 0.18463723 131 | 0 0 -0.46487990 0.12233681 0 0 0 0.32698962 -0.35355338 0.18463723 132 | 0 0 -0.46943083 0.13745764 0 0 0 0.30560553 -0.35355338 0.18463723 133 | 0 0 -0.47133929 0.15345930 0 0 0 0.28297579 -0.35355338 0.18463723 134 | 0 0 -0.47060525 0.17034177 0 0 0 0.25910035 -0.35355338 0.18463723 135 | 0 0 -0.46722877 0.18810509 0 0 0 0.23397924 -0.35355338 0.18463723 136 | 0 0 -0.46120977 0.20674922 0 0 0 0.20761245 -0.35355338 0.18463723 137 | 0 0 -0.45254833 0.22627416 0 0 0 0.18000001 -0.35355338 0.18463723 138 | 0 0 -0.44124442 0.24667995 0 0 0 0.15114187 -0.35355338 0.18463723 139 | 0 0 -0.42729801 0.26796657 0 0 0 0.12103806 -0.35355338 0.18463723 140 | 0 0 -0.41070914 0.29013398 0 0 0 0.089688584 -0.35355338 0.18463723 141 | 0 0 -0.39147779 0.31318223 0 0 0 0.057093427 -0.35355338 0.18463723 142 | 0 0 -0.36960399 0.33711132 0 0 0 0.023252595 -0.35355338 0.18463723 143 | 0 0 -0.34528342 0.36172548 0 0 0 -0.011695501 -0.35355338 0.18463723 144 | 0 0 -0.32106075 0.38448015 0 0 0 -0.045951556 -0.35355338 0.18463723 145 | 0 0 -0.29771888 0.40459231 0 0 0 -0.078961939 -0.35355338 0.18463723 146 | 0 0 -0.27525783 0.42206201 0 0 0 -0.11072665 -0.35355338 0.18463723 147 | 0 0 -0.25367761 0.43688923 0 0 0 -0.14124568 -0.35355338 0.18463723 148 | 0 0 -0.23297822 0.44907397 0 0 0 -0.17051902 -0.35355338 0.18463723 149 | 0 0 -0.21315967 0.45861626 0 0 0 -0.19854671 -0.35355338 0.18463723 150 | 0 0 -0.19422193 0.46551603 0 0 0 -0.22532871 -0.35355338 0.18463723 151 | 0 0 -0.17616501 0.46977335 0 0 0 -0.25086504 -0.35355338 0.18463723 152 | 0 0 -0.15898892 0.47138822 0 0 0 -0.27515572 -0.35355338 0.18463723 153 | 0 0 -0.14269365 0.47036058 0 0 0 -0.29820070 -0.35355338 0.18463723 154 | 0 0 -0.12727922 0.46669048 0 0 0 -0.31999999 -0.35355338 0.18463723 155 | 0 0 -0.11274561 0.46037790 0 0 0 -0.34055364 -0.35355338 0.18463723 156 | 0 0 -0.099092819 0.45142284 0 0 0 -0.35986158 -0.35355338 0.18463723 157 | 0 0 -0.086320855 0.43982533 0 0 0 -0.37792388 -0.35355338 0.18463723 158 | 0 0 -0.074429721 0.42558530 0 0 0 -0.39474049 -0.35355338 0.18463723 159 | 0 0 -0.063419402 0.40870282 0 0 0 -0.41031143 -0.35355338 0.18463723 160 | 0 0 -0.053289916 0.38917786 0 0 0 -0.42463669 -0.35355338 0.18463723 161 | 0 0 -0.044041254 0.36701044 0 0 0 -0.43771628 -0.35355338 0.18463723 162 | 0 0 -0.035673413 0.34220055 0 0 0 -0.44955018 -0.35355338 0.18463723 163 | 0 0 -0.028186401 0.31474817 0 0 0 -0.46013841 -0.35355338 0.18463723 164 | 0 0 -0.021580214 0.28465331 0 0 0 -0.46948096 -0.35355338 0.18463723 165 | 0 0 -0.015854850 0.25191596 0 0 0 -0.47757787 -0.35355338 0.18463723 166 | 0 0 -0.011010313 0.21653616 0 0 0 -0.48442906 -0.35355338 0.18463723 167 | 0 0 -0.0070466003 0.17851388 0 0 0 -0.49003461 -0.35355338 0.18463723 168 | 0 0 -0.0039637126 0.13784912 0 0 0 -0.49439445 -0.35355338 0.18463723 169 | 0 0 -0.0017616501 0.094541892 0 0 0 -0.49750865 -0.35355338 0.18463723 170 | 0 0 -0.00044041252 0.048592184 0 0 0 -0.49937716 -0.35355338 0.18463723 171 | 0 0 0 0 0 0 0 -0.50000000 -0.35355338 0.18463723 172 | 0 0 0 -0.048592184 0.00044041252 0.00025427228 0 -0.49968860 -0.35333318 0.18421558 173 | 0 0 0 -0.094541892 0.0017616501 0.0010170891 0 -0.49875432 -0.35267258 0.18295059 174 | 0 0 0 -0.13784912 0.0039637126 0.0022884507 0 -0.49719724 -0.35157153 0.18084227 175 | 0 0 0 -0.17851388 0.0070466003 0.0040683565 0 -0.49501729 -0.35003009 0.17789063 176 | 0 0 0 -0.21653616 0.011010313 0.0063568074 0 -0.49221453 -0.34804824 0.17409566 177 | 0 0 0 -0.25191596 0.015854850 0.0091538029 0 -0.48878893 -0.34562597 0.16945738 178 | 0 0 0 -0.28465331 0.021580214 0.012459342 0 -0.48474050 -0.34276327 0.16397576 179 | 0 0 0 -0.31474817 0.028186401 0.016273426 0 -0.48006919 -0.33946019 0.15765081 180 | 0 0 0 -0.34220055 0.035673413 0.020596055 0 -0.47477508 -0.33571669 0.15048254 181 | 0 0 0 -0.36701044 0.044041254 0.025427230 0 -0.46885812 -0.33153278 0.14247094 182 | 0 0 0 -0.38917786 0.053289916 0.030766947 0 -0.46231833 -0.32690844 0.13361603 183 | 0 0 0 -0.40870282 0.063419402 0.036615212 0 -0.45515570 -0.32184368 0.12391778 184 | 0 0 0 -0.42558530 0.074429721 0.042972017 0 -0.44737023 -0.31633854 0.11337621 185 | 0 0 0 -0.43982533 0.086320855 0.049837369 0 -0.43896192 -0.31039298 0.10199131 186 | 0 0 0 -0.45142284 0.099092819 0.057211265 0 -0.42993081 -0.30400699 0.089763083 187 | 0 0 0 -0.46037790 0.11274561 0.065093704 0 -0.42027682 -0.29718059 0.076691538 188 | 0 0 0 -0.46669048 0.12727922 0.073484689 0 -0.41000000 -0.28991377 0.062776662 189 | 0 0 0 -0.47036058 0.14269365 0.082384221 0 -0.39910033 -0.28220657 0.048018459 190 | 0 0 0 -0.47138822 0.15898892 0.091792300 0 -0.38757786 -0.27405894 0.032416932 191 | 0 0 0 -0.46977335 0.17616501 0.10170892 0 -0.37543252 -0.26547089 0.015972080 192 | 0 0 0 -0.46551603 0.19422193 0.11213408 0 -0.36266437 -0.25644243 -0.0013160993 193 | 0 0 0 -0.45861626 0.21315967 0.12306779 0 -0.34927335 -0.24697356 -0.019447604 194 | 0 0 0 -0.44907397 0.23297822 0.13451004 0 -0.33525953 -0.23706427 -0.038422436 195 | 0 0 0 -0.43688923 0.25367761 0.14646085 0 -0.32062283 -0.22671458 -0.058240589 196 | 0 0 0 -0.42206201 0.27525783 0.15892018 0 -0.30536333 -0.21592447 -0.078902073 197 | 0 0 0 -0.40459231 0.29771888 0.17188807 0 -0.28948095 -0.20469396 -0.10040688 198 | 0 0 0 -0.38448015 0.32106075 0.18536450 0 -0.27297577 -0.19302303 -0.12275501 199 | 0 0 0 -0.36172548 0.34528342 0.19934948 0 -0.25584775 -0.18091168 -0.14594647 200 | 0 0 0 -0.33711132 0.36960399 0.21361698 0 -0.23837370 -0.16855566 -0.16960645 201 | 0 0 0 -0.31318223 0.39147779 0.22743244 0 -0.22145329 -0.15659112 -0.19251679 202 | 0 0 0 -0.29013398 0.41070914 0.24073936 0 -0.20515572 -0.14506699 -0.21458381 203 | 0 0 0 -0.26796657 0.42729801 0.25353771 0 -0.18948098 -0.13398328 -0.23580752 204 | 0 0 0 -0.24667995 0.44124442 0.26582757 0 -0.17442906 -0.12333997 -0.25618789 205 | 0 0 0 -0.22627416 0.45254833 0.27760884 0 -0.16000000 -0.11313708 -0.27572495 206 | 0 0 0 -0.20674922 0.46120977 0.28888157 0 -0.14619377 -0.10337461 -0.29441866 207 | 0 0 0 -0.18810509 0.46722877 0.29964578 0 -0.13301039 -0.094052546 -0.31226906 208 | 0 0 0 -0.17034177 0.47060525 0.30990142 0 -0.12044983 -0.085170887 -0.32927611 209 | 0 0 0 -0.15345930 0.47133929 0.31964853 0 -0.10851211 -0.076729648 -0.34543988 210 | 0 0 0 -0.13745764 0.46943083 0.32888708 0 -0.097197235 -0.068728819 -0.36076030 211 | 0 0 0 -0.12233681 0.46487990 0.33761710 0 -0.086505190 -0.061168406 -0.37523738 212 | 0 0 0 -0.10809681 0.45768648 0.34583858 0 -0.076435983 -0.054048404 -0.38887116 213 | 0 0 0 -0.094737627 0.44785061 0.35355151 0 -0.066989623 -0.047368813 -0.40166160 214 | 0 0 0 -0.082259275 0.43537226 0.36075589 0 -0.058166090 -0.041129638 -0.41360870 215 | 0 0 0 -0.070661746 0.42025143 0.36745173 0 -0.049965397 -0.035330873 -0.42471251 216 | 0 0 0 -0.059945039 0.40248811 0.37363902 0 -0.042387545 -0.029972520 -0.43497297 217 | 0 0 0 -0.050109159 0.38208234 0.37931776 0 -0.035432525 -0.025054580 -0.44439009 218 | 0 0 0 -0.041154105 0.35903409 0.38448796 0 -0.029100345 -0.020577053 -0.45296392 219 | 0 0 0 -0.033079874 0.33334336 0.38914961 0 -0.023391003 -0.016539937 -0.46069440 220 | 0 0 0 -0.025886470 0.30501014 0.39330274 0 -0.018304499 -0.012943235 -0.46758157 221 | 0 0 0 -0.019573890 0.27403447 0.39694729 0 -0.013840831 -0.0097869448 -0.47362539 222 | 0 0 0 -0.014142135 0.24041630 0.40008333 0 -0.0099999998 -0.0070710676 -0.47882590 223 | 0 0 0 -0.0095912060 0.20415567 0.40271080 0 -0.0067820069 -0.0047956030 -0.48318309 224 | 0 0 0 -0.0059211017 0.16525257 0.40482974 0 -0.0041868514 -0.0029605508 -0.48669693 225 | 0 0 0 -0.0031318225 0.12370699 0.40644014 0 -0.0022145328 -0.0015659112 -0.48936749 226 | 0 0 0 -0.0012233681 0.079518929 0.40754199 0 -0.00086505193 -0.00061168405 -0.49119467 227 | 0 0 0 -0.00019573890 0.032688398 0.40813529 0 -0.00013840830 -9.7869452e-05 -0.49217856 228 | 0 0 0 0 -0.016491003 0.40816355 0 0 1.3877788e-17 -0.49236596 229 | 0 0 0 0 -0.064202361 0.40689218 0 0 1.3877788e-17 -0.49236596 230 | 0 0 0 0 -0.10927124 0.40409517 0 0 1.3877788e-17 -0.49236596 231 | 0 0 0 0 -0.15169765 0.39977255 0 0 1.3877788e-17 -0.49236596 232 | 0 0 0 0 -0.19148158 0.39392430 0 0 1.3877788e-17 -0.49236596 233 | 0 0 0 0 -0.22862303 0.38655040 0 0 1.3877788e-17 -0.49236596 234 | 0 0 0 0 -0.26312202 0.37765086 0 0 1.3877788e-17 -0.49236596 235 | 0 0 0 0 -0.29497853 0.36722571 0 0 1.3877788e-17 -0.49236596 236 | 0 0 0 0 -0.32419255 0.35527489 0 0 1.3877788e-17 -0.49236596 237 | 0 0 0 0 -0.35076413 0.34179845 0 0 1.3877788e-17 -0.49236596 238 | 0 0 0 0 -0.37469319 0.32679641 0 0 1.3877788e-17 -0.49236596 239 | 0 0 0 0 -0.39597979 0.31026870 0 0 1.3877788e-17 -0.49236596 240 | 0 0 0 0 -0.41462392 0.29221538 0 0 1.3877788e-17 -0.49236596 241 | 0 0 0 0 -0.43062559 0.27263641 0 0 1.3877788e-17 -0.49236596 242 | 0 0 0 0 -0.44398478 0.25153181 0 0 1.3877788e-17 -0.49236596 243 | 0 0 0 0 -0.45470145 0.22890157 0 0 1.3877788e-17 -0.49236596 244 | 0 0 0 0 -0.46277571 0.20474569 0 0 1.3877788e-17 -0.49236596 245 | 0 0 0 0 -0.46820745 0.17906420 0 0 1.3877788e-17 -0.49236596 246 | 0 0 0 0 -0.47099674 0.15185706 0 0 1.3877788e-17 -0.49236596 247 | 0 0 0 0 -0.47114354 0.12312429 0 0 1.3877788e-17 -0.49236596 248 | 0 0 0 0 -0.46864787 0.092865892 0 0 1.3877788e-17 -0.49236596 249 | 0 0 0 0 -0.46350971 0.061081856 0 0 1.3877788e-17 -0.49236596 250 | 0 0 0 0 -0.45572910 0.027772184 0 0 1.3877788e-17 -0.49236596 251 | 0 0 0 0 -0.44530600 -0.0070631192 0 0 1.3877788e-17 -0.49236596 252 | 0 0 0 0 -0.43224043 -0.043424059 0 0 1.3877788e-17 -0.49236596 253 | 0 0 0 0 -0.41653237 -0.081310630 0 0 1.3877788e-17 -0.49236596 254 | 0 0 0 0 -0.39818186 -0.12072283 0 0 1.3877788e-17 -0.49236596 255 | 0 0 0 0 -0.37718886 -0.16166067 0 0 1.3877788e-17 -0.49236596 256 | 0 0 0 0 -0.35355338 -0.20412415 0 0 1.3877788e-17 -0.49236596 -------------------------------------------------------------------------------- /look_tables/intensityChannelNorm6.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 0.50000000 0.28867513 2 | -0.021922758 8.6995067e-05 0 0.49987698 0.28867513 3 | -0.043323543 0.00034798027 0 0.49950787 0.28867513 4 | -0.064202361 0.00078295561 0 0.49889272 0.28867513 5 | -0.084559202 0.0013919211 0 0.49803153 0.28867513 6 | -0.10439408 0.0021748766 0 0.49692425 0.28867513 7 | -0.12370699 0.0031318225 0 0.49557093 0.28867513 8 | -0.14249793 0.0042627584 0 0.49397156 0.28867513 9 | -0.16076688 0.0055676843 0 0.49212611 0.28867513 10 | -0.17851388 0.0070466003 0 0.49003461 0.28867513 11 | -0.19573890 0.0086995065 0 0.48769704 0.28867513 12 | -0.21244195 0.010526403 0 0.48511341 0.28867513 13 | -0.22862303 0.012527290 0 0.48228374 0.28867513 14 | -0.24428216 0.014702166 0 0.47920799 0.28867513 15 | -0.25941929 0.017051034 0 0.47588620 0.28867513 16 | -0.27403447 0.019573890 0 0.47231835 0.28867513 17 | -0.28812766 0.022270737 0 0.46850443 0.28867513 18 | -0.30169889 0.025141574 0 0.46444446 0.28867513 19 | -0.31474817 0.028186401 0 0.46013841 0.28867513 20 | -0.32727545 0.031405218 0 0.45558631 0.28867513 21 | -0.33928075 0.034798026 0 0.45078817 0.28867513 22 | -0.35076413 0.038364824 0 0.44574395 0.28867513 23 | -0.36172548 0.042105611 0 0.44045368 0.28867513 24 | -0.37216491 0.046020392 0 0.43491733 0.28867513 25 | -0.38208234 0.050109159 0 0.42913494 0.28867513 26 | -0.39147779 0.054371916 0 0.42310649 0.28867513 27 | -0.40035129 0.058808666 0 0.41683200 0.28867513 28 | -0.40870282 0.063419402 0 0.41031143 0.28867513 29 | -0.41653237 0.068204135 0 0.40354478 0.28867513 30 | -0.42383996 0.073162854 0 0.39653209 0.28867513 31 | -0.43062559 0.078295559 0 0.38927335 0.28867513 32 | -0.43688923 0.083602257 0 0.38176855 0.28867513 33 | -0.44263092 0.089082949 0 0.37401769 0.28867513 34 | -0.44785061 0.094737627 0 0.36602077 0.28867513 35 | -0.45254833 0.10056630 0 0.35777777 0.28867513 36 | -0.45672411 0.10656895 0 0.34928873 0.28867513 37 | -0.46037790 0.11274561 0 0.34055364 0.28867513 38 | -0.46350971 0.11909625 0 0.33157247 0.28867513 39 | -0.46611956 0.12562087 0 0.32234526 0.28867513 40 | -0.46820745 0.13231950 0 0.31287196 0.28867513 41 | -0.46977335 0.13919210 0 0.30315262 0.28867513 42 | -0.47081730 0.14623871 0 0.29318723 0.28867513 43 | -0.47133929 0.15345930 0 0.28297579 0.28867513 44 | -0.47133929 0.16085388 0 0.27251825 0.28867513 45 | -0.47081730 0.16842245 0 0.26181468 0.28867513 46 | -0.46977335 0.17616501 0 0.25086504 0.28867513 47 | -0.46820745 0.18408157 0 0.23966935 0.28867513 48 | -0.46611956 0.19217211 0 0.22822760 0.28867513 49 | -0.46350971 0.20043664 0 0.21653979 0.28867513 50 | -0.46037790 0.20887515 0 0.20460592 0.28867513 51 | -0.45672411 0.21748766 0 0.19242600 0.28867513 52 | -0.45254833 0.22627416 0 0.18000001 0.28867513 53 | -0.44785061 0.23523466 0 0.16732796 0.28867513 54 | -0.44263092 0.24436915 0 0.15440984 0.28867513 55 | -0.43688923 0.25367761 0 0.14124568 0.28867513 56 | -0.43062559 0.26316008 0 0.12783545 0.28867513 57 | -0.42383996 0.27281654 0 0.11417916 0.28867513 58 | -0.41653237 0.28264698 0 0.10027681 0.28867513 59 | -0.40870282 0.29265141 0 0.086128414 0.28867513 60 | -0.40035129 0.30282983 0 0.071733952 0.28867513 61 | -0.39147779 0.31318223 0 0.057093427 0.28867513 62 | -0.38208234 0.32370865 0 0.042206842 0.28867513 63 | -0.37216491 0.33440903 0 0.027074203 0.28867513 64 | -0.36172548 0.34528342 0 0.011695501 0.28867513 65 | -0.35078585 0.35631004 0 -0.0039138794 0.28867513 66 | -0.33982447 0.36701044 0 -0.019415610 0.28867513 67 | -0.32903710 0.37718886 0 -0.034671281 0.28867513 68 | -0.31842369 0.38684532 0 -0.049680892 0.28867513 69 | -0.30798429 0.39597979 0 -0.064444445 0.28867513 70 | -0.29771888 0.40459231 0 -0.078961939 0.28867513 71 | -0.28762743 0.41268286 0 -0.093233369 0.28867513 72 | -0.27770999 0.42025143 0 -0.10725874 0.28867513 73 | -0.26796657 0.42729801 0 -0.12103806 0.28867513 74 | -0.25839710 0.43382266 0 -0.13457131 0.28867513 75 | -0.24900164 0.43982533 0 -0.14785852 0.28867513 76 | -0.23978016 0.44530600 0 -0.16089965 0.28867513 77 | -0.23073266 0.45026472 0 -0.17369473 0.28867513 78 | -0.22185917 0.45470145 0 -0.18624376 0.28867513 79 | -0.21315967 0.45861626 0 -0.19854671 0.28867513 80 | -0.20463414 0.46200904 0 -0.21060361 0.28867513 81 | -0.19628263 0.46487990 0 -0.22241445 0.28867513 82 | -0.18810509 0.46722877 0 -0.23397924 0.28867513 83 | -0.18010154 0.46905565 0 -0.24529797 0.28867513 84 | -0.17227198 0.47036058 0 -0.25637063 0.28867513 85 | -0.16461642 0.47114354 0 -0.26719722 0.28867513 86 | -0.15713485 0.47140452 0 -0.27777779 0.28867513 87 | -0.14982726 0.47114354 0 -0.28811225 0.28867513 88 | -0.14269365 0.47036058 0 -0.29820070 0.28867513 89 | -0.13573405 0.46905565 0 -0.30804306 0.28867513 90 | -0.12894844 0.46722877 0 -0.31763938 0.28867513 91 | -0.12233681 0.46487990 0 -0.32698962 0.28867513 92 | -0.11589918 0.46200904 0 -0.33609381 0.28867513 93 | -0.10963553 0.45861626 0 -0.34495193 0.28867513 94 | -0.10354588 0.45470145 0 -0.35356402 0.28867513 95 | -0.097630218 0.45026472 0 -0.36193001 0.28867513 96 | -0.091888539 0.44530600 0 -0.37004998 0.28867513 97 | -0.086320855 0.43982533 0 -0.37792388 0.28867513 98 | -0.080927163 0.43382266 0 -0.38555172 0.28867513 99 | -0.075707458 0.42729801 0 -0.39293349 0.28867513 100 | -0.070661746 0.42025143 0 -0.40006921 0.28867513 101 | -0.065790020 0.41268286 0 -0.40695885 0.28867513 102 | -0.061092287 0.40459231 0 -0.41360247 0.28867513 103 | -0.056568541 0.39597979 0 -0.41999999 0.28867513 104 | -0.052218787 0.38684532 0 -0.42615148 0.28867513 105 | -0.048043028 0.37718886 0 -0.43205690 0.28867513 106 | -0.044041254 0.36701044 0 -0.43771628 0.28867513 107 | -0.040213469 0.35631004 0 -0.44312957 0.28867513 108 | -0.036559679 0.34508768 0 -0.44829682 0.28867513 109 | -0.033079874 0.33334336 0 -0.45321798 0.28867513 110 | -0.029774062 0.32107705 0 -0.45789310 0.28867513 111 | -0.026642239 0.30828878 0 -0.46232218 0.28867513 112 | -0.023684407 0.29497853 0 -0.46650520 0.28867513 113 | -0.020900564 0.28114632 0 -0.47044215 0.28867513 114 | -0.018290713 0.26679212 0 -0.47413301 0.28867513 115 | -0.015854850 0.25191596 0 -0.47757787 0.28867513 116 | -0.013592979 0.23651785 0 -0.48077664 0.28867513 117 | -0.011505098 0.22059774 0 -0.48372933 0.28867513 118 | -0.0095912060 0.20415567 0 -0.48643598 0.28867513 119 | -0.0078513045 0.18719164 0 -0.48889658 0.28867513 120 | -0.0062853936 0.16970563 0 -0.49111110 0.28867513 121 | -0.0048934724 0.15169765 0 -0.49307957 0.28867513 122 | -0.0036755416 0.13316770 0 -0.49480200 0.28867513 123 | -0.0026316007 0.11411578 0 -0.49627835 0.28867513 124 | -0.0017616501 0.094541892 0 -0.49750865 0.28867513 125 | -0.0010656896 0.074446030 0 -0.49849290 0.28867513 126 | -0.00054371916 0.053828198 0 -0.49923107 0.28867513 127 | -0.00019573890 0.032688398 0 -0.49972320 0.28867513 128 | -2.1748767e-05 0.011026625 0 -0.49996924 0.28867513 129 | 0 -0.011026625 2.1748767e-05 -0.49998462 0.28864849 130 | 0 -0.032688398 0.00019573890 -0.49986160 0.28843540 131 | 0 -0.053828198 0.00054371916 -0.49961552 0.28800923 132 | 0 -0.074446030 0.0010656896 -0.49924645 0.28736994 133 | 0 -0.094541892 0.0017616501 -0.49875432 0.28651756 134 | 0 -0.11411578 0.0026316007 -0.49813917 0.28545210 135 | 0 -0.13316770 0.0036755416 -0.49740100 0.28417355 136 | 0 -0.15169765 0.0048934724 -0.49653980 0.28268188 137 | 0 -0.16970563 0.0062853936 -0.49555555 0.28097713 138 | 0 -0.18719164 0.0078513045 -0.49444827 0.27905929 139 | 0 -0.20415567 0.0095912060 -0.49321800 0.27692837 140 | 0 -0.22059774 0.011505098 -0.49186468 0.27458432 141 | 0 -0.23651785 0.013592979 -0.49038830 0.27202719 142 | 0 -0.25191596 0.015854850 -0.48878893 0.26925698 143 | 0 -0.26679212 0.018290713 -0.48706651 0.26627368 144 | 0 -0.28114632 0.020900564 -0.48522106 0.26307729 145 | 0 -0.29497853 0.023684407 -0.48325258 0.25966778 146 | 0 -0.30828878 0.026642239 -0.48116109 0.25604519 147 | 0 -0.32107705 0.029774062 -0.47894657 0.25220951 148 | 0 -0.33334336 0.033079874 -0.47660899 0.24816073 149 | 0 -0.34508768 0.036559679 -0.47414839 0.24389885 150 | 0 -0.35631004 0.040213469 -0.47156477 0.23942390 151 | 0 -0.36701044 0.044041254 -0.46885812 0.23473583 152 | 0 -0.37718886 0.048043028 -0.46602845 0.22983469 153 | 0 -0.38684532 0.052218787 -0.46307573 0.22472043 154 | 0 -0.39597979 0.056568541 -0.46000001 0.21939310 155 | 0 -0.40459231 0.061092287 -0.45680124 0.21385267 156 | 0 -0.41268286 0.065790020 -0.45347944 0.20809914 157 | 0 -0.42025143 0.070661746 -0.45003459 0.20213252 158 | 0 -0.42729801 0.075707458 -0.44646674 0.19595282 159 | 0 -0.43382266 0.080927163 -0.44277585 0.18956001 160 | 0 -0.43982533 0.086320855 -0.43896192 0.18295410 161 | 0 -0.44530600 0.091888539 -0.43502498 0.17613512 162 | 0 -0.45026472 0.097630218 -0.43096501 0.16910303 163 | 0 -0.45470145 0.10354588 -0.42678201 0.16185784 164 | 0 -0.45861626 0.10963553 -0.42247596 0.15439957 165 | 0 -0.46200904 0.11589918 -0.41804689 0.14672822 166 | 0 -0.46487990 0.12233681 -0.41349480 0.13884374 167 | 0 -0.46722877 0.12894844 -0.40881968 0.13074620 168 | 0 -0.46905565 0.13573405 -0.40402153 0.12243555 169 | 0 -0.47036058 0.14269365 -0.39910033 0.11391181 170 | 0 -0.47114354 0.14982726 -0.39405614 0.10517497 171 | 0 -0.47140452 0.15713485 -0.38888890 0.096225046 172 | 0 -0.47114354 0.16461642 -0.38359863 0.087062024 173 | 0 -0.47036058 0.17227198 -0.37818530 0.077685907 174 | 0 -0.46905565 0.18010154 -0.37264898 0.068096697 175 | 0 -0.46722877 0.18810509 -0.36698961 0.058294397 176 | 0 -0.46487990 0.19628263 -0.36120722 0.048279002 177 | 0 -0.46200904 0.20463414 -0.35530180 0.038050514 178 | 0 -0.45861626 0.21315967 -0.34927335 0.027608929 179 | 0 -0.45470145 0.22185917 -0.34312189 0.016954254 180 | 0 -0.45026472 0.23073266 -0.33684736 0.0060864836 181 | 0 -0.44530600 0.23978016 -0.33044982 -0.0049943794 182 | 0 -0.43982533 0.24900164 -0.32392925 -0.016288336 183 | 0 -0.43382266 0.25839710 -0.31728566 -0.027795387 184 | 0 -0.42729801 0.26796657 -0.31051904 -0.039515529 185 | 0 -0.42025143 0.27770999 -0.30362937 -0.051448766 186 | 0 -0.41268286 0.28762743 -0.29661667 -0.063595101 187 | 0 -0.40459231 0.29771888 -0.28948095 -0.075954527 188 | 0 -0.39597979 0.30798429 -0.28222221 -0.088527039 189 | 0 -0.38684532 0.31842369 -0.27484044 -0.10131265 190 | 0 -0.37718886 0.32903710 -0.26733565 -0.11431136 191 | 0 -0.36701044 0.33982447 -0.25970781 -0.12752315 192 | 0 -0.35631004 0.35078585 -0.25195694 -0.14094804 193 | 0 -0.34528342 0.36172548 -0.24415225 -0.15446617 194 | 0 -0.33440903 0.37216491 -0.23646291 -0.16778451 195 | 0 -0.32370865 0.38208234 -0.22889657 -0.18088977 196 | 0 -0.31318223 0.39147779 -0.22145329 -0.19378193 197 | 0 -0.30282983 0.40035129 -0.21413302 -0.20646098 198 | 0 -0.29265141 0.40870282 -0.20693579 -0.21892697 199 | 0 -0.28264698 0.41653237 -0.19986159 -0.23117983 200 | 0 -0.27281654 0.42383996 -0.19291042 -0.24321963 201 | 0 -0.26316008 0.43062559 -0.18608227 -0.25504631 202 | 0 -0.25367761 0.43688923 -0.17937717 -0.26665992 203 | 0 -0.24436915 0.44263092 -0.17279507 -0.27806041 204 | 0 -0.23523466 0.44785061 -0.16633603 -0.28924781 205 | 0 -0.22627416 0.45254833 -0.16000000 -0.30022213 206 | 0 -0.21748766 0.45672411 -0.15378700 -0.31098336 207 | 0 -0.20887515 0.46037790 -0.14769705 -0.32153150 208 | 0 -0.20043664 0.46350971 -0.14173010 -0.33186653 209 | 0 -0.19217211 0.46611956 -0.13588619 -0.34198847 210 | 0 -0.18408157 0.46820745 -0.13016532 -0.35189733 211 | 0 -0.17616501 0.46977335 -0.12456747 -0.36159307 212 | 0 -0.16842245 0.47081730 -0.11909266 -0.37107575 213 | 0 -0.16085388 0.47133929 -0.11374087 -0.38034531 214 | 0 -0.15345930 0.47133929 -0.10851211 -0.38940179 215 | 0 -0.14623871 0.47081730 -0.10340638 -0.39824516 216 | 0 -0.13919210 0.46977335 -0.098423682 -0.40687546 217 | 0 -0.13231950 0.46820745 -0.093564011 -0.41529265 218 | 0 -0.12562087 0.46611956 -0.088827372 -0.42349675 219 | 0 -0.11909625 0.46350971 -0.084213763 -0.43148774 220 | 0 -0.11274561 0.46037790 -0.079723187 -0.43926567 221 | 0 -0.10656895 0.45672411 -0.075355634 -0.44683048 222 | 0 -0.10056630 0.45254833 -0.071111113 -0.45418221 223 | 0 -0.094737627 0.44785061 -0.066989623 -0.46132085 224 | 0 -0.089082949 0.44263092 -0.062991157 -0.46824637 225 | 0 -0.083602257 0.43688923 -0.059115727 -0.47495884 226 | 0 -0.078295559 0.43062559 -0.055363324 -0.48145819 227 | 0 -0.073162854 0.42383996 -0.051733948 -0.48774445 228 | 0 -0.068204135 0.41653237 -0.048227604 -0.49381760 229 | 0 -0.063419402 0.40870282 -0.044844292 -0.49967769 230 | 0 -0.058808666 0.40035129 -0.041584007 -0.50532466 231 | 0 -0.054371916 0.39147779 -0.038446750 -0.51075852 232 | 0 -0.050109159 0.38208234 -0.035432525 -0.51597935 233 | 0 -0.046020392 0.37216491 -0.032541331 -0.52098703 234 | 0 -0.042105611 0.36172548 -0.029773165 -0.52578163 235 | 0 -0.038364824 0.35076413 -0.027128028 -0.53036314 236 | 0 -0.034798026 0.33928075 -0.024605921 -0.53473157 237 | 0 -0.031405218 0.32727545 -0.022206843 -0.53888690 238 | 0 -0.028186401 0.31474817 -0.019930797 -0.54282910 239 | 0 -0.025141574 0.30169889 -0.017777778 -0.54655826 240 | 0 -0.022270737 0.28812766 -0.015747789 -0.55007428 241 | 0 -0.019573890 0.27403447 -0.013840831 -0.55337727 242 | 0 -0.017051034 0.25941929 -0.012056901 -0.55646712 243 | 0 -0.014702166 0.24428216 -0.010396002 -0.55934387 244 | 0 -0.012527290 0.22862303 -0.0088581312 -0.56200755 245 | 0 -0.010526403 0.21244195 -0.0074432911 -0.56445813 246 | 0 -0.0086995065 0.19573890 -0.0061514801 -0.56669557 247 | 0 -0.0070466003 0.17851388 -0.0049826992 -0.56871998 248 | 0 -0.0055676843 0.16076688 -0.0039369473 -0.57053125 249 | 0 -0.0042627584 0.14249793 -0.0030142253 -0.57212949 250 | 0 -0.0031318225 0.12370699 -0.0022145328 -0.57351458 251 | 0 -0.0021748766 0.10439408 -0.0015378700 -0.57468659 252 | 0 -0.0013919211 0.084559202 -0.00098423683 -0.57564551 253 | 0 -0.00078295561 0.064202361 -0.00055363320 -0.57639134 254 | 0 -0.00034798027 0.043323543 -0.00024605921 -0.57692409 255 | 0 -8.6995067e-05 0.021922758 -6.1514802e-05 -0.57724375 256 | 0 0 0 0 -0.57735026 -------------------------------------------------------------------------------- /metrics.cc: -------------------------------------------------------------------------------- 1 | #include "metrics.hpp" 2 | 3 | float Metrics::center_error(const cv::Rect2f bbox, const cv::Rect2f bboxGroundtruth) 4 | { 5 | float cx = bbox.x + bbox.width / 2.0f; 6 | float cy = bbox.y + bbox.height / 2.0f; 7 | float cx_gt = bboxGroundtruth.x + bboxGroundtruth.width / 2.0f; 8 | float cy_gt = bboxGroundtruth.y + bboxGroundtruth.height / 2.0f; 9 | float result = std::sqrt(std::pow((cx - cx_gt), 2) + 10 | std::pow((cy - cy_gt), 2)); 11 | return result; 12 | } 13 | 14 | float Metrics::iou(const cv::Rect2f bbox, const cv::Rect2f bboxGroundtruth) 15 | { 16 | cv::Rect2f inter = Metrics::intersection(bbox, bboxGroundtruth); 17 | float area_bbox = bbox.area(); 18 | float area_bbox_gt = bboxGroundtruth.area(); 19 | float area_intersection = inter.area(); 20 | float iou = area_bbox + area_bbox_gt - area_intersection; 21 | iou = area_intersection / (iou + 1e-12); 22 | return iou; 23 | } 24 | 25 | cv::Rect2f Metrics::intersection(const cv::Rect2f bbox, 26 | const cv::Rect2f bboxGroundtruth) 27 | { 28 | float x1, y1, x2, y2, w, h; 29 | x1 = std::max(bbox.x, bboxGroundtruth.x); 30 | y1 = std::max(bbox.y, bboxGroundtruth.y); 31 | x2 = std::min(bbox.x + bbox.width, bboxGroundtruth.x + bboxGroundtruth.width); 32 | y2 = std::min(bbox.y + bbox.height, bboxGroundtruth.y + bboxGroundtruth.height); 33 | w = std::max(0.0f, x2 - x1); 34 | h = std::max(0.0f, y2 - y1); 35 | 36 | cv::Rect2f result(x1, y1, w, h); 37 | return result; 38 | } 39 | 40 | float Metrics::auc() 41 | { 42 | return 0; 43 | } -------------------------------------------------------------------------------- /metrics.hpp: -------------------------------------------------------------------------------- 1 | #ifndef METRICS_HPP 2 | #define METRICS_HPP 3 | 4 | //#include 5 | #include 6 | #include 7 | 8 | class Metrics 9 | { 10 | public: 11 | float center_error(const cv::Rect2f bbox, const cv::Rect2f bboxGroundtruth); 12 | float iou(const cv::Rect2f bbox, const cv::Rect2f bboxGroundtruth); 13 | cv::Rect2f intersection(const cv::Rect2f bbox, 14 | const cv::Rect2f bboxGroundtruth); 15 | float auc(); 16 | }; 17 | 18 | #endif -------------------------------------------------------------------------------- /model/VGG_mean.binaryproto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hez2010/EcoTracker/9258c3a037ae2e7b462a85f5630392aa44f98d6c/model/VGG_mean.binaryproto -------------------------------------------------------------------------------- /model/imagenet-vgg-m-2048.prototxt: -------------------------------------------------------------------------------- 1 | name: "VGG_CNN_M_2048" 2 | input: "data" 3 | input_dim: 10 4 | input_dim: 3 5 | input_dim: 224 6 | input_dim: 224 7 | layers { 8 | bottom: "data" 9 | top: "conv1" 10 | name: "conv1" 11 | type: CONVOLUTION 12 | convolution_param { 13 | num_output: 96 14 | kernel_size: 7 15 | stride: 2 16 | } 17 | } 18 | layers { 19 | bottom: "conv1" 20 | top: "conv1" 21 | name: "relu1" 22 | type: RELU 23 | } 24 | layers { 25 | bottom: "conv1" 26 | top: "norm1" 27 | name: "norm1" 28 | type: LRN 29 | lrn_param { 30 | local_size: 5 31 | alpha: 0.0005 32 | beta: 0.75 33 | k: 2 34 | } 35 | } 36 | layers { 37 | bottom: "norm1" 38 | top: "pool1" 39 | name: "pool1" 40 | type: POOLING 41 | pooling_param { 42 | pool: MAX 43 | kernel_size: 3 44 | stride: 2 45 | } 46 | } 47 | layers { 48 | bottom: "pool1" 49 | top: "conv2" 50 | name: "conv2" 51 | type: CONVOLUTION 52 | convolution_param { 53 | num_output: 256 54 | pad: 1 55 | kernel_size: 5 56 | stride: 2 57 | } 58 | } 59 | layers { 60 | bottom: "conv2" 61 | top: "conv2" 62 | name: "relu2" 63 | type: RELU 64 | } 65 | layers { 66 | bottom: "conv2" 67 | top: "norm2" 68 | name: "norm2" 69 | type: LRN 70 | lrn_param { 71 | local_size: 5 72 | alpha: 0.0005 73 | beta: 0.75 74 | k: 2 75 | } 76 | } 77 | layers { 78 | bottom: "norm2" 79 | top: "pool2" 80 | name: "pool2" 81 | type: POOLING 82 | pooling_param { 83 | pool: MAX 84 | kernel_size: 3 85 | stride: 2 86 | } 87 | } 88 | layers { 89 | bottom: "pool2" 90 | top: "conv3" 91 | name: "conv3" 92 | type: CONVOLUTION 93 | convolution_param { 94 | num_output: 512 95 | pad: 1 96 | kernel_size: 3 97 | } 98 | } 99 | layers { 100 | bottom: "conv3" 101 | top: "conv3" 102 | name: "relu3" 103 | type: RELU 104 | } 105 | layers { 106 | bottom: "conv3" 107 | top: "conv4" 108 | name: "conv4" 109 | type: CONVOLUTION 110 | convolution_param { 111 | num_output: 512 112 | pad: 1 113 | kernel_size: 3 114 | } 115 | } 116 | layers { 117 | bottom: "conv4" 118 | top: "conv4" 119 | name: "relu4" 120 | type: RELU 121 | } 122 | layers { 123 | bottom: "conv4" 124 | top: "conv5" 125 | name: "conv5" 126 | type: CONVOLUTION 127 | convolution_param { 128 | num_output: 512 129 | pad: 1 130 | kernel_size: 3 131 | } 132 | } 133 | layers { 134 | bottom: "conv5" 135 | top: "conv5" 136 | name: "relu5" 137 | type: RELU 138 | } -------------------------------------------------------------------------------- /model/imagenet-vgg-m-2048.prototxt.origin: -------------------------------------------------------------------------------- 1 | name: "VGG_CNN_M_2048" 2 | input: "data" 3 | input_dim: 10 4 | input_dim: 3 5 | input_dim: 224 6 | input_dim: 224 7 | layers { 8 | bottom: "data" 9 | top: "conv1" 10 | name: "conv1" 11 | type: CONVOLUTION 12 | convolution_param { 13 | num_output: 96 14 | kernel_size: 7 15 | stride: 2 16 | } 17 | } 18 | layers { 19 | bottom: "conv1" 20 | top: "conv1" 21 | name: "relu1" 22 | type: RELU 23 | } 24 | layers { 25 | bottom: "conv1" 26 | top: "norm1" 27 | name: "norm1" 28 | type: LRN 29 | lrn_param { 30 | local_size: 5 31 | alpha: 0.0005 32 | beta: 0.75 33 | k: 2 34 | } 35 | } 36 | layers { 37 | bottom: "norm1" 38 | top: "pool1" 39 | name: "pool1" 40 | type: POOLING 41 | pooling_param { 42 | pool: MAX 43 | kernel_size: 3 44 | stride: 2 45 | } 46 | } 47 | layers { 48 | bottom: "pool1" 49 | top: "conv2" 50 | name: "conv2" 51 | type: CONVOLUTION 52 | convolution_param { 53 | num_output: 256 54 | pad: 1 55 | kernel_size: 5 56 | stride: 2 57 | } 58 | } 59 | layers { 60 | bottom: "conv2" 61 | top: "conv2" 62 | name: "relu2" 63 | type: RELU 64 | } 65 | layers { 66 | bottom: "conv2" 67 | top: "norm2" 68 | name: "norm2" 69 | type: LRN 70 | lrn_param { 71 | local_size: 5 72 | alpha: 0.0005 73 | beta: 0.75 74 | k: 2 75 | } 76 | } 77 | layers { 78 | bottom: "norm2" 79 | top: "pool2" 80 | name: "pool2" 81 | type: POOLING 82 | pooling_param { 83 | pool: MAX 84 | kernel_size: 3 85 | stride: 2 86 | } 87 | } 88 | layers { 89 | bottom: "pool2" 90 | top: "conv3" 91 | name: "conv3" 92 | type: CONVOLUTION 93 | convolution_param { 94 | num_output: 512 95 | pad: 1 96 | kernel_size: 3 97 | } 98 | } 99 | layers { 100 | bottom: "conv3" 101 | top: "conv3" 102 | name: "relu3" 103 | type: RELU 104 | } 105 | layers { 106 | bottom: "conv3" 107 | top: "conv4" 108 | name: "conv4" 109 | type: CONVOLUTION 110 | convolution_param { 111 | num_output: 512 112 | pad: 1 113 | kernel_size: 3 114 | } 115 | } 116 | layers { 117 | bottom: "conv4" 118 | top: "conv4" 119 | name: "relu4" 120 | type: RELU 121 | } 122 | layers { 123 | bottom: "conv4" 124 | top: "conv5" 125 | name: "conv5" 126 | type: CONVOLUTION 127 | convolution_param { 128 | num_output: 512 129 | pad: 1 130 | kernel_size: 3 131 | } 132 | } 133 | layers { 134 | bottom: "conv5" 135 | top: "conv5" 136 | name: "relu5" 137 | type: RELU 138 | } 139 | layers { 140 | bottom: "conv5" 141 | top: "pool5" 142 | name: "pool5" 143 | type: POOLING 144 | pooling_param { 145 | pool: MAX 146 | kernel_size: 3 147 | stride: 2 148 | } 149 | } 150 | layers { 151 | bottom: "pool5" 152 | top: "fc6" 153 | name: "fc6" 154 | type: INNER_PRODUCT 155 | inner_product_param { 156 | num_output: 4096 157 | } 158 | } 159 | layers { 160 | bottom: "fc6" 161 | top: "fc6" 162 | name: "relu6" 163 | type: RELU 164 | } 165 | layers { 166 | bottom: "fc6" 167 | top: "fc6" 168 | name: "drop6" 169 | type: DROPOUT 170 | dropout_param { 171 | dropout_ratio: 0.5 172 | } 173 | } 174 | layers { 175 | bottom: "fc6" 176 | top: "fc7" 177 | name: "fc7" 178 | type: INNER_PRODUCT 179 | inner_product_param { 180 | num_output: 2048 181 | } 182 | } 183 | layers { 184 | bottom: "fc7" 185 | top: "fc7" 186 | name: "relu7" 187 | type: RELU 188 | } 189 | layers { 190 | bottom: "fc7" 191 | top: "fc7" 192 | name: "drop7" 193 | type: DROPOUT 194 | dropout_param { 195 | dropout_ratio: 0.5 196 | } 197 | } 198 | layers { 199 | bottom: "fc7" 200 | top: "fc8" 201 | name: "fc8" 202 | type: INNER_PRODUCT 203 | inner_product_param { 204 | num_output: 1000 205 | } 206 | } 207 | layers { 208 | bottom: "fc8" 209 | top: "prob" 210 | name: "prob" 211 | type: SOFTMAX 212 | } 213 | 214 | -------------------------------------------------------------------------------- /optimize_scores.cc: -------------------------------------------------------------------------------- 1 | #include"optimize_scores.hpp" 2 | 3 | namespace eco{ 4 | void OptimizeScores::compute_scores() 5 | { 6 | std::vector sampled_scores; 7 | // Do inverse fft to the scores in the Fourier domain back to spacial domain 8 | for (size_t i = 0; i < scores_fs_.size(); ++i) // for each scale 9 | { 10 | int area = scores_fs_[i].size().area(); 11 | cv::Mat tmp = dft(fftshift(scores_fs_[i], 1, 1, 1), 1);// inverse dft 12 | sampled_scores.push_back(real(tmp * area)); // spacial domain only contains real part 13 | } 14 | 15 | // to store the position of maximum value of response 16 | std::vector row, col; 17 | std::vector init_max_score; // inialized max score 18 | for (size_t i = 0; i < scores_fs_.size(); ++i) // for each scale 19 | { 20 | cv::Point pos; 21 | double maxValue = 0, minValue = 0; 22 | cv::minMaxLoc(sampled_scores[i], &minValue, &maxValue, NULL, &pos); 23 | row.push_back(pos.y); 24 | col.push_back(pos.x); 25 | init_max_score.push_back(sampled_scores[i].at(pos.y, pos.x)); 26 | //debug("init_max_score %lu: value: %lf %lf y:%d x:%d", i, minValue, maxValue, pos.y, pos.x); 27 | } 28 | 29 | // Shift and rescale the coordinate system to [-pi, pi] 30 | int h = scores_fs_[0].rows, w = scores_fs_[0].cols; 31 | std::vector max_pos_y, max_pos_x, init_pos_y, init_pos_x; 32 | for (size_t i = 0; i < row.size(); ++i) 33 | { 34 | max_pos_y.push_back( (row[i] + (h - 1) / 2) % h - (h - 1) / 2); 35 | max_pos_y[i] *= 2 * CV_PI / h; 36 | max_pos_x.push_back( (col[i] + (w - 1) / 2) % w - (w - 1) / 2); 37 | max_pos_x[i] *= 2 * CV_PI / w; 38 | } 39 | init_pos_y = max_pos_y; init_pos_x = max_pos_x; 40 | // Construct grid 41 | std::vector ky, kx, ky2, kx2; 42 | for (int i = 0; i < h; ++i) 43 | { 44 | ky.push_back(i - (h - 1) / 2); 45 | ky2.push_back(ky[i] * ky[i]); 46 | } 47 | for (int i = 0; i < w; ++i) 48 | { 49 | kx.push_back(i - (w - 1) / 2); 50 | kx2.push_back(kx[i] * kx[i]); 51 | } 52 | // Pre-compute complex exponential 53 | std::vector exp_iky, exp_ikx; 54 | for (unsigned int i = 0; i < scores_fs_.size(); ++i) 55 | { 56 | cv::Mat tempy(1, h, CV_32FC2); 57 | cv::Mat tempx(w, 1, CV_32FC2); 58 | for (int y = 0; y < h; ++y) 59 | tempy.at>(0, y) = cv::Vec(cos(ky[y] * max_pos_y[i]), sin(ky[y] * max_pos_y[i])); 60 | for (int x = 0; x < w; ++x) 61 | tempx.at>(x, 0) = cv::Vec(cos(kx[x] * max_pos_x[i]), sin(kx[x] * max_pos_x[i])); 62 | exp_iky.push_back(tempy); 63 | exp_ikx.push_back(tempx); 64 | } 65 | 66 | cv::Mat kyMat(1, h, CV_32FC1, &ky[0]); 67 | cv::Mat ky2Mat(1, h, CV_32FC1, &ky2[0]); 68 | cv::Mat kxMat(w, 1, CV_32FC1, &kx[0]); 69 | cv::Mat kx2Mat(w, 1, CV_32FC1, &kx2[0]); 70 | 71 | for (int ite = 0; ite < iterations_; ++ite) 72 | { 73 | // Compute gradient 74 | std::vector ky_exp_ky, kx_exp_kx, y_resp, resp_x, grad_y, grad_x; 75 | std::vector ival, H_yy, H_xx, H_xy, det_H; 76 | for (unsigned int i = 0; i < scores_fs_.size(); i++) 77 | { 78 | ky_exp_ky.push_back(complexDotMultiplication(kyMat, exp_iky[i])); 79 | kx_exp_kx.push_back(complexDotMultiplication(kxMat, exp_ikx[i])); 80 | 81 | y_resp.push_back(exp_iky[i] * scores_fs_[i]); 82 | resp_x.push_back(scores_fs_[i] * exp_ikx[i]); 83 | 84 | grad_y.push_back(-1 * imag(ky_exp_ky[i] * resp_x[i])); 85 | grad_x.push_back(-1 * imag(y_resp[i] * kx_exp_kx[i])); 86 | 87 | // Compute Hessian 88 | ival.push_back(exp_iky[i] * resp_x[i]); 89 | std::vector tmp; 90 | cv::split(ival[i], tmp); 91 | cv::merge(std::vector({-1 * tmp[1], tmp[0]}), ival[i]); 92 | 93 | H_yy.push_back(real(-1 * complexDotMultiplication(ky2Mat, exp_iky[i]) * resp_x[i] + ival[i])); 94 | H_xx.push_back(real(-1 * y_resp[i] * complexDotMultiplication(kx2Mat, exp_ikx[i]) + ival[i])); 95 | H_xy.push_back(real(-1 * ky_exp_ky[i] * (scores_fs_[i] * kx_exp_kx[i]))); 96 | 97 | det_H.push_back(H_yy[i].mul(H_xx[i]) - H_xy[i].mul(H_xy[i])); 98 | 99 | // Compute new position using newtons method 100 | cv::Mat tmp1, tmp2; 101 | cv::divide(H_xx[i].mul(grad_y[i]) - H_xy[i].mul(grad_x[i]), det_H[i], tmp1); 102 | max_pos_y[i] -= tmp1.at(0, 0); 103 | cv::divide(H_yy[i].mul(grad_x[i]) - H_xy[i].mul(grad_y[i]), det_H[i], tmp2); 104 | max_pos_x[i] -= tmp2.at(0, 0); 105 | 106 | // Evaluate maximum 107 | cv::Mat tempy(1, h, CV_32FC2), tempx(w, 1, CV_32FC2); 108 | for (int y = 0; y < h; ++y) 109 | tempy.at>(0, y) = cv::Vec(cos(ky[y] * max_pos_y[i]), sin(ky[y] * max_pos_y[i])); 110 | for (int x = 0; x < w; ++x) 111 | tempx.at>(x, 0) = cv::Vec(cos(kx[x] * max_pos_x[i]), sin(kx[x] * max_pos_x[i])); 112 | exp_iky[i] = tempy; 113 | exp_ikx[i] = tempx; 114 | } 115 | } 116 | // Evaluate the Fourier series at the estimated locations to find the corresponding scores. 117 | std::vector max_score; 118 | for (size_t i = 0; i < sampled_scores.size(); ++i) 119 | { 120 | float new_scores = real(exp_iky[i] * scores_fs_[i] * exp_ikx[i]).at(0, 0); 121 | // check for scales that have not increased in score 122 | if (new_scores > init_max_score[i]) 123 | { 124 | max_score.push_back(new_scores); 125 | } 126 | else 127 | { 128 | max_score.push_back(init_max_score[i]); 129 | max_pos_y[i] = init_pos_y[i]; 130 | max_pos_x[i] = init_pos_x[i]; 131 | } 132 | 133 | } 134 | 135 | // Find the scale with the maximum response 136 | std::vector::iterator pos = max_element(max_score.begin(), max_score.end()); 137 | scale_ind_ = pos - max_score.begin(); 138 | max_score_ = *pos; 139 | 140 | // Scale the coordinate system to output_sz 141 | disp_row_ = (fmod(max_pos_y[scale_ind_] + CV_PI, CV_PI * 2.0) - CV_PI) / (CV_PI * 2.0) * h; 142 | disp_col_ = (fmod(max_pos_x[scale_ind_] + CV_PI, CV_PI * 2.0) - CV_PI) / (CV_PI * 2.0) * w; 143 | //return sampled_scores; 144 | } 145 | } -------------------------------------------------------------------------------- /optimize_scores.hpp: -------------------------------------------------------------------------------- 1 | #ifndef OPTIMIZE_SCORES_HPP 2 | #define OPTIMIZE_SCORES_HPP 3 | 4 | //#include 5 | #include 6 | 7 | #include "ffttools.hpp" 8 | #include "debug.hpp" 9 | 10 | namespace eco 11 | { 12 | class OptimizeScores 13 | { 14 | public: 15 | virtual ~OptimizeScores() {} 16 | OptimizeScores() {} 17 | OptimizeScores(std::vector &scores_fs, int ite) 18 | : scores_fs_(scores_fs), iterations_(ite) {} 19 | 20 | void compute_scores(); 21 | 22 | inline int get_scale_ind() const { return scale_ind_; } 23 | inline float get_disp_row() const { return disp_row_; } 24 | inline float get_disp_col() const { return disp_col_; } 25 | inline float get_max_score() const { return max_score_; } 26 | 27 | private: 28 | std::vector scores_fs_; 29 | int iterations_; 30 | 31 | int scale_ind_; 32 | float disp_row_; 33 | float disp_col_; 34 | float max_score_; 35 | }; 36 | } // namespace eco 37 | #endif 38 | -------------------------------------------------------------------------------- /parameters.hpp: -------------------------------------------------------------------------------- 1 | // Set the value the same as testing_ECO_gpu.m 2 | #ifndef PARAMETERS_HPP 3 | #define PARAMETERS_HPP 4 | 5 | #ifdef USE_CAFFE 6 | #include 7 | #include 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #define INF 0x7f800000 //0x7fffffff 15 | 16 | using std::string; 17 | using std::vector; 18 | 19 | namespace eco 20 | { 21 | // ECO feature[Num_features][Dimension_of_the_feature]; 22 | typedef std::vector> ECO_FEATS; 23 | typedef cv::Vec COMPLEX; // represent a complex number; 24 | 25 | // cnn feature configuration ========================================= 26 | #ifdef USE_CAFFE 27 | struct CnnParameters 28 | { 29 | string proto = "model/imagenet-vgg-m-2048.prototxt"; 30 | string model = "model/VGG_CNN_M_2048.caffemodel"; 31 | string mean_file = "model/VGG_mean.binaryproto"; 32 | 33 | boost::shared_ptr> net; 34 | cv::Mat deep_mean_mat, deep_mean_mean_mat; 35 | 36 | string nn_name = "imagenet-vgg-m-2048.mat"; 37 | vector stride = {2, 16}; // stride in total 38 | vector cell_size = {4, 16}; // downsample_factor 39 | vector output_layer = {3, 14}; // Which layers to use 40 | vector downsample_factor = {2, 1}; // How much to downsample each output layer 41 | int input_size_scale = 1; // Extra scale factor of the input samples to the network (1 is no scaling) 42 | vector nDim = {96, 512}; // Original dimension of features (ECO Paper Table 1) 43 | vector compressed_dim = {16, 64}; // Compressed dimensionality of each output layer (ECO Paper Table 1) 44 | vector penalty = {0, 0}; 45 | 46 | vector start_ind = {3, 3, 1, 1}; // sample feature start index 47 | vector end_ind = {106, 106, 13, 13}; // sample feature end index 48 | }; 49 | struct CnnFeatures 50 | { 51 | CnnParameters fparams; 52 | cv::Size img_input_sz = cv::Size(224, 224); // VGG default input sample size 53 | cv::Size img_sample_sz; // the size of sample 54 | cv::Size data_sz_block0, data_sz_block1; 55 | cv::Mat mean; 56 | }; 57 | #endif 58 | 59 | // hog parameters cofiguration ========================================= 60 | struct HogParameters 61 | { 62 | int cell_size = 6; 63 | int compressed_dim = 10; // Compressed dimensionality of each output layer (ECO Paper Table 1) 64 | int nOrients = 9; 65 | size_t nDim = 31; // Original dimension of feature 66 | float penalty = 0; 67 | }; 68 | struct HogFeatures 69 | { 70 | HogParameters fparams; 71 | cv::Size img_input_sz; // input sample size 72 | cv::Size img_sample_sz; // the size of sample 73 | cv::Size data_sz_block0; 74 | }; 75 | 76 | // CN parameters configuration ========================================= 77 | struct ColorspaceParameters 78 | { 79 | string colorspace = "gray"; 80 | int cell_size = 1; 81 | }; 82 | struct ColorspaceFeatures 83 | { 84 | ColorspaceParameters fparams; 85 | cv::Size img_input_sz; 86 | cv::Size img_sample_sz; 87 | cv::Size data_sz_block0; 88 | }; 89 | //--------------------------- 90 | struct CnParameters // only used for Color image 91 | { 92 | string tablename = "look_tables/CNnorm.txt"; 93 | float table[32768][10]; 94 | int cell_size = 4; 95 | int compressed_dim = 3; 96 | size_t nDim = 10; 97 | float penalty = 0; 98 | }; 99 | struct CnFeatures 100 | { 101 | CnParameters fparams; 102 | cv::Size img_input_sz; 103 | cv::Size img_sample_sz; 104 | cv::Size data_sz_block0; 105 | }; 106 | //--------------------------- 107 | struct IcParameters // only used for gray image 108 | { 109 | string tablename = "look_tables/intensityChannelNorm6"; 110 | float table[256][5]; 111 | int cell_size = 4; 112 | int compressed_dim = 3; 113 | size_t nDim = 5; 114 | float penalty = 0; 115 | }; 116 | struct IcFeatures 117 | { 118 | IcParameters fparams; 119 | cv::Size img_input_sz; 120 | cv::Size img_sample_sz; 121 | cv::Size data_sz_block0; 122 | }; 123 | 124 | // Cojugate Gradient Options Structure ===================================== 125 | struct CgOpts 126 | { 127 | bool debug; 128 | bool CG_use_FR; 129 | float tol; 130 | bool CG_standard_alpha; 131 | float init_forget_factor; 132 | int maxit; 133 | }; 134 | 135 | // Parameters set exactly the same as 'testing_ECO_HC.m'==================== 136 | struct EcoParameters 137 | { 138 | // Features 139 | bool useDeepFeature = false; 140 | bool useHogFeature = true; 141 | bool useColorspaceFeature = false;// not implemented yet 142 | bool useCnFeature = false; 143 | bool useIcFeature = true; 144 | 145 | #ifdef USE_CAFFE 146 | CnnFeatures cnn_features; 147 | #endif 148 | HogFeatures hog_features; 149 | ColorspaceFeatures colorspace_feature; 150 | CnFeatures cn_features; 151 | IcFeatures ic_features; 152 | 153 | // extra parameters 154 | CgOpts CG_opts; 155 | float max_score_threshhold = 0.1; 156 | 157 | // Global feature parameters1s 158 | int normalize_power = 2; 159 | bool normalize_size = true; 160 | bool normalize_dim = true; 161 | 162 | // img sample parameters 163 | string search_area_shape = "square"; // The shape of the samples 164 | float search_area_scale = 4.0; // The scaling of the target size to get the search area 165 | int min_image_sample_size = 22500; // Minimum area of image samples, 200x200 166 | int max_image_sample_size = 40000; // Maximum area of image samples, 250x250 167 | 168 | // Detection parameters 169 | int refinement_iterations = 1; // Number of iterations used to refine the resulting position in a frame 170 | int newton_iterations = 5; // The number of Newton iterations used for optimizing the detection score 171 | bool clamp_position = false; // Clamp the target position to be inside the image 172 | 173 | // Learning parameters 174 | float output_sigma_factor = 1.0f / 16.0f; // Label function sigma 175 | float learning_rate = 0.009; // Learning rate 176 | size_t nSamples = 30; // Maximum number of stored training samples 177 | string sample_replace_strategy = "lowest_prior"; // Which sample to replace when the memory is full 178 | bool lt_size = 0; // The size of the long - term memory(where all samples have equal weight) 179 | int train_gap = 5; // The number of intermediate frames with no training(0 corresponds to training every frame) 180 | int skip_after_frame = 10; // After which frame number the sparse update scheme should start(1 is directly) 181 | bool use_detection_sample = true; // Use the sample that was extracted at the detection stage also for learning 182 | 183 | // Factorized convolution parameters 184 | bool use_projection_matrix = true; // Use projection matrix, i.e. use the factorized convolution formulation 185 | bool update_projection_matrix = true; // Whether the projection matrix should be optimized or not 186 | string proj_init_method = "pca"; // Method for initializing the projection matrix 187 | float projection_reg = 1e-7; // Regularization paremeter of the projection matrix (lambda) 188 | 189 | // Generative sample space model parameters 190 | bool use_sample_merge = true; // Use the generative sample space model to merge samples 191 | string sample_merge_type = "Merge"; // Strategy for updating the samples 192 | string distance_matrix_update_type = "exact"; // Strategy for updating the distance matrix 193 | 194 | // Conjugate Gradient parameters 195 | int CG_iter = 5; // The number of Conjugate Gradient iterations in each update after the first frame 196 | int init_CG_iter = 10 * 15; // The total number of Conjugate Gradient iterations used in the first frame 197 | int init_GN_iter = 10; // The number of Gauss-Newton iterations used in the first frame(only if the projection matrix is updated) 198 | bool CG_use_FR = false; // Use the Fletcher-Reeves(true) or Polak-Ribiere(false) formula in the Conjugate Gradient 199 | bool CG_standard_alpha = true; // Use the standard formula for computing the step length in Conjugate Gradient 200 | int CG_forgetting_rate = 50; // Forgetting rate of the last conjugate direction 201 | float precond_data_param = 0.75; // Weight of the data term in the preconditioner 202 | float precond_reg_param = 0.25; // Weight of the regularization term in the preconditioner 203 | int precond_proj_param = 40; // Weight of the projection matrix part in the preconditioner 204 | 205 | // Regularization window parameters 206 | bool use_reg_window = true; // Use spatial regularization or not 207 | double reg_window_min = 1e-4; // The minimum value of the regularization window 208 | double reg_window_edge = 10e-3; // The impact of the spatial regularization 209 | size_t reg_window_power = 2; // The degree of the polynomial to use(e.g. 2 is a quadratic window) 210 | float reg_sparsity_threshold = 0.05; // A relative threshold of which DFT coefficients that should be set to zero 211 | 212 | // Interpolation parameters 213 | string interpolation_method = "bicubic"; // The kind of interpolation kernel 214 | float interpolation_bicubic_a = -0.75; // The parameter for the bicubic interpolation kernel 215 | bool interpolation_centering = true; // Center the kernel at the feature sample 216 | bool interpolation_windowing = false; // Do additional windowing on the Fourier coefficients of the kernel 217 | 218 | // Scale parameters for the translation model 219 | // Only used if: use_scale_filter = false 220 | size_t number_of_scales = 7; // Number of scales to run the detector 221 | float scale_step = 1.01f; // The scale factor 222 | float min_scale_factor; 223 | float max_scale_factor; 224 | 225 | // Scale filter parameters 226 | // Only used if: use_scale_filter = true 227 | bool use_scale_filter = false; // Use the fDSST scale filter or not (for speed) 228 | float scale_sigma_factor = 1.0f / 16.0f; // Scale label function sigma 229 | float scale_learning_rate = 0.025; // Scale filter learning rate 230 | int number_of_scales_filter = 17; // Number of scales 231 | int number_of_interp_scales = 33; // Number of interpolated scales 232 | float scale_model_factor = 1.0; // Scaling of the scale model 233 | float scale_step_filter = 1.02; // The scale factor for the scale filter 234 | float scale_model_max_area = 32 * 16; // Maximume area for the scale sample patch 235 | string scale_feature = "HOG4"; // Features for the scale filter (only HOG4 supported) 236 | int s_num_compressed_dim = 17; // Number of compressed feature dimensions in the scale filter 237 | float lambda = 1e-2; // Scale filter regularization 238 | float do_poly_interp = true; // Do 2nd order polynomial interpolation to obtain more accurate scale 239 | cv::Size scale_model_sz; 240 | 241 | 242 | bool debug = 0; // to show heatmap or not 243 | 244 | // GPU 245 | bool use_gpu = true; // whether Caffe use gpu or not 246 | int gpu_id = 0; 247 | }; 248 | } // namespace eco 249 | #endif 250 | -------------------------------------------------------------------------------- /recttools.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Author: Christian Bailer 3 | Contact address: Christian.Bailer@dfki.de 4 | Department Augmented Vision DFKI 5 | 6 | License Agreement 7 | For Open Source Computer Vision Library 8 | (3-clause BSD License) 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, 14 | this list of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, 17 | this list of conditions and the following disclaimer in the documentation 18 | and/or other materials provided with the distribution. 19 | 20 | * Neither the names of the copyright holders nor the names of the contributors 21 | may be used to endorse or promote products derived from this software 22 | without specific prior written permission. 23 | 24 | This software is provided by the copyright holders and contributors "as is" and 25 | any express or implied warranties, including, but not limited to, the implied 26 | warranties of merchantability and fitness for a particular purpose are disclaimed. 27 | In no event shall copyright holders or contributors be liable for any direct, 28 | indirect, incidental, special, exemplary, or consequential damages 29 | (including, but not limited to, procurement of substitute goods or services; 30 | loss of use, data, or profits; or business interruption) however caused 31 | and on any theory of liability, whether in contract, strict liability, 32 | or tort (including negligence or otherwise) arising in any way out of 33 | the use of this software, even if advised of the possibility of such damage. 34 | */ 35 | 36 | #ifndef RECTTOOLS_HPP 37 | #define RECTTOOLS_HPP 38 | 39 | #include 40 | #include 41 | #include 42 | #include "debug.hpp" 43 | 44 | namespace eco 45 | { 46 | template 47 | inline cv::Vec center(const cv::Rect_ &rect) 48 | { 49 | return cv::Vec(rect.x + rect.width / (t)2.0f, rect.y + rect.height / (t)2.0f); 50 | } 51 | 52 | template 53 | inline t x2(const cv::Rect_ &rect) 54 | { 55 | return rect.x + rect.width; 56 | } 57 | 58 | template 59 | inline t y2(const cv::Rect_ &rect) 60 | { 61 | return rect.y + rect.height; 62 | } 63 | 64 | template 65 | inline void resize(cv::Rect_ &rect, float scalex, float scaley = 0) 66 | { 67 | if (!scaley) 68 | { 69 | scaley = scalex; 70 | } 71 | rect.x -= rect.width * (scalex - 1.0f) / 2.0f; 72 | rect.width *= scalex; 73 | 74 | rect.y -= rect.height * (scaley - 1.0f) / 2.0f; 75 | rect.height *= scaley; 76 | } 77 | 78 | template 79 | inline void limit(cv::Rect_ &rect, cv::Rect_ limit) 80 | { 81 | if (rect.x + rect.width > limit.x + limit.width) 82 | { 83 | rect.width = limit.x + limit.width - rect.x; 84 | } 85 | if (rect.y + rect.height > limit.y + limit.height) 86 | { 87 | rect.height = limit.y + limit.height - rect.y; 88 | } 89 | if (rect.x < limit.x) 90 | { 91 | rect.width -= (limit.x - rect.x); 92 | rect.x = limit.x; 93 | } 94 | if (rect.y < limit.y) 95 | { 96 | rect.height -= (limit.y - rect.y); 97 | rect.y = limit.y; 98 | } 99 | if (rect.width < 0) 100 | { 101 | rect.width = 0; 102 | } 103 | if (rect.height < 0) 104 | { 105 | rect.height = 0; 106 | } 107 | } 108 | 109 | template 110 | inline void limit(cv::Rect_ &rect, t width, t height, t x = 0, t y = 0) 111 | { 112 | limit(rect, cv::Rect_(x, y, width, height)); 113 | } 114 | 115 | template 116 | inline cv::Rect getBorder(const cv::Rect_ &original, cv::Rect_ &limited) 117 | { 118 | cv::Rect_ res; 119 | res.x = limited.x - original.x; 120 | res.y = limited.y - original.y; 121 | res.width = x2(original) - x2(limited); 122 | res.height = y2(original) - y2(limited); 123 | assert(res.x >= 0 && res.y >= 0 && res.width >= 0 && res.height >= 0); 124 | return res; 125 | } 126 | // cut "window" out from "input". 127 | inline cv::Mat subwindow(const cv::Mat &input, const cv::Rect &window, int borderType = cv::BORDER_CONSTANT) 128 | { 129 | cv::Mat res; 130 | cv::Rect cutWindow = window; 131 | limit(cutWindow, input.cols, input.rows); 132 | //debug("cutWindow: %d x %d", cutWindow.height, cutWindow.width); 133 | if (cutWindow.height <= 0 || cutWindow.width <= 0) 134 | { 135 | //assert(0 && "error: cutWindow size error!\n"); 136 | return res;//cv::Mat(window.height,window.width,input.type(),0) ; 137 | } 138 | cv::Rect border = getBorder(window, cutWindow); 139 | res = input(cutWindow); 140 | if (border != cv::Rect(0, 0, 0, 0)) 141 | { 142 | cv::copyMakeBorder(res, res, border.y, border.height, border.x, border.width, borderType); 143 | } 144 | return res; 145 | } 146 | 147 | inline cv::Mat getGrayImage(cv::Mat img) 148 | { 149 | cv::cvtColor(img, img, CV_BGR2GRAY); 150 | img.convertTo(img, CV_32F, 1 / 255.f); 151 | return img; 152 | } 153 | 154 | } // namespace eco 155 | 156 | #endif -------------------------------------------------------------------------------- /regularization_filter.cc: -------------------------------------------------------------------------------- 1 | #include "regularization_filter.hpp" 2 | 3 | namespace eco 4 | { 5 | cv::Mat get_regularization_filter(cv::Size sz, 6 | cv::Size2f target_sz, 7 | const EcoParameters ¶ms) 8 | { 9 | cv::Mat result; 10 | 11 | if (params.use_reg_window) 12 | { 13 | cv::Size2d reg_scale = cv::Size2d(target_sz.width * 0.5, 14 | target_sz.height * 0.5); 15 | 16 | // construct the regularization window 17 | cv::Mat reg_window(sz, CV_64FC1); 18 | for (double x = -0.5 * (sz.height - 1), counter1 = 0; 19 | counter1 < sz.height; x += 1, ++counter1) 20 | for (double y = -0.5 * (sz.width - 1), counter2 = 0; 21 | counter2 < sz.width; y += 1, ++counter2) 22 | { // use abs() directly will cause error because it returns int!!! 23 | reg_window.at(counter1, counter2) = 24 | (params.reg_window_edge - params.reg_window_min) * 25 | (std::pow(std::abs(x / reg_scale.height), params.reg_window_power) + 26 | std::pow(std::abs(y / reg_scale.width), params.reg_window_power)) + 27 | params.reg_window_min; 28 | } 29 | /* debug 30 | debug("%f %f", reg_scale.height, reg_scale.width); 31 | debug("%d %d", sz.height, sz.width); 32 | debug("Channels: %d",reg_window.channels()); 33 | printMat(reg_window); 34 | //showmat1channels(reg_window, 3); 35 | debug("%lf, %lf", reg_window.at(46, 23), reg_window.at(143,89)); 36 | */ 37 | 38 | // compute the DFT and enforce sparsity 39 | cv::Mat reg_window_dft = dft(reg_window) / sz.area(); 40 | cv::Mat reg_win_abs(sz, CV_64FC1); 41 | reg_win_abs = magnitude(reg_window_dft); 42 | double minv = 0.0, maxv = 0.0; 43 | cv::minMaxLoc(reg_win_abs, &minv, &maxv); 44 | // set to zero while the element smaller than threshold 45 | for (size_t i = 0; i < (size_t)reg_window_dft.rows; i++) 46 | for (size_t j = 0; j < (size_t)reg_window_dft.cols; j++) 47 | { 48 | if (reg_win_abs.at(i, j) < (params.reg_sparsity_threshold * maxv)) 49 | reg_window_dft.at>(i, j) = cv::Vec(0.0, 0.0); 50 | } 51 | /* debug 52 | showmat2channels(reg_window_dft, 3); 53 | debug("%lf, %lf", reg_window_dft.at>(0, 0)[0], reg_window_dft.at>(0,1)[0]); 54 | */ 55 | 56 | // do the inverse transform, correct window minimum 57 | cv::Mat reg_window_sparse = real(dft(reg_window_dft, true)); 58 | //showmat1channels(reg_window_sparse, 3); 59 | cv::minMaxLoc(reg_window_sparse, &minv, &maxv); 60 | //debug("%lf, %lf, %lf, %d", minv, maxv, params.reg_window_min, sz.area()); 61 | reg_window_dft.at(0, 0) = reg_window_dft.at(0, 0) - sz.area() * minv + params.reg_window_min; 62 | reg_window_dft = fftshift(reg_window_dft); 63 | 64 | // find the regularization filter by removing the zeros 65 | cv::Mat tmp; 66 | for (size_t i = 0; i < (size_t)reg_window_dft.rows; i++) 67 | { 68 | for (size_t j = 0; j < (size_t)reg_window_dft.cols; j++) 69 | { 70 | if (((reg_window_dft.at>(i, j) != 71 | cv::Vec(0, 0)) && 72 | (reg_window_dft.at>(i, j) != 73 | cv::Vec(2, 0)))) 74 | { 75 | tmp.push_back(reg_window_dft.row(i)); 76 | break; 77 | } 78 | } //end for 79 | } //end for 80 | 81 | tmp = tmp.t(); 82 | for (size_t i = 0; i < (size_t)tmp.rows; i++) 83 | { 84 | for (size_t j = 0; j < (size_t)tmp.cols; j++) 85 | { 86 | if (((tmp.at>(i, j) != 87 | cv::Vec(0, 0)) && 88 | (tmp.at>(i, j) != 89 | cv::Vec(1, 0)))) 90 | { 91 | result.push_back(real(tmp.row(i))); 92 | break; 93 | } 94 | } //end for 95 | } //end for 96 | result = result.t(); 97 | } // if params.use_reg_window 98 | else 99 | { 100 | result.push_back(params.reg_window_min); 101 | } 102 | 103 | return result; 104 | } 105 | } // namespace eco -------------------------------------------------------------------------------- /regularization_filter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REGULARIZATION_FILTER_HPP 2 | #define REGULARIZATION_FILTER_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include "parameters.hpp" 8 | #include "ffttools.hpp" 9 | #include "debug.hpp" 10 | 11 | namespace eco 12 | { 13 | cv::Mat get_regularization_filter(cv::Size sz, 14 | cv::Size2f target_sz, 15 | const EcoParameters ¶ms); 16 | } 17 | #endif -------------------------------------------------------------------------------- /sample_update.cc: -------------------------------------------------------------------------------- 1 | #include "sample_update.hpp" 2 | 3 | namespace eco 4 | { 5 | void SampleUpdate::init(const std::vector &filter, 6 | const std::vector &feature_dim, 7 | const size_t nSamples, 8 | const float learning_rate) 9 | { 10 | distance_matrix_.release(); 11 | gram_matrix_.release(); 12 | nSamples_ = nSamples; 13 | learning_rate_ = learning_rate; 14 | sample_weight_.clear(); 15 | samples_f_.clear(); 16 | num_training_samples_ = 0; 17 | prior_weights_.clear(); 18 | new_sample_.clear(); 19 | merged_sample_.clear(); 20 | new_sample_id_ = -1; 21 | merged_sample_id_ = -1; 22 | 23 | // distance matrix initialization 24 | distance_matrix_.create(cv::Size(nSamples_, nSamples_), CV_32FC2); 25 | gram_matrix_.create(cv::Size(nSamples_, nSamples_), CV_32FC2); 26 | 27 | // initialization to INF 28 | for (size_t i = 0; i < (size_t)distance_matrix_.rows; i++) 29 | { 30 | for (size_t j = 0; j < (size_t)distance_matrix_.cols; j++) 31 | { 32 | distance_matrix_.at>(i, j) = cv::Vec(INF, 0); 33 | gram_matrix_.at>(i, j) = cv::Vec(INF, 0); 34 | } 35 | } 36 | // Samples memory initialization 37 | samples_f_.clear(); 38 | 39 | for (size_t n = 0; n < nSamples_; n++) 40 | { 41 | ECO_FEATS temp; 42 | for (size_t j = 0; j < (size_t)feature_dim.size(); j++) // for each feature 43 | { 44 | std::vector temp_single_feat; 45 | for (size_t i = 0; i < (size_t)feature_dim[j]; i++) // for each dimension of the feature 46 | temp_single_feat.push_back(cv::Mat::zeros( 47 | cv::Size((filter[j].height + 1) / 2, filter[j].width), 48 | CV_32FC2)); 49 | temp.push_back(temp_single_feat); 50 | } 51 | samples_f_.push_back(temp); 52 | } 53 | 54 | // resize prior weights to the same as nSamples_ 55 | 56 | prior_weights_.resize(nSamples_); 57 | 58 | // Show debug. 59 | for (size_t j = 0; j < (size_t)feature_dim.size(); j++) 60 | { 61 | debug("samples: %lu, feature %lu, size: %lu, mat: %d x %d", 62 | nSamples_, j, samples_f_[nSamples_ - 1][j].size(), 63 | samples_f_[nSamples_ - 1][j][feature_dim[j] - 1].rows, 64 | samples_f_[nSamples_ - 1][j][feature_dim[j] - 1].cols); 65 | } 66 | /* 67 | debug("prior_weights_ size: %lu ", prior_weights_.size()); 68 | for (size_t j = 0; j < (size_t)prior_weights_.size(); j++) 69 | { 70 | printf("%f ", prior_weights_[j]); 71 | } 72 | printf("\n"); 73 | */ 74 | } 75 | 76 | void SampleUpdate::update_sample_space_model(const ECO_FEATS &new_train_sample) 77 | { 78 | // Calculate the distance 79 | cv::Mat gram_vector = find_gram_vector(new_train_sample); // 32FC2 50 x 1, 2(ac+bd) 80 | float new_train_sample_norm = 2 * FeatureComputeEnergy(new_train_sample); //2(c^2+d^2) 81 | cv::Mat distance(nSamples_, 1, CV_32FC2); 82 | for (size_t i = 0; i < nSamples_; i++) 83 | { 84 | // a^2 + b^2 + c^2 + d^2 - 2(ac+bd) 85 | float temp = new_train_sample_norm + gram_matrix_.at>(i, i)[0] - 2 * gram_vector.at>(i, 0)[0]; 86 | if (i < (size_t)num_training_samples_) 87 | distance.at>(i, 0) = 88 | cv::Vec(std::max(temp, 0.0f), 0); 89 | else 90 | distance.at>(i, 0) = cv::Vec(INF, 0); 91 | } 92 | // End of calcualte the distance 93 | 94 | if (num_training_samples_ == nSamples_) // if memory is full 95 | { 96 | float min_sample_weight_ = INF; 97 | size_t min_sample_id = 0; 98 | findMin(min_sample_weight_, min_sample_id); 99 | // debug("min_sample: %d %f", min_sample_id, min_sample_weight_); 100 | 101 | if (min_sample_weight_ < minmum_sample_weight_) 102 | // If any prior weight is less than the minimum allowed weight, 103 | // replace that sample with the new sample 104 | { 105 | update_distance_matrix(gram_vector, new_train_sample_norm, min_sample_id, -1, 0, 1); 106 | prior_weights_[min_sample_id] = 0; 107 | // normalize the prior_weights_ 108 | float sum = std::accumulate(prior_weights_.begin(), prior_weights_.end(), 0.0f); 109 | for (size_t i = 0; i < (size_t)nSamples_; i++) 110 | { 111 | prior_weights_[i] = prior_weights_[i] * 112 | (1 - learning_rate_) / sum; 113 | } 114 | // set the new sample's weight as learning_rate_ 115 | prior_weights_[min_sample_id] = learning_rate_; 116 | 117 | // update sampel space. 118 | merged_sample_id_ = -1; 119 | new_sample_id_ = min_sample_id; 120 | new_sample_ = new_train_sample; 121 | replace_sample(new_sample_, new_sample_id_); 122 | } 123 | else // If no sample has low enough prior weight, then we either merge 124 | // the new sample with an existing sample, or merge two of the 125 | // existing samples and insert the new sample in the vacated position 126 | { 127 | // Find the minimum distance between new sample and exsiting samples. 128 | double new_sample_min_dist; 129 | cv::Point min_sample_id; 130 | cv::minMaxLoc(real(distance), &new_sample_min_dist, 0, &min_sample_id); 131 | 132 | // Find the closest pair amongst existing samples. 133 | double existing_samples_min_dist; 134 | cv::Point closest_exist_sample_pair; 135 | cv::Mat duplicate = distance_matrix_.clone(); 136 | cv::minMaxLoc(real(duplicate), &existing_samples_min_dist, 0, &closest_exist_sample_pair); 137 | 138 | if (closest_exist_sample_pair.x == closest_exist_sample_pair.y) 139 | assert(0 && "error: distance matrix diagonal filled wrongly."); 140 | 141 | if (new_sample_min_dist < existing_samples_min_dist) 142 | { 143 | // If the min distance of the new sample to the existing samples is less than the min distance 144 | // amongst any of the existing samples, we merge the new sample with the nearest existing 145 | 146 | // renormalize prior weights 147 | for (size_t i = 0; i < prior_weights_[i]; i++) 148 | prior_weights_[i] *= (1 - learning_rate_); 149 | 150 | // Set the position of the merged sample 151 | merged_sample_id_ = min_sample_id.y; 152 | 153 | // Extract the existing sample to merge 154 | ECO_FEATS existing_sample_to_merge = samples_f_[merged_sample_id_]; 155 | 156 | // Merge the new_train_sample with existing sample 157 | merged_sample_ = 158 | merge_samples(existing_sample_to_merge, 159 | new_train_sample, 160 | prior_weights_[merged_sample_id_], learning_rate_, 161 | std::string("merge")); 162 | 163 | // Update distance matrix and the gram matrix 164 | update_distance_matrix(gram_vector, new_train_sample_norm, merged_sample_id_, -1, prior_weights_[merged_sample_id_], learning_rate_); 165 | 166 | // Update the prior weight of the merged sample 167 | prior_weights_[min_sample_id.y] += learning_rate_; 168 | 169 | // update the merged sample and discard new sample 170 | replace_sample(merged_sample_, merged_sample_id_); 171 | } 172 | else 173 | { 174 | // we merge the nearest existing samples and insert the new sample in the vacated position 175 | 176 | // renormalize prior weights 177 | for (size_t i = 0; i < prior_weights_[i]; i++) 178 | prior_weights_[i] *= (1 - learning_rate_); 179 | 180 | // Ensure that the sample with higher prior weight is assigned id1. 181 | if (prior_weights_[closest_exist_sample_pair.x] > 182 | prior_weights_[closest_exist_sample_pair.y]) 183 | std::swap(closest_exist_sample_pair.x, 184 | closest_exist_sample_pair.y); 185 | 186 | // Merge the existing closest samples 187 | merged_sample_ = 188 | merge_samples(samples_f_[closest_exist_sample_pair.x], 189 | samples_f_[closest_exist_sample_pair.y], 190 | prior_weights_[closest_exist_sample_pair.x], prior_weights_[closest_exist_sample_pair.y], 191 | std::string("merge")); 192 | 193 | // Update distance matrix and the gram matrix 194 | update_distance_matrix(gram_vector, new_train_sample_norm, closest_exist_sample_pair.x, closest_exist_sample_pair.y, prior_weights_[closest_exist_sample_pair.x], prior_weights_[closest_exist_sample_pair.y]); 195 | 196 | // Update prior weights for the merged sample and the new sample 197 | prior_weights_[closest_exist_sample_pair.x] += 198 | prior_weights_[closest_exist_sample_pair.y]; 199 | prior_weights_[closest_exist_sample_pair.y] = learning_rate_; 200 | 201 | // Update the merged sample and insert new sample 202 | merged_sample_id_ = closest_exist_sample_pair.x; 203 | new_sample_id_ = closest_exist_sample_pair.y; 204 | new_sample_ = new_train_sample; 205 | replace_sample(merged_sample_, merged_sample_id_); 206 | replace_sample(new_sample_, new_sample_id_); 207 | } 208 | } 209 | } // end if memory is full 210 | else // if memory is not full 211 | { 212 | size_t sample_position = num_training_samples_; 213 | update_distance_matrix(gram_vector, new_train_sample_norm, sample_position, -1, 0, 1); 214 | 215 | if (sample_position == 0) 216 | { 217 | prior_weights_[sample_position] = 1; 218 | } 219 | else 220 | { 221 | for (size_t i = 0; i < sample_position; i++) 222 | prior_weights_[i] *= (1 - learning_rate_); 223 | prior_weights_[sample_position] = learning_rate_; 224 | } 225 | // update sample space 226 | new_sample_id_ = sample_position; 227 | new_sample_ = new_train_sample; 228 | replace_sample(new_sample_, new_sample_id_); 229 | 230 | num_training_samples_++; 231 | } 232 | //debug("num_training_samples_: %lu", num_training_samples_); 233 | } 234 | 235 | void SampleUpdate::update_distance_matrix(cv::Mat &gram_vector, float new_sample_norm, int id1, int id2, float w1, float w2) 236 | { 237 | float alpha1 = w1 / (w1 + w2); 238 | float alpha2 = 1 - alpha1; 239 | //debug("alpha1: %f, alpha2: %f", alpha1, alpha2); 240 | if (id2 < 0) // 241 | { 242 | COMPLEX norm_id1 = gram_matrix_.at(id1, id1); 243 | 244 | // update the matrix 245 | if (alpha1 == 0) 246 | { 247 | gram_vector.col(0).copyTo(gram_matrix_.col(id1)); 248 | cv::Mat tt = gram_vector.t(); 249 | tt.row(0).copyTo(gram_matrix_.row(id1)); 250 | gram_matrix_.at(id1, id1) = COMPLEX(new_sample_norm, 0); 251 | } 252 | else if (alpha2 == 0) 253 | { 254 | // do nothing discard new sample 255 | } 256 | else 257 | { // The new sample is merge with an existing sample 258 | cv::Mat t = alpha1 * gram_matrix_.col(id1) + alpha2 * gram_vector.col(0), t_t; 259 | t.col(0).copyTo(gram_matrix_.col(id1)); 260 | t_t = t.t(); 261 | t_t.row(0).copyTo(gram_matrix_.row(id1)); 262 | gram_matrix_.at(id1, id1) = 263 | COMPLEX(std::pow(alpha1, 2) * norm_id1[0] + std::pow(alpha2, 2) * new_sample_norm + 2 * alpha1 * alpha2 * gram_vector.at(id1)[0], 0); 264 | } 265 | 266 | // Update distance matrix 267 | cv::Mat distance(nSamples_, 1, CV_32FC2); 268 | for (size_t i = 0; i < nSamples_; i++) 269 | { 270 | float temp = gram_matrix_.at(id1, id1)[0] + 271 | gram_matrix_.at(i, i)[0] - 272 | 2 * gram_matrix_.at(i, id1)[0]; 273 | distance.at(i, 0) = COMPLEX(std::max(temp, 0.0f), 0); 274 | } 275 | distance.col(0).copyTo(distance_matrix_.col(id1)); 276 | cv::Mat tt = distance.t(); 277 | tt.row(0).copyTo(distance_matrix_.row(id1)); 278 | distance_matrix_.at(id1, id1) = COMPLEX(INF, 0); 279 | } 280 | else 281 | { 282 | if (alpha1 == 0 || alpha2 == 0) 283 | { 284 | assert(0 && "error: alpha1 or alpha2 equals 0"); 285 | } 286 | // Two existing samples are merged and the new sample fills the empty 287 | COMPLEX norm_id1 = gram_matrix_.at(id1, id1); 288 | COMPLEX norm_id2 = gram_matrix_.at(id2, id2); 289 | COMPLEX ip_id1_id2 = gram_matrix_.at(id1, id2); 290 | //debug("%d %d, %f %f, %f %f %f", id1, id2, w1, w2, norm_id1[0], norm_id2[0], ip_id1_id2[0]); 291 | // Handle the merge of existing samples 292 | cv::Mat t = alpha1 * gram_matrix_.col(id1) + 293 | alpha2 * gram_matrix_.col(id2), 294 | t_t; 295 | 296 | t.col(0).copyTo(gram_matrix_.col(id1)); 297 | 298 | cv::Mat tt = t.t(); 299 | tt.row(0).copyTo(gram_matrix_.row(id1)); 300 | 301 | gram_matrix_.at(id1, id1) = 302 | COMPLEX(std::pow(alpha1, 2) * norm_id1[0] + 303 | std::pow(alpha2, 2) * norm_id2[0] + 304 | 2 * alpha1 * alpha2 * ip_id1_id2[0], 305 | 0); 306 | gram_vector.at(id1) = 307 | COMPLEX(alpha1 * gram_vector.at(id1, 0)[0] + 308 | alpha2 * gram_vector.at(id2, 0)[0], 309 | 0); 310 | 311 | // Handle the new sample 312 | gram_vector.col(0).copyTo(gram_matrix_.col(id2)); 313 | tt = gram_vector.t(); 314 | tt.row(0).copyTo(gram_matrix_.row(id2)); 315 | gram_matrix_.at(id2, id2) = new_sample_norm; 316 | 317 | // Update the distance matrix 318 | cv::Mat distance(nSamples_, 1, CV_32FC2); 319 | std::vector id({id1, id2}); 320 | for (size_t i = 0; i < 2; i++) 321 | { 322 | for (size_t j = 0; j < nSamples_; j++) 323 | { 324 | float temp = gram_matrix_.at(id[i], id[i])[0] + 325 | gram_matrix_.at(j, j)[0] - 326 | 2 * gram_matrix_.at(j, id[i])[0]; 327 | distance.at(j, 0) = COMPLEX(std::max(temp, 0.0f), 0); 328 | } 329 | distance.col(0).copyTo(distance_matrix_.col(id[i])); 330 | cv::Mat tt = distance.t(); 331 | tt.row(0).copyTo(distance_matrix_.row(id[i])); 332 | distance_matrix_.at(id[i], id[i]) = COMPLEX(INF, 0); 333 | } 334 | } //if end 335 | } //function end 336 | } // namespace eco 337 | -------------------------------------------------------------------------------- /sample_update.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SAMPLE_UPDATE_HPP 2 | #define SAMPLE_UPDATE_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "parameters.hpp" 10 | #include "ffttools.hpp" 11 | #include "feature_operator.hpp" 12 | #include "debug.hpp" 13 | 14 | namespace eco 15 | { 16 | 17 | class SampleUpdate 18 | { 19 | public: 20 | SampleUpdate(){}; 21 | virtual ~SampleUpdate(){}; 22 | 23 | void init(const std::vector &filter, 24 | const std::vector &feature_dim, 25 | const size_t nSamples, 26 | const float learning_rate); 27 | 28 | void update_sample_space_model(const ECO_FEATS &new_train_sample); 29 | 30 | void update_distance_matrix(cv::Mat &gram_vector, float new_sample_norm, 31 | int id1, int id2, float w1, float w2); 32 | 33 | inline cv::Mat find_gram_vector(const ECO_FEATS &new_train_sample) 34 | { 35 | cv::Mat result(cv::Size(1, nSamples_), CV_32FC2); 36 | for (size_t i = 0; i < (size_t)result.rows; i++) // init to INF; 37 | result.at>(i, 0) = cv::Vec(INF, 0); 38 | 39 | std::vector distance_vector; 40 | for (size_t i = 0; i < num_training_samples_; i++) // calculate the distance; 41 | distance_vector.push_back(2 * 42 | FeatureComputeInnerProduct(samples_f_[i], new_train_sample)); 43 | 44 | for (size_t i = 0; i < distance_vector.size(); i++) 45 | result.at>(i, 0) = 46 | cv::Vec(distance_vector[i], 0); 47 | 48 | return result; 49 | }; 50 | // find the minimum element in prior_weights_; 51 | inline void findMin(float &min_w, size_t &index) const 52 | { 53 | std::vector::const_iterator pos = std::min_element(prior_weights_.begin(), prior_weights_.end()); 54 | min_w = *pos; 55 | index = pos - prior_weights_.begin(); 56 | }; 57 | 58 | inline ECO_FEATS merge_samples(const ECO_FEATS &sample1, 59 | const ECO_FEATS &sample2, 60 | const float w1, const float w2, 61 | const std::string sample_merge_type = "merge") 62 | { 63 | float alpha1 = w1 / (w1 + w2); 64 | float alpha2 = 1 - alpha1; 65 | ECO_FEATS merged_sample = sample1; 66 | 67 | if (sample_merge_type == std::string("replace")) 68 | { 69 | } 70 | else if (sample_merge_type == std::string("merge")) 71 | { 72 | for (size_t i = 0; i < sample1.size(); i++) 73 | for (size_t j = 0; j < sample1[i].size(); j++) 74 | merged_sample[i][j] = alpha1 * sample1[i][j] + alpha2 * sample2[i][j]; 75 | } 76 | return merged_sample; 77 | }; 78 | 79 | inline void replace_sample(const ECO_FEATS &new_sample, const size_t idx) 80 | { 81 | samples_f_[idx] = new_sample; 82 | }; 83 | 84 | inline void set_gram_matrix(const int r, const int c, const float val) 85 | { 86 | gram_matrix_.at(r, c) = val; 87 | }; 88 | 89 | int get_merged_sample_id() const { return merged_sample_id_; } 90 | 91 | int get_new_sample_id() const { return new_sample_id_; } 92 | 93 | std::vector get_prior_weights() const { return prior_weights_; } 94 | 95 | std::vector get_samples() const { return samples_f_; } 96 | 97 | private: 98 | cv::Mat distance_matrix_, gram_matrix_; // distance matrix and its kernel 99 | 100 | size_t nSamples_ = 50; 101 | 102 | float learning_rate_ = 0.009; 103 | 104 | const float minmum_sample_weight_ = 0.0036; 105 | 106 | std::vector sample_weight_; 107 | 108 | std::vector samples_f_; // all samples frontier 109 | 110 | size_t num_training_samples_ = 0; 111 | 112 | std::vector prior_weights_; 113 | 114 | ECO_FEATS new_sample_, merged_sample_; 115 | 116 | int new_sample_id_ = -1, merged_sample_id_ = -1; 117 | }; 118 | 119 | } // namespace eco 120 | 121 | #endif -------------------------------------------------------------------------------- /scale_filter.cc: -------------------------------------------------------------------------------- 1 | #include "scale_filter.hpp" 2 | 3 | namespace eco 4 | { 5 | void ScaleFilter::init(int &nScales, float &scale_step, const EcoParameters ¶ms) 6 | { 7 | nScales = params.number_of_scales_filter; 8 | scale_step = params.scale_step_filter; 9 | float scale_sigma = params.number_of_interp_scales * params.scale_sigma_factor; 10 | vector scale_exp, scale_exp_shift; 11 | int scalemin = floor((1.0 - (float)nScales) / 2.0); 12 | int scalemax = floor(((float)nScales - 1.0) / 2.0); 13 | for (int i = scalemin; i <= scalemax; i++) 14 | { 15 | scale_exp.push_back(i * params.number_of_interp_scales / (float)nScales); 16 | } 17 | for (int i = 0; i < nScales; i++) 18 | { 19 | scale_exp_shift.push_back(scale_exp[(i + nScales / 2) % nScales]); 20 | } 21 | /* debug("scale: min:%d, max:%d", scalemin, scalemax); 22 | debug("scale_exp_shift:"); 23 | for (int i = 0; i < nScales; i++) 24 | { 25 | printf("%d:%f; ", i, scale_exp_shift[i]); 26 | } 27 | printf("\n"); 28 | */ 29 | vector interp_scale_exp, interp_scale_exp_shift; 30 | scalemin = floor((1.0 - (float)params.number_of_interp_scales) / 2.0); 31 | scalemax = floor(((float)params.number_of_interp_scales - 1.0) / 2.0); 32 | for (int i = scalemin; i <= scalemax; i++) 33 | { 34 | interp_scale_exp.push_back(i); 35 | } 36 | for (int i = 0; i < params.number_of_interp_scales; i++) 37 | { 38 | interp_scale_exp_shift.push_back(interp_scale_exp[(i + params.number_of_interp_scales / 2) % params.number_of_interp_scales]); 39 | } 40 | /* debug("scale: min:%d, max:%d", scalemin, scalemax); 41 | debug("interp_scale_exp_shift:"); 42 | for (int i = 0; i < params.number_of_interp_scales; i++) 43 | { 44 | printf("%d:%f; ", i, interp_scale_exp_shift[i]); 45 | } 46 | printf("\n"); 47 | */ 48 | for (int i = 0; i < nScales; i++) 49 | { 50 | scaleSizeFactors_.push_back(std::pow(scale_step, scale_exp[i])); 51 | } 52 | /* debug("scaleSizeFactors_:"); 53 | for (int i = 0; i < nScales; i++) 54 | { 55 | printf("%d:%f; ", i, scaleSizeFactors_[i]); 56 | } 57 | printf("\n"); 58 | */ 59 | for (int i = 0; i < params.number_of_interp_scales; i++) 60 | { 61 | interpScaleFactors_.push_back(std::pow(scale_step, interp_scale_exp_shift[i])); 62 | } 63 | /* debug("interpScaleFactors_:"); 64 | for (int i = 0; i < params.number_of_interp_scales; i++) 65 | { 66 | printf("%d:%f; ", i, interpScaleFactors_[i]); 67 | } 68 | printf("\n"); 69 | */ 70 | 71 | cv::Mat ys_mat = cv::Mat(cv::Size(nScales, 1), CV_32FC1); 72 | for (int i = 0; i < nScales; i++) 73 | { 74 | ys_mat.at(0, i) = std::exp(-0.5f * scale_exp_shift[i] * scale_exp_shift[i] / scale_sigma / scale_sigma); 75 | } 76 | /* 77 | debug("ys:"); 78 | printMat(ys_mat); 79 | showmat1channels(ys_mat,2); 80 | */ 81 | yf_ = real(dft(ys_mat, false)); 82 | /* 83 | debug("yf:"); 84 | printMat(yf_); 85 | showmat1channels(yf_,2); 86 | */ 87 | 88 | for (int i = 0; i < nScales; i++) 89 | { 90 | window_.push_back(0.5f * (1.0f - std::cos(2 * M_PI * i / (nScales - 1.0f)))); 91 | } 92 | /* 93 | debug("window_:"); 94 | for (int i = 0; i < nScales; i++) 95 | { 96 | printf("%d:%f; ", i, window_[i]); 97 | } 98 | */ 99 | //max_scale_dim_ = !params.s_num_compressed_dim.compare("MAX"); 100 | //debug("max_scale_dim_: %d", max_scale_dim_); 101 | } 102 | 103 | float ScaleFilter::scale_filter_track(const cv::Mat &im, const cv::Point2f &pos, const cv::Size2f &base_target_sz, const float ¤tScaleFactor, const EcoParameters ¶ms) 104 | { 105 | debug("%f", currentScaleFactor); 106 | vector scales; 107 | for (unsigned int i = 0; i < scaleSizeFactors_.size(); i++) 108 | { 109 | scales.push_back(scaleSizeFactors_[i] * currentScaleFactor); 110 | //printf("%f ", scaleSizeFactors_[i]); 111 | } 112 | cv::Mat xs = extract_scale_sample(im, pos, base_target_sz, scales, params.scale_model_sz); 113 | 114 | debug("Not finished!-------------------"); 115 | assert(0); 116 | 117 | float scale_change_factor; 118 | return scale_change_factor; 119 | } 120 | 121 | cv::Mat ScaleFilter::extract_scale_sample(const cv::Mat &im, const cv::Point2f &posf, const cv::Size2f &base_target_sz, vector &scaleFactors, const cv::Size &scale_model_sz) 122 | { 123 | //printMat(new_im); 124 | //showmat3channels(new_im, 0); 125 | //debug("pos: %f %f", posf.x, posf.y); 126 | cv::Point2i pos(posf); 127 | int nScales = scaleFactors.size(); 128 | int df = std::floor(*std::min_element(std::begin(scaleFactors), std::end(scaleFactors))); 129 | // debug("df:%d", df); 130 | 131 | cv::Mat new_im; 132 | im.copyTo(new_im); 133 | if (df > 1) 134 | { 135 | // compute offset and new center position 136 | cv::Point os((pos.x - 1) % df, ((pos.y - 1) % df)); 137 | pos.x = (pos.x - os.x - 1) / df + 1; 138 | pos.y = (pos.y - os.y - 1) / df + 1; 139 | 140 | for (unsigned int i = 0; i < scaleFactors.size(); i++) 141 | { 142 | scaleFactors[i] /= df; 143 | } 144 | // down sample image 145 | int r = (im.rows - os.y) / df + 1; 146 | int c = (im.cols - os.x) / df; 147 | cv::Mat new_im2(r, c, im.type()); 148 | new_im = new_im2; 149 | for (size_t i = 0 + os.y, m = 0; 150 | i < (size_t)im.rows && m < (size_t)new_im.rows; 151 | i += df, ++m) 152 | { 153 | for (size_t j = 0 + os.x, n = 0; 154 | j < (size_t)im.cols && n < (size_t)new_im.cols; 155 | j += df, ++n) 156 | { 157 | 158 | if (im.channels() == 1) 159 | { 160 | new_im.at(m, n) = im.at(i, j); 161 | } 162 | else 163 | { 164 | new_im.at(m, n) = im.at(i, j); 165 | } 166 | } 167 | } 168 | } 169 | 170 | for (int s = 0; s < nScales; s++) 171 | { 172 | cv::Size patch_sz; 173 | patch_sz.width = std::max(std::floor(base_target_sz.width * scaleFactors[s]), 2.0f); 174 | patch_sz.height = std::max(std::floor(base_target_sz.height * scaleFactors[s]), 2.0f); 175 | //debug("patch_sz:%d %d", patch_sz.height, patch_sz.width); 176 | 177 | cv::Point pos2(pos.x - floor((patch_sz.width + 1) / 2), 178 | pos.y - floor((patch_sz.height + 1) / 2)); 179 | 180 | cv::Mat im_patch = subwindow(new_im, cv::Rect(pos2, patch_sz), IPL_BORDER_REPLICATE); 181 | 182 | cv::Mat im_patch_resized; 183 | if (im_patch.cols == 0 || im_patch.rows == 0) 184 | { 185 | return im_patch_resized; 186 | } 187 | cv::resize(im_patch, im_patch_resized, scale_model_sz); 188 | //printMat(im_patch); 189 | //showmat3channels(im_patch, 0); 190 | //printMat(im_patch_resized); 191 | //showmat3channels(im_patch_resized, 0); 192 | 193 | vector im_vector, temp_hog; 194 | im_vector.push_back(im_patch); 195 | FeatureExtractor feature_extractor; 196 | #ifdef USE_SIMD 197 | temp_hog = feature_extractor.get_hog_features_simd(im_vector); 198 | #else 199 | temp_hog = feature_extractor.get_hog_features(im_vector); 200 | #endif 201 | temp_hog = feature_extractor.hog_feature_normalization(temp_hog); 202 | 203 | debug("Not finished!-------------------"); 204 | assert(0); 205 | } 206 | 207 | cv::Mat scale_sample; 208 | return scale_sample; 209 | } 210 | 211 | } // namespace eco -------------------------------------------------------------------------------- /scale_filter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SCALE_FILTER_HPP 2 | #define SCALE_FILTER_HPP 3 | 4 | #define _USE_MATH_DEFINES 5 | #include "parameters.hpp" 6 | #include "ffttools.hpp" 7 | #include "recttools.hpp" 8 | #include "feature_extractor.hpp" 9 | #include "debug.hpp" 10 | #include 11 | 12 | namespace eco 13 | { 14 | 15 | class ScaleFilter 16 | { 17 | public: 18 | ScaleFilter(){}; 19 | virtual ~ScaleFilter(){}; 20 | void init(int &nScales, float &scale_step, const EcoParameters ¶ms); 21 | float scale_filter_track(const cv::Mat &im, const cv::Point2f &pos, const cv::Size2f &base_target_sz, const float ¤tScaleFactor, const EcoParameters ¶ms); 22 | cv::Mat extract_scale_sample(const cv::Mat &im, const cv::Point2f &posf, const cv::Size2f &base_target_sz, vector &scaleFactors, const cv::Size &scale_model_sz); 23 | 24 | private: 25 | vector scaleSizeFactors_; 26 | vector interpScaleFactors_; 27 | cv::Mat yf_; 28 | vector window_; 29 | bool max_scale_dim_; 30 | }; 31 | } // namespace eco 32 | #endif -------------------------------------------------------------------------------- /sse.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Piotr's Computer Vision Matlab Toolbox Version 3.23 3 | * Copyright 2014 Piotr Dollar. [pdollar-at-gmail.com] 4 | * Licensed under the Simplified BSD License [see external/bsd.txt] 5 | *******************************************************************************/ 6 | // Intel Intrinsics Guide: https://software.intel.com/sites/landingpage/IntrinsicsGuide/# 7 | 8 | #ifndef _SSE_HPP_ 9 | #define _SSE_HPP_ 10 | 11 | #ifdef USE_NEON 12 | #include "sse2neon.h" 13 | #else 14 | #include // SSE2:, SSE3:, SSE4: 15 | #endif 16 | 17 | #define RETf inline __m128 18 | #define RETi inline __m128i 19 | 20 | // set, load and store values 21 | RETf SET( const float &x ) { return _mm_set1_ps(x); } 22 | RETf SET( float x, float y, float z, float w ) { return _mm_set_ps(x,y,z,w); } 23 | RETi SET( const int &x ) { return _mm_set1_epi32(x); } 24 | RETf LD( const float &x ) { return _mm_load_ps(&x); } 25 | RETf LDu( const float &x ) { return _mm_loadu_ps(&x); } 26 | RETf STR( float &x, const __m128 y ) { _mm_store_ps(&x,y); return y; } 27 | RETf STR1( float &x, const __m128 y ) { _mm_store_ss(&x,y); return y; } 28 | RETf STRu( float &x, const __m128 y ) { _mm_storeu_ps(&x,y); return y; } 29 | RETf STR( float &x, const float y ) { return STR(x,SET(y)); } 30 | 31 | // arithmetic operators 32 | RETi ADD( const __m128i x, const __m128i y ) { return _mm_add_epi32(x,y); } 33 | RETf ADD( const __m128 x, const __m128 y ) { return _mm_add_ps(x,y); } 34 | RETf ADD( const __m128 x, const __m128 y, const __m128 z ) { 35 | return ADD(ADD(x,y),z); } 36 | RETf ADD( const __m128 a, const __m128 b, const __m128 c, const __m128 &d ) { 37 | return ADD(ADD(ADD(a,b),c),d); } 38 | RETf SUB( const __m128 x, const __m128 y ) { return _mm_sub_ps(x,y); } 39 | RETf MUL( const __m128 x, const __m128 y ) { return _mm_mul_ps(x,y); } 40 | RETf MUL( const __m128 x, const float y ) { return MUL(x,SET(y)); } 41 | RETf MUL( const float x, const __m128 y ) { return MUL(SET(x),y); } 42 | RETf INC( __m128 &x, const __m128 y ) { return x = ADD(x,y); } 43 | RETf INC( float &x, const __m128 y ) { __m128 t=ADD(LD(x),y); return STR(x,t); } 44 | RETf DEC( __m128 &x, const __m128 y ) { return x = SUB(x,y); } 45 | RETf DEC( float &x, const __m128 y ) { __m128 t=SUB(LD(x),y); return STR(x,t); } 46 | RETf MINN( const __m128 x, const __m128 y ) { return _mm_min_ps(x,y); } 47 | RETf RCP( const __m128 x ) { return _mm_rcp_ps(x); } 48 | RETf RCPSQRT( const __m128 x ) { return _mm_rsqrt_ps(x); } 49 | 50 | // logical operators 51 | RETf AND( const __m128 x, const __m128 y ) { return _mm_and_ps(x,y); } 52 | RETi AND( const __m128i x, const __m128i y ) { return _mm_and_si128(x,y); } 53 | RETf ANDNOT( const __m128 x, const __m128 y ) { return _mm_andnot_ps(x,y); } 54 | RETf OR( const __m128 x, const __m128 y ) { return _mm_or_ps(x,y); } 55 | RETf XOR( const __m128 x, const __m128 y ) { return _mm_xor_ps(x,y); } 56 | 57 | // comparison operators 58 | RETf CMPGT( const __m128 x, const __m128 y ) { return _mm_cmpgt_ps(x,y); } 59 | RETf CMPLT( const __m128 x, const __m128 y ) { return _mm_cmplt_ps(x,y); } 60 | RETi CMPGT( const __m128i x, const __m128i y ) { return _mm_cmpgt_epi32(x,y); } 61 | RETi CMPLT( const __m128i x, const __m128i y ) { return _mm_cmplt_epi32(x,y); } 62 | 63 | // conversion operators 64 | RETf CVT( const __m128i x ) { return _mm_cvtepi32_ps(x); } 65 | RETi CVT( const __m128 x ) { return _mm_cvttps_epi32(x); } 66 | 67 | #undef RETf 68 | #undef RETi 69 | #endif 70 | -------------------------------------------------------------------------------- /training.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TRAINING_HPP 2 | #define TRAINING_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "ffttools.hpp" 13 | #include "recttools.hpp" 14 | #include "parameters.hpp" 15 | #include "feature_operator.hpp" 16 | #include "debug.hpp" 17 | 18 | namespace eco 19 | { 20 | class EcoTrain 21 | { 22 | public: 23 | EcoTrain(); 24 | virtual ~EcoTrain(); 25 | 26 | struct STATE 27 | { 28 | ECO_FEATS p, r_prev; 29 | float rho; 30 | }; 31 | // the right and left side of the equation (18) of suppl. paper ECO 32 | struct ECO_EQ 33 | { 34 | ECO_EQ() {} 35 | ECO_EQ(ECO_FEATS up_part, std::vector low_part) : up_part_(up_part), low_part_(low_part) {} 36 | 37 | ECO_FEATS up_part_; // this is f + delta(f) 38 | std::vector low_part_; // this is delta(P) 39 | 40 | ECO_EQ operator+(const ECO_EQ data); 41 | ECO_EQ operator-(const ECO_EQ data); 42 | ECO_EQ operator*(const float scale); 43 | }; 44 | 45 | void train_init(const ECO_FEATS &hf, 46 | const ECO_FEATS &hf_inc, 47 | const vector &proj_matrix, 48 | const ECO_FEATS &xlf, 49 | const vector &yf, 50 | const vector ®_filter, 51 | const ECO_FEATS &sample_energy, 52 | const vector ®_energy, 53 | const vector &proj_energy, 54 | const EcoParameters ¶ms); 55 | 56 | // Filter training and Projection updating(for the 1st Frame)============== 57 | void train_joint(); 58 | 59 | ECO_EQ pcg_eco_joint(const ECO_FEATS &init_samplef_proj, 60 | const vector ®_filter, 61 | const ECO_FEATS &init_samplef, 62 | const vector &init_samplesf_H, 63 | const ECO_FEATS &init_hf, 64 | const ECO_EQ &rhs_samplef, 65 | const ECO_EQ &diag_M, // preconditionor 66 | const ECO_EQ &hf); 67 | 68 | ECO_EQ lhs_operation_joint(const ECO_EQ &hf, 69 | const ECO_FEATS &samplesf, 70 | const vector ®_filter, 71 | const ECO_FEATS &init_samplef, 72 | const vector &XH, 73 | const ECO_FEATS &init_hf); 74 | // Only filter training(for tracker update)=============================== 75 | void train_filter(const vector &samplesf, 76 | const vector &sample_weights, 77 | const ECO_FEATS &sample_energy); 78 | 79 | ECO_FEATS pcg_eco_filter(const vector &samplesf, 80 | const vector ®_filter, 81 | const vector &sample_weights, 82 | const ECO_FEATS &rhs_samplef, 83 | const ECO_FEATS &diag_M, 84 | const ECO_FEATS &hf); 85 | 86 | ECO_FEATS lhs_operation_filter(const ECO_FEATS &hf, 87 | const vector &samplesf, 88 | const vector ®_filter, 89 | const vector &sample_weights); 90 | // joint structure basic operation================================ 91 | ECO_EQ jointDotDivision(const ECO_EQ &a, const ECO_EQ &b); 92 | float inner_product_joint(const ECO_EQ &a, const ECO_EQ &b); 93 | float inner_product_filter(const ECO_FEATS &a, const ECO_FEATS &b); 94 | vector get_proj() const { return projection_matrix_; } 95 | ECO_FEATS get_hf() const { return hf_; } 96 | 97 | private: 98 | ECO_FEATS hf_, hf_inc_; // filter parameters and its increament 99 | 100 | ECO_FEATS xlf_, sample_energy_; 101 | 102 | vector yf_; // the label of sample 103 | 104 | vector reg_filter_; 105 | vector reg_energy_; 106 | 107 | vector projection_matrix_, proj_energy_; 108 | 109 | EcoParameters params_; 110 | STATE state_; 111 | }; // end of class 112 | } // namespace eco 113 | #endif -------------------------------------------------------------------------------- /vot.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */ 2 | /* 3 | * This header file contains C functions that can be used to quickly integrate 4 | * VOT challenge support into your C or C++ tracker. 5 | * 6 | * Copyright (c) 2017, VOT Committee 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright notice, 15 | * this list of conditions and the following disclaimer in the documentation 16 | * and/or other materials provided with the distribution. 17 | 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | * The views and conclusions contained in the software and documentation are those 30 | * of the authors and should not be interpreted as representing official policies, 31 | * either expressed or implied, of the FreeBSD Project. 32 | */ 33 | 34 | #ifndef _VOT_TOOLKIT_H 35 | #define _VOT_TOOLKIT_H 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | 45 | #define VOT_READ_BUFFER 2024 46 | 47 | // Define VOT_OPENCV after including OpenCV core header to enable better OpenCV support 48 | #if defined(__OPENCV_CORE_HPP__) || defined(OPENCV_CORE_HPP) 49 | #define VOT_OPENCV 50 | #endif 51 | 52 | #ifndef VOT_RECTANGLE 53 | #define VOT_POLYGON 54 | #endif 55 | 56 | #ifdef VOT_POLYGON 57 | typedef struct vot_region 58 | { 59 | float *x; 60 | float *y; 61 | int count; 62 | } vot_region; 63 | 64 | void vot_region_release(vot_region **region) 65 | { 66 | if (!(*region)) 67 | return; 68 | 69 | if ((*region)->x) 70 | { 71 | free((*region)->x); 72 | (*region)->x = NULL; 73 | } 74 | if ((*region)->y) 75 | { 76 | free((*region)->y); 77 | (*region)->y = NULL; 78 | } 79 | 80 | free(*region); 81 | 82 | *region = NULL; 83 | } 84 | 85 | vot_region *vot_region_create(int n) 86 | { 87 | vot_region *region = (vot_region *)malloc(sizeof(vot_region)); 88 | region->x = (float *)malloc(sizeof(float) * n); 89 | region->y = (float *)malloc(sizeof(float) * n); 90 | memset(region->x, 0, sizeof(float) * n); 91 | memset(region->y, 0, sizeof(float) * n); 92 | region->count = n; 93 | return region; 94 | } 95 | 96 | vot_region *vot_region_copy(const vot_region *region) 97 | { 98 | vot_region *copy = vot_region_create(region->count); 99 | int i; 100 | for (i = 0; i < region->count; i++) 101 | { 102 | copy->x[i] = region->x[i]; 103 | copy->y[i] = region->y[i]; 104 | } 105 | return copy; 106 | } 107 | 108 | #else 109 | typedef struct vot_region 110 | { 111 | float x; 112 | float y; 113 | float width; 114 | float height; 115 | } vot_region; 116 | 117 | void vot_region_release(vot_region **region) 118 | { 119 | 120 | if (!(*region)) 121 | return; 122 | 123 | free(*region); 124 | 125 | *region = NULL; 126 | } 127 | 128 | vot_region *vot_region_create() 129 | { 130 | vot_region *region = (vot_region *)malloc(sizeof(vot_region)); 131 | region->x = 0; 132 | region->y = 0; 133 | region->width = 0; 134 | region->height = 0; 135 | return region; 136 | } 137 | 138 | vot_region *vot_region_copy(const vot_region *region) 139 | { 140 | vot_region *copy = vot_region_create(); 141 | copy->x = region->x; 142 | copy->y = region->y; 143 | copy->width = region->width; 144 | copy->height = region->height; 145 | return copy; 146 | } 147 | 148 | #endif 149 | 150 | #ifdef __cplusplus 151 | 152 | #include 153 | #include 154 | #include 155 | 156 | using namespace std; 157 | 158 | class VOT; 159 | 160 | class VOTRegion 161 | { 162 | friend class VOT; 163 | 164 | public: 165 | ~VOTRegion() 166 | { 167 | vot_region_release(&_region); 168 | } 169 | 170 | VOTRegion(const vot_region *region) 171 | { 172 | _region = vot_region_copy(region); 173 | } 174 | 175 | #ifdef VOT_POLYGON 176 | VOTRegion(int count) 177 | { 178 | _region = vot_region_create(count); 179 | } 180 | 181 | void set(int i, float x, float y) 182 | { 183 | assert(i >= 0 && i < _region->count); 184 | _region->x[i] = x; 185 | _region->y[i] = y; 186 | } 187 | float get_x(int i) const 188 | { 189 | assert(i >= 0 && i < _region->count); 190 | return _region->x[i]; 191 | } 192 | float get_y(int i) const 193 | { 194 | assert(i >= 0 && i < _region->count); 195 | return _region->y[i]; 196 | } 197 | int count() const { return _region->count; } 198 | 199 | #else 200 | 201 | VOTRegion() 202 | { 203 | _region = vot_region_create(); 204 | } 205 | 206 | float get_x() const { return _region->x; } 207 | float get_y() const { return _region->y; } 208 | float get_width() const { return _region->width; } 209 | float get_height() const { return _region->height; } 210 | 211 | float set_x(float x) { return _region->x = x; } 212 | float set_y(float y) { return _region->y = y; } 213 | float set_width(float width) { return _region->width = width; } 214 | float set_height(float height) { return _region->height = height; } 215 | 216 | #endif 217 | 218 | VOTRegion &operator=(const VOTRegion &source) 219 | { 220 | 221 | if (this == &source) 222 | return *this; 223 | 224 | #ifdef VOT_POLYGON 225 | 226 | if (this->_region->count != source.count()) 227 | { 228 | vot_region_release(&(this->_region)); 229 | this->_region = vot_region_create(source.count()); 230 | } 231 | 232 | for (int i = 0; i < source.count(); i++) 233 | { 234 | set(i, source.get_x(i), source.get_y(i)); 235 | } 236 | 237 | #else 238 | 239 | set_x(source.get_x()); 240 | set_y(source.get_y()); 241 | set_width(source.get_width()); 242 | set_height(source.get_height()); 243 | 244 | #endif 245 | 246 | return *this; 247 | } 248 | 249 | #ifdef VOT_OPENCV 250 | 251 | VOTRegion(const cv::Rect2f &rectangle) 252 | { 253 | #ifdef VOT_POLYGON 254 | _region = vot_region_create(4); 255 | #else 256 | _region = vot_region_create(); 257 | #endif 258 | set(rectangle); 259 | } 260 | 261 | void set(const cv::Rect2f &rectangle) 262 | { 263 | 264 | #ifdef VOT_POLYGON 265 | 266 | if (_region->count != 4) 267 | { 268 | vot_region_release(&(this->_region)); 269 | _region = vot_region_create(4); 270 | } 271 | 272 | set(0, rectangle.x, rectangle.y); 273 | set(1, rectangle.x + rectangle.width, rectangle.y); 274 | set(2, rectangle.x + rectangle.width, rectangle.y + rectangle.height); 275 | set(3, rectangle.x, rectangle.y + rectangle.height); 276 | 277 | #else 278 | 279 | set_x(rectangle.x); 280 | set_y(rectangle.y); 281 | set_width(rectangle.width); 282 | set_height(rectangle.height); 283 | 284 | #endif 285 | } 286 | 287 | void get(cv::Rect2f &rectangle) const 288 | { 289 | 290 | #ifdef VOT_POLYGON 291 | 292 | float top = FLT_MAX; 293 | float bottom = FLT_MIN; 294 | float left = FLT_MAX; 295 | float right = FLT_MIN; 296 | 297 | for (int j = 0; j < _region->count; j++) 298 | { 299 | top = MIN(top, _region->y[j]); 300 | bottom = MAX(bottom, _region->y[j]); 301 | left = MIN(left, _region->x[j]); 302 | right = MAX(right, _region->x[j]); 303 | } 304 | 305 | rectangle.x = left; 306 | rectangle.y = top; 307 | rectangle.width = right - left; 308 | rectangle.height = bottom - top; 309 | #else 310 | 311 | rectangle.x = get_x(); 312 | rectangle.y = get_y(); 313 | rectangle.width = get_width(); 314 | rectangle.height = get_height(); 315 | 316 | #endif 317 | } 318 | 319 | void operator=(cv::Rect2f &rectangle) 320 | { 321 | this->get(rectangle); 322 | } 323 | 324 | #endif 325 | 326 | protected: 327 | vot_region *_region; 328 | }; 329 | 330 | #ifdef VOT_OPENCV 331 | 332 | void operator<<(VOTRegion &source, const cv::Rect2f &rectangle) 333 | { 334 | source.set(rectangle); 335 | } 336 | 337 | void operator>>(const VOTRegion &source, cv::Rect2f &rectangle) 338 | { 339 | source.get(rectangle); 340 | } 341 | 342 | void operator<<(cv::Rect2f &rectangle, const VOTRegion &source) 343 | { 344 | source.get(rectangle); 345 | } 346 | 347 | void operator>>(const cv::Rect2f &rectangle, VOTRegion &source) 348 | { 349 | source.set(rectangle); 350 | } 351 | 352 | #endif 353 | 354 | class VOT 355 | { 356 | public: 357 | VOT() 358 | { 359 | _region = vot_initialize(); 360 | } 361 | 362 | ~VOT() 363 | { 364 | vot_quit(); 365 | } 366 | 367 | const VOTRegion region() 368 | { 369 | return VOTRegion(_region); 370 | } 371 | 372 | void report(const VOTRegion ®ion, float confidence = 1) 373 | { 374 | 375 | vot_report2(region._region, confidence); 376 | } 377 | 378 | const string frame() 379 | { 380 | 381 | const char *result = vot_frame(); 382 | 383 | if (!result) 384 | return string(); 385 | 386 | return string(result); 387 | } 388 | 389 | bool end() 390 | { 391 | return vot_end() != 0; 392 | } 393 | 394 | private: 395 | vot_region *vot_initialize(); 396 | 397 | void vot_quit(); 398 | 399 | const char *vot_frame(); 400 | 401 | void vot_report(vot_region *region); 402 | 403 | void vot_report2(vot_region *region, float confidence); 404 | 405 | int vot_end(); 406 | 407 | vot_region *_region; 408 | 409 | #endif 410 | 411 | // Current position in the sequence 412 | int _vot_sequence_position; 413 | // Size of the sequence 414 | int _vot_sequence_size; 415 | // List of image file names 416 | char **_vot_sequence; 417 | // List of results 418 | vot_region **_vot_result; 419 | 420 | trax_handle *_trax_handle; 421 | char _trax_image_buffer[VOT_READ_BUFFER]; 422 | 423 | #ifdef VOT_POLYGON 424 | 425 | vot_region *_trax_to_region(const trax_region *_trax_region) 426 | { 427 | int i; 428 | int count = trax_region_get_polygon_count(_trax_region); 429 | vot_region *region = vot_region_create(count); 430 | for (i = 0; i < count; i++) 431 | trax_region_get_polygon_point(_trax_region, i, &(region->x[i]), &(region->y[i])); 432 | return region; 433 | } 434 | trax_region *_region_to_trax(const vot_region *region) 435 | { 436 | int i; 437 | trax_region *_trax_region = trax_region_create_polygon(region->count); 438 | assert(trax_region_get_type(_trax_region) == TRAX_REGION_POLYGON); 439 | for (i = 0; i < region->count; i++) 440 | trax_region_set_polygon_point(_trax_region, i, region->x[i], region->y[i]); 441 | return _trax_region; 442 | } 443 | #else 444 | 445 | vot_region *_trax_to_region(const trax_region *_trax_region) 446 | { 447 | vot_region *region = vot_region_create(); 448 | assert(trax_region_get_type(_trax_region) == TRAX_REGION_RECTANGLE); 449 | trax_region_get_rectangle(_trax_region, &(region->x), &(region->y), &(region->width), &(region->height)); 450 | return region; 451 | } 452 | trax_region *_region_to_trax(const vot_region *region) 453 | { 454 | return trax_region_create_rectangle(region->x, region->y, region->width, region->height); 455 | } 456 | 457 | #endif 458 | 459 | #ifdef __cplusplus 460 | }; 461 | 462 | #endif 463 | 464 | #ifdef __cplusplus 465 | #define VOT_PREFIX(FUN) VOT::FUN 466 | #else 467 | #define VOT_PREFIX(FUN) FUN 468 | #endif 469 | 470 | /** 471 | * Reads the input data and initializes all structures. Returns the initial 472 | * position of the object as specified in the input data. This function should 473 | * be called at the beginning of the program. 474 | */ 475 | vot_region *VOT_PREFIX(vot_initialize)() 476 | { 477 | 478 | //int j; 479 | //FILE *inputfile; 480 | // FILE *imagesfile; 481 | 482 | _vot_sequence_position = 0; 483 | _vot_sequence_size = 0; 484 | 485 | //trax_configuration config; 486 | trax_image *_trax_image = NULL; 487 | trax_region *_trax_region = NULL; 488 | _trax_handle = NULL; 489 | int response; 490 | #ifdef VOT_POLYGON 491 | int region_format = TRAX_REGION_POLYGON; 492 | #else 493 | int region_format = TRAX_REGION_RECTANGLE; 494 | #endif 495 | 496 | trax_metadata *metadata = trax_metadata_create(region_format, TRAX_IMAGE_PATH, NULL, NULL, NULL); 497 | 498 | _trax_handle = trax_server_setup(metadata, trax_no_log); 499 | 500 | trax_metadata_release(&metadata); 501 | 502 | response = trax_server_wait(_trax_handle, &_trax_image, &_trax_region, NULL); 503 | 504 | assert(response == TRAX_INITIALIZE); 505 | 506 | strcpy(_trax_image_buffer, trax_image_get_path(_trax_image)); 507 | 508 | trax_server_reply(_trax_handle, _trax_region, NULL); 509 | 510 | vot_region *region = _trax_to_region(_trax_region); 511 | 512 | trax_region_release(&_trax_region); 513 | trax_image_release(&_trax_image); 514 | 515 | return region; 516 | } 517 | 518 | /** 519 | * Stores results to the result file and frees memory. This function should be 520 | * called at the end of the tracking program. 521 | */ 522 | void VOT_PREFIX(vot_quit)() 523 | { 524 | 525 | if (_trax_handle) 526 | { 527 | trax_cleanup(&_trax_handle); 528 | return; 529 | } 530 | } 531 | 532 | /** 533 | * Returns the file name of the current frame. This function does not advance 534 | * the current position. 535 | */ 536 | const char *VOT_PREFIX(vot_frame)() 537 | { 538 | 539 | if (_trax_handle) 540 | { 541 | int response; 542 | trax_image *_trax_image = NULL; 543 | trax_region *_trax_region = NULL; 544 | 545 | if (_vot_sequence_position == 0) 546 | { 547 | _vot_sequence_position++; 548 | return _trax_image_buffer; 549 | } 550 | 551 | response = trax_server_wait(_trax_handle, &_trax_image, &_trax_region, NULL); 552 | 553 | if (response != TRAX_FRAME) 554 | { 555 | vot_quit(); 556 | exit(0); 557 | } 558 | 559 | strcpy(_trax_image_buffer, trax_image_get_path(_trax_image)); 560 | trax_image_release(&_trax_image); 561 | 562 | return _trax_image_buffer; 563 | } 564 | } 565 | 566 | /** 567 | * Used to report position of the object. This function also advances the 568 | * current position. 569 | */ 570 | void VOT_PREFIX(vot_report)(vot_region *region) 571 | { 572 | 573 | if (_trax_handle) 574 | { 575 | trax_region *_trax_region = _region_to_trax(region); 576 | trax_server_reply(_trax_handle, _trax_region, NULL); 577 | trax_region_release(&_trax_region); 578 | return; 579 | } 580 | } 581 | 582 | /** 583 | * Used to report position of the object. This function also advances the 584 | * current position. 585 | */ 586 | void VOT_PREFIX(vot_report2)(vot_region *region, float confidence) 587 | { 588 | 589 | if (_trax_handle) 590 | { 591 | trax_region *_trax_region = _region_to_trax(region); 592 | trax_properties *_trax_properties = trax_properties_create(); 593 | trax_properties_set_float(_trax_properties, "confidence", confidence); 594 | trax_server_reply(_trax_handle, _trax_region, _trax_properties); 595 | trax_region_release(&_trax_region); 596 | trax_properties_release(&_trax_properties); 597 | return; 598 | } 599 | } 600 | 601 | int VOT_PREFIX(vot_end)() 602 | { 603 | 604 | return 0; 605 | } 606 | 607 | #endif 608 | -------------------------------------------------------------------------------- /vot_eco.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */ 2 | /* 3 | * This is an example of a stationary tracker. It only reports the initial 4 | * position for all frames and is used for testing purposes. 5 | * The main function of this example is to show the developers how to modify 6 | * their trackers to work with the evaluation environment. 7 | * 8 | * Copyright (c) 2015, VOT Committee 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions are met: 13 | 14 | * 1. Redistributions of source code must retain the above copyright notice, this 15 | * list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 24 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | * 31 | * The views and conclusions contained in the software and documentation are those 32 | * of the authors and should not be interpreted as representing official policies, 33 | * either expressed or implied, of the FreeBSD Project. 34 | * 35 | */ 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include "eco.hpp" 43 | 44 | #define VOT_RECTANGLE 45 | #include "vot.h" 46 | 47 | int main(int argc, char **argv) 48 | { 49 | VOT vot; 50 | eco::ECO tracker; 51 | cv::Rect2f initialization; 52 | initialization << vot.region(); 53 | cv::Mat image = cv::imread(vot.frame()); 54 | eco::EcoParameters parameters; 55 | 56 | tracker.init(image, initialization, parameters); 57 | 58 | while (!vot.end()) 59 | { 60 | string imagepath = vot.frame(); 61 | 62 | if (imagepath.empty()) 63 | break; 64 | 65 | cv::Mat image = cv::imread(imagepath); 66 | 67 | float confidence = 1; 68 | cv::Rect2f bbox; 69 | confidence = tracker.update(image, bbox); 70 | cv::Rect2f rect = cv::Rect(bbox); 71 | vot.report(rect, confidence); 72 | } 73 | #ifdef USE_MULTI_THREAD 74 | if (ecotracker.thread_train_ != nullptr) { 75 | if (!ecotracker.thread_train_->joinable()) 76 | { 77 | cout << "Error:unable to join!" << rc << std::endl; 78 | exit(-1); 79 | } 80 | ecotracker.thread_train_->join(); 81 | } 82 | #endif 83 | } 84 | -------------------------------------------------------------------------------- /wrappers.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Piotr's Computer Vision Matlab Toolbox Version 3.00 3 | * Copyright 2014 Piotr Dollar. [pdollar-at-gmail.com] 4 | * Licensed under the Simplified BSD License [see external/bsd.txt] 5 | *******************************************************************************/ 6 | #ifndef _WRAPPERS_HPP_ 7 | #define _WRAPPERS_HPP_ 8 | 9 | #include 10 | 11 | // wrapper functions if compiling from C/C++ 12 | inline void wrError(const char *errormsg) { throw errormsg; } 13 | inline void *wrCalloc(size_t num, size_t size) { return calloc(num, size); } 14 | inline void *wrMalloc(size_t size) { return malloc(size); } 15 | inline void wrFree(void *ptr) { free(ptr); } 16 | 17 | // platform independent aligned memory allocation (see also alFree) 18 | // __m128 should be 128/8=16 byte aligned 19 | inline void *alMalloc(size_t size, int alignment) 20 | { 21 | const size_t pSize = sizeof(void *), a = alignment - 1; 22 | void *raw = wrMalloc(size + a + pSize); 23 | // get the aligned address, alignment should be 2^N. 24 | void *aligned = (void *)(((size_t)raw + pSize + a) & ~a); 25 | *(void **)((size_t)aligned - pSize) = raw; // save address of raw in -1 26 | return aligned; 27 | } 28 | 29 | // platform independent alignned memory de-allocation (see also alMalloc) 30 | inline void alFree(void *aligned) 31 | { 32 | // raw: the address of (void *) pointer. 33 | // aligned: the address of a (void *) pointer now point to (char *) 34 | // - sizeof(void *): minus the address by sizeof(void *) 35 | // (void **): the address of a pointer point to a (void *) pointer 36 | // *: the pointer point to a (void *) pointer = the address of (void *)pointer 37 | void *raw = *(void **)((char *)aligned - sizeof(void *)); 38 | wrFree(raw); 39 | } 40 | 41 | #endif 42 | --------------------------------------------------------------------------------