├── .gitattributes ├── README.md ├── feature ├── average_feature_region.m ├── fhog.m ├── get_colorspace.m ├── get_features.m ├── get_fhog.m ├── get_pixels.m ├── get_table_feature.m ├── gradient2.m ├── gradientHist.m ├── gradientMag.m ├── gradientMex.cpp ├── gradientMex.mexa64 ├── gradientMex.mexmaci64 ├── gradientMex.mexw64 └── lookup_tables │ └── CNnorm.mat ├── figures ├── DTB70 │ ├── error_OPE_DTB70.png │ └── overlap_OPE_DTB70.png ├── UAV123_10fps │ ├── error_OPE_UAV123_10fps.png │ └── overlap_OPE_UAV123_10fps.png ├── UAVDT │ ├── error_OPE_UAVDT.png │ └── overlap_OPE_UAVDT.png └── VisDrone_test_dev │ ├── error_OPE_VisDrone_test_dev.png │ └── overlap_OPE_VisDrone_test_dev.png ├── implementation ├── AutoTrack_optimized.m ├── average_feature_region.m ├── crop_scale_sample.m ├── init_regwindow.m ├── shift_sample_scale.m └── updateRefmu.m ├── results_OPE ├── DTB70 │ └── AutoTrack │ │ ├── Animal1_AutoTrack.mat │ │ ├── Animal2_AutoTrack.mat │ │ ├── Animal3_AutoTrack.mat │ │ ├── Animal4_AutoTrack.mat │ │ ├── BMX2_AutoTrack.mat │ │ ├── BMX3_AutoTrack.mat │ │ ├── BMX4_AutoTrack.mat │ │ ├── BMX5_AutoTrack.mat │ │ ├── Basketball_AutoTrack.mat │ │ ├── Car2_AutoTrack.mat │ │ ├── Car4_AutoTrack.mat │ │ ├── Car5_AutoTrack.mat │ │ ├── Car6_AutoTrack.mat │ │ ├── Car8_AutoTrack.mat │ │ ├── ChasingDrones_AutoTrack.mat │ │ ├── Girl1_AutoTrack.mat │ │ ├── Girl2_AutoTrack.mat │ │ ├── Gull1_AutoTrack.mat │ │ ├── Gull2_AutoTrack.mat │ │ ├── Horse1_AutoTrack.mat │ │ ├── Horse2_AutoTrack.mat │ │ ├── Kiting_AutoTrack.mat │ │ ├── ManRunning1_AutoTrack.mat │ │ ├── ManRunning2_AutoTrack.mat │ │ ├── Motor1_AutoTrack.mat │ │ ├── Motor2_AutoTrack.mat │ │ ├── MountainBike1_AutoTrack.mat │ │ ├── MountainBike5_AutoTrack.mat │ │ ├── MountainBike6_AutoTrack.mat │ │ ├── Paragliding3_AutoTrack.mat │ │ ├── Paragliding5_AutoTrack.mat │ │ ├── RaceCar1_AutoTrack.mat │ │ ├── RaceCar_AutoTrack.mat │ │ ├── RcCar3_AutoTrack.mat │ │ ├── RcCar4_AutoTrack.mat │ │ ├── RcCar5_AutoTrack.mat │ │ ├── RcCar6_AutoTrack.mat │ │ ├── RcCar7_AutoTrack.mat │ │ ├── RcCar8_AutoTrack.mat │ │ ├── RcCar9_AutoTrack.mat │ │ ├── SUP2_AutoTrack.mat │ │ ├── SUP4_AutoTrack.mat │ │ ├── SUP5_AutoTrack.mat │ │ ├── Sheep1_AutoTrack.mat │ │ ├── Sheep2_AutoTrack.mat │ │ ├── SkateBoarding4_AutoTrack.mat │ │ ├── Skiing1_AutoTrack.mat │ │ ├── Skiing2_AutoTrack.mat │ │ ├── SnowBoarding2_AutoTrack.mat │ │ ├── SnowBoarding4_AutoTrack.mat │ │ ├── SnowBoarding6_AutoTrack.mat │ │ ├── Soccer1_AutoTrack.mat │ │ ├── Soccer2_AutoTrack.mat │ │ ├── SpeedCar2_AutoTrack.mat │ │ ├── SpeedCar4_AutoTrack.mat │ │ ├── StreetBasketball1_AutoTrack.mat │ │ ├── StreetBasketball2_AutoTrack.mat │ │ ├── StreetBasketball3_AutoTrack.mat │ │ ├── Surfing03_AutoTrack.mat │ │ ├── Surfing04_AutoTrack.mat │ │ ├── Surfing06_AutoTrack.mat │ │ ├── Surfing10_AutoTrack.mat │ │ ├── Surfing12_AutoTrack.mat │ │ ├── Vaulting_AutoTrack.mat │ │ ├── Wakeboarding1_AutoTrack.mat │ │ ├── Wakeboarding2_AutoTrack.mat │ │ ├── Walking_AutoTrack.mat │ │ ├── Yacht2_AutoTrack.mat │ │ ├── Yacht4_AutoTrack.mat │ │ └── Zebra_AutoTrack.mat ├── UAV123_10fps │ └── AutoTrack │ │ ├── bike1_AutoTrack.mat │ │ ├── bike2_AutoTrack.mat │ │ ├── bike3_AutoTrack.mat │ │ ├── bird1_1_AutoTrack.mat │ │ ├── bird1_2_AutoTrack.mat │ │ ├── bird1_3_AutoTrack.mat │ │ ├── boat1_AutoTrack.mat │ │ ├── boat2_AutoTrack.mat │ │ ├── boat3_AutoTrack.mat │ │ ├── boat4_AutoTrack.mat │ │ ├── boat5_AutoTrack.mat │ │ ├── boat6_AutoTrack.mat │ │ ├── boat7_AutoTrack.mat │ │ ├── boat8_AutoTrack.mat │ │ ├── boat9_AutoTrack.mat │ │ ├── building1_AutoTrack.mat │ │ ├── building2_AutoTrack.mat │ │ ├── building3_AutoTrack.mat │ │ ├── building4_AutoTrack.mat │ │ ├── building5_AutoTrack.mat │ │ ├── car10_AutoTrack.mat │ │ ├── car11_AutoTrack.mat │ │ ├── car12_AutoTrack.mat │ │ ├── car13_AutoTrack.mat │ │ ├── car14_AutoTrack.mat │ │ ├── car15_AutoTrack.mat │ │ ├── car16_1_AutoTrack.mat │ │ ├── car16_2_AutoTrack.mat │ │ ├── car17_AutoTrack.mat │ │ ├── car18_AutoTrack.mat │ │ ├── car1_1_AutoTrack.mat │ │ ├── car1_2_AutoTrack.mat │ │ ├── car1_3_AutoTrack.mat │ │ ├── car1_s_AutoTrack.mat │ │ ├── car2_AutoTrack.mat │ │ ├── car2_s_AutoTrack.mat │ │ ├── car3_AutoTrack.mat │ │ ├── car3_s_AutoTrack.mat │ │ ├── car4_AutoTrack.mat │ │ ├── car4_s_AutoTrack.mat │ │ ├── car5_AutoTrack.mat │ │ ├── car6_1_AutoTrack.mat │ │ ├── car6_2_AutoTrack.mat │ │ ├── car6_3_AutoTrack.mat │ │ ├── car6_4_AutoTrack.mat │ │ ├── car6_5_AutoTrack.mat │ │ ├── car7_AutoTrack.mat │ │ ├── car8_1_AutoTrack.mat │ │ ├── car8_2_AutoTrack.mat │ │ ├── car9_AutoTrack.mat │ │ ├── group1_1_AutoTrack.mat │ │ ├── group1_2_AutoTrack.mat │ │ ├── group1_3_AutoTrack.mat │ │ ├── group1_4_AutoTrack.mat │ │ ├── group2_1_AutoTrack.mat │ │ ├── group2_2_AutoTrack.mat │ │ ├── group2_3_AutoTrack.mat │ │ ├── group3_1_AutoTrack.mat │ │ ├── group3_2_AutoTrack.mat │ │ ├── group3_3_AutoTrack.mat │ │ ├── group3_4_AutoTrack.mat │ │ ├── person10_AutoTrack.mat │ │ ├── person11_AutoTrack.mat │ │ ├── person12_1_AutoTrack.mat │ │ ├── person12_2_AutoTrack.mat │ │ ├── person13_AutoTrack.mat │ │ ├── person14_1_AutoTrack.mat │ │ ├── person14_2_AutoTrack.mat │ │ ├── person14_3_AutoTrack.mat │ │ ├── person15_AutoTrack.mat │ │ ├── person16_AutoTrack.mat │ │ ├── person17_1_AutoTrack.mat │ │ ├── person17_2_AutoTrack.mat │ │ ├── person18_AutoTrack.mat │ │ ├── person19_1_AutoTrack.mat │ │ ├── person19_2_AutoTrack.mat │ │ ├── person19_3_AutoTrack.mat │ │ ├── person1_AutoTrack.mat │ │ ├── person1_s_AutoTrack.mat │ │ ├── person20_AutoTrack.mat │ │ ├── person21_AutoTrack.mat │ │ ├── person22_AutoTrack.mat │ │ ├── person23_AutoTrack.mat │ │ ├── person2_1_AutoTrack.mat │ │ ├── person2_2_AutoTrack.mat │ │ ├── person2_s_AutoTrack.mat │ │ ├── person3_AutoTrack.mat │ │ ├── person3_s_AutoTrack.mat │ │ ├── person4_1_AutoTrack.mat │ │ ├── person4_2_AutoTrack.mat │ │ ├── person5_1_AutoTrack.mat │ │ ├── person5_2_AutoTrack.mat │ │ ├── person6_AutoTrack.mat │ │ ├── person7_1_AutoTrack.mat │ │ ├── person7_2_AutoTrack.mat │ │ ├── person8_1_AutoTrack.mat │ │ ├── person8_2_AutoTrack.mat │ │ ├── person9_AutoTrack.mat │ │ ├── truck1_AutoTrack.mat │ │ ├── truck2_AutoTrack.mat │ │ ├── truck3_AutoTrack.mat │ │ ├── truck4_1_AutoTrack.mat │ │ ├── truck4_2_AutoTrack.mat │ │ ├── uav1_1_AutoTrack.mat │ │ ├── uav1_2_AutoTrack.mat │ │ ├── uav1_3_AutoTrack.mat │ │ ├── uav2_AutoTrack.mat │ │ ├── uav3_AutoTrack.mat │ │ ├── uav4_AutoTrack.mat │ │ ├── uav5_AutoTrack.mat │ │ ├── uav6_AutoTrack.mat │ │ ├── uav7_AutoTrack.mat │ │ ├── uav8_AutoTrack.mat │ │ ├── wakeboard10_AutoTrack.mat │ │ ├── wakeboard1_AutoTrack.mat │ │ ├── wakeboard2_AutoTrack.mat │ │ ├── wakeboard3_AutoTrack.mat │ │ ├── wakeboard4_AutoTrack.mat │ │ ├── wakeboard5_AutoTrack.mat │ │ ├── wakeboard6_AutoTrack.mat │ │ ├── wakeboard7_AutoTrack.mat │ │ ├── wakeboard8_AutoTrack.mat │ │ └── wakeboard9_AutoTrack.mat ├── UAVDT │ └── AutoTrack │ │ ├── S0101_AutoTrack.mat │ │ ├── S0102_AutoTrack.mat │ │ ├── S0103_AutoTrack.mat │ │ ├── S0201_AutoTrack.mat │ │ ├── S0301_AutoTrack.mat │ │ ├── S0302_AutoTrack.mat │ │ ├── S0303_AutoTrack.mat │ │ ├── S0304_AutoTrack.mat │ │ ├── S0305_AutoTrack.mat │ │ ├── S0306_AutoTrack.mat │ │ ├── S0307_AutoTrack.mat │ │ ├── S0308_AutoTrack.mat │ │ ├── S0309_AutoTrack.mat │ │ ├── S0310_AutoTrack.mat │ │ ├── S0401_AutoTrack.mat │ │ ├── S0402_AutoTrack.mat │ │ ├── S0501_AutoTrack.mat │ │ ├── S0601_AutoTrack.mat │ │ ├── S0602_AutoTrack.mat │ │ ├── S0701_AutoTrack.mat │ │ ├── S0801_AutoTrack.mat │ │ ├── S0901_AutoTrack.mat │ │ ├── S1001_AutoTrack.mat │ │ ├── S1101_AutoTrack.mat │ │ ├── S1201_AutoTrack.mat │ │ ├── S1202_AutoTrack.mat │ │ ├── S1301_AutoTrack.mat │ │ ├── S1302_AutoTrack.mat │ │ ├── S1303_AutoTrack.mat │ │ ├── S1304_AutoTrack.mat │ │ ├── S1305_AutoTrack.mat │ │ ├── S1306_AutoTrack.mat │ │ ├── S1307_AutoTrack.mat │ │ ├── S1308_AutoTrack.mat │ │ ├── S1309_AutoTrack.mat │ │ ├── S1310_AutoTrack.mat │ │ ├── S1311_AutoTrack.mat │ │ ├── S1312_AutoTrack.mat │ │ ├── S1313_AutoTrack.mat │ │ ├── S1401_AutoTrack.mat │ │ ├── S1501_AutoTrack.mat │ │ ├── S1601_AutoTrack.mat │ │ ├── S1602_AutoTrack.mat │ │ ├── S1603_AutoTrack.mat │ │ ├── S1604_AutoTrack.mat │ │ ├── S1605_AutoTrack.mat │ │ ├── S1606_AutoTrack.mat │ │ ├── S1607_AutoTrack.mat │ │ ├── S1701_AutoTrack.mat │ │ └── S1702_AutoTrack.mat ├── VisDrone-test-dev │ └── AutoTrack │ │ ├── uav0000011_00000_s_AutoTrack.mat │ │ ├── uav0000021_00000_s_AutoTrack.mat │ │ ├── uav0000069_00576_s_AutoTrack.mat │ │ ├── uav0000074_01656_s_AutoTrack.mat │ │ ├── uav0000074_04320_s_AutoTrack.mat │ │ ├── uav0000074_04992_s_AutoTrack.mat │ │ ├── uav0000074_05712_s_AutoTrack.mat │ │ ├── uav0000074_06312_s_AutoTrack.mat │ │ ├── uav0000074_11915_s_AutoTrack.mat │ │ ├── uav0000079_02568_s_AutoTrack.mat │ │ ├── uav0000088_00000_s_AutoTrack.mat │ │ ├── uav0000093_00000_s_AutoTrack.mat │ │ ├── uav0000093_01817_s_AutoTrack.mat │ │ ├── uav0000116_00503_s_AutoTrack.mat │ │ ├── uav0000151_00000_s_AutoTrack.mat │ │ ├── uav0000155_01201_s_AutoTrack.mat │ │ ├── uav0000164_00000_s_AutoTrack.mat │ │ ├── uav0000180_00050_s_AutoTrack.mat │ │ ├── uav0000184_00625_s_AutoTrack.mat │ │ ├── uav0000207_00675_s_AutoTrack.mat │ │ ├── uav0000208_00000_s_AutoTrack.mat │ │ ├── uav0000241_00001_s_AutoTrack.mat │ │ ├── uav0000242_02327_s_AutoTrack.mat │ │ ├── uav0000242_05160_s_AutoTrack.mat │ │ ├── uav0000294_00000_s_AutoTrack.mat │ │ ├── uav0000294_00069_s_AutoTrack.mat │ │ ├── uav0000294_01449_s_AutoTrack.mat │ │ ├── uav0000324_00069_s_AutoTrack.mat │ │ ├── uav0000340_01356_s_AutoTrack.mat │ │ ├── uav0000353_00001_s_AutoTrack.mat │ │ ├── uav0000353_01127_s_AutoTrack.mat │ │ ├── uav0000367_02761_s_AutoTrack.mat │ │ ├── uav0000367_04137_s_AutoTrack.mat │ │ ├── uav0000368_03312_s_AutoTrack.mat │ │ └── uav0000368_03612_s_AutoTrack.mat └── results_pdf │ ├── error_OPE_DTB70.pdf │ ├── error_OPE_UAV123_10fps.pdf │ ├── error_OPE_UAVDT.pdf │ ├── error_OPE_VisDrone_test_dev.pdf │ ├── overlap_OPE_DTB70.pdf │ ├── overlap_OPE_UAV123_10fps.pdf │ ├── overlap_OPE_UAVDT.pdf │ └── overlap_OPE_VisDrone_test_dev.pdf ├── run_AutoTrack.m └── utils ├── integralVecImage.m ├── mexResize.cpp ├── mexResize.mexa64 ├── mexResize.mexmaci64 ├── mexResize.mexw64 ├── mtimesx.c ├── mtimesx.m ├── mtimesx.mexa64 ├── mtimesx.mexmaci64 ├── mtimesx.mexw64 ├── mtimesx_RealTimesReal.c ├── mtimesx_build.m ├── mtimesx_sparse.m ├── opencv_core242.dll ├── opencv_imgproc242.dll ├── resizeDFT2.m ├── resp_newton.m ├── shift_sample.m └── table_lookup.m /.gitattributes: -------------------------------------------------------------------------------- 1 | *.cpp linguist-language=MATLAB 2 | *.c linguist-language=MATLAB 3 | *.dll linguist-language=MATLAB 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AutoTrack: Towards High-Performance Visual Tracking for UAV with Automatic Spatio-Temporal Regularization 2 | 3 | Matlab implementation of our automatic spatial-temporal regularization tracker (AutoTrack). 4 | 5 | The code for UAV localization is coming soon. 6 | 7 | The paper can be found here: https://arxiv.org/abs/2003.12949. 8 | 9 | # Abstract 10 | 11 | Most existing trackers based on discriminative correlation filters (DCF) try to introduce predefined regularization term to improve the learning of target objects, e.g., by suppressing background learning or by restricting change rate of correlation filters. However, predefined parameters introduce much effort in tuning them and they still fail to adapt to new situations that the designer didn’t think of. In this work, a novel approach is proposed to online automatically and adaptively learn spatio-temporal regularization term. Spatially local response map variation is introduced as spatial regularization to make DCF focus on the learning of trust-worthy parts of the object, and global response map variation determines the updating rate of the filter. Extensive experiments on four UAV benchmarks, i.e., DTB70, UAVDT, UAV123@10fps and VisDrone-test-dev, have proven that our tracker performs favorably against the state-of-theart CPU- and GPU-based trackers, with average speed of 59.2 frames per second (FPS) running on a single CPU. 12 | Our tracker is additionally proposed to be applied to localize the moving camera. Considerable tests in the indoor practical scenarios have proven the effectiveness and versatility of our localization method. 13 | 14 | # Publication and citation 15 | 16 | AutoTrack is proposed in our paper accepted by CVPR 2020. Detailed explanation of our method can be found in the paper: 17 | 18 | Yiming Li, Changhong Fu, Fangqiang Ding, Ziyuan Huang and Geng Lu 19 | 20 | AutoTrack: Towards High-Performance Visual Tracking for UAV with Automatic Spatio-Temporal Regularization. 21 | 22 | In Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR), 2020 23 | 24 | Please cite the aforementioned publication when you compare AutoTrack in your work. Bibtex entry: 25 | 26 | > @Inproceedings{Li2020CVPR, 27 | > 28 | > title={AutoTrack: Towards High-Performance Visual Tracking for UAV with Automatic Spatio-Temporal Regularization}, 29 | > 30 | > author={Li, Yiming and Fu, Changhong and Ding, Fangqiang and Huang, Ziyuan and Lu, Geng}, 31 | > 32 | > booktitle={CVPR}, 33 | > 34 | > year={2020}, 35 | > 36 | > } 37 | 38 | 39 | 40 | # Contact 41 | 42 | Yiming Li 43 | 44 | yimingli9702@gmail.com 45 | 46 | Changhong Fu 47 | 48 | Email: [changhong.fu@tongji.edu.cn](mailto:changhong.fu@tongji.edu.cn) 49 | 50 | Fangqiang Ding 51 | 52 | Email: dfq.toytiny@gmail.com 53 | 54 | # Demonstration running instructions 55 | 56 | This code is compatible with UAV123@10fps, DTB70, UAVDT and VisDrone-test-dev benchmark. Therefore, if you want to run it in benchmark, just put AutoTrack folder in trackers, and config sequences and trackers according to instructions from aforementioned benchmarks. 57 | 58 | # Results on UAV datasets 59 | 60 | ### DTB70 61 | 62 | ![](figures/DTB70/error_OPE_DTB70.png) 63 | 64 | ![](figures/DTB70/overlap_OPE_DTB70.png) 65 | 66 | ### UAV123@10fps 67 | 68 | ![](figures/UAV123_10fps/error_OPE_UAV123_10fps.png) 69 | 70 | ![](figures/UAV123_10fps/overlap_OPE_UAV123_10fps.png) 71 | 72 | ### UAVDT 73 | 74 | ![](figures/UAVDT/error_OPE_UAVDT.png) 75 | 76 | ![](figures/UAVDT/overlap_OPE_UAVDT.png) 77 | 78 | ### VisDrone-test-dev 79 | 80 | ![](figures/VisDrone_test_dev/error_OPE_VisDrone_test_dev.png) 81 | 82 | ![](figures/VisDrone_test_dev/overlap_OPE_VisDrone_test_dev.png) 83 | 84 | 85 | 86 | # Acknowledgements 87 | 88 | We thank the contribution of Feng Li, Ning Wang and Martin Danelljan for their previous work STRCF, MCCT-H and DSST. The feature extraction modules and some of the parameter are borrowed from the MCCT tracker (https://github.com/594422814/MCCT). The scale estimation method is borrowed from the DSST tracker (http://www.cvl.isy.liu.se/en/research/objrec/visualtracking/scalvistrack/index.html). 89 | 90 | 91 | -------------------------------------------------------------------------------- /feature/average_feature_region.m: -------------------------------------------------------------------------------- 1 | function [ region_image ] = average_feature_region(im, region_size) 2 | % compute cell wise averages, where a cell is a region_size*region_sized 3 | % region in the image. Input can be uint8t, single or double matrices 4 | % of arbitrary dimension 5 | 6 | region_area = region_size.^2; 7 | 8 | if isa(im,'double') || isa(im,'single') || isa(im,'gpuArray') 9 | maxval = 1.0; 10 | elseif isa(im,'unit8') 11 | maxval = 255; 12 | end 13 | 14 | % compute the integral image 15 | iImage = integralVecImage(im); 16 | 17 | % region indices 18 | i1 = (region_size:region_size:size(im,1)) + 1; 19 | i2 = (region_size:region_size:size(im,2)) + 1; 20 | 21 | % sum over region, divided by number of elements, and normalize to [0,1] 22 | % range if integer image 23 | region_image = (iImage(i1,i2,:,:) - iImage(i1,i2-region_size,:,:) - iImage(i1-region_size,i2,:,:) + iImage(i1-region_size,i2-region_size,:,:)) ./ (region_area * maxval); 24 | 25 | end 26 | 27 | -------------------------------------------------------------------------------- /feature/fhog.m: -------------------------------------------------------------------------------- 1 | function H = fhog( I, binSize, nOrients, clip, crop ) 2 | % Efficiently compute Felzenszwalb's HOG (FHOG) features. 3 | % 4 | % A fast implementation of the HOG variant used by Felzenszwalb et al. 5 | % in their work on discriminatively trained deformable part models. 6 | % http://www.cs.berkeley.edu/~rbg/latent/index.html 7 | % Gives nearly identical results to features.cc in code release version 5 8 | % but runs 4x faster (over 125 fps on VGA color images). 9 | % 10 | % The computed HOG features are 3*nOrients+5 dimensional. There are 11 | % 2*nOrients contrast sensitive orientation channels, nOrients contrast 12 | % insensitive orientation channels, 4 texture channels and 1 all zeros 13 | % channel (used as a 'truncation' feature). Using the standard value of 14 | % nOrients=9 gives a 32 dimensional feature vector at each cell. This 15 | % variant of HOG, refered to as FHOG, has been shown to achieve superior 16 | % performance to the original HOG features. For details please refer to 17 | % work by Felzenszwalb et al. (see link above). 18 | % 19 | % This function is essentially a wrapper for calls to gradientMag() 20 | % and gradientHist(). Specifically, it is equivalent to the following: 21 | % [M,O] = gradientMag( I,0,0,0,1 ); softBin = -1; useHog = 2; 22 | % H = gradientHist(M,O,binSize,nOrients,softBin,useHog,clip); 23 | % See gradientHist() for more general usage. 24 | % 25 | % This code requires SSE2 to compile and run (most modern Intel and AMD 26 | % processors support SSE2). Please see: http://en.wikipedia.org/wiki/SSE2. 27 | % 28 | % USAGE 29 | % H = fhog( I, [binSize], [nOrients], [clip], [crop] ) 30 | % 31 | % INPUTS 32 | % I - [hxw] color or grayscale input image (must have type single) 33 | % binSize - [8] spatial bin size 34 | % nOrients - [9] number of orientation bins 35 | % clip - [.2] value at which to clip histogram bins 36 | % crop - [0] if true crop boundaries 37 | % 38 | % OUTPUTS 39 | % H - [h/binSize w/binSize nOrients*3+5] computed hog features 40 | % 41 | % EXAMPLE 42 | % I=imResample(single(imread('peppers.png'))/255,[480 640]); 43 | % tic, for i=1:100, H=fhog(I,8,9); end; disp(100/toc) % >125 fps 44 | % figure(1); im(I); V=hogDraw(H,25,1); figure(2); im(V) 45 | % 46 | % EXAMPLE 47 | % % comparison to features.cc (requires DPM code release version 5) 48 | % I=imResample(single(imread('peppers.png'))/255,[480 640]); Id=double(I); 49 | % tic, for i=1:100, H1=features(Id,8); end; disp(100/toc) 50 | % tic, for i=1:100, H2=fhog(I,8,9,.2,1); end; disp(100/toc) 51 | % figure(1); montage2(H1); figure(2); montage2(H2); 52 | % D=abs(H1-H2); mean(D(:)) 53 | % 54 | % See also hog, hogDraw, gradientHist 55 | % 56 | % Piotr's Image&Video Toolbox Version 3.23 57 | % Copyright 2013 Piotr Dollar. [pdollar-at-caltech.edu] 58 | % Please email me if you find bugs, or have suggestions or questions! 59 | % Licensed under the Simplified BSD License [see external/bsd.txt] 60 | 61 | %Note: modified to be more self-contained 62 | 63 | if( nargin<2 ), binSize=8; end 64 | if( nargin<3 ), nOrients=9; end 65 | if( nargin<4 ), clip=.2; end 66 | if( nargin<5 ), crop=0; end 67 | 68 | softBin = -1; useHog = 2; b = binSize; 69 | 70 | [M,O]=gradientMex('gradientMag',I,0,1); 71 | 72 | H = gradientMex('gradientHist',M,O,binSize,nOrients,softBin,useHog,clip); 73 | 74 | if( crop ), e=mod(size(I),b) 1 32 | colorspace = average_feature_region(t_colorspace,gparam.cell_size); 33 | else 34 | colorspace = t_colorspace; 35 | end 36 | end 37 | 38 | -------------------------------------------------------------------------------- /feature/get_features.m: -------------------------------------------------------------------------------- 1 | function [feature_pixels, support_sz] = get_features(image, features, gparams, fg_size) 2 | 3 | if ~ iscell(features) 4 | features = {features}; 5 | end 6 | 7 | [im_height, im_width, num_im_chan, num_images] = size(image); 8 | 9 | colorImage = num_im_chan == 3; 10 | 11 | %compute total dimension of all features 12 | tot_feature_dim = 0; 13 | for n = 1:length(features) 14 | 15 | if ~isfield(features{n}.fparams,'useForColor') 16 | features{n}.fparams.useForColor = true; 17 | end 18 | 19 | if ~isfield(features{n}.fparams,'useForGray') 20 | features{n}.fparams.useForGray = true; 21 | end 22 | 23 | if (features{n}.fparams.useForColor && colorImage) || (features{n}.fparams.useForGray && ~colorImage) 24 | tot_feature_dim = tot_feature_dim + features{n}.fparams.nDim; 25 | end 26 | 27 | end 28 | 29 | if nargin < 4 || isempty(fg_size) 30 | if gparams.cell_size == -1 31 | fg_size = size(features{1}.getFeature(image,features{1}.fparams,gparams)); 32 | else 33 | fg_size = [floor(im_height/gparams.cell_size), floor(im_width/gparams.cell_size)]; 34 | end 35 | end 36 | 37 | % temporary hack for fixing deep features 38 | if gparams.cell_size == -1 39 | cf = features{1}; 40 | if (cf.fparams.useForColor && colorImage) || (cf.fparams.useForGray && ~colorImage) 41 | [feature_pixels, support_sz] = cf.getFeature(image,cf.fparams,gparams); 42 | end 43 | else 44 | %compute the feature set 45 | feature_pixels = zeros(fg_size(1),fg_size(2),tot_feature_dim, num_images, 'single'); 46 | 47 | currDim = 1; 48 | for n = 1:length(features) 49 | cf = features{n}; 50 | if (cf.fparams.useForColor && colorImage) || (cf.fparams.useForGray && ~colorImage) 51 | feature_pixels(:,:,currDim:(currDim+cf.fparams.nDim-1),:) = cf.getFeature(image,cf.fparams,gparams); 52 | currDim = currDim + cf.fparams.nDim; 53 | end 54 | end 55 | support_sz = [im_height, im_width]; 56 | end 57 | 58 | end -------------------------------------------------------------------------------- /feature/get_fhog.m: -------------------------------------------------------------------------------- 1 | function [ feature_image ] = get_fhog(im, fparam, gparam ) 2 | %extract fhog features using piotrs toolbox. Currently takes no parameters 3 | %except hog-cell-size 4 | if ~isfield(fparam, 'nOrients') 5 | fparam.nOrients = 9; 6 | end 7 | [im_height, im_width,~, num_images] = size(im); 8 | feature_image = zeros(floor(im_height/gparam.cell_size), floor(im_width/gparam.cell_size), fparam.nDim, num_images, 'single'); 9 | for k = 1:num_images 10 | hog_image = fhog(single(im(:,:,:,k)), gparam.cell_size, fparam.nOrients); 11 | %the last dimension is all 0 so we can discard it 12 | feature_image(:,:,:,k) = hog_image(:,:,1:end-1); 13 | end 14 | end -------------------------------------------------------------------------------- /feature/get_pixels.m: -------------------------------------------------------------------------------- 1 | function [ resized_patch ] = get_pixels(im, pos, sz, resize_target) 2 | 3 | if isscalar(sz) %square sub-window 4 | sz = [sz, sz]; 5 | end 6 | 7 | %make sure the size is not to small 8 | if sz(1) < 1 9 | sz(1) = 2; 10 | end 11 | if sz(2) < 1 12 | sz(2) = 2; 13 | end 14 | 15 | 16 | xs = floor(pos(2)) + (1:sz(2)) - floor(sz(2)/2); 17 | ys = floor(pos(1)) + (1:sz(1)) - floor(sz(1)/2); 18 | 19 | %check for out-of-bounds coordinates, and set them to the values at 20 | %the borders 21 | xs(xs < 1) = 1; 22 | ys(ys < 1) = 1; 23 | xs(xs > size(im,2)) = size(im,2); 24 | ys(ys > size(im,1)) = size(im,1); 25 | 26 | %extract image 27 | im_patch = im(ys, xs, :); 28 | 29 | if isempty(resize_target) 30 | resized_patch = im_patch; 31 | else 32 | resized_patch = mexResize(im_patch,resize_target,'auto'); 33 | end 34 | end 35 | 36 | -------------------------------------------------------------------------------- /feature/get_table_feature.m: -------------------------------------------------------------------------------- 1 | function [ features ] = get_table_feature(im, fparam, gparam) 2 | %get per-pixel features using a lookup table, if the gparam feature cell 3 | %size is set to something large than one, the resulting data will be 4 | %averaged in cells of the specified size. 5 | %tables are loaded dynamically when needed from the lookup_tables folder, 6 | %and stored in a persistent variable 7 | 8 | persistent tables; 9 | 10 | if isempty(tables) 11 | tables = {}; 12 | end 13 | 14 | tab_ind = 0; 15 | for k = 1:length(tables) 16 | if isfield(tables{k}, fparam.tablename) 17 | tab_ind = k; 18 | break; 19 | end 20 | end 21 | 22 | if tab_ind == 0 23 | tables{end+1} = load(['lookup_tables/' fparam.tablename]); 24 | tab_ind = length(tables); 25 | end 26 | 27 | if strcmp(tables{tab_ind}.inputType,'color') 28 | if size(im,3) ~= 3 29 | except = MException('cannot get colorfeature from non color image'); 30 | raise(except); 31 | end 32 | elseif strcmp(tables{tab_ind}.inputType,'gray') 33 | if size(im,3) == 3 34 | im_gray = zeros(size(im,1),size(im,2),1,size(im,4),'uint8'); 35 | for k = 1:size(im,4) 36 | im_gray(:,:,:,k) = rgb2gray(im(:,:,:,k)); 37 | end 38 | im = im_gray; 39 | end 40 | end 41 | 42 | %else extract the feature and return it 43 | temp_features = table_lookup(im,tables{tab_ind}.(fparam.tablename)); 44 | 45 | if gparam.cell_size > 1 46 | features = average_feature_region(temp_features,gparam.cell_size); 47 | else 48 | features = temp_features; 49 | end 50 | 51 | end 52 | 53 | -------------------------------------------------------------------------------- /feature/gradient2.m: -------------------------------------------------------------------------------- 1 | function [Gx,Gy] = gradient2( I ) 2 | % Compute numerical gradients along x and y directions. 3 | % 4 | % For 2D arrays identical to Matlab's gradient() with a spacing value of 5 | % h=1 but ~10-20x faster (due to mexed implementation). Like gradient(), 6 | % computes centered derivatives in interior of image and uncentered 7 | % derivatives along boundaries. For 3D arrays computes x and y gradient 8 | % separately for each channel and concatenates the results. 9 | % 10 | % This code requires SSE2 to compile and run (most modern Intel and AMD 11 | % processors support SSE2). Please see: http://en.wikipedia.org/wiki/SSE2. 12 | % 13 | % USAGE 14 | % [Gx,Gy] = gradient2( I ) 15 | % 16 | % INPUTS 17 | % I - [hxwxk] input k channel single image 18 | % 19 | % OUTPUTS 20 | % Gx - [hxwxk] x-gradient (horizontal) 21 | % Gy - [hxwxk] y-gradient (vertical) 22 | % 23 | % EXAMPLE 24 | % I=single(imread('peppers.png'))/255; 25 | % tic, [Gx1,Gy1]=gradient(I,1); toc 26 | % tic, [Gx2,Gy2]=gradient2(I); toc 27 | % isequal(Gx1,Gx2), isequal(Gy1,Gy2) 28 | % 29 | % See also gradient, gradientMag 30 | % 31 | % Piotr's Computer Vision Matlab Toolbox Version 3.00 32 | % Copyright 2014 Piotr Dollar & Ron Appel. [pdollar-at-gmail.com] 33 | % Licensed under the Simplified BSD License [see external/bsd.txt] 34 | 35 | [Gx,Gy]=gradientMex('gradient2',I); 36 | -------------------------------------------------------------------------------- /feature/gradientHist.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/feature/gradientHist.m -------------------------------------------------------------------------------- /feature/gradientMag.m: -------------------------------------------------------------------------------- 1 | function [M,O] = gradientMag( I, channel, normRad, normConst, full ) 2 | % Compute gradient magnitude and orientation at each image location. 3 | % 4 | % If input image has k>1 channels and channel=0, keeps gradient with 5 | % maximum magnitude (over all channels) at each location. Otherwise if 6 | % channel is between 1 and k computes gradient for the given channel. 7 | % If full==1 orientation is computed in [0,2*pi) else it is in [0,pi). 8 | % 9 | % If normRad>0, normalization is performed by first computing S, a smoothed 10 | % version of the gradient magnitude, then setting: M = M./(S + normConst). 11 | % S is computed by S = convTri( M, normRad ). 12 | % 13 | % This code requires SSE2 to compile and run (most modern Intel and AMD 14 | % processors support SSE2). Please see: http://en.wikipedia.org/wiki/SSE2. 15 | % 16 | % USAGE 17 | % [M,O] = gradientMag( I, [channel], [normRad], [normConst], [full] ) 18 | % 19 | % INPUTS 20 | % I - [hxwxk] input k channel single image 21 | % channel - [0] if>0 color channel to use for gradient computation 22 | % normRad - [0] normalization radius (no normalization if 0) 23 | % normConst - [.005] normalization constant 24 | % full - [0] if true compute angles in [0,2*pi) else in [0,pi) 25 | % 26 | % OUTPUTS 27 | % M - [hxw] gradient magnitude at each location 28 | % O - [hxw] approximate gradient orientation modulo PI 29 | % 30 | % EXAMPLE 31 | % I=rgbConvert(imread('peppers.png'),'gray'); 32 | % [Gx,Gy]=gradient2(I); M=sqrt(Gx.^2+Gy.^2); O=atan2(Gy,Gx); 33 | % full=0; [M1,O1]=gradientMag(I,0,0,0,full); 34 | % D=abs(M-M1); mean2(D), if(full), o=pi*2; else o=pi; end 35 | % D=abs(O-O1); D(~M)=0; D(D>o*.99)=o-D(D>o*.99); mean2(abs(D)) 36 | % 37 | % See also gradient, gradient2, gradientHist, convTri 38 | % 39 | % Piotr's Computer Vision Matlab Toolbox Version 3.23 40 | % Copyright 2014 Piotr Dollar & Ron Appel. [pdollar-at-gmail.com] 41 | % Licensed under the Simplified BSD License [see external/bsd.txt] 42 | 43 | if(nargin<1 || isempty(I)), M=single([]); O=M; return; end 44 | if(nargin<2 || isempty(channel)), channel=0; end 45 | if(nargin<3 || isempty(normRad)), normRad=0; end 46 | if(nargin<4 || isempty(normConst)), normConst=.005; end 47 | if(nargin<5 || isempty(full)), full=0; end 48 | 49 | if(nargout<=1), M=gradientMex('gradientMag',I,channel,full); 50 | else [M,O]=gradientMex('gradientMag',I,channel,full); end 51 | 52 | if( normRad==0 ), return; end; S = convTri( M, normRad ); 53 | gradientMex('gradientMagNorm',M,S,normConst); % operates on M 54 | -------------------------------------------------------------------------------- /feature/gradientMex.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 | #include "wrappers.hpp" 7 | #include 8 | #include "string.h" 9 | #include "sse.hpp" 10 | 11 | #define PI 3.14159265f 12 | 13 | // compute x and y gradients for just one column (uses sse) 14 | void grad1( float *I, float *Gx, float *Gy, int h, int w, int x ) { 15 | int y, y1; float *Ip, *In, r; __m128 *_Ip, *_In, *_G, _r; 16 | // compute column of Gx 17 | Ip=I-h; In=I+h; r=.5f; 18 | if(x==0) { r=1; Ip+=h; } else if(x==w-1) { r=1; In-=h; } 19 | if( h<4 || h%4>0 || (size_t(I)&15) || (size_t(Gx)&15) ) { 20 | for( y=0; yh-1) y1=h-1; 30 | GRADY(1); Ip--; for(y=1; y PI-1e-6f ) a1[i]=PI-1e-6f; 54 | init=true; return a1; 55 | } 56 | 57 | // compute gradient magnitude and orientation at each location (uses sse) 58 | void gradMag( float *I, float *M, float *O, int h, int w, int d, bool full ) { 59 | int x, y, y1, c, h4, s; float *Gx, *Gy, *M2; __m128 *_Gx, *_Gy, *_M2, _m; 60 | float *acost = acosTable(), acMult=10000.0f; 61 | // allocate memory for storing one column of output (padded so h4%4==0) 62 | h4=(h%4==0) ? h : h-(h%4)+4; s=d*h4*sizeof(float); 63 | M2=(float*) alMalloc(s,16); _M2=(__m128*) M2; 64 | Gx=(float*) alMalloc(s,16); _Gx=(__m128*) Gx; 65 | Gy=(float*) alMalloc(s,16); _Gy=(__m128*) Gy; 66 | // compute gradient magnitude and orientation for each column 67 | for( x=0; x=oMax) o0=0; O0[i]=o0; 137 | o1=o0+nb; if(o1==oMax) o1=0; O1[i]=o1; 138 | m=M[i]*norm; M1[i]=od*m; M0[i]=m-M1[i]; 139 | } else for(; i=oMax) o0=0; O0[i]=o0; 142 | M0[i]=M[i]*norm; M1[i]=0; O1[i]=0; 143 | } 144 | } 145 | 146 | // compute nOrients gradient histograms per bin x bin block of pixels 147 | void gradHist( float *M, float *O, float *H, int h, int w, 148 | int bin, int nOrients, int softBin, bool full ) 149 | { 150 | const int hb=h/bin, wb=w/bin, h0=hb*bin, w0=wb*bin, nb=wb*hb; 151 | const float s=(float)bin, sInv=1/s, sInv2=1/s/s; 152 | float *H0, *H1, *M0, *M1; int x, y; int *O0, *O1; float xb, init; 153 | O0=(int*)alMalloc(h*sizeof(int),16); M0=(float*) alMalloc(h*sizeof(float),16); 154 | O1=(int*)alMalloc(h*sizeof(int),16); M1=(float*) alMalloc(h*sizeof(float),16); 155 | // main loop 156 | for( x=0; x=0); 159 | 160 | if( softBin<0 && softBin%2==0 ) { 161 | // no interpolation w.r.t. either orienation or spatial bin 162 | H1=H+(x/bin)*hb; 163 | #define GH H1[O0[y]]+=M0[y]; y++; 164 | if( bin==1 ) for(y=0; y=0; xb0 = hasLf?(int)xb:-1; hasRt = xb0 < wb-1; 188 | xd=xb-xb0; xb+=sInv; yb=init; y=0; 189 | // macros for code conciseness 190 | #define GHinit yd=yb-yb0; yb+=sInv; H0=H+xb0*hb+yb0; xyd=xd*yd; \ 191 | ms[0]=1-xd-yd+xyd; ms[1]=yd-xyd; ms[2]=xd-xyd; ms[3]=xyd; 192 | #define GH(H,ma,mb) H1=H; STRu(*H1,ADD(LDu(*H1),MUL(ma,mb))); 193 | // leading rows, no top bin 194 | for( ; y=hb-1) break; GHinit; _m0=SET(M0[y]); 202 | if(hasLf) { _m=SET(0,0,ms[1],ms[0]); GH(H0+O0[y],_m,_m0); } 203 | if(hasRt) { _m=SET(0,0,ms[3],ms[2]); GH(H0+O0[y]+hb,_m,_m0); } 204 | } else for( ; ; y++ ) { 205 | yb0 = (int) yb; if(yb0>=hb-1) break; GHinit; 206 | _m0=SET(M0[y]); _m1=SET(M1[y]); 207 | if(hasLf) { _m=SET(0,0,ms[1],ms[0]); 208 | GH(H0+O0[y],_m,_m0); GH(H0+O1[y],_m,_m1); } 209 | if(hasRt) { _m=SET(0,0,ms[3],ms[2]); 210 | GH(H0+O0[y]+hb,_m,_m0); GH(H0+O1[y]+hb,_m,_m1); } 211 | } 212 | // final rows, no bottom bin 213 | for( ; yclip) t=clip; c++; 259 | const float r=.2357f; int o, x, y, c; float t; 260 | const int nb=wb*hb, nbo=nOrients*nb, hb1=hb+1; 261 | for( o=0; onl1 ) mexErrMsgTxt("Incorrect number of outputs."); 338 | if( nrnr1 ) mexErrMsgTxt("Incorrect number of inputs."); 339 | nDims = mxGetNumberOfDimensions(pr[0]); dims = mxGetDimensions(pr[0]); 340 | *h=dims[0]; *w=dims[1]; *d=(nDims==2) ? 1 : dims[2]; *I = mxGetPr(pr[0]); 341 | if( nDims!=2 && nDims!=3 ) mexErrMsgTxt("I must be a 2D or 3D array."); 342 | if( mxGetClassID(pr[0])!=id ) mexErrMsgTxt("I has incorrect type."); 343 | } 344 | 345 | // [Gx,Gy] = grad2(I) - see gradient2.m 346 | void mGrad2( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { 347 | int h, w, d; float *I, *Gx, *Gy; 348 | checkArgs(nl,pl,nr,pr,1,2,1,1,&h,&w,&d,mxSINGLE_CLASS,(void**)&I); 349 | if(h<2 || w<2) mexErrMsgTxt("I must be at least 2x2."); 350 | pl[0]= mxCreateMatrix3( h, w, d, mxSINGLE_CLASS, 0, (void**) &Gx ); 351 | pl[1]= mxCreateMatrix3( h, w, d, mxSINGLE_CLASS, 0, (void**) &Gy ); 352 | grad2( I, Gx, Gy, h, w, d ); 353 | } 354 | 355 | // [M,O] = gradMag( I, channel, full ) - see gradientMag.m 356 | void mGradMag( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { 357 | int h, w, d, c, full; float *I, *M, *O=0; 358 | checkArgs(nl,pl,nr,pr,1,2,3,3,&h,&w,&d,mxSINGLE_CLASS,(void**)&I); 359 | if(h<2 || w<2) mexErrMsgTxt("I must be at least 2x2."); 360 | c = (int) mxGetScalar(pr[1]); full = (int) mxGetScalar(pr[2]); 361 | if( c>0 && c<=d ) { I += h*w*(c-1); d=1; } 362 | pl[0] = mxCreateMatrix3(h,w,1,mxSINGLE_CLASS,0,(void**)&M); 363 | if(nl>=2) pl[1] = mxCreateMatrix3(h,w,1,mxSINGLE_CLASS,0,(void**)&O); 364 | gradMag(I, M, O, h, w, d, full>0 ); 365 | } 366 | 367 | // gradMagNorm( M, S, norm ) - operates on M - see gradientMag.m 368 | void mGradMagNorm( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { 369 | int h, w, d; float *M, *S, norm; 370 | checkArgs(nl,pl,nr,pr,0,0,3,3,&h,&w,&d,mxSINGLE_CLASS,(void**)&M); 371 | if( mxGetM(pr[1])!=h || mxGetN(pr[1])!=w || d!=1 || 372 | mxGetClassID(pr[1])!=mxSINGLE_CLASS ) mexErrMsgTxt("M or S is bad."); 373 | S = (float*) mxGetPr(pr[1]); norm = (float) mxGetScalar(pr[2]); 374 | gradMagNorm(M,S,h,w,norm); 375 | } 376 | 377 | // H=gradHist(M,O,[...]) - see gradientHist.m 378 | void mGradHist( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { 379 | int h, w, d, hb, wb, nChns, binSize, nOrients, softBin, useHog; 380 | bool full; float *M, *O, *H, clipHog; 381 | checkArgs(nl,pl,nr,pr,1,3,2,8,&h,&w,&d,mxSINGLE_CLASS,(void**)&M); 382 | O = (float*) mxGetPr(pr[1]); 383 | if( mxGetM(pr[1])!=h || mxGetN(pr[1])!=w || d!=1 || 384 | mxGetClassID(pr[1])!=mxSINGLE_CLASS ) mexErrMsgTxt("M or O is bad."); 385 | binSize = (nr>=3) ? (int) mxGetScalar(pr[2]) : 8; 386 | nOrients = (nr>=4) ? (int) mxGetScalar(pr[3]) : 9; 387 | softBin = (nr>=5) ? (int) mxGetScalar(pr[4]) : 1; 388 | useHog = (nr>=6) ? (int) mxGetScalar(pr[5]) : 0; 389 | clipHog = (nr>=7) ? (float) mxGetScalar(pr[6]) : 0.2f; 390 | full = (nr>=8) ? (bool) (mxGetScalar(pr[7])>0) : false; 391 | hb = h/binSize; wb = w/binSize; 392 | nChns = useHog== 0 ? nOrients : (useHog==1 ? nOrients*4 : nOrients*3+5); 393 | pl[0] = mxCreateMatrix3(hb,wb,nChns,mxSINGLE_CLASS,1,(void**)&H); 394 | if( nOrients==0 ) return; 395 | if( useHog==0 ) { 396 | gradHist( M, O, H, h, w, binSize, nOrients, softBin, full ); 397 | } else if(useHog==1) { 398 | hog( M, O, H, h, w, binSize, nOrients, softBin, full, clipHog ); 399 | } else { 400 | fhog( M, O, H, h, w, binSize, nOrients, softBin, clipHog ); 401 | } 402 | } 403 | 404 | // inteface to various gradient functions (see corresponding Matlab functions) 405 | void mexFunction( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { 406 | int f; char action[1024]; f=mxGetString(pr[0],action,1024); nr--; pr++; 407 | if(f) mexErrMsgTxt("Failed to get action."); 408 | else if(!strcmp(action,"gradient2")) mGrad2(nl,pl,nr,pr); 409 | else if(!strcmp(action,"gradientMag")) mGradMag(nl,pl,nr,pr); 410 | else if(!strcmp(action,"gradientMagNorm")) mGradMagNorm(nl,pl,nr,pr); 411 | else if(!strcmp(action,"gradientHist")) mGradHist(nl,pl,nr,pr); 412 | else mexErrMsgTxt("Invalid action."); 413 | } 414 | #endif 415 | -------------------------------------------------------------------------------- /feature/gradientMex.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/feature/gradientMex.mexa64 -------------------------------------------------------------------------------- /feature/gradientMex.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/feature/gradientMex.mexmaci64 -------------------------------------------------------------------------------- /feature/gradientMex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/feature/gradientMex.mexw64 -------------------------------------------------------------------------------- /feature/lookup_tables/CNnorm.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/feature/lookup_tables/CNnorm.mat -------------------------------------------------------------------------------- /figures/DTB70/error_OPE_DTB70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/figures/DTB70/error_OPE_DTB70.png -------------------------------------------------------------------------------- /figures/DTB70/overlap_OPE_DTB70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/figures/DTB70/overlap_OPE_DTB70.png -------------------------------------------------------------------------------- /figures/UAV123_10fps/error_OPE_UAV123_10fps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/figures/UAV123_10fps/error_OPE_UAV123_10fps.png -------------------------------------------------------------------------------- /figures/UAV123_10fps/overlap_OPE_UAV123_10fps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/figures/UAV123_10fps/overlap_OPE_UAV123_10fps.png -------------------------------------------------------------------------------- /figures/UAVDT/error_OPE_UAVDT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/figures/UAVDT/error_OPE_UAVDT.png -------------------------------------------------------------------------------- /figures/UAVDT/overlap_OPE_UAVDT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/figures/UAVDT/overlap_OPE_UAVDT.png -------------------------------------------------------------------------------- /figures/VisDrone_test_dev/error_OPE_VisDrone_test_dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/figures/VisDrone_test_dev/error_OPE_VisDrone_test_dev.png -------------------------------------------------------------------------------- /figures/VisDrone_test_dev/overlap_OPE_VisDrone_test_dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/figures/VisDrone_test_dev/overlap_OPE_VisDrone_test_dev.png -------------------------------------------------------------------------------- /implementation/AutoTrack_optimized.m: -------------------------------------------------------------------------------- 1 | % This function implements the ASRCF tracker. 2 | 3 | function [results] = AutoTrack_optimized(params) 4 | % Setting parameters for local use. 5 | admm_iterations = params.admm_iterations; 6 | search_area_scale = params.search_area_scale; 7 | max_image_sample_size=params.max_image_sample_size; 8 | min_image_sample_size=params.min_image_sample_size; 9 | output_sigma_factor = params.output_sigma_factor; 10 | % Scale parameters 11 | num_scales=params.num_scales; 12 | scale_sigma_factor=params.scale_sigma_factor; 13 | scale_step=params.scale_step; 14 | scale_lambda=params.scale_lambda; 15 | scale_model_factor=params.scale_model_factor; 16 | scale_model_max_area =params.scale_model_max_area; 17 | lambda=params.admm_lambda; 18 | features = params.t_features; 19 | video_path = params.video_path; 20 | s_frames = params.s_frames; 21 | pos = floor(params.init_pos); 22 | target_sz = floor(params.wsize); 23 | visualization = params.visualization; 24 | num_frames = params.no_fram; 25 | epsilon=params.epsilon; 26 | delta=params.delta; 27 | zeta=params.zeta; 28 | newton_iterations = params.newton_iterations; 29 | featureRatio = params.t_global.cell_size; 30 | search_area = prod(target_sz * search_area_scale); 31 | global_feat_params = params.t_global; 32 | nu=params.nu; 33 | if search_area > max_image_sample_size 34 | currentScaleFactor = sqrt(search_area / max_image_sample_size); 35 | elseif search_area 1 && colorImage == false 111 | im = im(:,:,1); 112 | end 113 | 114 | %% SCALE ADAPTATION INITIALIZATION 115 | % Use the translation filter to estimate the scale 116 | scale_sigma = sqrt(num_scales) * scale_sigma_factor; 117 | ss = (1:num_scales) - ceil(num_scales/2); 118 | ys = exp(-0.5 * (ss.^2) / scale_sigma^2); 119 | ysf = single(fft(ys)); 120 | if mod(num_scales,2) == 0 121 | scale_window = single(hann(num_scales+1)); 122 | scale_window = scale_window(2:end); 123 | else 124 | scale_window = single(hann(num_scales)); 125 | end 126 | ss = 1:num_scales; 127 | scaleFactors = scale_step.^(ceil(num_scales/2) - ss); 128 | if scale_model_factor^2 * prod(target_sz) > scale_model_max_area 129 | scale_model_factor = sqrt(scale_model_max_area/prod(target_sz)); 130 | end 131 | if prod(target_sz) >scale_model_max_area 132 | params.scale_model_factor = sqrt(scale_model_max_area/prod(target_sz)); 133 | end 134 | scale_model_sz = floor(target_sz * scale_model_factor); 135 | 136 | % set maximum and minimum scales 137 | min_scale_factor = scale_step ^ ceil(log(max(5 ./sz)) / log(scale_step)); 138 | max_scale_factor =scale_step ^ floor(log(min([size(im,1) size(im,2)] ./ base_target_sz)) / log(scale_step)); 139 | 140 | % Pre-computes the grid that is used for score optimization 141 | ky = circshift(-floor((use_sz(1) - 1)/2) : ceil((use_sz(1) - 1)/2), [1, -floor((use_sz(1) - 1)/2)]); 142 | kx = circshift(-floor((use_sz(2) - 1)/2) : ceil((use_sz(2) - 1)/2), [1, -floor((use_sz(2) - 1)/2)])'; 143 | 144 | % initialize the projection matrix (x,y,h,w) 145 | rect_position = zeros(num_frames, 4); 146 | time = 0; 147 | loop_frame = 1; 148 | 149 | for frame = 1:num_frames 150 | %load image 151 | try 152 | im = imread([video_path '/img/' s_frames{frame}]); 153 | catch 154 | try 155 | im = imread([s_frames{frame}]); 156 | catch 157 | im = imread([video_path '/' s_frames{frame}]); 158 | end 159 | end 160 | if size(im,3) > 1 && colorImage == false 161 | im = im(:,:,1); 162 | end 163 | tic(); 164 | %% main loop 165 | occ=false; 166 | if frame > 1 167 | pixel_template=get_pixels(im, pos, round(sz*currentScaleFactor), sz); 168 | xt=get_features(pixel_template,features,global_feat_params); 169 | xtf=fft2(bsxfun(@times,xt,cos_window)); 170 | responsef=permute(sum(bsxfun(@times, conj(g_f), xtf), 3), [1 2 4 3]); 171 | % if we undersampled features, we want to interpolate the 172 | % response so it has the same size as the image patch 173 | responsef_padded = resizeDFT2(responsef, interp_sz); 174 | % response in the spatial domain 175 | response = ifft2(responsef_padded, 'symmetric'); 176 | % find maximum peak 177 | [disp_row, disp_col] = resp_newton(response, responsef_padded, newton_iterations, ky, kx, use_sz); 178 | % update reference mu for Admm 179 | if frame>2 180 | response_shift=circshift(response,[-floor(disp_row) -floor(disp_col)]); 181 | response_pre_shift=circshift(response_pre,[-floor(disp_row_pre) -floor(disp_col_pre)]); 182 | response_diff=abs(abs(response_shift-response_pre_shift)./response_pre_shift); 183 | [ref_mu,occ]=updateRefmu(response_diff,zeta,nu,frame); 184 | response_diff=circshift(response_diff,floor(size(response_diff)/2)); 185 | varience=delta*log(response_diff(range_h, range_w)+1); 186 | w(range_h, range_w) = varience; 187 | end 188 | % save response in last frame 189 | response_pre=response; 190 | % save translation of response in last frame 191 | disp_row_pre=disp_row; 192 | disp_col_pre=disp_col; 193 | % calculate translation 194 | translation_vec = round([disp_row, disp_col] * featureRatio * currentScaleFactor); 195 | %update position 196 | pos = pos + translation_vec; 197 | 198 | %%Scale Search 199 | xs = crop_scale_sample(im, pos, base_target_sz, currentScaleFactor * scaleFactors, scale_window, scale_model_sz); 200 | xsf = fft(xs,[],2); 201 | scale_response = real(ifft(sum(sf_num .* xsf, 1) ./ (sf_den+scale_lambda))); 202 | % find the maximum scale response 203 | recovered_scale = find(scale_response == max(scale_response(:)), 1); 204 | % update the scale 205 | currentScaleFactor = currentScaleFactor * scaleFactors(recovered_scale); 206 | if currentScaleFactor < min_scale_factor 207 | currentScaleFactor = min_scale_factor; 208 | elseif currentScaleFactor > max_scale_factor 209 | currentScaleFactor = max_scale_factor; 210 | end 211 | end 212 | target_sz =round(base_target_sz * currentScaleFactor); 213 | 214 | %save position 215 | rect_position(loop_frame,:) =[pos([2,1]) - (target_sz([2,1]))/2, target_sz([2,1])]; 216 | 217 | if frame==1 218 | % extract training sample image region 219 | pixels = get_pixels(im,pos,round(sz*currentScaleFactor),sz); 220 | pixels = uint8(gather(pixels)); 221 | x=get_features(pixels,features,global_feat_params); 222 | xf=fft2(bsxfun(@times,x,cos_window)); 223 | else 224 | % use detection features 225 | shift_samp_pos = 2*pi * translation_vec ./(currentScaleFactor* sz); 226 | xf = shift_sample(xtf, shift_samp_pos, kx', ky'); 227 | end 228 | 229 | if frame == 1 230 | [range_h,range_w,w]=init_regwindow(use_sz,reg_sz,params); 231 | g_pre= zeros(size(xf)); 232 | mu = 0; 233 | else 234 | mu=zeta; 235 | end 236 | 237 | if ~occ 238 | g_f = single(zeros(size(xf))); 239 | h_f = g_f; 240 | l_f = h_f; 241 | gamma = 1; 242 | betha = 10; 243 | gamma_max = 10000; 244 | 245 | 246 | % ADMM solution 247 | T = prod(use_sz); 248 | S_xx = sum(conj(xf) .* xf, 3); 249 | Sg_pre= sum(conj(xf) .* g_pre, 3); 250 | Sgx_pre= bsxfun(@times, xf, Sg_pre); 251 | iter = 1; 252 | while (iter <= admm_iterations) 253 | % subproblem g 254 | B = S_xx + T * (gamma + mu); 255 | Shx_f = sum(conj(xf) .* h_f, 3); 256 | Slx_f = sum(conj(xf) .* l_f, 3); 257 | g_f = ((1/(T*(gamma + mu)) * bsxfun(@times, yf, xf)) - ((1/(gamma + mu)) * l_f) +(gamma/(gamma + mu)) * h_f) + (mu/(gamma + mu)) * g_pre - ... 258 | bsxfun(@rdivide,(1/(T*(gamma + mu)) * bsxfun(@times, xf, (S_xx .* yf)) + (mu/(gamma + mu)) * Sgx_pre- ... 259 | (1/(gamma + mu))* (bsxfun(@times, xf, Slx_f)) +(gamma/(gamma + mu))* (bsxfun(@times, xf, Shx_f))), B); 260 | % subproblem h 261 | lhd= T ./ (lambda*w .^2 + gamma*T); 262 | X=ifft2(gamma*(g_f + l_f)); 263 | h=bsxfun(@times,lhd,X); 264 | h_f = fft2(h); 265 | % subproblem mu 266 | if frame>2&&iter size(im,2)) = size(im,2); 21 | ys(ys > size(im,1)) = size(im,1); 22 | 23 | % extract image 24 | im_patch = im(ys, xs, :); 25 | 26 | % resize image to model size 27 | im_patch_resized = mexResize(im_patch, scale_model_sz, 'auto'); 28 | 29 | % extract scale features 30 | temp_hog = fhog(single(im_patch_resized), 4); 31 | temp = temp_hog(:,:,1:31); 32 | 33 | if s == 1 34 | out = zeros(numel(temp), nScales, 'single'); 35 | end 36 | 37 | % window 38 | out(:,s) = temp(:) * scale_window(s); 39 | end -------------------------------------------------------------------------------- /implementation/init_regwindow.m: -------------------------------------------------------------------------------- 1 | function [range_h,range_w,reg_window]=init_regwindow(sz,target_sz,params) 2 | reg_scale =target_sz; 3 | use_sz = sz; 4 | reg_window = ones(use_sz) * params.reg_window_max; 5 | range = zeros(numel(reg_scale), 2); 6 | 7 | % determine the target center and range in the regularization windows 8 | for j = 1:numel(reg_scale) 9 | range(j,:) = [0, reg_scale(j) - 1] - floor(reg_scale(j) / 2); 10 | end 11 | center = floor((use_sz + 1)/ 2) + mod(use_sz + 1,2); 12 | range_h = (center(1)+ range(1,1)) : (center(1) + range(1,2)); 13 | range_w = (center(2)+ range(2,1)) : (center(2) + range(2,2)); 14 | reg_window(range_h, range_w) = params.reg_window_min; 15 | 16 | 17 | -------------------------------------------------------------------------------- /implementation/shift_sample_scale.m: -------------------------------------------------------------------------------- 1 | function out = shift_sample_scale(im, pos, base_target_sz,xs,recovered_scale,scaleFactors,scale_window,scale_model_sz) 2 | nScales = length(scaleFactors); 3 | out = zeros(size(xs,1), nScales, 'single'); 4 | shift_pos=recovered_scale-ceil(nScales/2); 5 | if shift_pos==0 6 | out=xs; 7 | elseif shift_pos>0 8 | for j=1:nScales-shift_pos 9 | out(:,j)=xs(:,j+shift_pos)/(scale_window(j+shift_pos)+1e-5)*scale_window(j); 10 | end 11 | for i=1:shift_pos 12 | patch_sz = floor(base_target_sz * scaleFactors(nScales-shift_pos+i)); 13 | patch_sz = max(patch_sz, 2); 14 | xs = floor(pos(2)) + (1:patch_sz(2)) - floor(patch_sz(2)/2); 15 | ys = floor(pos(1)) + (1:patch_sz(1)) - floor(patch_sz(1)/2); 16 | % check for out-of-bounds coordinates, and set them to the values at 17 | % the borders 18 | xs(xs < 1) = 1; 19 | ys(ys < 1) = 1; 20 | xs(xs > size(im,2)) = size(im,2); 21 | ys(ys > size(im,1)) = size(im,1); 22 | 23 | % extract image 24 | im_patch = im(ys, xs, :); 25 | 26 | % resize image to model size 27 | im_patch_resized = mexResize(im_patch, scale_model_sz, 'auto'); 28 | 29 | % extract scale features 30 | temp_hog = fhog(single(im_patch_resized), 4); 31 | temp = temp_hog(:,:,1:31); 32 | % window 33 | out(:,nScales-shift_pos+i) = temp(:) * scale_window(nScales-shift_pos+i); 34 | end 35 | else 36 | for j=1:nScales+shift_pos 37 | out(:,j-shift_pos)=xs(:,j)/(scale_window(j)+1e-5).*scale_window(j-shift_pos); 38 | end 39 | for i=1:-shift_pos 40 | patch_sz = floor(base_target_sz * scaleFactors(i)); 41 | patch_sz = max(patch_sz, 2); 42 | xs = floor(pos(2)) + (1:patch_sz(2)) - floor(patch_sz(2)/2); 43 | ys = floor(pos(1)) + (1:patch_sz(1)) - floor(patch_sz(1)/2); 44 | % check for out-of-bounds coordinates, and set them to the values at 45 | % the borders 46 | xs(xs < 1) = 1; 47 | ys(ys < 1) = 1; 48 | xs(xs > size(im,2)) = size(im,2); 49 | ys(ys > size(im,1)) = size(im,1); 50 | 51 | % extract image 52 | im_patch = im(ys, xs, :); 53 | 54 | % resize image to model size 55 | im_patch_resized = mexResize(im_patch, scale_model_sz, 'auto'); 56 | 57 | % extract scale features 58 | temp_hog = fhog(single(im_patch_resized), 4); 59 | temp = temp_hog(:,:,1:31); 60 | % window 61 | out(:,i) = temp(:) * scale_window(i); 62 | end 63 | end 64 | 65 | -------------------------------------------------------------------------------- /implementation/updateRefmu.m: -------------------------------------------------------------------------------- 1 | function [ref_mu,occ]= updateRefmu(response_diff,init_mu,p,frame) 2 | 3 | [ref_mu,occ]=varphiFunction(response_diff,init_mu,p,frame); 4 | end 5 | function [y,occ]=varphiFunction(response_diff,init_mu,p,frame) 6 | % global eta_list; 7 | phi=0.3; %0.3 8 | m=init_mu; 9 | eta=norm(response_diff,2)/1e4; 10 | % eta_list(frame)=eta; 11 | if eta 38 | %#ok<*EMCA> 39 | 40 | % validateattributes(I, {'numeric','logical'}, {'2d', 'nonsparse', 'real'},... 41 | % 'integralImage', 'I'); 42 | 43 | if ~isempty(I) 44 | intImage = zeros(size(I,1)+1, size(I,2)+1, size(I,3), size(I,4), 'single'); 45 | intImage(2:end, 2:end, :, :) = cumsum(cumsum(I,1),2); 46 | else 47 | intImage = []; 48 | end 49 | 50 | -------------------------------------------------------------------------------- /utils/mexResize.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "mex.h" 5 | #include "MxArray.hpp" 6 | #include 7 | 8 | #include 9 | 10 | using namespace std; 11 | using namespace cv; 12 | 13 | /* 14 | * Use opencv function to resample image quickly 15 | */ 16 | 17 | // matlab entry point 18 | // dst = resize(src, scale) 19 | // image should be color with double values 20 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 21 | if (nrhs < 2){ 22 | mexErrMsgTxt("Wrong number of inputs"); 23 | } 24 | if (nlhs != 1){ 25 | mexErrMsgTxt("Wrong number of outputs"); 26 | } 27 | 28 | vector rhs(prhs,prhs+nrhs); 29 | 30 | //convert input data to opencv matrix 31 | Mat img = rhs[0].toMat(); 32 | Mat imgr; 33 | Size s = rhs[1].toSize(); 34 | Size newSize = Size(s.height,s.width); 35 | Size oldSize = img.size(); 36 | //interpolation method 37 | int interpolation = INTER_LINEAR; 38 | 39 | //if interpolation method provided set it 40 | if(nrhs == 3){ 41 | string interp = rhs[2].toString(); 42 | if(interp.compare("antialias") == 0){ 43 | interpolation = INTER_AREA; 44 | }else if(interp.compare("linear") == 0){ 45 | interpolation = INTER_LINEAR; 46 | }else if(interp.compare("auto") == 0){ //if we are zooming, use linear else use area interpolation 47 | //old array has width and height swapped, newArray does not 48 | if(newSize.width > oldSize.height){ 49 | interpolation = INTER_LINEAR; 50 | }else{ 51 | interpolation = INTER_AREA; 52 | } 53 | }else{ 54 | mexErrMsgTxt("Invalid interpolation provided, valid is linear (default), antialias, auto"); 55 | } 56 | } 57 | 58 | //use opencv resize function 59 | resize(img,imgr,newSize,0,0,interpolation); 60 | //convert back to matlab representation 61 | plhs[0] = MxArray(imgr); 62 | } 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /utils/mexResize.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/mexResize.mexa64 -------------------------------------------------------------------------------- /utils/mexResize.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/mexResize.mexmaci64 -------------------------------------------------------------------------------- /utils/mexResize.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/mexResize.mexw64 -------------------------------------------------------------------------------- /utils/mtimesx.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/mtimesx.c -------------------------------------------------------------------------------- /utils/mtimesx.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/mtimesx.m -------------------------------------------------------------------------------- /utils/mtimesx.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/mtimesx.mexa64 -------------------------------------------------------------------------------- /utils/mtimesx.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/mtimesx.mexmaci64 -------------------------------------------------------------------------------- /utils/mtimesx.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/mtimesx.mexw64 -------------------------------------------------------------------------------- /utils/mtimesx_build.m: -------------------------------------------------------------------------------- 1 | % mtimesx_build compiles mtimesx.c with BLAS libraries 2 | %****************************************************************************** 3 | % 4 | % MATLAB (R) is a trademark of The Mathworks (R) Corporation 5 | % 6 | % Function: mtimesx_build 7 | % Filename: mtimesx_build.m 8 | % Programmer: James Tursa 9 | % Version: 1.40 10 | % Date: October 4, 2010 11 | % Copyright: (c) 2009, 2010 by James Tursa, All Rights Reserved 12 | % 13 | % This code uses the BSD License: 14 | % 15 | % Redistribution and use in source and binary forms, with or without 16 | % modification, are permitted provided that the following conditions are 17 | % met: 18 | % 19 | % * Redistributions of source code must retain the above copyright 20 | % notice, this list of conditions and the following disclaimer. 21 | % * Redistributions in binary form must reproduce the above copyright 22 | % notice, this list of conditions and the following disclaimer in 23 | % the documentation and/or other materials provided with the distribution 24 | % 25 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | % IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 | % ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 29 | % LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | % POSSIBILITY OF SUCH DAMAGE. 36 | % 37 | %-- 38 | % 39 | % mtimesx_build compiles mtimesx.c and mtimesx_RealTimesReal.c with the BLAS 40 | % libraries libmwblas.lib (if present) or libmwlapack.lib (if libmwblas.lib 41 | % is not present). This function basically works as follows: 42 | % 43 | % - Opens the current mexopts.bat file in the directory [prefdir], and 44 | % checks to make sure that the compiler selected is cl or lcc. If it 45 | % is not, then a warning is issued and the compilation continues with 46 | % the assumption that the microsoft BLAS libraries will work. 47 | % 48 | % - Looks for the file libmwblas.lib or libmwlapack.lib files in the 49 | % appropriate directory: [matlabroot '\extern\lib\win32\microsoft'] 50 | % or [matlabroot '\extern\lib\win32\lcc'] 51 | % or [matlabroot '\extern\lib\win64\microsoft'] 52 | % or [matlabroot '\extern\lib\win64\lcc'] 53 | % 54 | % - Changes directory to the directory of the file mtimesx.m. 55 | % 56 | % - Compiles mtimesx.c (which includes mtimesx_RealTimesReal.c) along with 57 | % either libmwblas.lib or libmwlapack.lib depending on the version of 58 | % MATLAB. The resulting exedcutable mex file is placed in the same 59 | % directory as the source code. The files mtimesx.m, mtimesx.c, and 60 | % mtimesx_RealTimesReal.c must all be in the same directory. 61 | % 62 | % - Changes the directory back to the original directory. 63 | % 64 | % Change Log: 65 | % 2009/Sep/27 --> 1.00, Initial Release 66 | % 2010/Feb/15 --> 1.10, Fixed largearrardims typo to largeArrayDims 67 | % 2010/Oct/04 --> 1.40, Updated support for OpenMP compiling 68 | % 69 | %************************************************************************** 70 | 71 | function mtimesx_build(x) 72 | disp(' '); 73 | disp('... Build routine for mtimesx'); 74 | 75 | TRUE = 1; 76 | FALSE = 0; 77 | 78 | %\ 79 | % Check for number of inputs & outputs 80 | %/ 81 | 82 | noopenmp = FALSE; 83 | if( nargin == 1 ) 84 | if( isequal(upper(x),'NOOPENMP') ) 85 | noopenmp = TRUE; 86 | else 87 | error('Invalid input.'); 88 | end 89 | elseif( nargin ~= 0 ) 90 | error('Too many inputs. Expected none.'); 91 | end 92 | if( nargout ~= 0 ) 93 | error('Too many outputs. Expected none.'); 94 | end 95 | 96 | %\ 97 | % Check for non-PC 98 | %/ 99 | 100 | disp('... Checking for PC'); 101 | try 102 | % ispc does not appear in MATLAB 5.3 103 | pc = ispc ; 104 | catch 105 | % if ispc fails, assume we are on a Windows PC if it's not unix 106 | pc = ~isunix ; 107 | end 108 | 109 | if( ~pc ) 110 | disp('Non-PC auto build is not currently supported. You will have to'); 111 | disp('manually compile the mex routine. E.g., as follows:'); 112 | disp(' '); 113 | disp('>> blas_lib = ''the_actual_path_and_name_of_your_systems_BLAS_library'''); 114 | disp('>> mex(''-DDEFINEUNIX'',''mtimesx.c'',blas_lib)'); 115 | disp(' '); 116 | disp('or'); 117 | disp(' '); 118 | disp('>> mex(''-DDEFINEUNIX'',''-largeArrayDims'',''mtimesx.c'',blas_lib)'); 119 | disp(' '); 120 | error('Unable to compile mtimesx.c'); 121 | end 122 | 123 | %\ 124 | % Check to see that mtimesx.c source code is present 125 | %/ 126 | 127 | disp('... Finding path of mtimesx C source code files'); 128 | try 129 | mname = mfilename('fullpath'); 130 | catch 131 | mname = mfilename; 132 | end 133 | cname = [mname(1:end-6) '.c']; 134 | if( isempty(dir(cname)) ) 135 | disp('Cannot find the file mtimesx.c in the same directory as the'); 136 | disp('file mtimesx_build.m. Please ensure that they are in the same'); 137 | disp('directory and try again. The following file was not found:'); 138 | disp(' '); 139 | disp(cname); 140 | disp(' '); 141 | error('Unable to compile mtimesx.c'); 142 | end 143 | disp(['... Found file mtimesx.c in ' cname]); 144 | 145 | %\ 146 | % Check to see that mtimesx_RealTimesReal.c source code is present 147 | %/ 148 | 149 | rname = [mname(1:end-13) 'mtimesx_RealTimesReal.c']; 150 | if( isempty(dir(rname)) ) 151 | disp('Cannot find the file mtimesx_RealTimesReal.c in the same'); 152 | disp('directory as the file mtimesx_build.m. Please ensure that'); 153 | disp('they are in the same directory and try again. The'); 154 | disp('following file was not found:'); 155 | disp(' '); 156 | disp(rname); 157 | disp(' '); 158 | error('Unable to compile mtimesx.c'); 159 | end 160 | disp(['... Found file mtimesx_RealTimesReal.c in ' rname]); 161 | 162 | %\ 163 | % Open the current mexopts.bat file 164 | %/ 165 | 166 | mexopts = [prefdir '\mexopts.bat']; 167 | fid = fopen(mexopts); 168 | if( fid == -1 ) 169 | error('A C/C++ compiler has not been selected with mex -setup'); 170 | end 171 | disp(['... Opened the mexopts.bat file in ' mexopts]); 172 | disp('... Reading the mexopts.bat file to find the compiler and options used.'); 173 | 174 | %\ 175 | % Check for the correct compiler selected. 176 | %/ 177 | 178 | ok_cl = FALSE; 179 | ok_lcc = FALSE; 180 | omp_option = ''; 181 | compiler = '(unknown)'; 182 | compilername = ''; 183 | while( TRUE ) 184 | tline = fgets(fid); 185 | if( isequal(tline,-1) ) 186 | break; 187 | else 188 | if( isempty(compilername) ) 189 | y = findstr(tline,'OPTS.BAT'); 190 | if( ~isempty(y) ) 191 | x = findstr(tline,'rem '); 192 | if( ~isempty(x) ) 193 | compilername = tline(x+4:y-1); 194 | end 195 | end 196 | end 197 | x = findstr(tline,'COMPILER=lcc'); 198 | if( ~isempty(x) ) 199 | ok_lcc = TRUE; 200 | libdir = 'lcc'; 201 | compiler = 'LCC'; 202 | disp(['... ' compiler ' is the selected compiler']); 203 | break; 204 | end 205 | x = findstr(tline,'COMPILER=cl'); 206 | if( ~isempty(x) ) 207 | ok_cl = TRUE; 208 | libdir = 'microsoft'; 209 | compiler = ['Microsoft_' compilername '_cl']; 210 | omp_option = ' /openmp'; 211 | disp(['... ' compiler ' is the selected compiler']); 212 | break; 213 | end 214 | x = findstr(tline,'COMPILER=bcc32'); 215 | if( ~isempty(x) ) 216 | ok_cl = TRUE; 217 | libdir = 'microsoft'; 218 | compiler = ['Borland_' compilername '_bcc32']; 219 | disp(['... ' compiler ' is the selected compiler']); 220 | disp('... Assuming that Borland will link with Microsoft libraries'); 221 | break; 222 | end 223 | x = findstr(tline,'COMPILER=icl'); 224 | if( ~isempty(x) ) 225 | ok_cl = TRUE; 226 | if( pc ) 227 | omp_option = ' -Qopenmp'; 228 | else 229 | omp_option = ' -openmp'; 230 | end 231 | libdir = 'microsoft'; 232 | compiler = ['Intel_' compilername '_icl']; 233 | disp(['... ' compiler ' is the selected compiler']); 234 | disp('... Assuming that Intel will link with Microsoft libraries'); 235 | break; 236 | end 237 | x = findstr(tline,'COMPILER=wc1386'); 238 | if( ~isempty(x) ) 239 | ok_cl = TRUE; 240 | libdir = 'microsoft'; 241 | compiler = ['Watcom_' compilername '_wc1386']; 242 | disp(['... ' compiler ' is the selected compiler']); 243 | disp('... Assuming that Watcom will link with Microsoft libraries'); 244 | break; 245 | end 246 | x = findstr(tline,'COMPILER=gcc'); 247 | if( ~isempty(x) ) 248 | ok_cl = TRUE; 249 | libdir = 'microsoft'; 250 | omp_option = ' -fopenmp'; 251 | compiler = 'GCC'; 252 | disp(['... ' compiler ' is the selected compiler']); 253 | disp('... Assuming that GCC will link with Microsoft libraries'); 254 | break; 255 | end 256 | end 257 | end 258 | fclose(fid); 259 | 260 | %\ 261 | % MS Visual C/C++ or lcc compiler has not been selected 262 | %/ 263 | 264 | if( ~(ok_cl | ok_lcc) ) 265 | warning('... Supported C/C++ compiler has not been selected with mex -setup'); 266 | warning('... Assuming that Selected Compiler will link with Microsoft libraries'); 267 | warning('... Continuing at risk ...'); 268 | libdir = 'microsoft'; 269 | end 270 | 271 | %\ 272 | % If an OpenMP supported compiler is potentially present, make sure that the 273 | % necessary compile option is present in the mexopts.bat file on the COMPFLAGS 274 | % line. If necessary, build a new mexopts.bat file with the correct option 275 | % added to the COMPFLAGS line. 276 | %/ 277 | 278 | while( TRUE ) 279 | ok_openmp = FALSE; 280 | ok_compflags = FALSE; 281 | xname = ''; 282 | if( isempty(omp_option) ) 283 | disp('... OpenMP compiler not detected ... you may want to check this website:'); 284 | disp(' http://openmp.org/wp/openmp-compilers/'); 285 | elseif( noopenmp ) 286 | disp(['... OpenMP compiler potentially detected, but not checking for ''' omp_option ''' compile option']); 287 | else 288 | disp('... OpenMP compiler potentially detected'); 289 | disp(['... Checking to see that the ''' omp_option ''' compile option is present']); 290 | fid = fopen(mexopts); 291 | while( TRUE ) 292 | tline = fgets(fid); 293 | if( isequal(tline,-1) ) 294 | break; 295 | else 296 | x = findstr(tline,'set COMPFLAGS'); 297 | if( ~isempty(x) ) 298 | ok_compflags = TRUE; 299 | x = findstr(tline,omp_option); 300 | if( ~isempty(x) ) 301 | ok_openmp = TRUE; 302 | end 303 | break; 304 | end 305 | end 306 | end 307 | fclose(fid); 308 | if( ~ok_compflags ) 309 | warning(['... COMPFLAGS line not found ... ''' omp_option ''' will not be added.']); 310 | elseif( ~ok_openmp ) 311 | disp(['... The ''' omp_option ''' compile option is not present ... adding it']); 312 | xname = [mname(1:end-6) '_mexopts.bat']; 313 | disp(['... Creating custom options file ' xname ' with the ''' omp_option ''' option added.']); 314 | fid = fopen(mexopts); 315 | fidx = fopen(xname,'w'); 316 | if( fidx == -1 ) 317 | xname = ''; 318 | warning(['... Unable to create custom mexopts.bat file ... ''' omp_option ''' will not be added']); 319 | else 320 | while( TRUE ) 321 | tline = fgets(fid); 322 | if( isequal(tline,-1) ) 323 | break; 324 | else 325 | x = findstr(tline,'set COMPFLAGS'); 326 | if( ~isempty(x) ) 327 | n = numel(tline); 328 | e = n; 329 | while( tline(e) < 32 ) 330 | e = e - 1; 331 | end 332 | tline = [tline(1:e) omp_option tline(e+1:n)]; 333 | end 334 | fwrite(fidx,tline); 335 | end 336 | end 337 | fclose(fidx); 338 | end 339 | fclose(fid); 340 | end 341 | end 342 | 343 | %\ 344 | % Construct full file name of libmwblas.lib and libmwlapack.lib. Note that 345 | % not all versions have both files. Earlier versions only had the lapack 346 | % file, which contained both blas and lapack routines. 347 | %/ 348 | 349 | comp = computer; 350 | mext = mexext; 351 | lc = length(comp); 352 | lm = length(mext); 353 | cbits = comp(max(1:lc-1):lc); 354 | mbits = mext(max(1:lm-1):lm); 355 | if( isequal(cbits,'64') | isequal(mbits,'64') ) 356 | compdir = 'win64'; 357 | largearraydims = '-largeArrayDims'; 358 | else 359 | compdir = 'win32'; 360 | largearraydims = ''; 361 | end 362 | 363 | lib_blas = [matlabroot '\extern\lib\' compdir '\' libdir '\libmwblas.lib']; 364 | d = dir(lib_blas); 365 | if( isempty(d) ) 366 | disp('... BLAS library file not found, so linking with the LAPACK library'); 367 | lib_blas = [matlabroot '\extern\lib\' compdir '\' libdir '\libmwlapack.lib']; 368 | end 369 | disp(['... Using BLAS library lib_blas = ''' lib_blas '''']); 370 | 371 | %\ 372 | % Save old directory and change to source code directory 373 | %/ 374 | 375 | cdold = cd; 376 | if( length(mname) > 13 ) 377 | cd(mname(1:end-13)); 378 | end 379 | 380 | %\ 381 | % Do the compile 382 | %/ 383 | 384 | disp('... Now attempting to compile ...'); 385 | disp(' '); 386 | try 387 | if( isunix ) 388 | if( isempty(largearraydims) ) 389 | if( isempty(xname) ) 390 | disp(['mex(''-DDEFINEUNIX'',''' cname ''',lib_blas,''-DCOMPILER=' compiler ''')']); 391 | disp(' '); 392 | mex('-DDEFINEUNIX',cname,lib_blas,['-DCOMPILER=' compiler]); 393 | else 394 | disp(['mex(''-f'',''' xname ''',''-DDEFINEUNIX'',''' cname ''',lib_blas,''-DCOMPILER=' compiler ''')']); 395 | disp(' '); 396 | mex('-f',xname,'-DDEFINEUNIX',cname,lib_blas,['-DCOMPILER=' compiler]); 397 | end 398 | else 399 | if( isempty(xname) ) 400 | disp(['mex(''-DDEFINEUNIX'',''' cname ''',''' largearraydims ''',lib_blas,''-DCOMPILER=' compiler ''')']); 401 | disp(' '); 402 | mex('-DDEFINEUNIX',largearraydims,cname,lib_blas,['-DCOMPILER=' compiler]); 403 | else 404 | disp(['mex(''-f'',''' xname ''',''-DDEFINEUNIX'',''' cname ''',''' largearraydims ''',lib_blas,''-DCOMPILER=' compiler ''')']); 405 | disp(' '); 406 | mex('-f',xname,'-DDEFINEUNIX',largearraydims,cname,lib_blas,['-DCOMPILER=' compiler]); 407 | end 408 | end 409 | else 410 | if( isempty(largearraydims) ) 411 | if( isempty(xname) ) 412 | disp(['mex(''' cname ''',lib_blas,''-DCOMPILER=' compiler ''')']); 413 | disp(' '); 414 | mex(cname,lib_blas,['-DCOMPILER=' compiler]); 415 | else 416 | disp(['mex(''-f'',''' xname ''',''' cname ''',lib_blas,''-DCOMPILER=' compiler ''')']); 417 | disp(' '); 418 | mex('-f',xname,cname,lib_blas,['-DCOMPILER=' compiler]); 419 | end 420 | else 421 | if( isempty(xname) ) 422 | disp(['mex(''' cname ''',''' largearraydims ''',lib_blas,''-DCOMPILER=' compiler ''')']); 423 | disp(' '); 424 | mex(cname,largearraydims,lib_blas,['-DCOMPILER=' compiler]); 425 | else 426 | disp(['mex(''-f'',''' xname ''',''' cname ''',''' largearraydims ''',lib_blas,''-DCOMPILER=' compiler ''')']); 427 | disp(' '); 428 | mex('-f',xname,cname,largearraydims,lib_blas,['-DCOMPILER=' compiler]); 429 | end 430 | end 431 | end 432 | disp('... mex mtimesx.c build completed ... you may now use mtimesx.'); 433 | disp(' '); 434 | mtimesx; 435 | break; 436 | catch 437 | if( noopenmp ) 438 | cd(cdold); 439 | disp(' '); 440 | disp('... Well, *that* didn''t work either!'); 441 | disp(' '); 442 | disp('The mex command failed. This may be because you have already run'); 443 | disp('mex -setup and selected a non-C compiler, such as Fortran. If this'); 444 | disp('is the case, then rerun mex -setup and select a C/C++ compiler.'); 445 | disp(' '); 446 | error('Unable to compile mtimesx.c'); 447 | else 448 | disp(' '); 449 | disp('... Well, *that* didn''t work ...'); 450 | disp(' '); 451 | if( isequal(omp_option,' /openmp') ) 452 | disp('This may be because an OpenMP compile option was added that the'); 453 | disp('compiler did not like. For example, the Standard versions of the'); 454 | disp('Microsoft C/C++ compilers do not support OpenMP, only the'); 455 | disp('Professional versions do. Attempting to compile again but this'); 456 | disp(['time will not add the ''' omp_option ''' option.']) 457 | else 458 | disp('This may be because an OpenMP compile option was added that the'); 459 | disp('compiler did not like. Attempting to compile again, but this time'); 460 | disp(['will not add the ''' omp_option ''' option.']) 461 | end 462 | disp(' '); 463 | noopenmp = TRUE; 464 | end 465 | end 466 | end 467 | 468 | %\ 469 | % Restore old directory 470 | %/ 471 | 472 | cd(cdold); 473 | 474 | return 475 | end 476 | -------------------------------------------------------------------------------- /utils/mtimesx_sparse.m: -------------------------------------------------------------------------------- 1 | % mtimesx_sparse does sparse matrix multiply of two inputs 2 | %****************************************************************************** 3 | % 4 | % MATLAB (R) is a trademark of The Mathworks (R) Corporation 5 | % 6 | % Function: mtimesx_sparse 7 | % Filename: mtimesx_sparse.m 8 | % Programmer: James Tursa 9 | % Version: 1.00 10 | % Date: September 27, 2009 11 | % Copyright: (c) 2009 by James Tursa, All Rights Reserved 12 | % 13 | % This code uses the BSD License: 14 | % 15 | % Redistribution and use in source and binary forms, with or without 16 | % modification, are permitted provided that the following conditions are 17 | % met: 18 | % 19 | % * Redistributions of source code must retain the above copyright 20 | % notice, this list of conditions and the following disclaimer. 21 | % * Redistributions in binary form must reproduce the above copyright 22 | % notice, this list of conditions and the following disclaimer in 23 | % the documentation and/or other materials provided with the distribution 24 | % 25 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | % IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 | % ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 29 | % LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | % POSSIBILITY OF SUCH DAMAGE. 36 | % 37 | %-- 38 | % 39 | % mtimesx_sparse is a helper function for mtimesx and is not intended to be called 40 | % directly by the user. 41 | % 42 | % --------------------------------------------------------------------------------------------------------------------------------- 43 | 44 | function result = mtimesx_sparse(a,transa,b,transb) 45 | if( transa == 'N' ) 46 | if( transb == 'N' ) 47 | result = a * b; 48 | elseif( transb == 'G' ) 49 | result = a * conj(b); 50 | elseif( transb == 'T' ) 51 | result = a * b.'; 52 | else 53 | result = a * b'; 54 | end 55 | elseif( transa == 'G' ) 56 | if( transb == 'N' ) 57 | result = conj(a) * b; 58 | elseif( transb == 'G' ) 59 | result = conj(a) * conj(b); 60 | elseif( transb == 'T' ) 61 | result = conj(a) * b.'; 62 | else 63 | result = conj(a) * b'; 64 | end 65 | elseif( transa == 'T' ) 66 | if( transb == 'N' ) 67 | result = a.' * b; 68 | elseif( transb == 'G' ) 69 | result = a.' * conj(b); 70 | elseif( transb == 'T' ) 71 | result = a.' * b.'; 72 | else 73 | result = a.' * b'; 74 | end 75 | else 76 | if( transb == 'N' ) 77 | result = a' * b; 78 | elseif( transb == 'G' ) 79 | result = a' * conj(b); 80 | elseif( transb == 'T' ) 81 | result = a' * b.'; 82 | else 83 | result = a' * b'; 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /utils/opencv_core242.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/opencv_core242.dll -------------------------------------------------------------------------------- /utils/opencv_imgproc242.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vision4robotics/AutoTrack/e9b34ae09702f152407a7bf7cce5e3ed75bf2797/utils/opencv_imgproc242.dll -------------------------------------------------------------------------------- /utils/resizeDFT2.m: -------------------------------------------------------------------------------- 1 | function resizeddft = resizeDFT2(inputdft, desiredSize) 2 | 3 | [imh, imw, n1, n2] = size(inputdft); 4 | imsz = [imh, imw]; 5 | 6 | if any(desiredSize ~= imsz) 7 | minsz = min(imsz, desiredSize); 8 | 9 | scaling = prod(desiredSize)/prod(imsz); 10 | 11 | resizeddft = complex(zeros([desiredSize n1 n2], 'single')); 12 | 13 | mids = ceil(minsz/2); 14 | mide = floor((minsz-1)/2) - 1; 15 | 16 | resizeddft(1:mids(1), 1:mids(2), :, :) = scaling * inputdft(1:mids(1), 1:mids(2), :, :); 17 | resizeddft(1:mids(1), end - mide(2):end, :, :) = scaling * inputdft(1:mids(1), end - mide(2):end, :, :); 18 | resizeddft(end - mide(1):end, 1:mids(2), :, :) = scaling * inputdft(end - mide(1):end, 1:mids(2), :, :); 19 | resizeddft(end - mide(1):end, end - mide(2):end, :, :) = scaling * inputdft(end - mide(1):end, end - mide(2):end, :, :); 20 | else 21 | resizeddft = inputdft; 22 | end 23 | end -------------------------------------------------------------------------------- /utils/resp_newton.m: -------------------------------------------------------------------------------- 1 | function [disp_row, disp_col] = resp_newton(response, responsef, iterations, ky, kx, use_sz) 2 | 3 | [max_resp_row, max_row] = max(response, [], 1); 4 | [init_max_response, max_col] = max(max_resp_row, [], 2); 5 | max_row_perm = permute(max_row, [2 3 1]); 6 | col = max_col(:)'; 7 | row = max_row_perm(sub2ind(size(max_row_perm), col, 1:size(response,3))); 8 | 9 | trans_row = mod(row - 1 + floor((use_sz(1)-1)/2), use_sz(1)) - floor((use_sz(1)-1)/2); 10 | trans_col = mod(col - 1 + floor((use_sz(2)-1)/2), use_sz(2)) - floor((use_sz(2)-1)/2); 11 | init_pos_y = permute(2*pi * trans_row / use_sz(1), [1 3 2]); 12 | init_pos_x = permute(2*pi * trans_col / use_sz(2), [1 3 2]); 13 | max_pos_y = init_pos_y; 14 | max_pos_x = init_pos_x; 15 | 16 | % pre-compute complex exponential 17 | exp_iky = exp(bsxfun(@times, 1i * ky, max_pos_y)); 18 | exp_ikx = exp(bsxfun(@times, 1i * kx, max_pos_x)); 19 | 20 | % gradient_step_size = gradient_step_size / prod(use_sz); 21 | 22 | ky2 = ky.*ky; 23 | kx2 = kx.*kx; 24 | 25 | iter = 1; 26 | while iter <= iterations 27 | % Compute gradient 28 | ky_exp_ky = bsxfun(@times, ky, exp_iky); 29 | kx_exp_kx = bsxfun(@times, kx, exp_ikx); 30 | y_resp = mtimesx(exp_iky, responsef, 'speed'); 31 | resp_x = mtimesx(responsef, exp_ikx, 'speed'); 32 | grad_y = -imag(mtimesx(ky_exp_ky, resp_x, 'speed')); 33 | grad_x = -imag(mtimesx(y_resp, kx_exp_kx, 'speed')); 34 | ival = 1i * mtimesx(exp_iky, resp_x, 'speed'); 35 | H_yy = real(-mtimesx(bsxfun(@times, ky2, exp_iky), resp_x, 'speed') + ival); 36 | H_xx = real(-mtimesx(y_resp, bsxfun(@times, kx2, exp_ikx), 'speed') + ival); 37 | H_xy = real(-mtimesx(ky_exp_ky, mtimesx(responsef, kx_exp_kx, 'speed'), 'speed')); 38 | det_H = H_yy .* H_xx - H_xy .* H_xy; 39 | 40 | % Compute new position using newtons method 41 | max_pos_y = max_pos_y - (H_xx .* grad_y - H_xy .* grad_x) ./ det_H; 42 | max_pos_x = max_pos_x - (H_yy .* grad_x - H_xy .* grad_y) ./ det_H; 43 | 44 | % Evaluate maximum 45 | exp_iky = exp(bsxfun(@times, 1i * ky, max_pos_y)); 46 | exp_ikx = exp(bsxfun(@times, 1i * kx, max_pos_x)); 47 | 48 | iter = iter + 1; 49 | end 50 | max_response = 1 / prod(use_sz) * real(mtimesx(mtimesx(exp_iky, responsef, 'speed'), exp_ikx, 'speed')); 51 | 52 | % check for scales that have not increased in score 53 | ind = max_response < init_max_response; 54 | max_pos_y(ind) = init_pos_y(ind); 55 | max_pos_x(ind) = init_pos_x(ind); 56 | disp_row = (mod(max_pos_y(1,1,1) + pi, 2*pi) - pi) / (2*pi) * use_sz(1); 57 | disp_col = (mod(max_pos_x(1,1,1) + pi, 2*pi) - pi) / (2*pi) * use_sz(2); 58 | end -------------------------------------------------------------------------------- /utils/shift_sample.m: -------------------------------------------------------------------------------- 1 | function xf = shift_sample(xf, shift, kx, ky) 2 | 3 | % Shift a sample in the Fourier domain. The shift should be normalized to 4 | % the range [-pi, pi]. 5 | 6 | shift_exp_y =exp((1i * shift(1)) * ky); 7 | shift_exp_x = exp((1i * shift(2)) * kx); 8 | xf =bsxfun(@times, bsxfun(@times, xf, shift_exp_y), shift_exp_x); -------------------------------------------------------------------------------- /utils/table_lookup.m: -------------------------------------------------------------------------------- 1 | function out=table_lookup(im,table) 2 | 3 | if isa(im,'uint8') 4 | im = int32(im); 5 | end; 6 | 7 | [im_height, im_width, num_im_chan, num_images] = size(im); 8 | 9 | den = int32(8); 10 | fac = int32(32); 11 | offset = int32(1); 12 | 13 | if num_im_chan == 3 14 | RR=im(:,:,1,:);GG=im(:,:,2,:);BB=im(:,:,3,:); 15 | index_im = offset + idivide(RR,den) + fac*idivide(GG,den) + fac*fac*idivide(BB,den); 16 | out = permute(reshape(table(index_im(:),:), im_height, im_width, num_images, size(table,2)), [1 2 4 3]); 17 | else 18 | out = permute(reshape(table(im(:)+1,:), im_height, im_width, num_images, size(table,2)), [1 2 4 3]); 19 | end; 20 | --------------------------------------------------------------------------------