├── README.md ├── gmcpalgorithm.py ├── trackletdetections.csv ├── trackvideos └── video1.mp4 ├── voc-release4.01 ├── 000034.jpg ├── 000061.jpg ├── 000084.jpg ├── 0201.jpg ├── 0351.jpg ├── COPYING ├── HOGpicture.m ├── INRIA │ └── inriaperson_final.mat ├── Makefile ├── README ├── VOC2006 │ ├── bicycle_final.mat │ ├── bicycle_rescore_classifier.mat │ ├── bus_final.mat │ ├── bus_rescore_classifier.mat │ ├── car_final.mat │ ├── car_rescore_classifier.mat │ ├── cat_final.mat │ ├── cat_rescore_classifier.mat │ ├── cow_final.mat │ ├── cow_rescore_classifier.mat │ ├── dog_final.mat │ ├── dog_rescore_classifier.mat │ ├── horse_final.mat │ ├── horse_rescore_classifier.mat │ ├── motorbike_final.mat │ ├── motorbike_rescore_classifier.mat │ ├── person_final.mat │ ├── person_rescore_classifier.mat │ ├── sheep_final.mat │ └── sheep_rescore_classifier.mat ├── VOC2007 │ ├── aeroplane_final.mat │ ├── aeroplane_rescore_classifier.mat │ ├── bicycle_final.mat │ ├── bicycle_rescore_classifier.mat │ ├── bird_final.mat │ ├── bird_rescore_classifier.mat │ ├── boat_final.mat │ ├── boat_rescore_classifier.mat │ ├── bottle_final.mat │ ├── bottle_rescore_classifier.mat │ ├── bus_final.mat │ ├── bus_rescore_classifier.mat │ ├── car_final.mat │ ├── car_rescore_classifier.mat │ ├── cat_final.mat │ ├── cat_rescore_classifier.mat │ ├── chair_final.mat │ ├── chair_rescore_classifier.mat │ ├── cow_final.mat │ ├── cow_rescore_classifier.mat │ ├── diningtable_final.mat │ ├── diningtable_rescore_classifier.mat │ ├── dog_final.mat │ ├── dog_rescore_classifier.mat │ ├── horse_final.mat │ ├── horse_rescore_classifier.mat │ ├── motorbike_final.mat │ ├── motorbike_rescore_classifier.mat │ ├── person_final.mat │ ├── person_rescore_classifier.mat │ ├── pottedplant_final.mat │ ├── pottedplant_rescore_classifier.mat │ ├── sheep_final.mat │ ├── sheep_rescore_classifier.mat │ ├── sofa_final.mat │ ├── sofa_rescore_classifier.mat │ ├── train_final.mat │ ├── train_rescore_classifier.mat │ ├── tvmonitor_final.mat │ └── tvmonitor_rescore_classifier.mat ├── VOC2009 │ ├── aeroplane_final.mat │ ├── aeroplane_rescore_classifier.mat │ ├── bicycle_final.mat │ ├── bicycle_rescore_classifier.mat │ ├── bird_final.mat │ ├── bird_rescore_classifier.mat │ ├── boat_final.mat │ ├── boat_rescore_classifier.mat │ ├── bottle_final.mat │ ├── bottle_rescore_classifier.mat │ ├── bus_final.mat │ ├── bus_rescore_classifier.mat │ ├── car_final.mat │ ├── car_rescore_classifier.mat │ ├── cat_final.mat │ ├── cat_rescore_classifier.mat │ ├── chair_final.mat │ ├── chair_rescore_classifier.mat │ ├── cow_final.mat │ ├── cow_rescore_classifier.mat │ ├── diningtable_final.mat │ ├── diningtable_rescore_classifier.mat │ ├── dog_final.mat │ ├── dog_rescore_classifier.mat │ ├── horse_final.mat │ ├── horse_rescore_classifier.mat │ ├── motorbike_final.mat │ ├── motorbike_rescore_classifier.mat │ ├── person_final.mat │ ├── person_rescore_classifier.mat │ ├── pottedplant_final.mat │ ├── pottedplant_rescore_classifier.mat │ ├── sheep_final.mat │ ├── sheep_rescore_classifier.mat │ ├── sofa_final.mat │ ├── sofa_rescore_classifier.mat │ ├── train_final.mat │ ├── train_rescore_classifier.mat │ └── tvmonitor_final.mat ├── bboxpred_data.m ├── bboxpred_get.m ├── bboxpred_input.m ├── bboxpred_rescore.m ├── bboxpred_train.m ├── boxoverlap.m ├── changelog ├── clipboxes.m ├── color.m ├── compile.m ├── croppos.m ├── demo.m ├── documentation.txt ├── dt.cc ├── dt.mexmaci64 ├── fconv.cc ├── fconv.mexmaci64 ├── fconvMT.cc ├── fconvblas.cc ├── fconvblasMT.cc ├── fconvsse.cc ├── fconvsse.mexmaci64 ├── featpyramid.m ├── features.cc ├── features.mexmaci64 ├── flipfeat.m ├── foldHOG.m ├── frame_0168.jpg ├── gdetect.m ├── gdetectwrite.m ├── getcontextlabels.m ├── getdetections.cc ├── getdetections.mexmaci64 ├── getpadding.m ├── globals.m ├── imgdetect.m ├── imreadx.m ├── initmodel.m ├── initrand.m ├── labeldata.m ├── learn.cc ├── lrmodel.m ├── lrsplit.m ├── matlabengine.py ├── mergemodels.m ├── mkpartfilters.m ├── mlabtest.m ├── model_addblock.m ├── model_addfilter.m ├── model_addmirroredfilter.m ├── model_addnonterminal.m ├── model_addparts.m ├── model_addrule.m ├── model_addsymbol.m ├── model_create.m ├── model_setdetwindow.m ├── model_sort.m ├── nms.m ├── parsemodel.m ├── pascal.m ├── pascal_data.m ├── pascal_eval.m ├── pascal_init.m ├── pascal_test.m ├── pascal_train.m ├── persontest.m ├── process.m ├── procid.m ├── readinfo.m ├── readmodel.m ├── reduceboxes.m ├── release4-notes.pdf ├── rescore_data.m ├── rescore_labels.m ├── rescore_test.m ├── rescore_train.m ├── resize.cc ├── resize.mexmaci64 ├── rewritedat.m ├── rules_with_lhs.m ├── showboxes.m ├── split.m ├── subarray.m ├── train.m ├── trainval.m ├── visualizeHOG.m ├── visualizemodel.m ├── warppos.m ├── writecomponentinfo.m └── writeheader.m └── www ├── BebasNeue-webfont.woff ├── OpenSans-Light.eot ├── OpenSans-Light.svg ├── OpenSans-Light.ttf ├── OpenSans-Light.woff ├── css ├── simple-slider-volume.css └── simple-slider.css ├── drzamirface.jpg ├── gmcpweb.css ├── index.html ├── js ├── simple-slider.coffee ├── simple-slider.js └── simple-slider.min.js ├── parkinglot.mp4 ├── petsvideolarge.mp4 ├── sweetalert.css ├── sweetalert.min.js ├── tracklets2.jpg ├── tudcrossing.mp4 └── utkarshtandonimgface.jpg /README.md: -------------------------------------------------------------------------------- 1 | # GMCP-Tracker-Python-Implementation 2 | This human tracking algorithm is a Python implementation of the paper "GMCP-Tracker: Global Multi-object Tracking Using Generalized Minimum Clique Graphs". The algorithm attempts to solve the optimization problem of human tracking data association which in our methods minimizes motion and appearance cost in order to generate a tracklet of a human even if occlusion exists. 3 | 4 | Visit tracker website: http://cs.stanford.edu/~gmcp/ 5 | 6 | ## How to use: 7 | 1. Install necessary python imports 8 | 2. Run gmcpalgorithm.py 9 | 3. Edit www/index.html to match your IP address for HTTP post 10 | 4. Open www/index.html in browser 11 | 12 | Message utkarsh.tandon1@gmail.com if you have any questions. 13 | -------------------------------------------------------------------------------- /trackletdetections.csv: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /trackvideos/video1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/trackvideos/video1.mp4 -------------------------------------------------------------------------------- /voc-release4.01/000034.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/000034.jpg -------------------------------------------------------------------------------- /voc-release4.01/000061.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/000061.jpg -------------------------------------------------------------------------------- /voc-release4.01/000084.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/000084.jpg -------------------------------------------------------------------------------- /voc-release4.01/0201.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/0201.jpg -------------------------------------------------------------------------------- /voc-release4.01/0351.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/0351.jpg -------------------------------------------------------------------------------- /voc-release4.01/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2008, 2009, 2010 Pedro Felzenszwalb, Ross Girshick 2 | Copyright (C) 2007 Pedro Felzenszwalb, Deva Ramanan 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /voc-release4.01/HOGpicture.m: -------------------------------------------------------------------------------- 1 | function im = HOGpicture(w, bs) 2 | 3 | % HOGpicture(w, bs) 4 | % Make picture of positive HOG weights. 5 | 6 | % construct a "glyph" for each orientaion 7 | bim1 = zeros(bs, bs); 8 | bim1(:,round(bs/2):round(bs/2)+1) = 1; 9 | bim = zeros([size(bim1) 9]); 10 | bim(:,:,1) = bim1; 11 | for i = 2:9, 12 | bim(:,:,i) = imrotate(bim1, -(i-1)*20, 'crop'); 13 | end 14 | 15 | % make pictures of positive weights bs adding up weighted glyphs 16 | s = size(w); 17 | w(w < 0) = 0; 18 | im = zeros(bs*s(1), bs*s(2)); 19 | for i = 1:s(1), 20 | iis = (i-1)*bs+1:i*bs; 21 | for j = 1:s(2), 22 | jjs = (j-1)*bs+1:j*bs; 23 | for k = 1:9, 24 | im(iis,jjs) = im(iis,jjs) + bim(:,:,k) * w(i,j,k); 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /voc-release4.01/INRIA/inriaperson_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/INRIA/inriaperson_final.mat -------------------------------------------------------------------------------- /voc-release4.01/Makefile: -------------------------------------------------------------------------------- 1 | all: learn 2 | 3 | learn: learn.cc 4 | g++ -O3 -D_FILE_OFFSET_BITS=64 -o learn learn.cc 5 | 6 | clean: 7 | /bin/rm learn 8 | /bin/rm *.mex* 9 | -------------------------------------------------------------------------------- /voc-release4.01/README: -------------------------------------------------------------------------------- 1 | 2 | Information 3 | =========== 4 | 5 | Project webpage: http://www.cs.uchicago.edu/~pff/latent/. 6 | 7 | This is an implementation of our object detection system based on 8 | mixtures of deformable part models. The current implementation extends 9 | the system in [2] as described in [3]. The models in this implementation 10 | are structured using the grammar formalism presented in [4]. 11 | 12 | The distribution contains object detection and model learning code, as 13 | well as models trained on the PASCAL and INRIA Person datasets. This 14 | release also includes code for rescoring detections based on 15 | contextual information. 16 | 17 | The system is implemented in Matlab, with a few helper functions 18 | written in C/C++ for efficiency reasons. The software was tested on 19 | several versions of Linux and Mac OS X using Matlab versions R2009b 20 | and R2010a. There may be compatibility issues with other versions of 21 | Matlab. 22 | 23 | For questions concerning the code please contact Ross Girshick at 24 | . 25 | 26 | This project has been supported by the National Science Foundation under Grant 27 | No. 0534820, 0746569 and 0811340. 28 | 29 | 30 | References 31 | ========== 32 | 33 | [1] P. Felzenszwalb, D. McAllester, D. Ramaman. 34 | A Discriminatively Trained, Multiscale, Deformable Part Model. 35 | Proceedings of the IEEE CVPR 2008. 36 | 37 | [2] P. Felzenszwalb, R. Girshick, D. McAllester, D. Ramanan. Object 38 | Detection with Discriminatively Trained Part Based Models. 39 | To appear in the IEEE Transactions on Pattern Analysis and Machine 40 | Intelligence. 41 | 42 | [3] P. Felzenszwalb, R. Girshick, D. McAllester. 43 | release4-notes.pdf -- included in this code release. 44 | 45 | [4] P. Felzenszwalb, D. McAllester 46 | Object Detection Grammars 47 | University of Chicago, Computer Science TR-2010-02, February 2010 48 | 49 | 50 | How to Cite 51 | =========== 52 | When citing our system, please cite reference [2] and the website for 53 | the specific release. The website bibtex reference is below. 54 | 55 | @misc{voc-release4, 56 | author = "Felzenszwalb, P. F. and Girshick, R. B. and McAllester, D.", 57 | title = "Discriminatively Trained Deformable Part Models, Release 4", 58 | howpublished = "http://people.cs.uchicago.edu/~pff/latent-release4/"} 59 | 60 | 61 | Basic Usage 62 | =========== 63 | 64 | 1. Unpack the code. 65 | 2. Start matlab. 66 | 3. Run the 'compile' script to compile the helper functions. 67 | (you may need to edit compile.m to use a different convolution 68 | routine depending on your system) 69 | 4. Load a model and an image. 70 | 5. Use 'process' to detect objects. 71 | 72 | example: 73 | > load VOC2007/car_final.mat; % car model trained on the PASCAL 2007 dataset 74 | > im = imread('000034.jpg'); % test image 75 | > bbox = process(im, model, 0); % detect objects 76 | > showboxes(im, bbox); % display results 77 | 78 | The main functions defined in the object detection code are: 79 | 80 | boxes = imgdetect(im, model, thresh) % detect objects in image im 81 | bbox = bboxpred_get(model.bboxpred, dets, boxes) % bounding box location regression 82 | I = nms(bbox, overlap) % non-maximal suppression 83 | bbox = clipboxes(im, bbox) % clip boxes to image boundary 84 | showboxes(im, boxes) % visualize detections 85 | visualizemodel(model) % visualize models 86 | 87 | Their usage is demonstrated in the 'demo' script. 88 | 89 | The directories 'VOC200?' contain matlab datafiles with models trained 90 | on several PASCAL datasets (the train+val subsets). Loading one of 91 | these files from within matlab will define a variable 'model' with the 92 | model trained for a particular object category. The value 93 | 'model.thresh' defines a threshold that can be used in the 'detect' 94 | function to obtain a high recall rate. 95 | 96 | Using the learning code 97 | ======================= 98 | 99 | 1. Download and install the 2006/2007/2008 PASCAL VOC devkit and dataset. 100 | (you should set VOCopts.testset='test' in VOCinit.m) 101 | 2. Modify 'globals.m' according to your configuration. 102 | 3. Run 'make' to compile learn.cc, the LSVM gradient descent code. 103 | (Run from a shell, not Matlab.) 104 | 4. Start matlab. 105 | 5. Run the 'compile' script to compile the helper functions. 106 | (you may need to edit compile.m to use a different convolution 107 | routine depending on your system) 108 | 6. Use the 'pascal' script to train and evaluate a model. 109 | 110 | example: 111 | > pascal('person', 3); % train and evaluate a 6 component person model 112 | 113 | The learning code saves a number of intermediate files in a cache 114 | directory defined in 'globals.m'. You should delete these files before 115 | training models on different datasets, or when training new models after 116 | modifing the code. 117 | 118 | The code also generates some very large temporary files during training 119 | (the default configuration produces files up to about 3GB). They are 120 | placed in a temporary directory defined in 'globals.m'. This directory 121 | should be in a local filesystem. 122 | 123 | 124 | Context Rescoring 125 | ================= 126 | 127 | This release includes code for rescoring detections based on contextual 128 | information. Context rescoring is performed by class-specific SVMs. 129 | To train these SVMs, the following steps are required. 130 | 1) Models for all 20 PASCAL object classes must be trained. 131 | 2) Detections must be computed on the PASCAL trainval and test datasets. 132 | (The script trainval.m can be used for computing detections on the 133 | trainval dataset.) 134 | 3) The svm-mex MATLAB interface for SVM^light must be installed. It 135 | can be downloaded from http://sourceforge.net/projects/mex-svm/. 136 | (This in turn requires downloading SVM^light version *6.01*.) 137 | Place the 'svm_mex601' directory from the installation in this 138 | code directory. 139 | After these steps have been completed, the context rescoring SVMs 140 | can be trained by calling the function 'rescore_train()' in matlab. 141 | The detections on the test datasets, for all classes, can be rescored 142 | by calling the function 'rescore_test()' in matlab. 143 | 144 | example: 145 | > rescore_train() 146 | > rescore_test() 147 | 148 | 149 | Multicore Support 150 | ================= 151 | 152 | In addition to multithreaded convolutions (see notes in compile.m), 153 | multicore support is also available through the Matlab Parallel 154 | Computing Toolbox. Various loops (e.g., negative example data mining, 155 | positive latent labeling, and testing) are implemented using the 'parfor' 156 | parallel for-loop construct. To take advantage of the parfor loops, 157 | use the 'matlabpool' command. 158 | 159 | example: 160 | > matlabpool open 8 % start 8 parallel matlab instances 161 | 162 | The parfor loops work without any changes when running a single 163 | Matlab instance. Note that due to the use of parfor loops you may 164 | see non-sequential ordering of loop indexes in the terminal output when 165 | training and testing. This is expected behavior. The parallel computing 166 | toolbox has been tested on Linux using Matlab 2009b and 2010a. The OS 167 | X version of Matlab tends to crash when using the parallel computing 168 | toolbox. 169 | -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/bicycle_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/bicycle_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/bicycle_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/bicycle_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/bus_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/bus_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/bus_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/bus_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/car_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/car_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/car_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/car_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/cat_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/cat_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/cat_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/cat_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/cow_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/cow_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/cow_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/cow_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/dog_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/dog_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/dog_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/dog_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/horse_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/horse_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/horse_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/horse_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/motorbike_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/motorbike_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/motorbike_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/motorbike_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/person_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/person_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/person_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/person_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/sheep_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/sheep_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2006/sheep_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2006/sheep_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/aeroplane_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/aeroplane_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/aeroplane_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/aeroplane_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/bicycle_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/bicycle_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/bicycle_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/bicycle_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/bird_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/bird_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/bird_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/bird_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/boat_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/boat_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/boat_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/boat_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/bottle_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/bottle_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/bottle_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/bottle_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/bus_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/bus_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/bus_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/bus_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/car_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/car_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/car_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/car_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/cat_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/cat_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/cat_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/cat_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/chair_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/chair_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/chair_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/chair_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/cow_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/cow_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/cow_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/cow_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/diningtable_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/diningtable_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/diningtable_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/diningtable_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/dog_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/dog_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/dog_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/dog_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/horse_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/horse_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/horse_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/horse_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/motorbike_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/motorbike_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/motorbike_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/motorbike_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/person_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/person_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/person_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/person_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/pottedplant_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/pottedplant_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/pottedplant_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/pottedplant_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/sheep_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/sheep_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/sheep_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/sheep_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/sofa_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/sofa_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/sofa_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/sofa_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/train_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/train_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/train_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/train_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/tvmonitor_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/tvmonitor_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2007/tvmonitor_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2007/tvmonitor_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/aeroplane_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/aeroplane_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/aeroplane_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/aeroplane_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/bicycle_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/bicycle_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/bicycle_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/bicycle_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/bird_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/bird_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/bird_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/bird_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/boat_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/boat_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/boat_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/boat_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/bottle_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/bottle_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/bottle_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/bottle_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/bus_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/bus_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/bus_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/bus_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/car_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/car_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/car_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/car_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/cat_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/cat_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/cat_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/cat_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/chair_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/chair_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/chair_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/chair_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/cow_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/cow_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/cow_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/cow_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/diningtable_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/diningtable_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/diningtable_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/diningtable_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/dog_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/dog_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/dog_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/dog_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/horse_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/horse_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/horse_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/horse_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/motorbike_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/motorbike_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/motorbike_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/motorbike_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/person_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/person_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/person_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/person_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/pottedplant_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/pottedplant_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/pottedplant_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/pottedplant_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/sheep_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/sheep_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/sheep_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/sheep_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/sofa_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/sofa_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/sofa_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/sofa_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/train_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/train_final.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/train_rescore_classifier.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/train_rescore_classifier.mat -------------------------------------------------------------------------------- /voc-release4.01/VOC2009/tvmonitor_final.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/VOC2009/tvmonitor_final.mat -------------------------------------------------------------------------------- /voc-release4.01/bboxpred_data.m: -------------------------------------------------------------------------------- 1 | function [dets, boxes, targets] = bboxpred_data(name) 2 | % Collect training data for bounding box prediction. 3 | % 4 | % name class name 5 | 6 | globals; 7 | 8 | try 9 | load([cachedir name '_bboxdata']); 10 | catch 11 | % load final model for class 12 | load([cachedir name '_final']); 13 | % get training data 14 | [pos,neg] = pascal_data(model.class, true, model.year); 15 | 16 | numpos = length(pos); 17 | model.interval = 5; 18 | pixels = model.minsize * model.sbin; 19 | minsize = prod(pixels); 20 | nrules = length(model.rules{model.start}); 21 | parb = cell(1,numpos); 22 | part = cell(1,numpos); 23 | 24 | % compute latent filter locations and record target bounding boxes 25 | parfor i = 1:numpos 26 | pard{i} = cell(1,nrules); 27 | parb{i} = cell(1,nrules); 28 | part{i} = cell(1,nrules); 29 | fprintf('%s %s: bboxdata: %d/%d\n', procid(), name, i, numpos); 30 | bbox = [pos(i).x1 pos(i).y1 pos(i).x2 pos(i).y2]; 31 | % skip small examples 32 | if (bbox(3)-bbox(1)+1)*(bbox(4)-bbox(2)+1) < minsize 33 | continue; 34 | end 35 | % get example 36 | im = imreadx(pos(i)); 37 | [im, bbox] = croppos(im, bbox); 38 | [det, boxes] = imgdetect(im, model, 0, bbox, 0.7); 39 | if ~isempty(det) 40 | % component index 41 | c = det(1,end-1); 42 | boxes = reduceboxes(model, boxes); 43 | det = clipboxes(im, det); 44 | pard{i}{c} = [pard{i}{c}; det(:,1:end-2)]; 45 | parb{i}{c} = [parb{i}{c}; boxes(:,1:end-2)]; 46 | part{i}{c} = [part{i}{c}; bbox]; 47 | %showboxes(im, box); 48 | end 49 | end 50 | dets = cell(1,nrules); 51 | boxes = cell(1,nrules); 52 | targets = cell(1,nrules); 53 | for i = 1:numpos 54 | for c = 1:nrules 55 | dets{c} = [dets{c}; pard{i}{c}]; 56 | boxes{c} = [boxes{c}; parb{i}{c}]; 57 | targets{c} = [targets{c}; part{i}{c}]; 58 | end 59 | end 60 | save([cachedir name '_bboxdata'], 'dets', 'boxes', 'targets'); 61 | end 62 | -------------------------------------------------------------------------------- /voc-release4.01/bboxpred_get.m: -------------------------------------------------------------------------------- 1 | function [bbox parts] = bboxpred_get(bboxpred, dets, boxes) 2 | % Get predicted bounding boxes. 3 | % 4 | % bboxpred saved bounding box prediction coefficients 5 | % dets source detection windows 6 | % boxes source filter bounding boxes 7 | 8 | bbox = []; 9 | parts = []; 10 | % number of components 11 | maxc = max(boxes(:,end-1)); 12 | for c = 1:maxc 13 | % limit boxes to just component c 14 | cinds = find(boxes(:,end-1) == c); 15 | b = boxes(cinds,:); 16 | d = dets(cinds,:); 17 | if isempty(b) 18 | continue; 19 | end 20 | % build test data 21 | [A x1 y1 x2 y2 w h] = bboxpred_input(d, b(:,1:end-2)); 22 | % predict displacements 23 | dx1 = A*bboxpred{c}.x1; 24 | dy1 = A*bboxpred{c}.y1; 25 | dx2 = A*bboxpred{c}.x2; 26 | dy2 = A*bboxpred{c}.y2; 27 | 28 | % compute object location from predicted displacements 29 | tmp = [x1 + (w.*dx1) ... 30 | y1 + (h.*dy1) ... 31 | x2 + (w.*dx2) ... 32 | y2 + (h.*dy2) ... 33 | b(:, end)]; 34 | bbox = [bbox; tmp]; 35 | parts = [parts; b]; 36 | end 37 | -------------------------------------------------------------------------------- /voc-release4.01/bboxpred_input.m: -------------------------------------------------------------------------------- 1 | function [A x1 y1 x2 y2 w h] = bboxpred_input(dets, boxes) 2 | % Prepare input for the bbox predictor from detections dets 3 | % and filter bounding boxes boxes. 4 | % 5 | % dets detection window coordinates 6 | % boxes coordinates for each filter placed in the detection 7 | 8 | % detection windows' coordinates 9 | x1 = dets(:,1); 10 | x2 = dets(:,3); 11 | y1 = dets(:,2); 12 | y2 = dets(:,4); 13 | % detection windows' widths and heights 14 | w = x2 - x1; 15 | h = y2 - y1; 16 | % detection windows' centers 17 | rx = x1 + w/2; 18 | ry = y1 + h/2; 19 | 20 | A = []; 21 | for j = 1:4:size(boxes, 2) 22 | % filters' centers 23 | px = boxes(:,j) + (boxes(:,j+2) - boxes(:,j))/2; 24 | py = boxes(:,j+1) + (boxes(:,j+3) - boxes(:,j+1))/2; 25 | A = [A ... 26 | (px-rx)./w ... 27 | (py-ry)./h ... 28 | ]; 29 | end 30 | % add bias feature 31 | A = [A ones(size(boxes,1),1)]; 32 | -------------------------------------------------------------------------------- /voc-release4.01/bboxpred_rescore.m: -------------------------------------------------------------------------------- 1 | function [ap, newap] = bboxpred_rescore(name, testset, year, method) 2 | % Recompute score on testset using bounding box prediction. 3 | % 4 | % name class name 5 | % testset test set name 6 | % year dataset year 7 | % method regression method 8 | 9 | if nargin < 4 10 | method = 'default'; 11 | end 12 | 13 | setVOCyear = year; 14 | globals; 15 | pascal_init; 16 | 17 | try 18 | load([cachedir name '_final']); 19 | if ~isempty(model.bboxpred) 20 | bboxpred = model.bboxpred; 21 | end 22 | catch 23 | model = bboxpred_train(name, year, method); 24 | bboxpred = model.bboxpred; 25 | end 26 | 27 | % load test boxes (loads vars: boxes1, parts1) 28 | load([cachedir name '_boxes_' testset '_' year]); 29 | 30 | ids = textread(sprintf(VOCopts.imgsetpath, testset), '%s'); 31 | newboxes = cell(length(parts1),1); 32 | newparts = cell(length(parts1),1); 33 | for i = 1:length(parts1) 34 | fprintf('%s %s: bbox rescoring %s: %d/%d\n', procid(), name, testset, i, length(parts1)); 35 | if isempty(parts1{i}) 36 | continue; 37 | end 38 | [bbox parts] = bboxpred_get(bboxpred, boxes1{i}, parts1{i}); 39 | if strcmp('inriaperson', name) 40 | % INRIA uses a mixutre of PNGs and JPGs, so we need to use the annotation 41 | % to locate the image. The annotation is not generally available for PASCAL 42 | % test data (e.g., 2009 test), so this method can fail for PASCAL. 43 | rec = PASreadrecord(sprintf(VOCopts.annopath, ids{i})); 44 | im = imread([VOCopts.datadir rec.imgname]); 45 | else 46 | im = imread(sprintf(VOCopts.imgpath, ids{i})); 47 | end 48 | % clip to image boundary and apply NMS 49 | [bbox parts] = clipboxes(im, bbox, parts); 50 | I = nms(bbox, 0.5); 51 | newboxes{i} = bbox(I,:); 52 | newparts{i} = parts(I,:); 53 | end 54 | 55 | % save modified boxes 56 | boxes1 = newboxes; 57 | parts1 = newparts; 58 | save([cachedir name '_boxes_' testset '_bboxpred_' year], 'boxes1', 'parts1'); 59 | 60 | if str2num(year) < 2008 61 | % load old ap 62 | load([cachedir name '_pr_' testset '_' year]); 63 | newap = pascal_eval(name, newboxes, testset, year, ['bboxpred_' method '_' year]); 64 | else 65 | ap = 0; 66 | newap = 0; 67 | end 68 | -------------------------------------------------------------------------------- /voc-release4.01/bboxpred_train.m: -------------------------------------------------------------------------------- 1 | function model = bboxpred_train(name, year, method) 2 | % Train a bounding box predictor. 3 | % 4 | % name class name 5 | % year dataset year 6 | % method regression method (default is LS regression) 7 | 8 | if nargin < 3 9 | method = 'default'; 10 | end 11 | 12 | setVOCyear = year; 13 | globals; 14 | pascal_init; 15 | 16 | % load final model for class 17 | load([cachedir name '_final']); 18 | 19 | try 20 | % test to see if the bbox predictor was already trained 21 | bboxpred = model.bboxpred; 22 | catch 23 | % get training data 24 | [traindets, trainboxes, targets] = bboxpred_data(name); 25 | % train bbox predictor 26 | fprintf('%s %s: bbox predictor training...', procid(), name); 27 | nrules = length(model.rules{model.start}); 28 | bboxpred = cell(nrules, 1); 29 | for c = 1:nrules 30 | [A x1 y1 x2 y2 w h] = bboxpred_input(traindets{c}, trainboxes{c}); 31 | bboxpred{c}.x1 = getcoeffs(method, A, (targets{c}(:,1)-x1)./w); 32 | bboxpred{c}.y1 = getcoeffs(method, A, (targets{c}(:,2)-y1)./h); 33 | bboxpred{c}.x2 = getcoeffs(method, A, (targets{c}(:,3)-x2)./w); 34 | bboxpred{c}.y2 = getcoeffs(method, A, (targets{c}(:,4)-y2)./h); 35 | end 36 | fprintf('done\n'); 37 | % save bbox predictor coefficients in the model 38 | model.bboxpred = bboxpred; 39 | save([cachedir name '_final'], 'model'); 40 | end 41 | 42 | 43 | function beta = getcoeffs(method, X, y) 44 | switch lower(method) 45 | case 'default' 46 | % matlab's magic box of matrix inversion tricks 47 | beta = X\y; 48 | case 'minl2' 49 | % regularized LS regression 50 | lambda = 0.01; 51 | Xr = X'*X + eye(size(X,2))*lambda; 52 | iXr = inv(Xr); 53 | beta = iXr * (X'*y); 54 | case 'minl1' 55 | % require code from http://www.stanford.edu/~boyd/l1_ls/ 56 | addpath('l1_ls_matlab'); 57 | lambda = 0.01; 58 | rel_tol = 0.01; 59 | beta = l1_ls(X, y, lambda, rel_tol, true); 60 | case 'rtls' 61 | beta = rtlsqepslow(X, y, eye(size(X,2)), 0.2) 62 | otherwise 63 | error('unknown method'); 64 | end 65 | -------------------------------------------------------------------------------- /voc-release4.01/boxoverlap.m: -------------------------------------------------------------------------------- 1 | function o = boxoverlap(a, b) 2 | 3 | % Compute the symmetric intersection over union overlap between a set of 4 | % bounding boxes in a and a single bounding box in b. 5 | % 6 | % a a matrix where each row specifies a bounding box 7 | % b a single bounding box 8 | 9 | x1 = max(a(:,1), b(1)); 10 | y1 = max(a(:,2), b(2)); 11 | x2 = min(a(:,3), b(3)); 12 | y2 = min(a(:,4), b(4)); 13 | 14 | w = x2-x1+1; 15 | h = y2-y1+1; 16 | inter = w.*h; 17 | aarea = (a(:,3)-a(:,1)+1) .* (a(:,4)-a(:,2)+1); 18 | barea = (b(3)-b(1)+1) * (b(4)-b(2)+1); 19 | % intersection over union overlap 20 | o = inter ./ (aarea+barea-inter); 21 | % set invalid entries to 0 overlap 22 | o(w <= 0) = 0; 23 | o(h <= 0) = 0; 24 | -------------------------------------------------------------------------------- /voc-release4.01/changelog: -------------------------------------------------------------------------------- 1 | voc-release4.01 (11/23/11) 2 | --- 3 | Fixed a runtime performance bug when using fconvblas.cc as the convolution 4 | routine with MATLAB >= 2010b on Intel CPUs. 5 | 6 | The default convolution routine now uses SSE optimized code (fconvsse.cc). 7 | -------------------------------------------------------------------------------- /voc-release4.01/clipboxes.m: -------------------------------------------------------------------------------- 1 | function [dets, parts] = clipboxes(im, dets, parts) 2 | 3 | % [dets parts] = clipboxes(im, dets, parts) 4 | % Clips detection windows to image boundary. 5 | % Removes detections that are outside of the image. 6 | 7 | if nargin < 3 8 | parts = []; 9 | end 10 | 11 | if ~isempty(dets) 12 | dets(:,1) = max(dets(:,1), 1); 13 | dets(:,2) = max(dets(:,2), 1); 14 | dets(:,3) = min(dets(:,3), size(im, 2)); 15 | dets(:,4) = min(dets(:,4), size(im, 1)); 16 | 17 | % remove invalid detections 18 | w = dets(:,3)-dets(:,1)+1; 19 | h = dets(:,4)-dets(:,2)+1; 20 | I = find((w <= 0) | (h <= 0)); 21 | dets(I,:) = []; 22 | if ~isempty(parts) 23 | parts(I,:) = []; 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /voc-release4.01/color.m: -------------------------------------------------------------------------------- 1 | function im = color(input) 2 | 3 | % im = color(input) 4 | % Convert input image to color. 5 | 6 | if size(input, 3) == 1 7 | im(:,:,1) = input; 8 | im(:,:,2) = input; 9 | im(:,:,3) = input; 10 | else 11 | im = input; 12 | end 13 | -------------------------------------------------------------------------------- /voc-release4.01/compile.m: -------------------------------------------------------------------------------- 1 | mex -O resize.cc 2 | mex -O dt.cc 3 | mex -O features.cc 4 | mex -O getdetections.cc 5 | 6 | % use one of the following depending on your setup 7 | % 0 is fastest, 3 is slowest 8 | 9 | % 0) multithreaded convolution using SSE 10 | mex -O fconvsse.cc -output fconv 11 | 12 | % 1) multithreaded convolution using blas 13 | % WARNING: the blas version does not work with matlab >= 2010b 14 | % and Intel CPUs 15 | % mex -O fconvblasMT.cc -lmwblas -o fconv 16 | 17 | % 2) mulththreaded convolution without blas 18 | % mex -O fconvMT.cc -o fconv 19 | 20 | % 3) convolution using blas 21 | % mex -O fconvblas.cc -lmwblas -o fconv 22 | 23 | % 4) basic convolution, very compatible 24 | % mex -O fconv.cc -o fconv 25 | -------------------------------------------------------------------------------- /voc-release4.01/croppos.m: -------------------------------------------------------------------------------- 1 | function [im, box] = croppos(im, box) 2 | 3 | % [newim, newbox] = croppos(im, box) 4 | % Crop positive example to speed up latent search. 5 | 6 | % crop image around bounding box 7 | %pad = 0.5*((box(3)-box(1)+1)+(box(4)-box(2)+1)); 8 | %padx = pad; 9 | %pady = pad; 10 | padx = 0.5*(box(3)-box(1)+1); 11 | pady = 0.5*(box(4)-box(2)+1); 12 | x1 = max(1, round(box(1) - padx)); 13 | y1 = max(1, round(box(2) - pady)); 14 | x2 = min(size(im, 2), round(box(3) + padx)); 15 | y2 = min(size(im, 1), round(box(4) + pady)); 16 | 17 | im = im(y1:y2, x1:x2, :); 18 | box([1 3]) = box([1 3]) - x1 + 1; 19 | box([2 4]) = box([2 4]) - y1 + 1; 20 | -------------------------------------------------------------------------------- /voc-release4.01/demo.m: -------------------------------------------------------------------------------- 1 | function demo() 2 | 3 | load('VOC2007/car_final'); 4 | test('000034.jpg', model); 5 | 6 | load('INRIA/inriaperson_final'); 7 | test('000061.jpg', model); 8 | 9 | load('VOC2007/bicycle_final'); 10 | test('000084.jpg', model); 11 | 12 | function test(name, model) 13 | cls = model.class; 14 | % load and display image 15 | im = imread(name); 16 | clf; 17 | image(im); 18 | axis equal; 19 | axis on; 20 | disp('input image'); 21 | disp('press any key to continue'); pause; 22 | disp('continuing...'); 23 | 24 | % load and display model 25 | visualizemodel(model, 1:2:length(model.rules{model.start})); 26 | disp([cls ' model visualization']); 27 | disp('press any key to continue'); pause; 28 | disp('continuing...'); 29 | 30 | % detect objects 31 | [dets, boxes] = imgdetect(im, model, -0.3); 32 | top = nms(dets, 0.5); 33 | clf; 34 | showboxes(im, reduceboxes(model, boxes(top,:))); 35 | disp('detections'); 36 | disp('press any key to continue'); pause; 37 | disp('continuing...'); 38 | 39 | % get bounding boxes 40 | bbox = bboxpred_get(model.bboxpred, dets, reduceboxes(model, boxes)); 41 | bbox = clipboxes(im, bbox); 42 | top = nms(bbox, 0.5); 43 | clf; 44 | showboxes(im, bbox(top,:)); 45 | disp('bounding boxes'); 46 | disp('press any key to continue'); pause; 47 | -------------------------------------------------------------------------------- /voc-release4.01/documentation.txt: -------------------------------------------------------------------------------- 1 | Weight vector documentation 2 | =========================== 3 | 4 | The model parameters are encoded in a weight vector that is updated 5 | by a stochastic gradient descent procedure. The mapping from indexes 6 | in the weight vector to pieces of the object model (e.g., filters, 7 | deformation models, rule offests, ...) is done through 'blocklabels'. 8 | 9 | The weight vector is composed of contiguous blocks of parameters. 10 | Each block holds a related set of weights. A blocklabel is an index 11 | into the list of blocks that comprise the weight vector. For example 12 | the weight vector w = (w_1, w_2, ..., w_30) has 30 blocks, and a part 13 | filter for a model might be stored in w_12 (blocklabel = 12). 14 | 15 | The block layout of the weight vectors allows feature vectors to be 16 | stored in a sparse format where only the non-zero blocks are written. 17 | Likewise, learn.cc takes advantage of the sparse representation when 18 | computing dot products. 19 | 20 | 21 | Model format documentation 22 | ========================== 23 | 24 | This document describes how the model format has changed relative 25 | to the format used in the previous release. The new model format 26 | supports describing object models in terms of acyclic grammars. 27 | 28 | At the top level, the model structure has the following new fields: 29 | 30 | filters: [1x42 struct] 31 | rules: {1x81 cell} 32 | symbols: [1x81 struct] 33 | start: 2 34 | 35 | (Fields are shown with example values for the purpose of explaining 36 | their usage.) 37 | 38 | I'll go through each of these fields starting with the symbols struct array. 39 | 40 | model.symbols(i) = 41 | 42 | type: 'T' 43 | filter: 3 44 | 45 | The grammar is built out of symbols. Each symbol is labeled by a number 46 | (which will be synonymous with the word "symbol") and has a type: 'T' => 47 | terminal; 'N' => non-terminal. Each terminal corresponds to exactly one 48 | filter. In this case, the filter field is used to hold the filter's index. 49 | For non-terminal symbols, the filter field is empty. Since we're talking 50 | about filters, let's look at the filter struct array next. 51 | 52 | model.filters{i} = 53 | 54 | w: [7x11x31 double] 55 | blocklabel: 1 56 | symmetric: 'M' 57 | size: [7 11] 58 | flip: 0 59 | symbol: 1 60 | 61 | As expected, each entry holds the filter weights and the blocklabel. 62 | The symmetric field can be either: 'M' => has a vertically mirrored 63 | partner or 'N' => no symmetry constraint. If a filter has symmetric == 64 | 'M', then there will be two filters that share the same blocklabel. 65 | The flip field is used to indicate if the weights read from a model 66 | block should be flipped to form the filter (and likewise, if features 67 | written to the cache should be flipped). The symbol field is simply a 68 | reference back to the terminal symbol that uses the filter. 69 | 70 | Now let's look at model.rules. This cell array holds the grammar's 71 | productions. Each symbol has a (possibly empty) cell in model.rules. The 72 | cell model.rules{i} holds an array struct that lists the rules for which i 73 | acts as the left-hand side symbol. So, model.rules{4}(1) and 74 | model.rules{4}(2) are the first two productions for symbol 4 in some 75 | imaginary grammar. The field model.start holds the distinguished start 76 | symbol for the grammar. Let's use that symbol as an example. 77 | 78 | model.rules{model.start}(1) = 79 | 80 | type: 'S' 81 | lhs: 2 82 | rhs: [1 11 15 19 23 27 31] 83 | offset: { w: -3.394 blocklabel: 2 } 84 | anchor: {[0 0 0] [12 0 1] [4 5 1] [13 8 1] [0 0 1] [16 0 1] [0 5 1]} 85 | 86 | Here is the first rule with model.start on the LHS. In the case of a 6 87 | component mixture model, model.rules{model.start} is a struct array of 6 88 | elements. The field lhs is simply a convenience field indicating what the 89 | production's LHS is. The field rhs holds the symbols that appear on the 90 | production's right-hand side. The field type is 'S' if this is a structural 91 | rule or 'D' if this is a deformation rule. Now I'll split the description 92 | into two cases. 93 | 94 | case 1: structural rule 95 | 96 | The field offset holds the offset value and its blocklabel (these will be 97 | shared for mirrored components). The anchor field holds the parameters of 98 | the "structure function" that defines how each of the symbols in the rhs is 99 | placed relative to a placement of the lhs symbol. The format is [dx dy ds], 100 | where 2^ds is the scale change. So ds = 1 implies that the rhs symbol 101 | lives at twice resolution of the lhs symbol. The values of dx, dy are HOG 102 | cell displacements at the rhs's native scale. Note that dx and dy are 103 | displacements, so they are 1 less than the anchor values that were defined 104 | in the old model. The first symbol on the rhs has anchor = [0 0 0], 105 | because this symbol is a terminal for the root filter. 106 | 107 | case 2: deformation rule 108 | 109 | Let's look at the second symbol on the rhs in the rule above. 110 | 111 | model.rules{11} = 112 | 113 | type: 'D' 114 | lhs: 11 115 | rhs: 10 116 | def: { 117 | w: [0.0209 -0.0015 0.0155 0.0010] 118 | blocklabel: 8 119 | flip: 0 120 | symmetric: 'M' 121 | } 122 | offset: { w: 0 blocklabel: 7 } 123 | 124 | Deformation rules don't have an anchor field, but do have a def field. The 125 | def field describes the deformation model for this rule, and so it includes 126 | the coefficients and the blocklabel. The def.symmetric field can be 'M' if 127 | there is a vertically mirrored deformation rule or 'N' if there is no 128 | symmetry constraint. In the case of 'M', flip indicates how to write 129 | features and read models (just like features.flip). There's an implicit 130 | assumption in the code that deformation rules only have one symbol on the 131 | right-hand side (though it need not be a terminal). 132 | -------------------------------------------------------------------------------- /voc-release4.01/dt.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "mex.h" 4 | 5 | /* 6 | * Generalized distance transforms. 7 | * We use a simple nlog(n) divide and conquer algorithm instead of the 8 | * theoretically faster linear method, for no particular reason except 9 | * that this is a bit simpler and I wanted to test it out. 10 | * 11 | * The code is a bit convoluted because dt1d can operate either along 12 | * a row or column of an array. 13 | */ 14 | 15 | static inline int square(int x) { return x*x; } 16 | 17 | // dt helper function 18 | void dt_helper(double *src, double *dst, int *ptr, int step, 19 | int s1, int s2, int d1, int d2, double a, double b) { 20 | if (d2 >= d1) { 21 | int d = (d1+d2) >> 1; 22 | int s = s1; 23 | for (int p = s1+1; p <= s2; p++) 24 | if (src[s*step] - a*square(d-s) - b*(d-s) < 25 | src[p*step] - a*square(d-p) - b*(d-p)) 26 | s = p; 27 | dst[d*step] = src[s*step] - a*square(d-s) - b*(d-s); 28 | ptr[d*step] = s; 29 | dt_helper(src, dst, ptr, step, s1, s, d1, d-1, a, b); 30 | dt_helper(src, dst, ptr, step, s, s2, d+1, d2, a, b); 31 | } 32 | } 33 | 34 | // dt of 1d array 35 | void dt1d(double *src, double *dst, int *ptr, int step, int n, 36 | double a, double b) { 37 | dt_helper(src, dst, ptr, step, 0, n-1, 0, n-1, a, b); 38 | } 39 | 40 | // matlab entry point 41 | // [M, Ix, Iy] = dt(vals, ax, bx, ay, by) 42 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 43 | if (nrhs != 5) 44 | mexErrMsgTxt("Wrong number of inputs"); 45 | if (nlhs != 3) 46 | mexErrMsgTxt("Wrong number of outputs"); 47 | if (mxGetClassID(prhs[0]) != mxDOUBLE_CLASS) 48 | mexErrMsgTxt("Invalid input"); 49 | 50 | const int *dims = mxGetDimensions(prhs[0]); 51 | double *vals = (double *)mxGetPr(prhs[0]); 52 | double ax = mxGetScalar(prhs[1]); 53 | double bx = mxGetScalar(prhs[2]); 54 | double ay = mxGetScalar(prhs[3]); 55 | double by = mxGetScalar(prhs[4]); 56 | 57 | mxArray *mxM = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); 58 | mxArray *mxIx = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL); 59 | mxArray *mxIy = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL); 60 | double *M = (double *)mxGetPr(mxM); 61 | int32_t *Ix = (int32_t *)mxGetPr(mxIx); 62 | int32_t *Iy = (int32_t *)mxGetPr(mxIy); 63 | 64 | double *tmpM = (double *)mxCalloc(dims[0]*dims[1], sizeof(double)); 65 | int32_t *tmpIx = (int32_t *)mxCalloc(dims[0]*dims[1], sizeof(int32_t)); 66 | int32_t *tmpIy = (int32_t *)mxCalloc(dims[0]*dims[1], sizeof(int32_t)); 67 | 68 | for (int x = 0; x < dims[1]; x++) 69 | dt1d(vals+x*dims[0], tmpM+x*dims[0], tmpIy+x*dims[0], 1, dims[0], ay, by); 70 | 71 | for (int y = 0; y < dims[0]; y++) 72 | dt1d(tmpM+y, M+y, tmpIx+y, dims[0], dims[1], ax, bx); 73 | 74 | // get argmins and adjust for matlab indexing from 1 75 | for (int x = 0; x < dims[1]; x++) { 76 | for (int y = 0; y < dims[0]; y++) { 77 | int p = x*dims[0]+y; 78 | Ix[p] = tmpIx[p]+1; 79 | Iy[p] = tmpIy[tmpIx[p]*dims[0]+y]+1; 80 | } 81 | } 82 | 83 | mxFree(tmpM); 84 | mxFree(tmpIx); 85 | mxFree(tmpIy); 86 | plhs[0] = mxM; 87 | plhs[1] = mxIx; 88 | plhs[2] = mxIy; 89 | } 90 | -------------------------------------------------------------------------------- /voc-release4.01/dt.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/dt.mexmaci64 -------------------------------------------------------------------------------- /voc-release4.01/fconv.cc: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #include 3 | #include 4 | 5 | /* 6 | * This code is used for computing filter responses. It computes the 7 | * response of a set of filters with a feature map. 8 | * 9 | * Basic version, relatively slow but very compatible. 10 | */ 11 | 12 | struct thread_data { 13 | double *A; 14 | double *B; 15 | double *C; 16 | mxArray *mxC; 17 | const mwSize *A_dims; 18 | const mwSize *B_dims; 19 | mwSize C_dims[2]; 20 | }; 21 | 22 | // convolve A and B 23 | void *process(void *thread_arg) { 24 | thread_data *args = (thread_data *)thread_arg; 25 | double *A = args->A; 26 | double *B = args->B; 27 | double *C = args->C; 28 | const mwSize *A_dims = args->A_dims; 29 | const mwSize *B_dims = args->B_dims; 30 | const mwSize *C_dims = args->C_dims; 31 | int num_features = args->A_dims[2]; 32 | 33 | for (int f = 0; f < num_features; f++) { 34 | double *dst = C; 35 | double *A_src = A + f*A_dims[0]*A_dims[1]; 36 | double *B_src = B + f*B_dims[0]*B_dims[1]; 37 | for (int x = 0; x < C_dims[1]; x++) { 38 | for (int y = 0; y < C_dims[0]; y++) { 39 | double val = 0; 40 | for (int xp = 0; xp < B_dims[1]; xp++) { 41 | double *A_off = A_src + (x+xp)*A_dims[0] + y; 42 | double *B_off = B_src + xp*B_dims[0]; 43 | switch(B_dims[0]) { 44 | case 20: val += A_off[19] * B_off[19]; 45 | case 19: val += A_off[18] * B_off[18]; 46 | case 18: val += A_off[17] * B_off[17]; 47 | case 17: val += A_off[16] * B_off[16]; 48 | case 16: val += A_off[15] * B_off[15]; 49 | case 15: val += A_off[14] * B_off[14]; 50 | case 14: val += A_off[13] * B_off[13]; 51 | case 13: val += A_off[12] * B_off[12]; 52 | case 12: val += A_off[11] * B_off[11]; 53 | case 11: val += A_off[10] * B_off[10]; 54 | case 10: val += A_off[9] * B_off[9]; 55 | case 9: val += A_off[8] * B_off[8]; 56 | case 8: val += A_off[7] * B_off[7]; 57 | case 7: val += A_off[6] * B_off[6]; 58 | case 6: val += A_off[5] * B_off[5]; 59 | case 5: val += A_off[4] * B_off[4]; 60 | case 4: val += A_off[3] * B_off[3]; 61 | case 3: val += A_off[2] * B_off[2]; 62 | case 2: val += A_off[1] * B_off[1]; 63 | case 1: val += A_off[0] * B_off[0]; 64 | break; 65 | default: 66 | for (int yp = 0; yp < B_dims[0]; yp++) { 67 | val += *(A_off++) * *(B_off++); 68 | } 69 | } 70 | } 71 | *(dst++) += val; 72 | } 73 | } 74 | } 75 | } 76 | 77 | // matlab entry point 78 | // C = fconv(A, cell of B, start, end); 79 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 80 | if (nrhs != 4) 81 | mexErrMsgTxt("Wrong number of inputs"); 82 | if (nlhs != 1) 83 | mexErrMsgTxt("Wrong number of outputs"); 84 | 85 | // get A 86 | const mxArray *mxA = prhs[0]; 87 | if (mxGetNumberOfDimensions(mxA) != 3 || 88 | mxGetClassID(mxA) != mxDOUBLE_CLASS) 89 | mexErrMsgTxt("Invalid input: A"); 90 | 91 | // get B and start/end 92 | const mxArray *cellB = prhs[1]; 93 | mwSize num_bs = mxGetNumberOfElements(cellB); 94 | int start = (int)mxGetScalar(prhs[2]) - 1; 95 | int end = (int)mxGetScalar(prhs[3]) - 1; 96 | if (start < 0 || end >= num_bs || start > end) 97 | mexErrMsgTxt("Invalid input: start/end"); 98 | int len = end-start+1; 99 | 100 | // output cell 101 | plhs[0] = mxCreateCellMatrix(1, len); 102 | 103 | // do convolutions 104 | thread_data td; 105 | const mwSize *A_dims = mxGetDimensions(mxA); 106 | double *A = (double *)mxGetPr(mxA); 107 | for (int i = 0; i < len; i++) { 108 | const mxArray *mxB = mxGetCell(cellB, i+start); 109 | td.A_dims = A_dims; 110 | td.A = A; 111 | td.B_dims = mxGetDimensions(mxB); 112 | td.B = (double *)mxGetPr(mxB); 113 | if (mxGetNumberOfDimensions(mxB) != 3 || 114 | mxGetClassID(mxB) != mxDOUBLE_CLASS || 115 | td.A_dims[2] != td.B_dims[2]) 116 | mexErrMsgTxt("Invalid input: B"); 117 | 118 | // compute size of output 119 | int height = td.A_dims[0] - td.B_dims[0] + 1; 120 | int width = td.A_dims[1] - td.B_dims[1] + 1; 121 | if (height < 1 || width < 1) 122 | mexErrMsgTxt("Invalid input: B should be smaller than A"); 123 | td.C_dims[0] = height; 124 | td.C_dims[1] = width; 125 | td.mxC = mxCreateNumericArray(2, td.C_dims, mxDOUBLE_CLASS, mxREAL); 126 | td.C = (double *)mxGetPr(td.mxC); 127 | process((void *)&td); 128 | mxSetCell(plhs[0], i, td.mxC); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /voc-release4.01/fconv.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/fconv.mexmaci64 -------------------------------------------------------------------------------- /voc-release4.01/fconvMT.cc: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #include 3 | #include 4 | #include 5 | 6 | /* 7 | * This code is used for computing filter responses. It computes the 8 | * response of a set of filters with a feature map. 9 | * 10 | * Multithreaded version. 11 | */ 12 | 13 | struct thread_data { 14 | double *A; 15 | double *B; 16 | double *C; 17 | mxArray *mxC; 18 | const mwSize *A_dims; 19 | const mwSize *B_dims; 20 | mwSize C_dims[2]; 21 | }; 22 | 23 | // convolve A and B 24 | void *process(void *thread_arg) { 25 | thread_data *args = (thread_data *)thread_arg; 26 | double *A = args->A; 27 | double *B = args->B; 28 | double *C = args->C; 29 | const mwSize *A_dims = args->A_dims; 30 | const mwSize *B_dims = args->B_dims; 31 | const mwSize *C_dims = args->C_dims; 32 | int num_features = args->A_dims[2]; 33 | 34 | for (int f = 0; f < num_features; f++) { 35 | double *dst = C; 36 | double *A_src = A + f*A_dims[0]*A_dims[1]; 37 | double *B_src = B + f*B_dims[0]*B_dims[1]; 38 | for (int x = 0; x < C_dims[1]; x++) { 39 | for (int y = 0; y < C_dims[0]; y++) { 40 | double val = 0; 41 | for (int xp = 0; xp < B_dims[1]; xp++) { 42 | double *A_off = A_src + (x+xp)*A_dims[0] + y; 43 | double *B_off = B_src + xp*B_dims[0]; 44 | switch(B_dims[0]) { 45 | case 20: val += A_off[19] * B_off[19]; 46 | case 19: val += A_off[18] * B_off[18]; 47 | case 18: val += A_off[17] * B_off[17]; 48 | case 17: val += A_off[16] * B_off[16]; 49 | case 16: val += A_off[15] * B_off[15]; 50 | case 15: val += A_off[14] * B_off[14]; 51 | case 14: val += A_off[13] * B_off[13]; 52 | case 13: val += A_off[12] * B_off[12]; 53 | case 12: val += A_off[11] * B_off[11]; 54 | case 11: val += A_off[10] * B_off[10]; 55 | case 10: val += A_off[9] * B_off[9]; 56 | case 9: val += A_off[8] * B_off[8]; 57 | case 8: val += A_off[7] * B_off[7]; 58 | case 7: val += A_off[6] * B_off[6]; 59 | case 6: val += A_off[5] * B_off[5]; 60 | case 5: val += A_off[4] * B_off[4]; 61 | case 4: val += A_off[3] * B_off[3]; 62 | case 3: val += A_off[2] * B_off[2]; 63 | case 2: val += A_off[1] * B_off[1]; 64 | case 1: val += A_off[0] * B_off[0]; 65 | break; 66 | default: 67 | for (int yp = 0; yp < B_dims[0]; yp++) { 68 | val += *(A_off++) * *(B_off++); 69 | } 70 | } 71 | } 72 | *(dst++) += val; 73 | } 74 | } 75 | } 76 | pthread_exit(NULL); 77 | } 78 | 79 | // matlab entry point 80 | // C = fconv(A, cell of B, start, end); 81 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 82 | if (nrhs != 4) 83 | mexErrMsgTxt("Wrong number of inputs"); 84 | if (nlhs != 1) 85 | mexErrMsgTxt("Wrong number of outputs"); 86 | 87 | // get A 88 | const mxArray *mxA = prhs[0]; 89 | if (mxGetNumberOfDimensions(mxA) != 3 || 90 | mxGetClassID(mxA) != mxDOUBLE_CLASS) 91 | mexErrMsgTxt("Invalid input: A"); 92 | 93 | // get B and start/end 94 | const mxArray *cellB = prhs[1]; 95 | mwSize num_bs = mxGetNumberOfElements(cellB); 96 | int start = (int)mxGetScalar(prhs[2]) - 1; 97 | int end = (int)mxGetScalar(prhs[3]) - 1; 98 | if (start < 0 || end >= num_bs || start > end) 99 | mexErrMsgTxt("Invalid input: start/end"); 100 | int len = end-start+1; 101 | 102 | // start threads 103 | thread_data *td = (thread_data *)mxCalloc(len, sizeof(thread_data)); 104 | pthread_t *ts = (pthread_t *)mxCalloc(len, sizeof(pthread_t)); 105 | const mwSize *A_dims = mxGetDimensions(mxA); 106 | double *A = (double *)mxGetPr(mxA); 107 | for (int i = 0; i < len; i++) { 108 | const mxArray *mxB = mxGetCell(cellB, i+start); 109 | td[i].A_dims = A_dims; 110 | td[i].A = A; 111 | td[i].B_dims = mxGetDimensions(mxB); 112 | td[i].B = (double *)mxGetPr(mxB); 113 | if (mxGetNumberOfDimensions(mxB) != 3 || 114 | mxGetClassID(mxB) != mxDOUBLE_CLASS || 115 | td[i].A_dims[2] != td[i].B_dims[2]) 116 | mexErrMsgTxt("Invalid input: B"); 117 | 118 | // compute size of output 119 | int height = td[i].A_dims[0] - td[i].B_dims[0] + 1; 120 | int width = td[i].A_dims[1] - td[i].B_dims[1] + 1; 121 | if (height < 1 || width < 1) 122 | mexErrMsgTxt("Invalid input: B should be smaller than A"); 123 | td[i].C_dims[0] = height; 124 | td[i].C_dims[1] = width; 125 | td[i].mxC = mxCreateNumericArray(2, td[i].C_dims, mxDOUBLE_CLASS, mxREAL); 126 | td[i].C = (double *)mxGetPr(td[i].mxC); 127 | 128 | if (pthread_create(&ts[i], NULL, process, (void *)&td[i])) 129 | mexErrMsgTxt("Error creating thread"); 130 | } 131 | 132 | // wait for the treads to finish and set return values 133 | void *status; 134 | plhs[0] = mxCreateCellMatrix(1, len); 135 | for (int i = 0; i < len; i++) { 136 | pthread_join(ts[i], &status); 137 | mxSetCell(plhs[0], i, td[i].mxC); 138 | } 139 | mxFree(td); 140 | mxFree(ts); 141 | } 142 | 143 | 144 | -------------------------------------------------------------------------------- /voc-release4.01/fconvblas.cc: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #include "blas.h" 3 | #include 4 | #include 5 | #include 6 | 7 | /* 8 | * This code is used for computing filter responses. It computes the 9 | * response of a set of filters with a feature map. 10 | * 11 | * Multithreaded blas version. 12 | */ 13 | 14 | struct thread_data { 15 | double *A; 16 | double *B; 17 | double *C; 18 | mxArray *mxC; 19 | const mwSize *A_dims; 20 | const mwSize *B_dims; 21 | mwSize C_dims[2]; 22 | }; 23 | 24 | double *prepare_filter(double *B, const mwSize *B_dims) { 25 | double *F = (double *)mxCalloc(B_dims[0]*B_dims[1]*B_dims[2], sizeof(double)); 26 | for (int f = 0; f < B_dims[2]; f++) { 27 | for (int x = 0; x < B_dims[1]; x++) { 28 | for (int y = 0; y < B_dims[0]; y++) { 29 | F[f + x*(B_dims[2]) + y*(B_dims[2]*B_dims[1])] = 30 | B[y + x*B_dims[0] + f*(B_dims[0]*B_dims[1])]; 31 | } 32 | } 33 | } 34 | return F; 35 | } 36 | 37 | double *prepare_map(double *A, const mwSize *A_dims) { 38 | double *F = (double *)mxCalloc(A_dims[0]*A_dims[1]*A_dims[2], sizeof(double)); 39 | for (int f = 0; f < A_dims[2]; f++) { 40 | for (int x = 0; x < A_dims[1]; x++) { 41 | for (int y = 0; y < A_dims[0]; y++) { 42 | F[y + f*A_dims[0] + x*(A_dims[0]*A_dims[2])] = 43 | A[y + x*A_dims[0] + f*(A_dims[0]*A_dims[1])]; 44 | } 45 | } 46 | } 47 | return F; 48 | } 49 | 50 | // convolve A and B using blas 51 | void *process(void *thread_arg) { 52 | thread_data *args = (thread_data *)thread_arg; 53 | double *A = args->A; 54 | double *B = args->B; 55 | double *C = args->C; 56 | const mwSize *A_dims = args->A_dims; 57 | const mwSize *B_dims = args->B_dims; 58 | const mwSize *C_dims = args->C_dims; 59 | 60 | for (int x = 0; x < C_dims[1]; x++) { 61 | for (int y = 0; y < B_dims[0]; y++) { 62 | double *A_off = A + x*(A_dims[0]*A_dims[2]) + y; 63 | double *B_off = B + y*(B_dims[1]*B_dims[2]); 64 | double *C_off = C + x*C_dims[0]; 65 | char chn = 'N'; 66 | double one = 1; 67 | ptrdiff_t m = C_dims[0]; 68 | ptrdiff_t n = B_dims[1]*B_dims[2]; 69 | ptrdiff_t lda = A_dims[0]; 70 | ptrdiff_t incx = 1; 71 | ptrdiff_t incy = 1; 72 | dgemv(&chn, &m, &n, &one, A_off, &lda, B_off, &incx, &one, C_off, &incy); 73 | } 74 | } 75 | } 76 | 77 | // matlab entry point 78 | // C = fconv(A, cell of B, start, end); 79 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 80 | if (nrhs != 4) 81 | mexErrMsgTxt("Wrong number of inputs"); 82 | if (nlhs != 1) 83 | mexErrMsgTxt("Wrong number of outputs"); 84 | 85 | // get A 86 | const mxArray *mxA = prhs[0]; 87 | if (mxGetNumberOfDimensions(mxA) != 3 || 88 | mxGetClassID(mxA) != mxDOUBLE_CLASS) 89 | mexErrMsgTxt("Invalid input: A"); 90 | 91 | // get B and start/end 92 | const mxArray *cellB = prhs[1]; 93 | mwSize num_bs = mxGetNumberOfElements(cellB); 94 | int start = (int)mxGetScalar(prhs[2]) - 1; 95 | int end = (int)mxGetScalar(prhs[3]) - 1; 96 | if (start < 0 || end >= num_bs || start > end) 97 | mexErrMsgTxt("Invalid input: start/end"); 98 | int len = end-start+1; 99 | 100 | // output cell 101 | plhs[0] = mxCreateCellMatrix(1, len); 102 | 103 | // do convolutions 104 | thread_data td; 105 | const mwSize *A_dims = mxGetDimensions(mxA); 106 | double *A = prepare_map((double *)mxGetPr(mxA), A_dims); 107 | for (int i = 0; i < len; i++) { 108 | const mxArray *mxB = mxGetCell(cellB, i+start); 109 | td.A_dims = A_dims; 110 | td.A = A; 111 | td.B_dims = mxGetDimensions(mxB); 112 | td.B = prepare_filter((double *)mxGetPr(mxB), td.B_dims); 113 | if (mxGetNumberOfDimensions(mxB) != 3 || 114 | mxGetClassID(mxB) != mxDOUBLE_CLASS || 115 | td.A_dims[2] != td.B_dims[2]) 116 | mexErrMsgTxt("Invalid input: B"); 117 | 118 | // compute size of output 119 | int height = td.A_dims[0] - td.B_dims[0] + 1; 120 | int width = td.A_dims[1] - td.B_dims[1] + 1; 121 | if (height < 1 || width < 1) 122 | mexErrMsgTxt("Invalid input: B should be smaller than A"); 123 | td.C_dims[0] = height; 124 | td.C_dims[1] = width; 125 | td.mxC = mxCreateNumericArray(2, td.C_dims, mxDOUBLE_CLASS, mxREAL); 126 | td.C = (double *)mxGetPr(td.mxC); 127 | process((void *)&td); 128 | mxSetCell(plhs[0], i, td.mxC); 129 | } 130 | mxFree(A); 131 | } 132 | 133 | -------------------------------------------------------------------------------- /voc-release4.01/fconvblasMT.cc: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #include "blas.h" 3 | #include 4 | #include 5 | #include 6 | 7 | /* 8 | * This code is used for computing filter responses. It computes the 9 | * response of a set of filters with a feature map. 10 | * 11 | * Multithreaded blas version. 12 | */ 13 | 14 | struct thread_data { 15 | double *A; 16 | double *B; 17 | double *C; 18 | mxArray *mxC; 19 | const mwSize *A_dims; 20 | const mwSize *B_dims; 21 | mwSize C_dims[2]; 22 | }; 23 | 24 | double *prepare_filter(double *B, const mwSize *B_dims) { 25 | double *F = (double *)mxCalloc(B_dims[0]*B_dims[1]*B_dims[2], sizeof(double)); 26 | for (int f = 0; f < B_dims[2]; f++) { 27 | for (int x = 0; x < B_dims[1]; x++) { 28 | for (int y = 0; y < B_dims[0]; y++) { 29 | F[f + x*(B_dims[2]) + y*(B_dims[2]*B_dims[1])] = 30 | B[y + x*B_dims[0] + f*(B_dims[0]*B_dims[1])]; 31 | } 32 | } 33 | } 34 | return F; 35 | } 36 | 37 | double *prepare_map(double *A, const mwSize *A_dims) { 38 | double *F = (double *)mxCalloc(A_dims[0]*A_dims[1]*A_dims[2], sizeof(double)); 39 | for (int f = 0; f < A_dims[2]; f++) { 40 | for (int x = 0; x < A_dims[1]; x++) { 41 | for (int y = 0; y < A_dims[0]; y++) { 42 | F[y + f*A_dims[0] + x*(A_dims[0]*A_dims[2])] = 43 | A[y + x*A_dims[0] + f*(A_dims[0]*A_dims[1])]; 44 | } 45 | } 46 | } 47 | return F; 48 | } 49 | 50 | // convolve A and B using blas 51 | void *process(void *thread_arg) { 52 | thread_data *args = (thread_data *)thread_arg; 53 | double *A = args->A; 54 | double *B = args->B; 55 | double *C = args->C; 56 | const mwSize *A_dims = args->A_dims; 57 | const mwSize *B_dims = args->B_dims; 58 | const mwSize *C_dims = args->C_dims; 59 | 60 | for (int x = 0; x < C_dims[1]; x++) { 61 | for (int y = 0; y < B_dims[0]; y++) { 62 | double *A_off = A + x*(A_dims[0]*A_dims[2]) + y; 63 | double *B_off = B + y*(B_dims[1]*B_dims[2]); 64 | double *C_off = C + x*C_dims[0]; 65 | char chn = 'N'; 66 | double one = 1; 67 | ptrdiff_t m = C_dims[0]; 68 | ptrdiff_t n = B_dims[1]*B_dims[2]; 69 | ptrdiff_t lda = A_dims[0]; 70 | ptrdiff_t incx = 1; 71 | ptrdiff_t incy = 1; 72 | dgemv(&chn, &m, &n, &one, A_off, &lda, B_off, &incx, &one, C_off, &incy); 73 | } 74 | } 75 | pthread_exit(NULL); 76 | } 77 | 78 | // matlab entry point 79 | // C = fconv(A, cell of B, start, end); 80 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 81 | if (nrhs != 4) 82 | mexErrMsgTxt("Wrong number of inputs"); 83 | if (nlhs != 1) 84 | mexErrMsgTxt("Wrong number of outputs"); 85 | 86 | // get A 87 | const mxArray *mxA = prhs[0]; 88 | if (mxGetNumberOfDimensions(mxA) != 3 || 89 | mxGetClassID(mxA) != mxDOUBLE_CLASS) 90 | mexErrMsgTxt("Invalid input: A"); 91 | 92 | // get B and start/end 93 | const mxArray *cellB = prhs[1]; 94 | mwSize num_bs = mxGetNumberOfElements(cellB); 95 | int start = (int)mxGetScalar(prhs[2]) - 1; 96 | int end = (int)mxGetScalar(prhs[3]) - 1; 97 | if (start < 0 || end >= num_bs || start > end) 98 | mexErrMsgTxt("Invalid input: start/end"); 99 | int len = end-start+1; 100 | 101 | // start threads 102 | thread_data *td = (thread_data *)mxCalloc(len, sizeof(thread_data)); 103 | pthread_t *ts = (pthread_t *)mxCalloc(len, sizeof(pthread_t)); 104 | const mwSize *A_dims = mxGetDimensions(mxA); 105 | double *A = prepare_map((double *)mxGetPr(mxA), A_dims); 106 | for (int i = 0; i < len; i++) { 107 | const mxArray *mxB = mxGetCell(cellB, i+start); 108 | td[i].A_dims = A_dims; 109 | td[i].A = A; 110 | td[i].B_dims = mxGetDimensions(mxB); 111 | td[i].B = prepare_filter((double *)mxGetPr(mxB), td[i].B_dims); 112 | if (mxGetNumberOfDimensions(mxB) != 3 || 113 | mxGetClassID(mxB) != mxDOUBLE_CLASS || 114 | td[i].A_dims[2] != td[i].B_dims[2]) 115 | mexErrMsgTxt("Invalid input: B"); 116 | 117 | // compute size of output 118 | int height = td[i].A_dims[0] - td[i].B_dims[0] + 1; 119 | int width = td[i].A_dims[1] - td[i].B_dims[1] + 1; 120 | if (height < 1 || width < 1) 121 | mexErrMsgTxt("Invalid input: B should be smaller than A"); 122 | td[i].C_dims[0] = height; 123 | td[i].C_dims[1] = width; 124 | td[i].mxC = mxCreateNumericArray(2, td[i].C_dims, mxDOUBLE_CLASS, mxREAL); 125 | td[i].C = (double *)mxGetPr(td[i].mxC); 126 | 127 | if (pthread_create(&ts[i], NULL, process, (void *)&td[i])) 128 | mexErrMsgTxt("Error creating thread"); 129 | } 130 | 131 | // wait for the treads to finish and set return values 132 | void *status; 133 | plhs[0] = mxCreateCellMatrix(1, len); 134 | for (int i = 0; i < len; i++) { 135 | pthread_join(ts[i], &status); 136 | mxSetCell(plhs[0], i, td[i].mxC); 137 | mxFree(td[i].B); 138 | } 139 | mxFree(A); 140 | mxFree(td); 141 | mxFree(ts); 142 | } 143 | 144 | -------------------------------------------------------------------------------- /voc-release4.01/fconvsse.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * WARNING: This is an experimental implementation of filter convolutions 3 | * using SSE instructions. It produces responses that are slightly different 4 | * from what is computed by learn.cc and has not been thoroughly tested. 5 | */ 6 | 7 | #include "mex.h" 8 | #include 9 | #include 10 | #include 11 | 12 | // OS X aligns all memory at 16-byte boundaries (and doesn't provide 13 | // memalign/posix_memalign). On linux, we use memalign to allocated 14 | // 16-byte aligned memory. 15 | #if !defined(__APPLE__) 16 | #include 17 | #define malloc_aligned(a,b) memalign(a,b) 18 | #else 19 | #define malloc_aligned(a,b) malloc(b) 20 | #endif 21 | 22 | #define IS_ALIGNED(ptr) ((((uintptr_t)(ptr)) & 0xF) == 0) 23 | 24 | /** 25 | * Compile with: 26 | * mex -O CXXFLAGS="\$CXXFLAGS -march=native" fconvsse.cc 27 | * 28 | * You may need to replace `native` with the arch of your machine's CPU 29 | * if you're using an older version of gcc that doesn't support -march=native. 30 | */ 31 | 32 | // N.B. If you change the number of features you will need to unroll 33 | // the unrolled loop in process() more. 34 | #define NUM_FEATURES 32 35 | 36 | 37 | /* 38 | * This code is used for computing filter responses. It computes the 39 | * response of a set of filters with a feature map. 40 | * 41 | * Multithreaded version. 42 | */ 43 | 44 | struct thread_data { 45 | float *A; 46 | float *B; 47 | double *C; 48 | mxArray *mxC; 49 | const mwSize *A_dims; 50 | const mwSize *B_dims; 51 | mwSize C_dims[2]; 52 | }; 53 | 54 | // convolve A and B 55 | void *process(void *thread_arg) { 56 | thread_data *args = (thread_data *)thread_arg; 57 | float *A = args->A; 58 | float *B = args->B; 59 | double *C = args->C; 60 | const mwSize *A_dims = args->A_dims; 61 | const mwSize *B_dims = args->B_dims; 62 | const mwSize *C_dims = args->C_dims; 63 | 64 | __m128 a,b,c; 65 | double *dst = C; 66 | for (int x = 0; x < C_dims[1]; x++) { 67 | for (int y = 0; y < C_dims[0]; y++) { 68 | __m128 v = _mm_setzero_ps(); 69 | const float *A_src = A + y*NUM_FEATURES + x*A_dims[0]*NUM_FEATURES; 70 | const float *B_src = B; 71 | for (int xp = 0; xp < B_dims[1]; xp++) { 72 | const float *A_off = A_src; 73 | const float *B_off = B_src; 74 | for (int yp = 0; yp < B_dims[0]; yp++) { 75 | a = _mm_load_ps(A_off+0); 76 | b = _mm_load_ps(B_off+0); 77 | c = _mm_mul_ps(a, b); 78 | v = _mm_add_ps(v, c); 79 | 80 | a = _mm_load_ps(A_off+4); 81 | b = _mm_load_ps(B_off+4); 82 | c = _mm_mul_ps(a, b); 83 | v = _mm_add_ps(v, c); 84 | 85 | a = _mm_load_ps(A_off+8); 86 | b = _mm_load_ps(B_off+8); 87 | c = _mm_mul_ps(a, b); 88 | v = _mm_add_ps(v, c); 89 | 90 | a = _mm_load_ps(A_off+12); 91 | b = _mm_load_ps(B_off+12); 92 | c = _mm_mul_ps(a, b); 93 | v = _mm_add_ps(v, c); 94 | 95 | a = _mm_load_ps(A_off+16); 96 | b = _mm_load_ps(B_off+16); 97 | c = _mm_mul_ps(a, b); 98 | v = _mm_add_ps(v, c); 99 | 100 | a = _mm_load_ps(A_off+20); 101 | b = _mm_load_ps(B_off+20); 102 | c = _mm_mul_ps(a, b); 103 | v = _mm_add_ps(v, c); 104 | 105 | a = _mm_load_ps(A_off+24); 106 | b = _mm_load_ps(B_off+24); 107 | c = _mm_mul_ps(a, b); 108 | v = _mm_add_ps(v, c); 109 | 110 | a = _mm_load_ps(A_off+28); 111 | b = _mm_load_ps(B_off+28); 112 | c = _mm_mul_ps(a, b); 113 | v = _mm_add_ps(v, c); 114 | 115 | // N.B. Unroll me more/less if you change NUM_FEATURES 116 | 117 | A_off += NUM_FEATURES; 118 | B_off += NUM_FEATURES; 119 | } 120 | 121 | A_src += A_dims[0]*NUM_FEATURES; 122 | B_src += B_dims[0]*NUM_FEATURES; 123 | } 124 | // buf[] must be 16-byte aligned 125 | float buf[4] __attribute__ ((aligned (16))); 126 | _mm_store_ps(buf, v); 127 | _mm_empty(); 128 | *(dst++) = buf[0]+buf[1]+buf[2]+buf[3]; 129 | } 130 | } 131 | pthread_exit(NULL); 132 | } 133 | 134 | float *prepare(double *in, const int *dims) { 135 | float *F = (float *)malloc_aligned(16, dims[0]*dims[1]*dims[2]*sizeof(float)); 136 | // Sanity check that memory is aligned 137 | if (!IS_ALIGNED(F)) 138 | mexErrMsgTxt("Memory not aligned"); 139 | 140 | float *p = F; 141 | for (int x = 0; x < dims[1]; x++) 142 | for (int y = 0; y < dims[0]; y++) 143 | for (int f = 0; f < dims[2]; f++) 144 | *(p++) = in[y + f*dims[0]*dims[1] + x*dims[0]]; 145 | for (int f = dims[2]; f < NUM_FEATURES; f++) 146 | *(p++) = 0; 147 | return F; 148 | } 149 | 150 | // matlab entry point 151 | // C = fconv(A, cell of B, start, end); 152 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 153 | if (nrhs != 4) 154 | mexErrMsgTxt("Wrong number of inputs"); 155 | if (nlhs != 1) 156 | mexErrMsgTxt("Wrong number of outputs"); 157 | 158 | // get A 159 | const mxArray *mxA = prhs[0]; 160 | if (mxGetNumberOfDimensions(mxA) != 3 || 161 | mxGetClassID(mxA) != mxDOUBLE_CLASS) 162 | mexErrMsgTxt("Invalid input: A"); 163 | 164 | // get B and start/end 165 | const mxArray *cellB = prhs[1]; 166 | mwSize num_bs = mxGetNumberOfElements(cellB); 167 | int start = (int)mxGetScalar(prhs[2]) - 1; 168 | int end = (int)mxGetScalar(prhs[3]) - 1; 169 | if (start < 0 || end >= num_bs || start > end) 170 | mexErrMsgTxt("Invalid input: start/end"); 171 | int len = end-start+1; 172 | 173 | // start threads 174 | thread_data *td = (thread_data *)mxCalloc(len, sizeof(thread_data)); 175 | pthread_t *ts = (pthread_t *)mxCalloc(len, sizeof(pthread_t)); 176 | const mwSize *A_dims = mxGetDimensions(mxA); 177 | float *A = prepare(mxGetPr(mxA), A_dims); 178 | for (int i = 0; i < len; i++) { 179 | const mxArray *mxB = mxGetCell(cellB, i+start); 180 | td[i].A_dims = A_dims; 181 | td[i].A = A; 182 | td[i].B_dims = mxGetDimensions(mxB); 183 | td[i].B = prepare(mxGetPr(mxB), td[i].B_dims); 184 | if (mxGetNumberOfDimensions(mxB) != 3 || 185 | mxGetClassID(mxB) != mxDOUBLE_CLASS || 186 | td[i].A_dims[2] != td[i].B_dims[2]) 187 | mexErrMsgTxt("Invalid input: B"); 188 | 189 | // compute size of output 190 | int height = td[i].A_dims[0] - td[i].B_dims[0] + 1; 191 | int width = td[i].A_dims[1] - td[i].B_dims[1] + 1; 192 | if (height < 1 || width < 1) 193 | mexErrMsgTxt("Invalid input: B should be smaller than A"); 194 | td[i].C_dims[0] = height; 195 | td[i].C_dims[1] = width; 196 | td[i].mxC = mxCreateNumericArray(2, td[i].C_dims, mxDOUBLE_CLASS, mxREAL); 197 | td[i].C = (double *)mxGetPr(td[i].mxC); 198 | 199 | if (pthread_create(&ts[i], NULL, process, (void *)&td[i])) 200 | mexErrMsgTxt("Error creating thread"); 201 | } 202 | 203 | // wait for the treads to finish and set return values 204 | void *status; 205 | plhs[0] = mxCreateCellMatrix(1, len); 206 | for (int i = 0; i < len; i++) { 207 | pthread_join(ts[i], &status); 208 | mxSetCell(plhs[0], i, td[i].mxC); 209 | free(td[i].B); 210 | } 211 | mxFree(td); 212 | mxFree(ts); 213 | free(A); 214 | } 215 | 216 | 217 | -------------------------------------------------------------------------------- /voc-release4.01/fconvsse.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/fconvsse.mexmaci64 -------------------------------------------------------------------------------- /voc-release4.01/featpyramid.m: -------------------------------------------------------------------------------- 1 | function pyra = featpyramid(im, model, padx, pady) 2 | 3 | % pyra = featpyramid(im, model, padx, pady); 4 | % Compute feature pyramid. 5 | % 6 | % pyra.feat{i} is the i-th level of the feature pyramid. 7 | % pyra.scales{i} is the scaling factor used for the i-th level. 8 | % pyra.feat{i+interval} is computed at exactly half the resolution of feat{i}. 9 | % first octave halucinates higher resolution data. 10 | % padx,pady optionally pads each level of the feature pyramid 11 | 12 | if nargin < 3 13 | [padx, pady] = getpadding(model); 14 | end 15 | 16 | sbin = model.sbin; 17 | interval = model.interval; 18 | sc = 2 ^(1/interval); 19 | imsize = [size(im, 1) size(im, 2)]; 20 | max_scale = 1 + floor(log(min(imsize)/(5*sbin))/log(sc)); 21 | pyra.feat = cell(max_scale + interval, 1); 22 | pyra.scales = zeros(max_scale + interval, 1); 23 | pyra.imsize = imsize; 24 | 25 | % our resize function wants floating point values 26 | im = double(im); 27 | for i = 1:interval 28 | scaled = resize(im, 1/sc^(i-1)); 29 | % "first" 2x interval 30 | pyra.feat{i} = features(scaled, sbin/2); 31 | pyra.scales(i) = 2/sc^(i-1); 32 | % "second" 2x interval 33 | pyra.feat{i+interval} = features(scaled, sbin); 34 | pyra.scales(i+interval) = 1/sc^(i-1); 35 | % remaining interals 36 | for j = i+interval:interval:max_scale 37 | scaled = resize(scaled, 0.5); 38 | pyra.feat{j+interval} = features(scaled, sbin); 39 | pyra.scales(j+interval) = 0.5 * pyra.scales(j); 40 | end 41 | end 42 | 43 | for i = 1:length(pyra.feat) 44 | % add 1 to padding because feature generation deletes a 1-cell 45 | % wide border around the feature map 46 | pyra.feat{i} = padarray(pyra.feat{i}, [pady+1 padx+1 0], 0); 47 | % write boundary occlusion feature 48 | pyra.feat{i}(1:pady+1, :, 32) = 1; 49 | pyra.feat{i}(end-pady:end, :, 32) = 1; 50 | pyra.feat{i}(:, 1:padx+1, 32) = 1; 51 | pyra.feat{i}(:, end-padx:end, 32) = 1; 52 | end 53 | pyra.padx = padx; 54 | pyra.pady = pady; 55 | -------------------------------------------------------------------------------- /voc-release4.01/features.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "mex.h" 3 | 4 | // small value, used to avoid division by zero 5 | #define eps 0.0001 6 | 7 | // unit vectors used to compute gradient orientation 8 | double uu[9] = {1.0000, 9 | 0.9397, 10 | 0.7660, 11 | 0.500, 12 | 0.1736, 13 | -0.1736, 14 | -0.5000, 15 | -0.7660, 16 | -0.9397}; 17 | double vv[9] = {0.0000, 18 | 0.3420, 19 | 0.6428, 20 | 0.8660, 21 | 0.9848, 22 | 0.9848, 23 | 0.8660, 24 | 0.6428, 25 | 0.3420}; 26 | 27 | static inline double min(double x, double y) { return (x <= y ? x : y); } 28 | static inline double max(double x, double y) { return (x <= y ? y : x); } 29 | 30 | static inline int min(int x, int y) { return (x <= y ? x : y); } 31 | static inline int max(int x, int y) { return (x <= y ? y : x); } 32 | 33 | // main function: 34 | // takes a double color image and a bin size 35 | // returns HOG features 36 | mxArray *process(const mxArray *mximage, const mxArray *mxsbin) { 37 | double *im = (double *)mxGetPr(mximage); 38 | const int *dims = mxGetDimensions(mximage); 39 | if (mxGetNumberOfDimensions(mximage) != 3 || 40 | dims[2] != 3 || 41 | mxGetClassID(mximage) != mxDOUBLE_CLASS) 42 | mexErrMsgTxt("Invalid input"); 43 | 44 | int sbin = (int)mxGetScalar(mxsbin); 45 | 46 | // memory for caching orientation histograms & their norms 47 | int blocks[2]; 48 | blocks[0] = (int)round((double)dims[0]/(double)sbin); 49 | blocks[1] = (int)round((double)dims[1]/(double)sbin); 50 | double *hist = (double *)mxCalloc(blocks[0]*blocks[1]*18, sizeof(double)); 51 | double *norm = (double *)mxCalloc(blocks[0]*blocks[1], sizeof(double)); 52 | 53 | // memory for HOG features 54 | int out[3]; 55 | out[0] = max(blocks[0]-2, 0); 56 | out[1] = max(blocks[1]-2, 0); 57 | out[2] = 27+4+1; 58 | mxArray *mxfeat = mxCreateNumericArray(3, out, mxDOUBLE_CLASS, mxREAL); 59 | double *feat = (double *)mxGetPr(mxfeat); 60 | 61 | int visible[2]; 62 | visible[0] = blocks[0]*sbin; 63 | visible[1] = blocks[1]*sbin; 64 | 65 | for (int x = 1; x < visible[1]-1; x++) { 66 | for (int y = 1; y < visible[0]-1; y++) { 67 | // first color channel 68 | double *s = im + min(x, dims[1]-2)*dims[0] + min(y, dims[0]-2); 69 | double dy = *(s+1) - *(s-1); 70 | double dx = *(s+dims[0]) - *(s-dims[0]); 71 | double v = dx*dx + dy*dy; 72 | 73 | // second color channel 74 | s += dims[0]*dims[1]; 75 | double dy2 = *(s+1) - *(s-1); 76 | double dx2 = *(s+dims[0]) - *(s-dims[0]); 77 | double v2 = dx2*dx2 + dy2*dy2; 78 | 79 | // third color channel 80 | s += dims[0]*dims[1]; 81 | double dy3 = *(s+1) - *(s-1); 82 | double dx3 = *(s+dims[0]) - *(s-dims[0]); 83 | double v3 = dx3*dx3 + dy3*dy3; 84 | 85 | // pick channel with strongest gradient 86 | if (v2 > v) { 87 | v = v2; 88 | dx = dx2; 89 | dy = dy2; 90 | } 91 | if (v3 > v) { 92 | v = v3; 93 | dx = dx3; 94 | dy = dy3; 95 | } 96 | 97 | // snap to one of 18 orientations 98 | double best_dot = 0; 99 | int best_o = 0; 100 | for (int o = 0; o < 9; o++) { 101 | double dot = uu[o]*dx + vv[o]*dy; 102 | if (dot > best_dot) { 103 | best_dot = dot; 104 | best_o = o; 105 | } else if (-dot > best_dot) { 106 | best_dot = -dot; 107 | best_o = o+9; 108 | } 109 | } 110 | 111 | // add to 4 histograms around pixel using linear interpolation 112 | double xp = ((double)x+0.5)/(double)sbin - 0.5; 113 | double yp = ((double)y+0.5)/(double)sbin - 0.5; 114 | int ixp = (int)floor(xp); 115 | int iyp = (int)floor(yp); 116 | double vx0 = xp-ixp; 117 | double vy0 = yp-iyp; 118 | double vx1 = 1.0-vx0; 119 | double vy1 = 1.0-vy0; 120 | v = sqrt(v); 121 | 122 | if (ixp >= 0 && iyp >= 0) { 123 | *(hist + ixp*blocks[0] + iyp + best_o*blocks[0]*blocks[1]) += 124 | vx1*vy1*v; 125 | } 126 | 127 | if (ixp+1 < blocks[1] && iyp >= 0) { 128 | *(hist + (ixp+1)*blocks[0] + iyp + best_o*blocks[0]*blocks[1]) += 129 | vx0*vy1*v; 130 | } 131 | 132 | if (ixp >= 0 && iyp+1 < blocks[0]) { 133 | *(hist + ixp*blocks[0] + (iyp+1) + best_o*blocks[0]*blocks[1]) += 134 | vx1*vy0*v; 135 | } 136 | 137 | if (ixp+1 < blocks[1] && iyp+1 < blocks[0]) { 138 | *(hist + (ixp+1)*blocks[0] + (iyp+1) + best_o*blocks[0]*blocks[1]) += 139 | vx0*vy0*v; 140 | } 141 | } 142 | } 143 | 144 | // compute energy in each block by summing over orientations 145 | for (int o = 0; o < 9; o++) { 146 | double *src1 = hist + o*blocks[0]*blocks[1]; 147 | double *src2 = hist + (o+9)*blocks[0]*blocks[1]; 148 | double *dst = norm; 149 | double *end = norm + blocks[1]*blocks[0]; 150 | while (dst < end) { 151 | *(dst++) += (*src1 + *src2) * (*src1 + *src2); 152 | src1++; 153 | src2++; 154 | } 155 | } 156 | 157 | // compute features 158 | for (int x = 0; x < out[1]; x++) { 159 | for (int y = 0; y < out[0]; y++) { 160 | double *dst = feat + x*out[0] + y; 161 | double *src, *p, n1, n2, n3, n4; 162 | 163 | p = norm + (x+1)*blocks[0] + y+1; 164 | n1 = 1.0 / sqrt(*p + *(p+1) + *(p+blocks[0]) + *(p+blocks[0]+1) + eps); 165 | p = norm + (x+1)*blocks[0] + y; 166 | n2 = 1.0 / sqrt(*p + *(p+1) + *(p+blocks[0]) + *(p+blocks[0]+1) + eps); 167 | p = norm + x*blocks[0] + y+1; 168 | n3 = 1.0 / sqrt(*p + *(p+1) + *(p+blocks[0]) + *(p+blocks[0]+1) + eps); 169 | p = norm + x*blocks[0] + y; 170 | n4 = 1.0 / sqrt(*p + *(p+1) + *(p+blocks[0]) + *(p+blocks[0]+1) + eps); 171 | 172 | double t1 = 0; 173 | double t2 = 0; 174 | double t3 = 0; 175 | double t4 = 0; 176 | 177 | // contrast-sensitive features 178 | src = hist + (x+1)*blocks[0] + (y+1); 179 | for (int o = 0; o < 18; o++) { 180 | double h1 = min(*src * n1, 0.2); 181 | double h2 = min(*src * n2, 0.2); 182 | double h3 = min(*src * n3, 0.2); 183 | double h4 = min(*src * n4, 0.2); 184 | *dst = 0.5 * (h1 + h2 + h3 + h4); 185 | t1 += h1; 186 | t2 += h2; 187 | t3 += h3; 188 | t4 += h4; 189 | dst += out[0]*out[1]; 190 | src += blocks[0]*blocks[1]; 191 | } 192 | 193 | // contrast-insensitive features 194 | src = hist + (x+1)*blocks[0] + (y+1); 195 | for (int o = 0; o < 9; o++) { 196 | double sum = *src + *(src + 9*blocks[0]*blocks[1]); 197 | double h1 = min(sum * n1, 0.2); 198 | double h2 = min(sum * n2, 0.2); 199 | double h3 = min(sum * n3, 0.2); 200 | double h4 = min(sum * n4, 0.2); 201 | *dst = 0.5 * (h1 + h2 + h3 + h4); 202 | dst += out[0]*out[1]; 203 | src += blocks[0]*blocks[1]; 204 | } 205 | 206 | // texture features 207 | *dst = 0.2357 * t1; 208 | dst += out[0]*out[1]; 209 | *dst = 0.2357 * t2; 210 | dst += out[0]*out[1]; 211 | *dst = 0.2357 * t3; 212 | dst += out[0]*out[1]; 213 | *dst = 0.2357 * t4; 214 | 215 | // truncation feature 216 | dst += out[0]*out[1]; 217 | *dst = 0; 218 | } 219 | } 220 | 221 | mxFree(hist); 222 | mxFree(norm); 223 | return mxfeat; 224 | } 225 | 226 | // matlab entry point 227 | // F = features(image, bin) 228 | // image should be color with double values 229 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 230 | if (nrhs != 2) 231 | mexErrMsgTxt("Wrong number of inputs"); 232 | if (nlhs != 1) 233 | mexErrMsgTxt("Wrong number of outputs"); 234 | plhs[0] = process(prhs[0], prhs[1]); 235 | } 236 | 237 | 238 | 239 | -------------------------------------------------------------------------------- /voc-release4.01/features.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/features.mexmaci64 -------------------------------------------------------------------------------- /voc-release4.01/flipfeat.m: -------------------------------------------------------------------------------- 1 | function f = flipfeat(f) 2 | 3 | % f = flipfeat(f) 4 | % Horizontal-flip HOG features. 5 | % Used for learning symmetric models. 6 | 7 | % flip permutation 8 | p = [10 9 8 7 6 5 4 3 2 1 18 17 16 15 14 13 12 11 19 27 26 25 24 23 ... 9 | 22 21 20 30 31 28 29 32]; 10 | f = f(:,end:-1:1,p); 11 | -------------------------------------------------------------------------------- /voc-release4.01/foldHOG.m: -------------------------------------------------------------------------------- 1 | function f = foldHOG(w) 2 | 3 | % f = foldHOG(w) 4 | % Condense HOG features into one orientation histogram. 5 | % Used for displaying a feature. 6 | 7 | f=max(w(:,:,1:9),0)+max(w(:,:,10:18),0)+max(w(:,:,19:27),0); 8 | -------------------------------------------------------------------------------- /voc-release4.01/frame_0168.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/frame_0168.jpg -------------------------------------------------------------------------------- /voc-release4.01/gdetectwrite.m: -------------------------------------------------------------------------------- 1 | function [boxes, count] = gdetectwrite(pyra, model, boxes, info, label, ... 2 | fid, id, maxsize, maxnum) 3 | 4 | % Write detections from gdetect to the feature vector cache. 5 | % 6 | % pyra feature pyramid 7 | % model object model 8 | % boxes detection boxes 9 | % info detection info from gdetect.m 10 | % label +1 / -1 binary class label 11 | % fid cache's file descriptor from fopen() 12 | % id id for use in long label (e.g., image number the detection is from) 13 | % maxsize max cache size in bytes 14 | % maxnum max number of feature vectors to write 15 | 16 | if nargin < 8 17 | maxsize = inf; 18 | end 19 | 20 | if nargin < 9 21 | maxnum = inf; 22 | end 23 | 24 | if size(boxes,1) > maxnum 25 | boxes(maxnum+1:end, :) = []; 26 | info(:, :, maxnum+1:end) = []; 27 | end 28 | 29 | count = 0; 30 | if ~isempty(boxes) 31 | count = writefeatures(pyra, model, info, label, fid, id, maxsize); 32 | % truncate boxes 33 | boxes(count+1:end,:) = []; 34 | end 35 | 36 | 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | % writes feature vectors for the detections in info 39 | function count = writefeatures(pyra, model, info, label, fid, id, maxsize) 40 | % pyra feature pyramid 41 | % model object model 42 | % info detection info from gdetect.m 43 | % label +1 / -1 binary class label 44 | % fid cache's file descriptor from fopen() 45 | % id id for use in long label (e.g., image number the detection is from) 46 | % maxsize max cache size in bytes 47 | 48 | % indexes into info from getdetections.cc 49 | DET_USE = 1; % current symbol is used 50 | DET_IND = 2; % rule index 51 | DET_X = 3; % x coord (filter and deformation) 52 | DET_Y = 4; % y coord (filter and deformation) 53 | DET_L = 5; % level (filter) 54 | DET_DS = 6; % # of 2x scalings relative to the start symbol location 55 | DET_PX = 7; % x coord of "probe" (deformation) 56 | DET_PY = 8; % y coord of "probe" (deformation) 57 | DET_VAL = 9; % score of current symbol 58 | DET_SZ = 10; % 59 | 60 | count = 0; 61 | for i = 1:size(info,3) 62 | r = info(DET_IND, model.start, i); 63 | x = info(DET_X, model.start, i); 64 | y = info(DET_Y, model.start, i); 65 | l = info(DET_L, model.start, i); 66 | ex = []; 67 | ex.fid = fid; 68 | ex.maxsize = maxsize; 69 | ex.header = [label id l x y 0 0]; 70 | ex.blocks(model.numblocks).w = []; 71 | 72 | for j = 1:model.numsymbols 73 | % skip unused symbols 74 | if info(DET_USE, j, i) == 0 75 | continue; 76 | end 77 | 78 | if model.symbols(j).type == 'T' 79 | ex = addfilterfeat(model, ex, ... 80 | info(DET_X, j, i), ... 81 | info(DET_Y, j, i), ... 82 | pyra.padx, pyra.pady, ... 83 | info(DET_DS, j, i), ... 84 | model.symbols(j).filter, ... 85 | pyra.feat{info(DET_L, j, i)}); 86 | else 87 | ruleind = info(DET_IND, j, i); 88 | if model.rules{j}(ruleind).type == 'D' 89 | bl = model.rules{j}(ruleind).def.blocklabel; 90 | dx = info(DET_PX, j, i) - info(DET_X, j, i); 91 | dy = info(DET_PY, j, i) - info(DET_Y, j, i); 92 | def = [-(dx^2); -dx; -(dy^2); -dy]; 93 | if model.rules{j}.def.flip 94 | def(2) = -def(2); 95 | end 96 | if isempty(ex.blocks(bl).w) 97 | ex.blocks(bl).w = def; 98 | else 99 | ex.blocks(bl).w = ex.blocks(bl).w + def; 100 | end 101 | end 102 | bl = model.rules{j}(ruleind).offset.blocklabel; 103 | ex.blocks(bl).w = 1; 104 | end 105 | end 106 | status = exwrite(ex); 107 | count = count + 1; 108 | if ~status 109 | break 110 | end 111 | end 112 | 113 | 114 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 115 | % stores the filter feature vector in the example ex 116 | function ex = addfilterfeat(model, ex, x, y, padx, pady, ds, fi, feat) 117 | % model object model 118 | % ex example that is being extracted from the feature pyramid 119 | % x, y location of filter in feat (with virtual padding) 120 | % padx number of cols of padding 121 | % pady number of rows of padding 122 | % ds number of 2x scalings (0 => root level, 1 => first part level, ...) 123 | % fi filter index 124 | % feat padded feature map 125 | 126 | fsz = model.filters(fi).size; 127 | % remove virtual padding 128 | fy = y - pady*(2^ds-1); 129 | fx = x - padx*(2^ds-1); 130 | f = feat(fy:fy+fsz(1)-1, fx:fx+fsz(2)-1, :); 131 | 132 | % flipped filter 133 | if model.filters(fi).symmetric == 'M' && model.filters(fi).flip 134 | f = flipfeat(f); 135 | end 136 | 137 | % accumulate features 138 | bl = model.filters(fi).blocklabel; 139 | if isempty(ex.blocks(bl).w) 140 | ex.blocks(bl).w = f(:); 141 | else 142 | ex.blocks(bl).w = ex.blocks(bl).w + f(:); 143 | end 144 | 145 | 146 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 147 | % write ex to ex.fid 148 | function status = exwrite(ex) 149 | % ex example to write 150 | 151 | buf = []; 152 | numblocks = 0; 153 | for i = 1:length(ex.blocks) 154 | if ~isempty(ex.blocks(i).w) 155 | buf = [buf; i; ex.blocks(i).w]; 156 | numblocks = numblocks + 1; 157 | end 158 | end 159 | ex.header(6) = numblocks; 160 | ex.header(7) = length(buf); 161 | fwrite(ex.fid, ex.header, 'int32'); 162 | fwrite(ex.fid, buf, 'single'); 163 | 164 | % still under the limit? 165 | status = (ftell(ex.fid) < ex.maxsize); 166 | -------------------------------------------------------------------------------- /voc-release4.01/getcontextlabels.m: -------------------------------------------------------------------------------- 1 | function labels = getcontextlabels(cls, boxes, trainset) 2 | 3 | % labels = getcontextlabels(cls, boxes, trainset) 4 | % cls is the name of the PASCAL object class 5 | % boxes is a cell array of detections for each image 6 | % 7 | % Most of this code is copied from VOCpr.m with minor modifications. 8 | 9 | globals; 10 | pascal_init; 11 | 12 | try 13 | load([cachedir cls '_context_labels_' trainset '_' VOCyear]); 14 | catch 15 | % load test set 16 | [gtids,t]=textread(sprintf(VOCopts.imgsetpath,trainset),'%s %d'); 17 | 18 | % load ground truth objects 19 | tic; 20 | npos=0; 21 | for i=1:length(gtids) 22 | % display progress 23 | if toc>1 24 | fprintf('%s: context labels: load: %d/%d\n',cls,i,length(gtids)); 25 | drawnow; 26 | tic; 27 | end 28 | 29 | % read annotation 30 | rec=PASreadrecord(sprintf(VOCopts.annopath,gtids{i})); 31 | 32 | % extract objects of class 33 | clsinds=strmatch(cls,{rec.objects(:).class},'exact'); 34 | gt(i).BB=cat(1,rec.objects(clsinds).bbox)'; 35 | gt(i).diff=[rec.objects(clsinds).difficult]; 36 | gt(i).det=false(length(clsinds),1); 37 | npos=npos+sum(~gt(i).diff); 38 | end 39 | 40 | labels = cell(length(gtids),1); 41 | for i = 1:length(gtids) 42 | if isempty(boxes{i}) 43 | labels{i} = []; 44 | continue; 45 | end 46 | % get bounding boxes 47 | BB = boxes{i}(:,1:4); 48 | % labels for each box 49 | labels{i} = zeros(size(BB,1), 1); 50 | for j = 1:size(BB,1) 51 | % assign detection to ground truth object if any 52 | bb = BB(j,:)'; 53 | ovmax=-inf; 54 | for k=1:size(gt(i).BB,2) 55 | bbgt=gt(i).BB(:,k); 56 | bi=[max(bb(1),bbgt(1)) ; max(bb(2),bbgt(2)) ; min(bb(3),bbgt(3)) ; min(bb(4),bbgt(4))]; 57 | iw=bi(3)-bi(1)+1; 58 | ih=bi(4)-bi(2)+1; 59 | if iw>0 && ih>0 60 | % compute overlap as area of intersection / area of union 61 | ua=(bb(3)-bb(1)+1)*(bb(4)-bb(2)+1)+... 62 | (bbgt(3)-bbgt(1)+1)*(bbgt(4)-bbgt(2)+1)-... 63 | iw*ih; 64 | ov=iw*ih/ua; 65 | if ov>ovmax 66 | ovmax=ov; 67 | end 68 | end 69 | end 70 | % assign detection as true positive/don't care/false positive 71 | if ovmax >= VOCopts.minoverlap 72 | % counts both true positives and multiple detections as class 1 73 | labels{i}(j) = 1; 74 | else 75 | labels{i}(j) = -1; 76 | end 77 | end 78 | end 79 | save([cachedir cls '_context_labels_' trainset '_' VOCyear], 'labels'); 80 | end 81 | -------------------------------------------------------------------------------- /voc-release4.01/getdetections.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/getdetections.mexmaci64 -------------------------------------------------------------------------------- /voc-release4.01/getpadding.m: -------------------------------------------------------------------------------- 1 | function [padx, pady] = getpadding(model) 2 | 3 | % Return the default feature map padding used for detection. 4 | % We pad the feature maps to detect partially visible objects. 5 | 6 | padx = ceil(model.maxsize(2)); 7 | pady = ceil(model.maxsize(1)); 8 | -------------------------------------------------------------------------------- /voc-release4.01/globals.m: -------------------------------------------------------------------------------- 1 | % Set up global variables used throughout the code 2 | 3 | % setup svm mex for context rescoring (if it's installed) 4 | if exist('./svm_mex601') > 0 5 | addpath svm_mex601/bin; 6 | addpath svm_mex601/matlab; 7 | end 8 | 9 | % dataset to use 10 | if exist('setVOCyear') == 1 11 | VOCyear = setVOCyear; 12 | clear('setVOCyear'); 13 | else 14 | VOCyear = '2007'; 15 | end 16 | 17 | % directory for caching models, intermediate data, and results 18 | cachedir = ['/var/tmp/rbg/YOURPATH/' VOCyear '/']; 19 | 20 | if exist(cachedir) == 0 21 | unix(['mkdir -p ' cachedir]); 22 | if exist([cachedir 'learnlog/']) == 0 23 | unix(['mkdir -p ' cachedir 'learnlog/']); 24 | end 25 | end 26 | 27 | % directory for LARGE temporary files created during training 28 | tmpdir = ['/var/tmp/rbg/YOURPATH/dat/' VOCyear '/']; 29 | 30 | if exist(tmpdir) == 0 31 | unix(['mkdir -p ' tmpdir]); 32 | end 33 | 34 | % should the tmpdir be cleaned after training a model? 35 | cleantmpdir = true; 36 | 37 | % directory with PASCAL VOC development kit and dataset 38 | VOCdevkit = ['/var/tmp/rbg/VOC' VOCyear '/VOCdevkit/']; 39 | -------------------------------------------------------------------------------- /voc-release4.01/imgdetect.m: -------------------------------------------------------------------------------- 1 | function [dets, boxes, info] = imgdetect(input, model, thresh, bbox, overlap) 2 | 3 | % Wrapper that computes detections in the input image. 4 | % 5 | % input input image 6 | % model object model 7 | % thresh detection score threshold 8 | % bbox ground truth bounding box 9 | % overlap overlap requirement 10 | 11 | % we assume color images 12 | input = color(input); 13 | 14 | % get the feature pyramid 15 | pyra = featpyramid(input, model); 16 | 17 | if nargin < 4 18 | bbox = []; 19 | end 20 | 21 | if nargin < 5 22 | overlap = 0; 23 | end 24 | 25 | [dets, boxes, info] = gdetect(pyra, model, thresh, bbox, overlap); 26 | -------------------------------------------------------------------------------- /voc-release4.01/imreadx.m: -------------------------------------------------------------------------------- 1 | function im = imreadx(ex) 2 | 3 | % Read a training example image. 4 | % 5 | % ex an example returned by pascal_data.m 6 | 7 | im = color(imread(ex.im)); 8 | if ex.flip 9 | im = im(:,end:-1:1,:); 10 | end 11 | -------------------------------------------------------------------------------- /voc-release4.01/initmodel.m: -------------------------------------------------------------------------------- 1 | function model = initmodel(cls, pos, note, symmetry, sbin, sz) 2 | 3 | % model = initmodel(cls, pos, note, symmetry, sbin, sz) 4 | % Initialize model structure. 5 | % 6 | % If not supplied the dimensions of the model template are computed 7 | % from statistics in the postive examples. 8 | 9 | % pick mode of aspect ratios 10 | h = [pos(:).y2]' - [pos(:).y1]' + 1; 11 | w = [pos(:).x2]' - [pos(:).x1]' + 1; 12 | xx = -2:.02:2; 13 | filter = exp(-[-100:100].^2/400); 14 | aspects = hist(log(h./w), xx); 15 | aspects = convn(aspects, filter, 'same'); 16 | [peak, I] = max(aspects); 17 | aspect = exp(xx(I)); 18 | 19 | % pick 20 percentile area 20 | areas = sort(h.*w); 21 | area = areas(floor(length(areas) * 0.2)); 22 | area = max(min(area, 5000), 3000); 23 | 24 | % pick dimensions 25 | w = sqrt(area/aspect); 26 | h = w*aspect; 27 | 28 | if nargin < 3 29 | note = ''; 30 | end 31 | 32 | % get an empty model 33 | model = model_create(cls, note); 34 | model.interval = 10; 35 | 36 | if nargin < 4 37 | symmetry = 'N'; 38 | end 39 | 40 | % size of HOG features 41 | if nargin < 5 42 | model.sbin = 8; 43 | else 44 | model.sbin = sbin; 45 | end 46 | 47 | % size of root filter 48 | if nargin < 6 49 | sz = [round(h/model.sbin) round(w/model.sbin)]; 50 | end 51 | 52 | % add root filter 53 | [model, symbol, filter] = model_addfilter(model, zeros([sz 32]), symmetry); 54 | 55 | % start non-terminal 56 | [model, Q] = model_addnonterminal(model); 57 | model.start = Q; 58 | 59 | % add structure rule deriving only a root filter placement 60 | model = model_addrule(model, 'S', Q, symbol, 0, {[0 0 0]}); 61 | 62 | % set detection window 63 | model = model_setdetwindow(model, Q, 1, sz); 64 | -------------------------------------------------------------------------------- /voc-release4.01/initrand.m: -------------------------------------------------------------------------------- 1 | function initrand() 2 | % Initialize random number generator to a fixed seed. 3 | % This ensures that results are reproducible. 4 | 5 | % try make different versions of matlab happy 6 | try 7 | RandStream.setDefaultStream(RandStream('mt19937ar','seed',3)); 8 | catch 9 | rand('twister',3); 10 | end 11 | -------------------------------------------------------------------------------- /voc-release4.01/labeldata.m: -------------------------------------------------------------------------------- 1 | function [gt, npos] = labeldata(cls, dataset) 2 | 3 | % Load and cache ground-truth annontation data for fast 4 | % resuse when running context rescoring experiments. 5 | % Some of this code is borrowed from the PASCAL devkit. 6 | 7 | globals; 8 | pascal_init; 9 | 10 | try 11 | load([cachedir cls '_labeldata_' dataset '_' VOCyear]); 12 | catch 13 | % load ground truth objects 14 | [gtids,t] = textread(sprintf(VOCopts.imgsetpath,dataset),'%s %d'); 15 | tic; 16 | npos=0; 17 | for i=1:length(gtids) 18 | % display progress 19 | if toc>1 20 | fprintf('%s: rescore labels: load: %d/%d\n',cls,i,length(gtids)); 21 | drawnow; 22 | tic; 23 | end 24 | 25 | % read annotation 26 | rec=PASreadrecord(sprintf(VOCopts.annopath,gtids{i})); 27 | 28 | % extract objects of class 29 | clsinds=strmatch(cls,{rec.objects(:).class},'exact'); 30 | gt(i).BB=cat(1,rec.objects(clsinds).bbox)'; 31 | gt(i).diff=[rec.objects(clsinds).difficult]; 32 | gt(i).det=false(length(clsinds),1); 33 | npos=npos+sum(~gt(i).diff); 34 | end 35 | save([cachedir cls '_labeldata_' dataset '_' VOCyear], 'gt', 'npos'); 36 | end 37 | -------------------------------------------------------------------------------- /voc-release4.01/lrmodel.m: -------------------------------------------------------------------------------- 1 | function model = lrmodel(model) 2 | % produce a model with left/right symmetric root filters 3 | % 4 | % model object model with a single root filter 5 | 6 | % symbol of the root filter 7 | rootsym = model.rules{model.start}.rhs(1); 8 | % create a fresh nonterminal for the new deformation rule 9 | [model, N1] = model_addnonterminal(model); 10 | % add deformation rule 11 | defsym = 'M'; 12 | defoffset = 0; 13 | % rigid deformation model for root filter 14 | defparams = [1000 0 1000 0]; 15 | [model, offsetbl, defbl] = model_addrule(model, 'D', N1, rootsym, ... 16 | defoffset, defparams, defsym); 17 | % prevent learning or regularization penalty for root filter 18 | model.learnmult(defbl) = 0; 19 | model.regmult(defbl) = 0; 20 | % replace the old rhs symbol with the deformation rule symbol 21 | model.rules{model.start}.rhs(1) = N1; 22 | 23 | % add a mirrored filter 24 | model.filters(1).symmetric = 'M'; 25 | [model, filtersym, filterind] = model_addmirroredfilter(model, 1); 26 | 27 | % add mirrored deformation rule 28 | [model, N2] = model_addnonterminal(model); 29 | model = model_addrule(model, 'D', N2, filtersym, ... 30 | defoffset, defparams, defsym, offsetbl, defbl); 31 | 32 | % add a new structure rule for the flipped deformation rule & filter 33 | offset = model.rules{model.start}.offset.w; 34 | bl = model.rules{model.start}.offset.blocklabel; 35 | model = model_addrule(model, 'S', model.start, N2, offset, {[0 0 0]}, 'N', bl); 36 | model = model_setdetwindow(model, model.start, 2, ... 37 | model.rules{model.start}(1).detwindow); 38 | -------------------------------------------------------------------------------- /voc-release4.01/lrsplit.m: -------------------------------------------------------------------------------- 1 | function [A B] = lrsplit(model, pos, i) 2 | % Attempt to split examples in pos into a left facing cluster and a 3 | % right facing cluster. 4 | % 5 | % model object model 6 | % pos examples where i even and i-1 are flipped copies of each other 7 | % i index for caching warped positives 8 | 9 | globals; 10 | try 11 | load([cachedir model.class '_warped_' num2str(i) '_' model.year]); 12 | catch 13 | warped = warppos(model, pos); 14 | % useful for debugging: 15 | % save([cachedir model.class '_warped_' num2str(i) '_' model.year]); 16 | end 17 | 18 | % cache features 19 | fprintf('Caching features\n'); 20 | for i = 1:length(warped) 21 | fprintf('%d/%d\n', i, length(warped)); 22 | feats{i} = features(warped{i}, model.sbin); 23 | feats{i} = feats{i}(:); 24 | end 25 | 26 | maxiter = 25; 27 | bestv = inf; 28 | A = []; 29 | B = []; 30 | for j = 1:maxiter 31 | [tmpA tmpB v] = cluster(feats); 32 | if v < bestv 33 | fprintf('new total intra-cluster variance: %f\n', v); 34 | A = tmpA; 35 | B = tmpB; 36 | bestv = v; 37 | end 38 | end 39 | 40 | % useful for visualizing clusters: 41 | % 42 | %for i = A 43 | % imagesc(uint8(warped{i})); 44 | % axis image; 45 | % title('A'); 46 | % pause(0.5); 47 | %end 48 | 49 | %for i = B 50 | % imagesc(uint8(warped{i})); 51 | % axis image; 52 | % title('B'); 53 | % pause(0.5); 54 | %end 55 | 56 | 57 | function [A B v] = cluster(pos) 58 | numpos = length(pos); 59 | 60 | % pick seed example at random 61 | % we know that if k is even, then 62 | % k-1 is a flipped copy of k 63 | k = 2*ceil(rand(1)*floor(numpos/2)); 64 | A = [k]; 65 | B = [k-1]; 66 | 67 | Asum = pos{k}; 68 | Bsum = pos{k-1}; 69 | 70 | % go over data in a random order 71 | % greedily assign each example to the closest 72 | % cluster and its flipped copy to the other cluster 73 | inds = 2:2:numpos; 74 | inds = inds(randperm(length(inds))); 75 | for i = inds 76 | % skip seed 77 | if i == k 78 | continue; 79 | end 80 | 81 | f1 = pos{i}; 82 | f2 = pos{i-1}; 83 | 84 | dA = norm(f1 - Asum./length(A)); 85 | dB = norm(f1 - Bsum./length(B)); 86 | 87 | if dA < dB 88 | A = [A i]; 89 | B = [B i-1]; 90 | Asum = Asum + f1; 91 | Bsum = Bsum + f2; 92 | else 93 | A = [A i-1]; 94 | B = [B i]; 95 | Asum = Asum + f2; 96 | Bsum = Bsum + f1; 97 | end 98 | end 99 | 100 | % relax cluster 101 | % search for better local optima by swapping 102 | % a single example if advantageous 103 | maxiter = 10; 104 | prevv = inf; 105 | for j = 1:maxiter 106 | % go over data in a random order 107 | inds = 1:length(A); 108 | inds = inds(randperm(length(inds))); 109 | for i = inds 110 | Ai = A(i); 111 | Bi = B(i); 112 | f1 = pos{Ai}; 113 | f2 = pos{Bi}; 114 | 115 | dA = norm(f1 - (Asum-f1)./(length(A)-1)); 116 | dB = norm(f1 - (Bsum-f2)./(length(B)-1)); 117 | 118 | % check if we should swap 119 | if dB < dA 120 | A(i) = Bi; 121 | B(i) = Ai; 122 | Asum = Asum - f1 + f2; 123 | Bsum = Bsum - f2 + f1; 124 | end 125 | end 126 | 127 | % compute total intra-cluster variance 128 | v = 0; 129 | for i = A 130 | f = pos{i}; 131 | v = v + sum((f - Asum./length(A)).^2); 132 | end 133 | 134 | for i = B 135 | f = pos{i}; 136 | v = v + sum((f - Bsum./length(B)).^2); 137 | end 138 | 139 | if v == prevv 140 | break; 141 | end 142 | prevv = v; 143 | 144 | %fprintf('total intra-cluster variance: %f\n', v); 145 | end 146 | -------------------------------------------------------------------------------- /voc-release4.01/matlabengine.py: -------------------------------------------------------------------------------- 1 | import matlab.engine 2 | eng = matlab.engine.start_matlab() 3 | eng.persontest(nargout=0) -------------------------------------------------------------------------------- /voc-release4.01/mergemodels.m: -------------------------------------------------------------------------------- 1 | function model = mergemodels(models) 2 | 3 | % model = mergemodels(models) 4 | % Merge a set of models into a single mixture model. 5 | 6 | model = models{1}; 7 | 8 | for i = 2:length(models) 9 | m = models{i}; 10 | numb = model.numblocks; 11 | nums = model.numsymbols; 12 | numf = model.numfilters; 13 | 14 | model.blocksizes = [model.blocksizes m.blocksizes]; 15 | model.regmult = [model.regmult m.regmult]; 16 | model.learnmult = [model.learnmult m.learnmult]; 17 | model.lowerbounds = [model.lowerbounds m.lowerbounds]; 18 | 19 | % merge filters 20 | for j = 1:m.numfilters 21 | m.filters(j).blocklabel = m.filters(j).blocklabel + numb; 22 | m.filters(j).symbol = m.filters(j).symbol + nums; 23 | end 24 | model.filters = [model.filters m.filters]; 25 | 26 | % merge symbols 27 | for j = 1:m.numsymbols 28 | m.symbols(j).filter = m.symbols(j).filter + numf; 29 | m.symbols(j).i = m.symbols(j).i + nums; 30 | end 31 | model.symbols = [model.symbols m.symbols]; 32 | 33 | % merge rules 34 | for j = 1:length(m.rules) 35 | for k = 1:length(m.rules{j}) 36 | m.rules{j}(k).lhs = m.rules{j}(k).lhs + nums; 37 | m.rules{j}(k).rhs = m.rules{j}(k).rhs + nums; 38 | m.rules{j}(k).offset.blocklabel = ... 39 | m.rules{j}(k).offset.blocklabel + numb; 40 | if m.rules{j}(k).type == 'D' 41 | m.rules{j}(k).def.blocklabel = ... 42 | m.rules{j}(k).def.blocklabel + numb; 43 | end 44 | end 45 | end 46 | oldnumr = length(model.rules); 47 | model.rules = [model.rules m.rules]; 48 | model.rules{model.start} = [model.rules{model.start} m.rules{m.start}]; 49 | % sync up index and lhs 50 | for j = 1:length(model.rules{model.start}) 51 | model.rules{model.start}(j).i = j; 52 | model.rules{model.start}(j).lhs = model.start; 53 | end 54 | % blank old start rule 55 | model.rules{m.start+oldnumr} = []; 56 | 57 | model.maxsize = max(model.maxsize, m.maxsize); 58 | model.minsize = min(model.minsize, m.minsize); 59 | 60 | model.numblocks = model.numblocks + m.numblocks; 61 | model.numfilters = model.numfilters + m.numfilters; 62 | model.numsymbols = model.numsymbols + m.numsymbols; 63 | end 64 | -------------------------------------------------------------------------------- /voc-release4.01/mkpartfilters.m: -------------------------------------------------------------------------------- 1 | function pfilters = mkpartfilters(filter, psize, num) 2 | % Make part filters from a source filter. 3 | % 4 | % filter source filter 5 | % psize size for parts 6 | % num number of parts to make 7 | 8 | % interpolate source filter 9 | filter2x = imresize(filter, 2, 'bicubic'); 10 | template = fspecial('average', psize); 11 | alpha = 0.1; 12 | 13 | % Initial part placement based on greedy location selection. 14 | energy = sum(max(filter2x, 0).^2, 3); 15 | for k = 1:num 16 | [x y] = placepart(energy, template); 17 | f = mkfilter(filter2x, template, x, y, alpha); 18 | 19 | pfilters(k).anchor = [x-1 y-1 1]; 20 | pfilters(k).w = f; 21 | pfilters(k).alpha = alpha; 22 | 23 | % zero energy in source 24 | energy = zeroenergy(energy, x, y, template); 25 | end 26 | 27 | % sample part placements and pick the best energy covering 28 | maxiter = 1000; 29 | retries = 10; 30 | bestcover = -inf; 31 | best = []; 32 | % retry from randomized starting points 33 | for j = 1:retries 34 | tmp = pfilters; 35 | progress = ones(num,1); 36 | % relax: 37 | % remove a part at random and look for the best place to put it 38 | % continue until no more progress can be made (or maxiters) 39 | for k = 1:maxiter 40 | if sum(progress) == 0 41 | break; 42 | end 43 | energy = sum(max(filter2x, 0).^2, 3); 44 | p = ceil(num*rand(1)); 45 | for i = 1:num 46 | if i ~= p 47 | energy = zeroenergy(energy, tmp(i).anchor(1)+1, ... 48 | tmp(i).anchor(2)+1, template); 49 | end 50 | end 51 | [x y] = placepart(energy, template); 52 | 53 | if tmp(p).anchor(1)+1 == x && tmp(p).anchor(2)+1 == y 54 | % new location equals old location 55 | progress(p) = 0; 56 | continue; 57 | end 58 | progress(p) = 1; 59 | 60 | f = mkfilter(filter2x, template, x, y, alpha); 61 | 62 | tmp(p).anchor = [x-1 y-1 1]; 63 | tmp(p).w = f; 64 | tmp(p).alpha = alpha; 65 | end 66 | 67 | % compute the energy covered by this part arrangement 68 | covered = 0; 69 | energy = sum(max(filter2x, 0).^2, 3); 70 | for i = 1:num 71 | covered = covered + ... 72 | coveredenergy(energy, tmp(i).anchor(1)+1, ... 73 | tmp(i).anchor(2)+1, template); 74 | energy = zeroenergy(energy, tmp(i).anchor(1)+1, ... 75 | tmp(i).anchor(2)+1, template); 76 | end 77 | % record best covering 78 | if covered > bestcover 79 | bestcover = covered; 80 | best = tmp; 81 | end 82 | end 83 | pfilters = best; 84 | 85 | 86 | function [x y] = placepart(energy, template) 87 | 88 | score = conv2(energy, template, 'valid'); 89 | score = padarray(score, [1 1], -inf, 'post'); 90 | [v, Y] = max(score); 91 | [v, x] = max(v); 92 | y = Y(x); 93 | 94 | 95 | function f = mkfilter(w, template, x, y, alpha) 96 | 97 | f = w(y:y+size(template,1)-1, x:x+size(template,2)-1, :); 98 | f = max(f, 0); 99 | f = alpha*f/norm(f(:)); 100 | 101 | 102 | function energy = zeroenergy(energy, x, y, template) 103 | 104 | energy(y:y+size(template,1)-1, x:x+size(template,2)-1) = 0; 105 | 106 | 107 | function covered = coveredenergy(energy, x, y, template) 108 | 109 | e = energy(y:y+size(template,1)-1, x:x+size(template,2)-1); 110 | covered = sum(e(:).^2); 111 | -------------------------------------------------------------------------------- /voc-release4.01/mlabtest.m: -------------------------------------------------------------------------------- 1 | %% MATLAB 2 | function lol = mlabtest(args) 3 | arg1 = args.arg1; 4 | arg2 = args.arg2; 5 | lol = arg1 + arg2; 6 | disp(lol) 7 | end -------------------------------------------------------------------------------- /voc-release4.01/model_addblock.m: -------------------------------------------------------------------------------- 1 | function [m, blocklabel] = model_addblock(m, sz, regmult, learnmult, lowerbounds) 2 | % Add a block of weights to the model. 3 | % 4 | % m object model 5 | % sz number of weights in the block 6 | % regmult regularization multiplier for the entire block 7 | % learnmult learning rate multiplier for the entire block 8 | % lowerbounds lower-bound for each weight in the block 9 | 10 | blocklabel = m.numblocks + 1; 11 | m.numblocks = blocklabel; 12 | m.blocksizes(blocklabel) = sz; 13 | 14 | if nargin < 3 15 | regmult = 1; 16 | end 17 | 18 | if nargin < 4 19 | learnmult = 1; 20 | end 21 | 22 | if nargin < 5 23 | % default value that should be low enough to never 24 | % influence the model 25 | lowerbounds = -100*ones(sz, 1); 26 | end 27 | 28 | m.regmult(blocklabel) = regmult; 29 | m.learnmult(blocklabel) = learnmult; 30 | m.lowerbounds{blocklabel} = lowerbounds; 31 | -------------------------------------------------------------------------------- /voc-release4.01/model_addfilter.m: -------------------------------------------------------------------------------- 1 | function [m, symbol, filterind] = model_addfilter(m, w, symmetric, blocklabel, flip) 2 | % Add a filter to the model. Automatically allocates a new block if blocklabel is empty. 3 | % 4 | % m object model 5 | % w filter weights 6 | % symmetric 'M'irrored or 'N'one 7 | % blocklabel block to use for the filter weights 8 | % flip is this filter vertically flipped 9 | 10 | % set argument defaults 11 | if nargin < 3 12 | symmetric = 'N'; 13 | end 14 | 15 | if nargin < 4 16 | blocklabel = []; 17 | end 18 | 19 | if nargin < 5 20 | flip = false; 21 | end 22 | 23 | % M = vertical mirrored partner 24 | % N = none (no symmetry) 25 | if symmetric ~= 'M' && symmetric ~= 'N' 26 | error('parameter symmetric must be either M or N'); 27 | end 28 | 29 | % get index for new filter 30 | j = m.numfilters + 1; 31 | m.numfilters = j; 32 | 33 | % get new blocklabel 34 | if isempty(blocklabel) 35 | width = size(w,2); 36 | height = size(w,1); 37 | depth = size(w,3); 38 | [m, blocklabel] = model_addblock(m, width*height*depth); 39 | end 40 | 41 | m.filters(j).w = w; 42 | m.filters(j).blocklabel = blocklabel; 43 | m.filters(j).symmetric = symmetric; 44 | m.filters(j).size = [size(w, 1) size(w, 2)]; 45 | m.filters(j).flip = flip; 46 | 47 | % new symbol for terminal associated with filter f 48 | [m, i] = model_addsymbol(m, 'T'); 49 | m.symbols(i).filter = j; 50 | m.filters(j).symbol = i; 51 | 52 | filterind = j; 53 | symbol = i; 54 | -------------------------------------------------------------------------------- /voc-release4.01/model_addmirroredfilter.m: -------------------------------------------------------------------------------- 1 | function [m, symbol, filterind] = model_addmirroredfilter(m, fi) 2 | % Add a filter that mirrors one already in the model. 3 | % 4 | % m object model 5 | % fi mirror model.filters(fi) 6 | 7 | blocklabel = m.filters(fi).blocklabel; 8 | w = flipfeat(m.filters(fi).w); 9 | flip = ~m.filters(fi).flip; 10 | [m, symbol, filterind] = model_addfilter(m, w, 'M', ... 11 | blocklabel, flip); 12 | -------------------------------------------------------------------------------- /voc-release4.01/model_addnonterminal.m: -------------------------------------------------------------------------------- 1 | function [m, N] = model_addnonterminal(m) 2 | % Add a nonterminal symbol to the model. 3 | % 4 | % m object model 5 | 6 | [m, N] = model_addsymbol(m, 'N'); 7 | -------------------------------------------------------------------------------- /voc-release4.01/model_addparts.m: -------------------------------------------------------------------------------- 1 | function model = model_addparts(model, lhs, ruleind, filterind, numparts, psize) 2 | % Add part filters to a model. 3 | % 4 | % model object model 5 | % lhs add parts to: model.rules{lhs}(ruleind) 6 | % ruleind add parts to: model.rules{lhs}(ruleind) 7 | % filterind source filter to initialize parts from 8 | % numparts number of parts to add 9 | % psize size of each part 10 | 11 | % if the filter is mirrored, find its partner so mirrored 12 | % parts can be added to it as well 13 | partner = []; 14 | sym = 'N'; 15 | if model.filters(filterind).symmetric == 'M' 16 | bl = model.filters(filterind).blocklabel; 17 | for i = 1:model.numfilters 18 | if i ~= filterind && model.filters(i).blocklabel == bl 19 | partner = i; 20 | sym = 'M'; 21 | break; 22 | end 23 | end 24 | end 25 | 26 | source = model.filters(filterind).w; 27 | pfilters = mkpartfilters(source, psize, numparts); 28 | 29 | for i = 1:numparts 30 | [model, symbolf, fi] = model_addfilter(model, pfilters(i).w, sym); 31 | [model, N1] = model_addnonterminal(model); 32 | 33 | % add deformation rule 34 | defoffset = 0; 35 | defparams = pfilters(i).alpha*[0.1 0 0.1 0]; 36 | [model, offsetbl, defbl] = model_addrule(model, 'D', N1, symbolf, ... 37 | defoffset, defparams, sym); 38 | 39 | % add deformation symbols to rhs of rule 40 | anchor1 = pfilters(i).anchor; 41 | model.rules{lhs}(ruleind).rhs = [model.rules{lhs}(ruleind).rhs N1]; 42 | model.rules{lhs}(ruleind).anchor = [model.rules{lhs}(ruleind).anchor anchor1]; 43 | 44 | if ~isempty(partner) 45 | [model, symbolfp, fi] = model_addmirroredfilter(model, fi); 46 | [model, N2] = model_addnonterminal(model); 47 | 48 | % add mirrored deformation rule 49 | model = model_addrule(model, 'D', N2, symbolfp, ... 50 | defoffset, defparams, sym, offsetbl, defbl); 51 | 52 | x = pfilters(i).anchor(1) + 1; 53 | y = pfilters(i).anchor(2) + 1; 54 | % add deformation symbols to rhs of rule 55 | x2 = 2*size(source, 2)-(x+psize(2)-1)+1; 56 | anchor2 = [x2-1 y-1 1]; 57 | model.rules{lhs}(partner).rhs = [model.rules{lhs}(partner).rhs N2]; 58 | model.rules{lhs}(partner).anchor = [model.rules{lhs}(partner).anchor anchor2]; 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /voc-release4.01/model_addrule.m: -------------------------------------------------------------------------------- 1 | function [m, offsetbl, defbl] = model_addrule(m, type, lhs, rhs, offset, ... 2 | params, symmetric, offsetbl, defbl) 3 | % Add a rule to the model. 4 | % 5 | % m object model 6 | % type 'D'eformation or 'S'tructural 7 | % lhs left hand side rule symbol 8 | % rhs right hand side rule symbols 9 | % offset production score 10 | % params anchor position for structural rules 11 | % deformation model for deformation rules 12 | % symmetric 'N'one or 'M'irrored 13 | % offsetbl block for offset 14 | % defbl block for deformation model 15 | 16 | % validate input 17 | if length(type) ~= 1 || (type ~= 'S' && type ~= 'D') 18 | error('type must be either S or D'); 19 | end 20 | 21 | if nargin < 7 22 | symmetric = 'N'; 23 | else 24 | if symmetric ~= 'N' && symmetric ~= 'M' 25 | error('Parameter symmetric must be either N or M.'); 26 | end 27 | end 28 | 29 | if nargin < 8 30 | offsetbl = []; 31 | end 32 | 33 | if nargin < 9 34 | defbl = []; 35 | end 36 | 37 | try 38 | i = length(m.rules{lhs}) + 1; 39 | catch 40 | i = 1; 41 | m.rules{lhs} = []; 42 | end 43 | 44 | m.rules{lhs}(i).type = type; 45 | m.rules{lhs}(i).lhs = lhs; 46 | m.rules{lhs}(i).rhs = rhs; 47 | m.rules{lhs}(i).detwindow = [0 0]; 48 | m.rules{lhs}(i).i = i; 49 | if isempty(offsetbl) 50 | if type == 'S' 51 | [m, offsetbl] = model_addblock(m, 1, 0, 20); 52 | elseif type == 'D' 53 | % by default set the learning rate and regularization 54 | % multipliers to zero for deformation rule offsets 55 | [m, offsetbl] = model_addblock(m, 1, 0, 0); 56 | end 57 | end 58 | m.rules{lhs}(i).offset.w = offset; 59 | m.rules{lhs}(i).offset.blocklabel = offsetbl; 60 | if type == 'S' 61 | m.rules{lhs}(i).anchor = params; 62 | elseif type == 'D' 63 | if isempty(defbl) 64 | [m, defbl] = model_addblock(m, numel(params), ... 65 | 10, 0.1, [0.01 -100 0.01 -100]); 66 | flip = false; 67 | else 68 | % if a blocklabel is given, this deformation rule is mirroring 69 | % the deformation rule that uses the given blocklabel 70 | flip = true; 71 | end 72 | m.rules{lhs}(i).def.w = params; 73 | m.rules{lhs}(i).def.blocklabel = defbl; 74 | m.rules{lhs}(i).def.flip = flip; 75 | m.rules{lhs}(i).def.symmetric = symmetric; 76 | end 77 | -------------------------------------------------------------------------------- /voc-release4.01/model_addsymbol.m: -------------------------------------------------------------------------------- 1 | function [m, i] = model_addsymbol(m, type) 2 | % Add a symbol to the model. 3 | % 4 | % m object model 5 | % type 'N'onterminal or 'T'erminal 6 | 7 | % new symbol for terminal associated with filter f 8 | i = m.numsymbols + 1; 9 | m.numsymbols = i; 10 | m.symbols(i).type = type; 11 | m.symbols(i).i = i; 12 | -------------------------------------------------------------------------------- /voc-release4.01/model_create.m: -------------------------------------------------------------------------------- 1 | function m = model_create(cls, note) 2 | % Create an object model. 3 | % 4 | % cls object class (e.g., 'bicycle') 5 | % note a useful note (e.g., 'testing new features X, Y, and Z') 6 | 7 | globals; 8 | 9 | if nargin < 2 10 | note = ''; 11 | end 12 | 13 | m.class = cls; % object class/category 14 | m.year = VOCyear; % dataset year (PASCAL specific) 15 | m.note = note; % decription of the model 16 | m.filters = []; % filters (terminals) 17 | m.rules = {}; % rules 18 | m.symbols = []; % grammar symbol table 19 | m.numfilters = 0; % length(model.filters) 20 | m.numblocks = 0; % length(model.blocks) 21 | m.numsymbols = 0; % length(model.symbols) 22 | m.blocksizes = []; % length of each block of model parameters 23 | m.start = []; % grammar start symbol 24 | m.maxsize = -[inf inf]; % size of the largest detection window 25 | m.minsize = [inf inf]; % size of the smallest detection window 26 | m.interval = 10; % # levels in each feature pyramid octave 27 | m.sbin = 8; % pixel size of the HOG cells 28 | m.thresh = 0; % detection threshold 29 | m.regmult = []; % per block regularization multiplier 30 | m.learnmult = []; % per block learning rate multiplier 31 | m.lowerbounds = {}; % per parameter lower bound 32 | -------------------------------------------------------------------------------- /voc-release4.01/model_setdetwindow.m: -------------------------------------------------------------------------------- 1 | function m = model_setdetwindow(m, lhs, ruleind, win) 2 | % Set the detection window for a rule. 3 | % 4 | % m object model 5 | % lhs lhs symbol 6 | % ruleind rule index 7 | % win detection window [height width] 8 | 9 | m.rules{lhs}(ruleind).detwindow = win; 10 | m.maxsize = max([win; m.maxsize]); 11 | m.minsize = min([win; m.minsize]); 12 | -------------------------------------------------------------------------------- /voc-release4.01/model_sort.m: -------------------------------------------------------------------------------- 1 | function [L, V] = model_sort(m, i, L, V) 2 | % Perform topological sort of the non-terminal symbols in m's grammar. 3 | % 4 | % m object model 5 | % 6 | % internal use: 7 | % i current symbol 8 | % L post order accumulation of symbols 9 | % V symbol visitation state 10 | 11 | % initialize depth-first search at start symbol 12 | if nargin < 2 13 | i = m.start; 14 | L = []; 15 | V = zeros(m.numsymbols, 1); 16 | end 17 | 18 | % check for cycle containing symbol i 19 | if V(i) == 1 20 | error('Cycle detected in grammar!'); 21 | end 22 | 23 | % mark symbol i as pre-visit 24 | V(i) = 1; 25 | for r = rules_with_lhs(m, i) 26 | for s = r.rhs 27 | % recurse if s is a non-terminal and not already visited 28 | if m.symbols(s).type == 'N' && V(s) < 2 29 | [L, V] = model_sort(m, s, L, V); 30 | end 31 | end 32 | end 33 | % mark symbol i as post-visit 34 | V(i) = 2; 35 | L = [L i]; 36 | -------------------------------------------------------------------------------- /voc-release4.01/nms.m: -------------------------------------------------------------------------------- 1 | function pick = nms(boxes, overlap) 2 | 3 | % pick = nms(boxes, overlap) 4 | % Non-maximum suppression. 5 | % Greedily select high-scoring detections and skip detections 6 | % that are significantly covered by a previously selected detection. 7 | 8 | if isempty(boxes) 9 | pick = []; 10 | else 11 | x1 = boxes(:,1); 12 | y1 = boxes(:,2); 13 | x2 = boxes(:,3); 14 | y2 = boxes(:,4); 15 | s = boxes(:,end); 16 | area = (x2-x1+1) .* (y2-y1+1); 17 | 18 | [vals, I] = sort(s); 19 | pick = []; 20 | while ~isempty(I) 21 | last = length(I); 22 | i = I(last); 23 | pick = [pick; i]; 24 | suppress = [last]; 25 | for pos = 1:last-1 26 | j = I(pos); 27 | xx1 = max(x1(i), x1(j)); 28 | yy1 = max(y1(i), y1(j)); 29 | xx2 = min(x2(i), x2(j)); 30 | yy2 = min(y2(i), y2(j)); 31 | w = xx2-xx1+1; 32 | h = yy2-yy1+1; 33 | if w > 0 && h > 0 34 | % compute overlap 35 | o = w * h / area(j); 36 | if o > overlap 37 | suppress = [suppress; pos]; 38 | end 39 | end 40 | end 41 | I(suppress) = []; 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /voc-release4.01/parsemodel.m: -------------------------------------------------------------------------------- 1 | function model = parsemodel(model, blocks, i) 2 | 3 | % parsemodel(model, blocks) 4 | % Update model parameters from weight vector representation. 5 | 6 | if nargin < 3 7 | i = model.start; 8 | end 9 | 10 | if model.symbols(i).type == 'T' 11 | % i is a terminal/filter 12 | % save filter weights from blocks 13 | fi = model.symbols(i).filter; 14 | if model.filters(fi).symmetric == 'M' 15 | f = reshape(blocks{model.filters(fi).blocklabel}, ... 16 | size(model.filters(fi).w)); 17 | if model.filters(fi).flip 18 | f = flipfeat(f); 19 | end 20 | model.filters(fi).w = f; 21 | elseif model.filters(fi).symmetric == 'N' 22 | f = reshape(blocks{model.filters(fi).blocklabel}, ... 23 | size(model.filters(fi).w)); 24 | model.filters(fi).w = f; 25 | else 26 | error('unknown filter symmetry type'); 27 | end 28 | else 29 | % i is a non-terminal 30 | for r = rules_with_lhs(model, i) 31 | model.rules{r.lhs}(r.i).offset.w = blocks{r.offset.blocklabel}; 32 | if r.type == 'D' 33 | sz = size(model.rules{r.lhs}(r.i).def.w); 34 | model.rules{r.lhs}(r.i).def.w = reshape(blocks{r.def.blocklabel}, sz); 35 | if r.def.symmetric == 'M' && r.def.flip 36 | % flip linear term in horizontal deformation model 37 | model.rules{r.lhs}(r.i).def.w(2) = -model.rules{r.lhs}(r.i).def.w(2); 38 | end 39 | end 40 | for s = r.rhs 41 | % recurse 42 | model = parsemodel(model, blocks, s); 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /voc-release4.01/pascal.m: -------------------------------------------------------------------------------- 1 | function [ap1, ap2] = pascal(cls, n, note, dotrainval, testyear) 2 | 3 | % ap = pascal(cls, n, note) 4 | % Train and score a model with 2*n components. 5 | % note allows you to save a note with the trained model 6 | % example: note = 'testing FRHOG (FRobnicated HOG) features' 7 | % testyear allows you to test on a year other than VOCyear (set in globals.m) 8 | 9 | globals; 10 | pascal_init; 11 | 12 | if nargin < 4 13 | dotrainval = false; 14 | end 15 | 16 | if nargin < 5 17 | % which year to test on -- a string, e.g., '2007'. 18 | testyear = VOCyear; 19 | end 20 | 21 | % record a log of the training procedure 22 | diary([cachedir cls '.log']); 23 | 24 | % set the note to the training time if none is given 25 | if nargin < 3 26 | note = datestr(datevec(now()), 'HH-MM-SS'); 27 | end 28 | model = pascal_train(cls, n, note); 29 | % lower threshold to get high recall 30 | model.thresh = min(-1.1, model.thresh); 31 | 32 | boxes1 = pascal_test(cls, model, 'test', testyear, testyear); 33 | ap1 = pascal_eval(cls, boxes1, 'test', testyear, testyear); 34 | [ap1, ap2] = bboxpred_rescore(cls, 'test', testyear); 35 | 36 | % compute detections on the trainval dataset (used for context rescoring) 37 | if dotrainval 38 | trainval(cls); 39 | end 40 | 41 | % remove dat file if configured to do so 42 | if cleantmpdir 43 | unix(['rm ' tmpdir cls '.dat']); 44 | end 45 | -------------------------------------------------------------------------------- /voc-release4.01/pascal_data.m: -------------------------------------------------------------------------------- 1 | function [pos, neg] = pascal_data(cls, flippedpos, year) 2 | 3 | % [pos, neg] = pascal_data(cls) 4 | % Get training data from the PASCAL dataset. 5 | 6 | setVOCyear = year; 7 | globals; 8 | pascal_init; 9 | 10 | if nargin < 2 11 | flippedpos = false; 12 | end 13 | 14 | try 15 | load([cachedir cls '_train_' year]); 16 | catch 17 | % positive examples from train+val 18 | ids = textread(sprintf(VOCopts.imgsetpath, 'trainval'), '%s'); 19 | pos = []; 20 | numpos = 0; 21 | for i = 1:length(ids); 22 | fprintf('%s: parsing positives: %d/%d\n', cls, i, length(ids)); 23 | rec = PASreadrecord(sprintf(VOCopts.annopath, ids{i})); 24 | clsinds = strmatch(cls, {rec.objects(:).class}, 'exact'); 25 | % skip difficult examples 26 | diff = [rec.objects(clsinds).difficult]; 27 | clsinds(diff) = []; 28 | for j = clsinds(:)' 29 | numpos = numpos+1; 30 | pos(numpos).im = [VOCopts.datadir rec.imgname]; 31 | bbox = rec.objects(j).bbox; 32 | pos(numpos).x1 = bbox(1); 33 | pos(numpos).y1 = bbox(2); 34 | pos(numpos).x2 = bbox(3); 35 | pos(numpos).y2 = bbox(4); 36 | pos(numpos).flip = false; 37 | pos(numpos).trunc = rec.objects(j).truncated; 38 | if flippedpos 39 | oldx1 = bbox(1); 40 | oldx2 = bbox(3); 41 | bbox(1) = rec.imgsize(1) - oldx2 + 1; 42 | bbox(3) = rec.imgsize(1) - oldx1 + 1; 43 | numpos = numpos+1; 44 | pos(numpos).im = [VOCopts.datadir rec.imgname]; 45 | pos(numpos).x1 = bbox(1); 46 | pos(numpos).y1 = bbox(2); 47 | pos(numpos).x2 = bbox(3); 48 | pos(numpos).y2 = bbox(4); 49 | pos(numpos).flip = true; 50 | pos(numpos).trunc = rec.objects(j).truncated; 51 | end 52 | end 53 | end 54 | 55 | % negative examples from train (this seems enough!) 56 | ids = textread(sprintf(VOCopts.imgsetpath, 'train'), '%s'); 57 | neg = []; 58 | numneg = 0; 59 | for i = 1:length(ids); 60 | fprintf('%s: parsing negatives: %d/%d\n', cls, i, length(ids)); 61 | rec = PASreadrecord(sprintf(VOCopts.annopath, ids{i})); 62 | clsinds = strmatch(cls, {rec.objects(:).class}, 'exact'); 63 | if length(clsinds) == 0 64 | numneg = numneg+1; 65 | neg(numneg).im = [VOCopts.datadir rec.imgname]; 66 | neg(numneg).flip = false; 67 | end 68 | end 69 | 70 | save([cachedir cls '_train_' year], 'pos', 'neg'); 71 | end 72 | -------------------------------------------------------------------------------- /voc-release4.01/pascal_eval.m: -------------------------------------------------------------------------------- 1 | function ap = pascal_eval(cls, boxes, testset, year, suffix) 2 | 3 | % ap = pascal_eval(cls, boxes, testset, suffix) 4 | % Score bounding boxes using the PASCAL development kit. 5 | 6 | setVOCyear = year; 7 | globals; 8 | pascal_init; 9 | ids = textread(sprintf(VOCopts.imgsetpath, testset), '%s'); 10 | 11 | % write out detections in PASCAL format and score 12 | fid = fopen(sprintf(VOCopts.detrespath, 'comp3', cls), 'w'); 13 | for i = 1:length(ids); 14 | bbox = boxes{i}; 15 | for j = 1:size(bbox,1) 16 | fprintf(fid, '%s %f %d %d %d %d\n', ids{i}, bbox(j,end), bbox(j,1:4)); 17 | end 18 | end 19 | fclose(fid); 20 | 21 | VOCopts.testset = testset; 22 | if str2num(VOCyear) == 2006 23 | [recall, prec, ap] = VOCpr(VOCopts, 'comp3', cls, true); 24 | elseif str2num(VOCyear) < 2008 25 | [recall, prec, ap] = VOCevaldet(VOCopts, 'comp3', cls, true); 26 | else 27 | recall = 0; 28 | prec = 0; 29 | ap = 0; 30 | end 31 | 32 | if str2num(VOCyear) < 2008 33 | % force plot limits 34 | ylim([0 1]); 35 | xlim([0 1]); 36 | 37 | % save results 38 | save([cachedir cls '_pr_' testset '_' suffix], 'recall', 'prec', 'ap'); 39 | print(gcf, '-djpeg', '-r0', [cachedir cls '_pr_' testset '_' suffix '.jpg']); 40 | end 41 | -------------------------------------------------------------------------------- /voc-release4.01/pascal_init.m: -------------------------------------------------------------------------------- 1 | 2 | % initialize the PASCAL development kit 3 | tmp = pwd; 4 | cd(VOCdevkit); 5 | addpath([cd '/VOCcode']); 6 | VOCinit; 7 | cd(tmp); 8 | -------------------------------------------------------------------------------- /voc-release4.01/pascal_test.m: -------------------------------------------------------------------------------- 1 | function boxes1 = pascal_test(cls, model, testset, year, suffix) 2 | 3 | % boxes1 = pascal_test(cls, model, testset, year, suffix) 4 | % Compute bounding boxes in a test set. 5 | % boxes1 are detection windows and scores. 6 | 7 | % Now we also save the locations of each filter for rescoring 8 | % parts1 gives the locations for the detections in boxes1 9 | % (these are saved in the cache file, but not returned by the function) 10 | 11 | setVOCyear = year; 12 | globals; 13 | pascal_init; 14 | 15 | ids = textread(sprintf(VOCopts.imgsetpath, testset), '%s'); 16 | 17 | % run detector in each image 18 | try 19 | load([cachedir cls '_boxes_' testset '_' suffix]); 20 | catch 21 | % parfor gets confused if we use VOCopts 22 | opts = VOCopts; 23 | parfor i = 1:length(ids); 24 | fprintf('%s: testing: %s %s, %d/%d\n', cls, testset, year, ... 25 | i, length(ids)); 26 | if strcmp('inriaperson', cls) 27 | % INRIA uses a mixutre of PNGs and JPGs, so we need to use the annotation 28 | % to locate the image. The annotation is not generally available for PASCAL 29 | % test data (e.g., 2009 test), so this method can fail for PASCAL. 30 | rec = PASreadrecord(sprintf(opts.annopath, ids{i})); 31 | im = imread([opts.datadir rec.imgname]); 32 | else 33 | im = imread(sprintf(opts.imgpath, ids{i})); 34 | end 35 | [dets, boxes] = imgdetect(im, model, model.thresh); 36 | if ~isempty(boxes) 37 | boxes = reduceboxes(model, boxes); 38 | [dets boxes] = clipboxes(im, dets, boxes); 39 | I = nms(dets, 0.5); 40 | boxes1{i} = dets(I,[1:4 end]); 41 | parts1{i} = boxes(I,:); 42 | else 43 | boxes1{i} = []; 44 | parts1{i} = []; 45 | end 46 | %showboxes(im, boxes1{i}); 47 | end 48 | save([cachedir cls '_boxes_' testset '_' suffix], ... 49 | 'boxes1', 'parts1'); 50 | end 51 | -------------------------------------------------------------------------------- /voc-release4.01/pascal_train.m: -------------------------------------------------------------------------------- 1 | function model = pascal_train(cls, n, note) 2 | 3 | % model = pascal_train(cls, n, note) 4 | % Train a model with 2*n components using the PASCAL dataset. 5 | % note allows you to save a note with the trained model 6 | % example: note = 'testing FRHOG (FRobnicated HOG) 7 | 8 | % At every "checkpoint" in the training process we reset the 9 | % RNG's seed to a fixed value so that experimental results are 10 | % reproducible. 11 | initrand(); 12 | 13 | if nargin < 3 14 | note = ''; 15 | end 16 | 17 | globals; 18 | [pos, neg] = pascal_data(cls, true, VOCyear); 19 | % split data by aspect ratio into n groups 20 | spos = split(cls, pos, n); 21 | 22 | cachesize = 24000; 23 | maxneg = 200; 24 | 25 | % train root filters using warped positives & random negatives 26 | try 27 | load([cachedir cls '_lrsplit1']); 28 | catch 29 | initrand(); 30 | for i = 1:n 31 | % split data into two groups: left vs. right facing instances 32 | models{i} = initmodel(cls, spos{i}, note, 'N'); 33 | inds = lrsplit(models{i}, spos{i}, i); 34 | models{i} = train(cls, models{i}, spos{i}(inds), neg, i, 1, 1, 1, ... 35 | cachesize, true, 0.7, false, ['lrsplit1_' num2str(i)]); 36 | end 37 | save([cachedir cls '_lrsplit1'], 'models'); 38 | end 39 | 40 | % train root left vs. right facing root filters using latent detections 41 | % and hard negatives 42 | try 43 | load([cachedir cls '_lrsplit2']); 44 | catch 45 | initrand(); 46 | for i = 1:n 47 | models{i} = lrmodel(models{i}); 48 | models{i} = train(cls, models{i}, spos{i}, neg(1:maxneg), 0, 0, 4, 3, ... 49 | cachesize, true, 0.7, false, ['lrsplit2_' num2str(i)]); 50 | end 51 | save([cachedir cls '_lrsplit2'], 'models'); 52 | end 53 | 54 | % merge models and train using latent detections & hard negatives 55 | try 56 | load([cachedir cls '_mix']); 57 | catch 58 | initrand(); 59 | model = mergemodels(models); 60 | model = train(cls, model, pos, neg(1:maxneg), 0, 0, 1, 5, ... 61 | cachesize, true, 0.7, false, 'mix'); 62 | save([cachedir cls '_mix'], 'model'); 63 | end 64 | 65 | % add parts and update models using latent detections & hard negatives. 66 | try 67 | load([cachedir cls '_parts']); 68 | catch 69 | initrand(); 70 | for i = 1:2:2*n 71 | model = model_addparts(model, model.start, i, i, 8, [6 6]); 72 | end 73 | model = train(cls, model, pos, neg(1:maxneg), 0, 0, 8, 10, ... 74 | cachesize, true, 0.7, false, 'parts_1'); 75 | model = train(cls, model, pos, neg, 0, 0, 1, 5, ... 76 | cachesize, true, 0.7, true, 'parts_2'); 77 | save([cachedir cls '_parts'], 'model'); 78 | end 79 | 80 | save([cachedir cls '_final'], 'model'); 81 | -------------------------------------------------------------------------------- /voc-release4.01/persontest.m: -------------------------------------------------------------------------------- 1 | function lol = persontest(args) 2 | image = args.arg1; 3 | load INRIA/inriaperson_final.mat; 4 | im = imread(image); 5 | [dets, boxes] = imgdetect(im, model, -0.3); 6 | %disp(dets) 7 | top = nms(dets, 0.5); 8 | %disp(dets) 9 | %disp(boxes(top,:)); 10 | %showboxes(im, reduceboxes(model, boxes(top,:))); 11 | %disp(reduceboxes(model, boxes(top,:))) 12 | lol = reduceboxes(model, boxes(top,:)); 13 | end -------------------------------------------------------------------------------- /voc-release4.01/process.m: -------------------------------------------------------------------------------- 1 | function [det, all] = process(image, model, thresh) 2 | 3 | % bbox = process(image, model, thresh) 4 | % Detect objects that score above a threshold, return bonding boxes. 5 | % If the threshold is not included we use the one in the model. 6 | % This should lead to high-recall but low precision. 7 | 8 | globals; 9 | 10 | if nargin < 3 11 | thresh = model.thresh 12 | end 13 | 14 | [det, all] = imgdetect(image, model, thresh); 15 | 16 | if ~isempty(det) 17 | try 18 | % attempt to use bounding box prediction, if available 19 | bboxpred = model.bboxpred; 20 | [det all] = clipboxes(image, det, all); 21 | [det all] = bboxpred_get(bboxpred, det, reduceboxes(model, all)); 22 | catch 23 | warning('no bounding box predictor found'); 24 | end 25 | [det all] = clipboxes(image, det, all); 26 | I = nms(det, 0.5); 27 | det = det(I,:); 28 | all = all(I,:); 29 | end 30 | -------------------------------------------------------------------------------- /voc-release4.01/procid.m: -------------------------------------------------------------------------------- 1 | function s = procid() 2 | 3 | d = pwd(); 4 | i = strfind(d, '/'); 5 | d = d(i(end)+1:end); 6 | s = d; 7 | -------------------------------------------------------------------------------- /voc-release4.01/readinfo.m: -------------------------------------------------------------------------------- 1 | function [labels, scores, unique] = readinfo(inffile) 2 | 3 | % [labels, scores, unique] = readinfo(file) 4 | % Parse training info file. 5 | % Used in the interface with the gradient descent algorithm. 6 | 7 | [labels, scores, unique] = textread(inffile, '%d%f%d', 'delimiter', '\t'); 8 | -------------------------------------------------------------------------------- /voc-release4.01/readmodel.m: -------------------------------------------------------------------------------- 1 | function blocks = readmodel(f, model) 2 | 3 | % blocks = readmodel(f, model) 4 | % Read model paramaters from data file. 5 | % Used in the interface with the gradient descent algorithm. 6 | 7 | fid = fopen(f, 'rb'); 8 | for i = 1:model.numblocks 9 | blocks{i} = fread(fid, model.blocksizes(i), 'double'); 10 | end 11 | fclose(fid); 12 | -------------------------------------------------------------------------------- /voc-release4.01/reduceboxes.m: -------------------------------------------------------------------------------- 1 | function b = reduceboxes(model, boxes) 2 | % Eliminate columns for filters that are not used. 3 | % E.g., [0 0 0 0 10 20 110 120] -> [10 20 110 120] 4 | % Index end-1 is the component label and index end is the 5 | % detection score. 6 | % 7 | % model object model 8 | % boxes filter boxes returned by gdetect.m 9 | 10 | % n = #filters per component (assuming all components have 11 | % the same number of parts) 12 | n = length(model.rules{model.start}(1).rhs); 13 | % n*4+2 := 4 coordinates per boxes plus the component index 14 | % and score 15 | b = zeros(size(boxes, 1), n*4+2); 16 | maxc = max(boxes(:,end-1)); 17 | for i = 1:maxc 18 | % process boxes for component i 19 | I = find(boxes(:,end-1) == i); 20 | tmp = boxes(I,:); 21 | del = []; 22 | % find unused filters 23 | for j = 1:4:size(boxes, 2)-2 24 | % count # of non-zero coordinates 25 | s = sum(sum(tmp(:,j:j+3)~=0)); 26 | % the filter was not used if all coordinates are zero 27 | if s == 0 28 | del = [del j:j+3]; 29 | end 30 | end 31 | % remove all unused filters 32 | tmp(:,del) = []; 33 | b(I,:) = tmp; 34 | end 35 | -------------------------------------------------------------------------------- /voc-release4.01/release4-notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/release4-notes.pdf -------------------------------------------------------------------------------- /voc-release4.01/rescore_data.m: -------------------------------------------------------------------------------- 1 | function [boxes, parts, X] = rescore_data(dataset) 2 | 3 | % Compute feature vectors for context rescoring. 4 | 5 | globals; 6 | pascal_init; 7 | 8 | ids = textread(sprintf(VOCopts.imgsetpath, dataset), '%s'); 9 | numids = length(ids); 10 | numcls = length(VOCopts.classes); 11 | 12 | % get dimensions of each image in the dataset 13 | try 14 | load([cachedir 'sizes_' dataset '_' VOCyear]) 15 | catch 16 | sizes = cell(numids,1); 17 | for i = 1:numids; 18 | name = sprintf(VOCopts.imgpath, ids{i}); 19 | im = imread(name); 20 | sizes{i} = size(im); 21 | end 22 | save([cachedir 'sizes_' dataset '_' VOCyear], 'sizes'); 23 | end 24 | 25 | % generate the rescoring data 26 | try 27 | load([cachedir 'rescore_data_' dataset '_' VOCyear]); 28 | catch 29 | boxes = cell(numcls, 1); 30 | parts = cell(numcls, 1); 31 | models = cell(numcls, 1); 32 | for i = 1:numcls 33 | load([cachedir VOCopts.classes{i} '_final']); 34 | models{i} = model; 35 | load([cachedir VOCopts.classes{i} '_boxes_' dataset '_bboxpred_' VOCyear]); 36 | boxes{i} = boxes1; 37 | end 38 | 39 | for j = 1:numcls 40 | data = cell2mat(boxes{j}); 41 | % keep only highest scoring detections 42 | if size(data,1) > 50000 43 | s = data(:,end); 44 | s = sort(s); 45 | v = s(end-50000+1); 46 | for i = 1:numids; 47 | if ~isempty(boxes{j}{i}) 48 | I = find(boxes{j}{i}(:,end) >= v); 49 | boxes{j}{i} = boxes{j}{i}(I,:); 50 | end 51 | end 52 | end 53 | end 54 | 55 | % build data 56 | X = cell(numcls, numids); 57 | maxes = zeros(1, numcls); 58 | for i = 1:numids 59 | for j = 1:numcls 60 | if isempty(boxes{j}{i}) 61 | maxes(j) = models{j}.thresh; 62 | else 63 | maxes(j) = max(models{j}.thresh, max(boxes{j}{i}(:,end))); 64 | end 65 | end 66 | maxes = 1 ./ (1 + exp(-1.5*maxes)); 67 | 68 | s = sizes{i}; 69 | base = [zeros(1,5) maxes]; 70 | for j = 1:numcls 71 | bbox = boxes{j}{i}; 72 | if ~isempty(bbox) 73 | n = size(bbox,1); 74 | x = repmat(base, [n, 1]); 75 | score = bbox(:,end); 76 | x(:,1) = 1 ./ (1 + exp(-1.5*score)); 77 | x(:,2:5) = boxes{j}{i}(:,1:4); 78 | x(:,2) = x(:,2) / s(2); 79 | x(:,3) = x(:,3) / s(1); 80 | x(:,4) = x(:,4) / s(2); 81 | x(:,5) = x(:,5) / s(1); 82 | X{j,i} = x; 83 | end 84 | end 85 | 86 | end 87 | 88 | save([cachedir 'rescore_data_' dataset '_' VOCyear], 'X', ... 89 | 'boxes', 'parts'); 90 | end 91 | -------------------------------------------------------------------------------- /voc-release4.01/rescore_labels.m: -------------------------------------------------------------------------------- 1 | function labels = rescore_labels(cls, boxes, trainset) 2 | 3 | globals; 4 | pascal_init; 5 | 6 | try 7 | load([cachedir cls '_rescore_labels_' trainset '_' VOCyear]); 8 | catch 9 | [gt, npos] = labeldata(cls, trainset); 10 | [gtids,t] = textread(sprintf(VOCopts.imgsetpath,trainset),'%s %d'); 11 | 12 | labels = cell(length(gtids),1); 13 | 14 | L = 0; 15 | for i = 1:length(gtids) 16 | L = L + size(boxes{i},1); 17 | end 18 | 19 | detections = zeros(L,7); 20 | I = 1; 21 | for i = 1:length(gtids) 22 | if ~isempty(boxes{i}) 23 | l = size(boxes{i},1); 24 | detections(I:I+l-1,1) = boxes{i}(:,end); 25 | detections(I:I+l-1,2:5) = boxes{i}(:,1:4); 26 | detections(I:I+l-1,6) = i; 27 | detections(I:I+l-1,7) = 1:l; 28 | labels{i} = zeros(l,1); 29 | I = I+l; 30 | else 31 | labels{i} = []; 32 | end 33 | end 34 | 35 | [sc, si] = sort(-detections(:,1)); 36 | ids = detections(si,6); 37 | idx = detections(si,7); 38 | BB = detections(si,2:5)'; 39 | 40 | % assign detections to ground truth objects 41 | nd=length(si); 42 | tp=zeros(nd,1); 43 | fp=zeros(nd,1); 44 | for d=1:nd 45 | % find ground truth image 46 | i=ids(d); 47 | 48 | % assign detection to ground truth object if any 49 | bb=BB(:,d); 50 | ovmax=-inf; 51 | for j=1:size(gt(i).BB,2) 52 | bbgt=gt(i).BB(:,j); 53 | bi=[max(bb(1),bbgt(1)) ; max(bb(2),bbgt(2)) ; min(bb(3),bbgt(3)) ; min(bb(4),bbgt(4))]; 54 | iw=bi(3)-bi(1)+1; 55 | ih=bi(4)-bi(2)+1; 56 | if iw>0 & ih>0 57 | % compute overlap as area of intersection / area of union 58 | ua=(bb(3)-bb(1)+1)*(bb(4)-bb(2)+1)+... 59 | (bbgt(3)-bbgt(1)+1)*(bbgt(4)-bbgt(2)+1)-... 60 | iw*ih; 61 | ov=iw*ih/ua; 62 | if ov>ovmax 63 | ovmax=ov; 64 | jmax=j; 65 | end 66 | end 67 | end 68 | % assign detection as true positive/don't care/false positive 69 | if ovmax>=VOCopts.minoverlap 70 | if ~gt(i).diff(jmax) 71 | if ~gt(i).det(jmax) 72 | tp(d)=1; % true positive 73 | gt(i).det(jmax)=true; 74 | labels{i}(idx(d)) = 1; 75 | else 76 | fp(d)=1; % false positive (multiple detection) 77 | labels{i}(idx(d)) = -1; 78 | end 79 | else 80 | labels{i}(idx(d)) = 0; % difficult 81 | end 82 | else 83 | fp(d)=1; % false positive 84 | labels{i}(idx(d)) = -1; 85 | end 86 | end 87 | save([cachedir cls '_rescore_labels_' trainset '_' VOCyear], 'labels'); 88 | end 89 | -------------------------------------------------------------------------------- /voc-release4.01/rescore_test.m: -------------------------------------------------------------------------------- 1 | function ap = rescore_test() 2 | 3 | % Rescore detections on the test dataset using the context 4 | % rescoring SVMs trained by rescore_train.m. 5 | 6 | globals; 7 | pascal_init; 8 | 9 | dataset = 'test'; 10 | [boxes, parts, X] = rescore_data(dataset); 11 | 12 | % classify the test data 13 | ids = textread(sprintf(VOCopts.imgsetpath, dataset), '%s'); 14 | numids = length(ids); 15 | numcls = length(VOCopts.classes); 16 | ap = zeros(numcls, 1); 17 | 18 | fprintf('Rescoring detections\n'); 19 | for j = 1:numcls 20 | load([cachedir VOCopts.classes{j} '_rescore_classifier']); 21 | fprintf('%d/%d\n', j, numcls); 22 | for i = 1:numids 23 | if ~isempty(X{j,i}) 24 | [ignore, s] = svmclassify(X{j,i}, ones(size(X{j,i},1), 1), model); 25 | boxes{j}{i}(:,end) = s; 26 | end 27 | end 28 | ap(j) = pascal_eval(VOCopts.classes{j}, boxes{j}, dataset, VOCyear, ... 29 | ['rescore_' VOCyear]); 30 | end 31 | 32 | save([cachedir 'rescore_boxes_' dataset '_' VOCyear], 'boxes', 'parts'); 33 | fprintf('average = %f\n', sum(ap)/numcls); 34 | -------------------------------------------------------------------------------- /voc-release4.01/rescore_train.m: -------------------------------------------------------------------------------- 1 | function rescore_train() 2 | 3 | % Train context rescoring SVMs. 4 | 5 | globals; 6 | pascal_init; 7 | 8 | dataset = 'trainval'; 9 | [boxes, parts, XX] = rescore_data(dataset); 10 | 11 | % train classifiers 12 | numcls = length(VOCopts.classes); 13 | for i = 1:numcls 14 | cls = VOCopts.classes{i}; 15 | fprintf('\nTraining rescoring classifier: %d/%d\n', i, numcls); 16 | try 17 | load([cachedir cls '_rescore_classifier']); 18 | catch 19 | YY = rescore_labels(cls, boxes{i}, dataset); 20 | X = []; 21 | Y = []; 22 | for j = 1:size(XX,2) 23 | X = [X; XX{i,j}]; 24 | Y = [Y; YY{j}]; 25 | end 26 | I = find(Y == 0); 27 | Y(I) = []; 28 | X(I,:) = []; 29 | model = svmlearn(X, Y, ... 30 | '-t 1 -d 3 -r 1.0 -s 1.0 -j 2 -c 1.0 -e 0.001 -n 5 -m 500'); 31 | save([cachedir cls '_rescore_classifier'], 'model'); 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /voc-release4.01/resize.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "mex.h" 5 | 6 | /* 7 | * Fast image subsampling. 8 | * This is used to construct the feature pyramid. 9 | */ 10 | 11 | // struct used for caching interpolation values 12 | struct alphainfo { 13 | int si, di; 14 | double alpha; 15 | }; 16 | 17 | // copy src into dst using pre-computed interpolation values 18 | void alphacopy(double *src, double *dst, struct alphainfo *ofs, int n) { 19 | struct alphainfo *end = ofs + n; 20 | while (ofs != end) { 21 | dst[ofs->di] += ofs->alpha * src[ofs->si]; 22 | ofs++; 23 | } 24 | } 25 | 26 | // resize along each column 27 | // result is transposed, so we can apply it twice for a complete resize 28 | void resize1dtran(double *src, int sheight, double *dst, int dheight, 29 | int width, int chan) { 30 | double scale = (double)dheight/(double)sheight; 31 | double invscale = (double)sheight/(double)dheight; 32 | 33 | // we cache the interpolation values since they can be 34 | // shared among different columns 35 | int len = (int)ceil(dheight*invscale) + 2*dheight; 36 | alphainfo ofs[len]; 37 | int k = 0; 38 | for (int dy = 0; dy < dheight; dy++) { 39 | double fsy1 = dy * invscale; 40 | double fsy2 = fsy1 + invscale; 41 | int sy1 = (int)ceil(fsy1); 42 | int sy2 = (int)floor(fsy2); 43 | 44 | if (sy1 - fsy1 > 1e-3) { 45 | assert(k < len); 46 | assert(sy-1 >= 0); 47 | ofs[k].di = dy*width; 48 | ofs[k].si = sy1-1; 49 | ofs[k++].alpha = (sy1 - fsy1) * scale; 50 | } 51 | 52 | for (int sy = sy1; sy < sy2; sy++) { 53 | assert(k < len); 54 | assert(sy < sheight); 55 | ofs[k].di = dy*width; 56 | ofs[k].si = sy; 57 | ofs[k++].alpha = scale; 58 | } 59 | 60 | if (fsy2 - sy2 > 1e-3) { 61 | assert(k < len); 62 | assert(sy2 < sheight); 63 | ofs[k].di = dy*width; 64 | ofs[k].si = sy2; 65 | ofs[k++].alpha = (fsy2 - sy2) * scale; 66 | } 67 | } 68 | 69 | // resize each column of each color channel 70 | bzero(dst, chan*width*dheight*sizeof(double)); 71 | for (int c = 0; c < chan; c++) { 72 | for (int x = 0; x < width; x++) { 73 | double *s = src + c*width*sheight + x*sheight; 74 | double *d = dst + c*width*dheight + x; 75 | alphacopy(s, d, ofs, k); 76 | } 77 | } 78 | } 79 | 80 | // main function 81 | // takes a double color image and a scaling factor 82 | // returns resized image 83 | mxArray *resize(const mxArray *mxsrc, const mxArray *mxscale) { 84 | double *src = (double *)mxGetPr(mxsrc); 85 | const int *sdims = mxGetDimensions(mxsrc); 86 | if (mxGetNumberOfDimensions(mxsrc) != 3 || 87 | mxGetClassID(mxsrc) != mxDOUBLE_CLASS) 88 | mexErrMsgTxt("Invalid input"); 89 | 90 | double scale = mxGetScalar(mxscale); 91 | if (scale > 1) 92 | mexErrMsgTxt("Invalid scaling factor"); 93 | 94 | int ddims[3]; 95 | ddims[0] = (int)round(sdims[0]*scale); 96 | ddims[1] = (int)round(sdims[1]*scale); 97 | ddims[2] = sdims[2]; 98 | mxArray *mxdst = mxCreateNumericArray(3, ddims, mxDOUBLE_CLASS, mxREAL); 99 | double *dst = (double *)mxGetPr(mxdst); 100 | 101 | double *tmp = (double *)mxCalloc(ddims[0]*sdims[1]*sdims[2], sizeof(double)); 102 | resize1dtran(src, sdims[0], tmp, ddims[0], sdims[1], sdims[2]); 103 | resize1dtran(tmp, sdims[1], dst, ddims[1], ddims[0], sdims[2]); 104 | mxFree(tmp); 105 | 106 | return mxdst; 107 | } 108 | 109 | // matlab entry point 110 | // dst = resize(src, scale) 111 | // image should be color with double values 112 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 113 | if (nrhs != 2) 114 | mexErrMsgTxt("Wrong number of inputs"); 115 | if (nlhs != 1) 116 | mexErrMsgTxt("Wrong number of outputs"); 117 | plhs[0] = resize(prhs[0], prhs[1]); 118 | } 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /voc-release4.01/resize.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/voc-release4.01/resize.mexmaci64 -------------------------------------------------------------------------------- /voc-release4.01/rewritedat.m: -------------------------------------------------------------------------------- 1 | function rewritedat(datfile, inffile, hdrfile, I) 2 | 3 | % rewritedat(datfile, inffile, hdrfile, I) 4 | % Rewrite training files with a subset of the examples. 5 | % Used to shrink the cache. 6 | 7 | fhdr = fopen(hdrfile, 'rb'); 8 | header = fread(fhdr, 3, 'int32'); 9 | labelsize = header(2); 10 | fclose(fhdr); 11 | 12 | oldfile = [datfile '_tmp']; 13 | unix(['mv ' datfile ' ' oldfile]); 14 | fin = fopen(oldfile, 'rb'); 15 | fout = fopen(datfile, 'wb'); 16 | 17 | % sort indexes so we never have to seek before the current position 18 | I = sort(I); 19 | 20 | pos = 1; 21 | for i = 1:length(I) 22 | cnt = I(i)-pos; 23 | while cnt > 0 24 | % + 2 to include the num non-zero blocks and example length 25 | info = fread(fin, labelsize+2, 'int32'); 26 | dim = info(end); 27 | fseek(fin, dim*4, 0); 28 | cnt = cnt - 1; 29 | end 30 | y = fread(fin, labelsize+2, 'int32'); 31 | dim = y(end); 32 | x = fread(fin, dim, 'single'); 33 | fwrite(fout, y, 'int32'); 34 | fwrite(fout, x, 'single'); 35 | pos = I(i)+1; 36 | end 37 | 38 | fclose(fin); 39 | fclose(fout); 40 | 41 | % remove the old cache file 42 | unix(['rm ' oldfile]); 43 | 44 | % keep the info file in sync with the data file 45 | oldfile = [inffile '_tmp']; 46 | unix(['cp ' inffile ' ' oldfile]); 47 | [labels, scores, unique] = readinfo(inffile); 48 | labels = labels(I); 49 | scores = scores(I); 50 | unique = unique(I); 51 | fid = fopen(inffile, 'w'); 52 | for i = 1:length(I) 53 | fprintf(fid, '%d\t%f\t%d\n', labels(i), scores(i), unique(i)); 54 | end 55 | fclose(fid); 56 | -------------------------------------------------------------------------------- /voc-release4.01/rules_with_lhs.m: -------------------------------------------------------------------------------- 1 | function r = rules_with_lhs(m, i) 2 | 3 | % r = rules_with_lhs(m, i) 4 | % Return array of structs for all rules in m with symbol i on the 5 | % left-hand side. 6 | 7 | r = m.rules{i}; 8 | -------------------------------------------------------------------------------- /voc-release4.01/showboxes.m: -------------------------------------------------------------------------------- 1 | function sol = showboxes(im, boxes, out) 2 | 3 | % showboxes(im, boxes, out) 4 | % Draw bounding boxes on top of image. 5 | % If out is given, a pdf of the image is generated (requires export_fig). 6 | 7 | if nargin > 2 8 | % different settings for producing pdfs 9 | print = true; 10 | wwidth = 2.25; 11 | cwidth = 1.25; 12 | imsz = size(im); 13 | % resize so that the image is 300 pixels per inch 14 | % and 1.2 inches tall 15 | scale = 1.2 / (imsz(1)/300); 16 | im = imresize(im, scale, 'method', 'cubic'); 17 | %f = fspecial('gaussian', [3 3], 0.5); 18 | %im = imfilter(im, f); 19 | boxes = (boxes-1)*scale+1; 20 | else 21 | print = false; 22 | cwidth = 2; 23 | end 24 | 25 | image(im); 26 | if print 27 | truesize(gcf); 28 | end 29 | axis image; 30 | axis off; 31 | set(gcf, 'Color', 'white'); 32 | bigarr = []; 33 | if ~isempty(boxes) 34 | numfilters = floor(size(boxes, 2)/4); 35 | if print 36 | % if printing, increase the contrast around the boxes 37 | % by printing a white box under each color box 38 | for i = 1:numfilters 39 | x1 = boxes(:,1+(i-1)*4); 40 | y1 = boxes(:,2+(i-1)*4); 41 | x2 = boxes(:,3+(i-1)*4); 42 | y2 = boxes(:,4+(i-1)*4); 43 | % remove unused filters 44 | del = find(((x1 == 0) .* (x2 == 0) .* (y1 == 0) .* (y2 == 0)) == 1); 45 | x1(del) = []; 46 | x2(del) = []; 47 | y1(del) = []; 48 | y2(del) = []; 49 | if i == 1 50 | w = wwidth; 51 | else 52 | w = wwidth; 53 | end 54 | line([x1 x1 x2 x2 x1]', [y1 y2 y2 y1 y1]', 'color', 'w', 'linewidth', w); 55 | end 56 | end 57 | x = 0; 58 | arr = []; 59 | % draw the boxes with the detection window on top (reverse order) 60 | for i = numfilters:-1:1 61 | x1 = boxes(:,1+(i-1)*4); 62 | y1 = boxes(:,2+(i-1)*4); 63 | x2 = boxes(:,3+(i-1)*4); 64 | y2 = boxes(:,4+(i-1)*4); 65 | % remove unused filters 66 | del = find(((x1 == 0) .* (x2 == 0) .* (y1 == 0) .* (y2 == 0)) == 1); 67 | x1(del) = []; 68 | x2(del) = []; 69 | y1(del) = []; 70 | y2(del) = []; 71 | if i == 1 72 | c = [160/255 0 0]; 73 | s = '-'; 74 | else 75 | c = 'b'; 76 | s = '-'; 77 | end 78 | x = x+1; 79 | tarr =[]; 80 | if x<9 81 | tarr = [tarr x1]; 82 | tarr = [tarr y1]; 83 | tarr = [tarr x2]; 84 | tarr = [tarr y2]; 85 | disp(tarr) 86 | arr = [arr tarr]; 87 | end 88 | tarr = []; 89 | line([x1 x1 x2 x2 x1]', [y1 y2 y2 y1 y1]', 'color', c, 'linewidth', cwidth, 'linestyle', s); 90 | end 91 | bigarr = [bigarr arr]; 92 | sol = bigarr 93 | arr = []; 94 | end 95 | 96 | % save to pdf 97 | if print 98 | % requires export_fig from http://www.mathworks.com/matlabcentral/fileexchange/23629-exportfig 99 | export_fig([out]); 100 | end 101 | -------------------------------------------------------------------------------- /voc-release4.01/split.m: -------------------------------------------------------------------------------- 1 | function spos = split(name, pos, n) 2 | 3 | % spos = split(pos, n) 4 | % Split examples based on aspect ratio. 5 | % Used for initializing mixture models. 6 | 7 | h = [pos(:).y2]' - [pos(:).y1]' + 1; 8 | w = [pos(:).x2]' - [pos(:).x1]' + 1; 9 | aspects = h ./ w; 10 | aspects = sort(aspects); 11 | 12 | for i=1:n+1 13 | j = ceil((i-1)*length(aspects)/n)+1; 14 | if j > length(pos) 15 | b(i) = inf; 16 | else 17 | b(i) = aspects(j); 18 | end 19 | end 20 | 21 | aspects = h ./ w; 22 | for i=1:n 23 | I = find((aspects >= b(i)) .* (aspects < b(i+1))); 24 | spos{i} = pos(I); 25 | end 26 | -------------------------------------------------------------------------------- /voc-release4.01/subarray.m: -------------------------------------------------------------------------------- 1 | function B = subarray(A, i1, i2, j1, j2, pad) 2 | 3 | % B = subarray(A, i1, i2, j1, j2, pad) 4 | % Extract subarray from array 5 | % pad with boundary values if pad = 1 6 | % pad with zeros if pad = 0 7 | 8 | dim = size(A); 9 | B = zeros(i2-i1+1, j2-j1+1, dim(3)); 10 | if pad 11 | for i = i1:i2 12 | for j = j1:j2 13 | ii = min(max(i, 1), dim(1)); 14 | jj = min(max(j, 1), dim(2)); 15 | B(i-i1+1, j-j1+1, :) = A(ii, jj, :); 16 | end 17 | end 18 | else 19 | for i = max(i1,1):min(i2,dim(1)) 20 | for j = max(j1,1):min(j2,dim(2)) 21 | B(i-i1+1, j-j1+1, :) = A(i, j, :); 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /voc-release4.01/trainval.m: -------------------------------------------------------------------------------- 1 | function [ap1, ap2] = trainval(cls) 2 | % Evaluates the detector for class cls on the trainval dataset. 3 | % This function is used to collect detections for context rescoring. 4 | 5 | if nargin < 1 6 | % pass no arguments in order to run on all classes 7 | globals; 8 | pascal_init; 9 | for i = 1:length(VOCopts.classes) 10 | trainvalsingle(VOCopts.classes{i}); 11 | end 12 | ap1 = 0; 13 | ap2 = 0; 14 | else 15 | [ap1, ap2] = trainvalsingle(cls); 16 | end 17 | 18 | 19 | function [ap1, ap2] = trainvalsingle(cls) 20 | 21 | globals; 22 | load([cachedir cls '_final']); 23 | model.thresh = min(-1.1, model.thresh); 24 | boxes1 = pascal_test(cls, model, 'trainval', VOCyear, VOCyear); 25 | ap1 = pascal_eval(cls, boxes1, 'trainval', VOCyear, VOCyear); 26 | [ign, ap2] = bboxpred_rescore(cls, 'trainval', VOCyear); 27 | -------------------------------------------------------------------------------- /voc-release4.01/visualizeHOG.m: -------------------------------------------------------------------------------- 1 | function visualizeHOG(w) 2 | 3 | % visualizeHOG(w) 4 | % Visualize HOG features/weights. 5 | 6 | % make pictures of positive and negative weights 7 | bs = 20; 8 | w = w(:,:,1:9); 9 | scale = max(max(w(:)),max(-w(:))); 10 | pos = HOGpicture(w, bs) * 255/scale; 11 | neg = HOGpicture(-w, bs) * 255/scale; 12 | 13 | % put pictures together and draw 14 | buff = 10; 15 | pos = padarray(pos, [buff buff], 128, 'both'); 16 | if min(w(:)) < 0 17 | neg = padarray(neg, [buff buff], 128, 'both'); 18 | im = uint8([pos; neg]); 19 | else 20 | im = uint8(pos); 21 | end 22 | clf; 23 | imagesc(im); 24 | colormap gray; 25 | axis equal; 26 | axis off; 27 | 28 | 29 | -------------------------------------------------------------------------------- /voc-release4.01/visualizemodel.m: -------------------------------------------------------------------------------- 1 | function visualizemodel(model, components, layers) 2 | 3 | % visualizemodel(model) 4 | % Visualize a model. 5 | 6 | clf; 7 | if nargin < 2 8 | components = 1:length(model.rules{model.start}); 9 | end 10 | 11 | if nargin < 3 12 | layers = 1; 13 | end 14 | 15 | k = 1; 16 | for i = components 17 | for layer = layers 18 | visualizecomponent(model, i, length(layers)*length(components), k, layer); 19 | k = k+1; 20 | end 21 | end 22 | 23 | function visualizecomponent(model, c, nc, k, layer) 24 | 25 | rhs = model.rules{model.start}(c).rhs; 26 | root = -1; 27 | parts = []; 28 | defs = {}; 29 | anchors = {}; 30 | % assume the root filter is first on the rhs of the start rules 31 | if model.symbols(rhs(1)).type == 'T' 32 | % handle case where there's no deformation model for the root 33 | root = model.symbols(rhs(1)).filter; 34 | else 35 | % handle case where there is a deformation model for the root 36 | root = model.symbols(model.rules{rhs(1)}(layer).rhs).filter; 37 | end 38 | for i = 2:length(rhs) 39 | defs{end+1} = model.rules{rhs(i)}(layer).def.w; 40 | anchors{end+1} = model.rules{model.start}(c).anchor{i}; 41 | fi = model.symbols(model.rules{rhs(i)}(layer).rhs).filter; 42 | parts = [parts fi]; 43 | end 44 | % make picture of root filter 45 | pad = 2; 46 | bs = 20; 47 | w = foldHOG(model.filters(root).w); 48 | scale = max(w(:)); 49 | im = HOGpicture(w, bs); 50 | im = imresize(im, 2); 51 | im = padarray(im, [pad pad], 0); 52 | im = uint8(im * (255/scale)); 53 | 54 | % draw root 55 | numparts = length(parts); 56 | if numparts > 0 57 | subplot(nc,3,1+3*(k-1)); 58 | else 59 | subplot(nc,1,k); 60 | end 61 | imagesc(im) 62 | colormap gray; 63 | axis equal; 64 | axis off; 65 | 66 | % draw parts and deformation model 67 | if numparts > 0 68 | def_im = zeros(size(im)); 69 | def_scale = 500; 70 | for i = 1:numparts 71 | % part filter 72 | w = model.filters(parts(i)).w; 73 | p = HOGpicture(foldHOG(w), bs); 74 | p = padarray(p, [pad pad], 0); 75 | p = uint8(p * (255/scale)); 76 | % border 77 | p(:,1:2*pad) = 128; 78 | p(:,end-2*pad+1:end) = 128; 79 | p(1:2*pad,:) = 128; 80 | p(end-2*pad+1:end,:) = 128; 81 | % paste into root 82 | x1 = (anchors{i}(1))*bs+1; 83 | y1 = (anchors{i}(2))*bs+1; 84 | x2 = x1 + size(p, 2)-1; 85 | y2 = y1 + size(p, 1)-1; 86 | im(y1:y2, x1:x2) = p; 87 | 88 | % deformation model 89 | probex = size(p,2)/2; 90 | probey = size(p,1)/2; 91 | for y = 2*pad+1:size(p,1)-2*pad 92 | for x = 2*pad+1:size(p,2)-2*pad 93 | px = ((probex-x)/bs); 94 | py = ((probey-y)/bs); 95 | v = [px^2; px; py^2; py]; 96 | p(y, x) = defs{i} * v * def_scale; 97 | end 98 | end 99 | def_im(y1:y2, x1:x2) = p; 100 | end 101 | 102 | % plot parts 103 | subplot(nc,3,2+3*(k-1)); 104 | imagesc(im); 105 | colormap gray; 106 | axis equal; 107 | axis off; 108 | 109 | % plot deformation model 110 | subplot(nc,3,3+3*(k-1)); 111 | imagesc(def_im); 112 | colormap gray; 113 | axis equal; 114 | axis off; 115 | end 116 | 117 | set(gcf, 'Color', 'white') 118 | -------------------------------------------------------------------------------- /voc-release4.01/warppos.m: -------------------------------------------------------------------------------- 1 | function warped = warppos(model, pos) 2 | 3 | % warped = warppos(name, model, pos) 4 | % Warp positive examples to fit model dimensions. 5 | % Used for training root filters from positive bounding boxes. 6 | 7 | globals; 8 | 9 | fi = model.symbols(model.rules{model.start}.rhs).filter; 10 | fsize = model.filters(fi).size; 11 | pixels = fsize * model.sbin; 12 | heights = [pos(:).y2]' - [pos(:).y1]' + 1; 13 | widths = [pos(:).x2]' - [pos(:).x1]' + 1; 14 | numpos = length(pos); 15 | warped = cell(numpos); 16 | cropsize = (fsize+2) * model.sbin; 17 | for i = 1:numpos 18 | fprintf('%s: warp: %d/%d\n', model.class, i, numpos); 19 | im = imreadx(pos(i)); 20 | padx = model.sbin * widths(i) / pixels(2); 21 | pady = model.sbin * heights(i) / pixels(1); 22 | x1 = round(pos(i).x1-padx); 23 | x2 = round(pos(i).x2+padx); 24 | y1 = round(pos(i).y1-pady); 25 | y2 = round(pos(i).y2+pady); 26 | window = subarray(im, y1, y2, x1, x2, 1); 27 | warped{i} = imresize(window, cropsize, 'bilinear'); 28 | end 29 | -------------------------------------------------------------------------------- /voc-release4.01/writecomponentinfo.m: -------------------------------------------------------------------------------- 1 | function writecomponentinfo(f, model) 2 | 3 | % writecomponentinfo(f, model) 4 | % write the block labels used by each component 5 | % format: #components {#blocks blk1 ... blk#blocks}^#components 6 | % used in the interface with learn.cc 7 | 8 | n = length(model.rules{model.start}); 9 | comp = cell(n, 1); 10 | % we assume that rule i (i is odd) and i+1 are symmetric 11 | % mirrors of each other, so 12 | % skip every other component rule 13 | for i = 1:2:n 14 | % component offset block 15 | bl = model.rules{model.start}(i).offset.blocklabel; 16 | comp{i}(end+1) = bl-1; 17 | % collect part blocks 18 | for j = model.rules{model.start}(i).rhs 19 | if model.symbols(j).type == 'T' 20 | % filter block 21 | bl = model.filters(model.symbols(j).filter).blocklabel; 22 | comp{i}(end+1) = bl-1; 23 | else 24 | % def block 25 | bl = model.rules{j}.def.blocklabel; 26 | comp{i}(end+1) = bl-1; 27 | % offset block 28 | bl = model.rules{j}.offset.blocklabel; 29 | comp{i}(end+1) = bl-1; 30 | % filter block 31 | s = model.rules{j}.rhs(1); 32 | bl = model.filters(model.symbols(s).filter).blocklabel; 33 | comp{i}(end+1) = bl-1; 34 | end 35 | end 36 | end 37 | buf = n; 38 | numblocks = 0; 39 | for i = 1:n 40 | k = length(comp{i}); 41 | buf = [buf k comp{i}]; 42 | numblocks = numblocks + k; 43 | end 44 | % sanity check 45 | if numblocks ~= model.numblocks 46 | error('numblocks mismatch'); 47 | end 48 | fid = fopen(f, 'wb'); 49 | fwrite(fid, buf, 'int32'); 50 | fclose(fid); 51 | -------------------------------------------------------------------------------- /voc-release4.01/writeheader.m: -------------------------------------------------------------------------------- 1 | function writeheader(hdrfile, num, labelsize, model) 2 | 3 | % writeheader(file, num, labelssize, model) 4 | % Write training header file. 5 | % Used in the interface with the gradient descent algorithm. 6 | 7 | fid = fopen(hdrfile, 'wb'); 8 | header = [num labelsize model.numblocks model.blocksizes]; 9 | fwrite(fid, header, 'int32'); 10 | fwrite(fid, model.regmult, 'single'); 11 | fwrite(fid, model.learnmult, 'single'); 12 | fclose(fid); 13 | -------------------------------------------------------------------------------- /www/BebasNeue-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/www/BebasNeue-webfont.woff -------------------------------------------------------------------------------- /www/OpenSans-Light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/www/OpenSans-Light.eot -------------------------------------------------------------------------------- /www/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/www/OpenSans-Light.ttf -------------------------------------------------------------------------------- /www/OpenSans-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/www/OpenSans-Light.woff -------------------------------------------------------------------------------- /www/css/simple-slider-volume.css: -------------------------------------------------------------------------------- 1 | .slider-volume { 2 | width: 300px; 3 | } 4 | 5 | .slider-volume > .dragger { 6 | width: 16px; 7 | height: 16px; 8 | margin: 0 auto; 9 | border: 1px solid rgba(255,255,255,0.6); 10 | 11 | -moz-box-shadow: 0 0px 2px 1px rgba(0,0,0,0.5), 0 2px 5px 2px rgba(0,0,0,0.2); 12 | -webkit-box-shadow: 0 0px 2px 1px rgba(0,0,0,0.5), 0 2px 5px 2px rgba(0,0,0,0.2); 13 | box-shadow: 0 0px 2px 1px rgba(0,0,0,0.5), 0 2px 5px 2px rgba(0,0,0,0.2); 14 | 15 | -moz-border-radius: 10px; 16 | -webkit-border-radius: 10px; 17 | border-radius: 10px; 18 | 19 | background: #c5c5c5; 20 | background: -moz-linear-gradient(90deg, rgba(180,180,180,1) 20%, rgba(230,230,230,1) 50%, rgba(180,180,180,1) 80%); 21 | background: -webkit-radial-gradient( 50% 0%, 12% 50%, hsla(0,0%,100%,1) 0%, hsla(0,0%,100%,0) 100%), 22 | -webkit-radial-gradient( 50% 100%, 12% 50%, hsla(0,0%,100%,.6) 0%, hsla(0,0%,100%,0) 100%), 23 | -webkit-radial-gradient( 50% 50%, 200% 50%, hsla(0,0%,90%,1) 5%, hsla(0,0%,85%,1) 30%, hsla(0,0%,60%,1) 100%); 24 | } 25 | 26 | .slider-volume > .track, .slider-volume > .highlight-track { 27 | height: 11px; 28 | 29 | background: #787878; 30 | background: -moz-linear-gradient(top, #787878, #a2a2a2); 31 | background: -webkit-linear-gradient(top, #787878, #a2a2a2); 32 | background: linear-gradient(top, #787878, #a2a2a2); 33 | 34 | -moz-box-shadow: inset 0 2px 5px 1px rgba(0,0,0,0.15), 0 1px 0px 0px rgba(230,230,230,0.9), inset 0 0 1px 1px rgba(0,0,0,0.2); 35 | -webkit-box-shadow: inset 0 2px 5px 1px rgba(0,0,0,0.15), 0 1px 0px 0px rgba(230,230,230,0.9), inset 0 0 1px 1px rgba(0,0,0,0.2); 36 | box-shadow: inset 0 2px 5px 1px rgba(0,0,0,0.15), 0 1px 0px 0px rgba(230,230,230,0.9), inset 0 0 1px 1px rgba(0,0,0,0.2); 37 | 38 | -moz-border-radius: 5px; 39 | -webkit-border-radius: 5px; 40 | border-radius: 5px; 41 | } 42 | 43 | .slider-volume > .highlight-track { 44 | background-color: #c5c5c5; 45 | background: -moz-linear-gradient(top, #c5c5c5, #a2a2a2); 46 | background: -webkit-linear-gradient(top, #c5c5c5, #a2a2a2); 47 | background: linear-gradient(top, #c5c5c5, #a2a2a2); 48 | } 49 | -------------------------------------------------------------------------------- /www/css/simple-slider.css: -------------------------------------------------------------------------------- 1 | .slider { 2 | width: 200px; 3 | display: inline-block; 4 | } 5 | 6 | .slider > .dragger { 7 | background: #FF9D00; 8 | /* 9 | background: -webkit-linear-gradient(top, #8DCA09, #72A307); 10 | background: -moz-linear-gradient(top, #8DCA09, #72A307); 11 | background: linear-gradient(top, #8DCA09, #72A307); 12 | */ 13 | /* 14 | -webkit-box-shadow: inset 0 2px 2px rgba(255,255,255,0.5), 0 2px 8px rgba(0,0,0,0.2); 15 | -moz-box-shadow: inset 0 2px 2px rgba(255,255,255,0.5), 0 2px 8px rgba(0,0,0,0.2); 16 | box-shadow: inset 0 2px 2px rgba(255,255,255,0.5), 0 2px 8px rgba(0,0,0,0.2); 17 | */ 18 | -webkit-border-radius: 10px; 19 | -moz-border-radius: 10px; 20 | border-radius: 10px; 21 | 22 | border: 1px solid #FF9D00; 23 | width: 16px; 24 | height: 16px; 25 | } 26 | 27 | .slider > .dragger:hover { 28 | background: -webkit-linear-gradient(top, #FF9D00, #FF9D00); 29 | } 30 | 31 | 32 | .slider > .track, .slider > .highlight-track { 33 | background: #ccc; 34 | /* 35 | background: -webkit-linear-gradient(top, #bbb, #ddd); 36 | background: -moz-linear-gradient(top, #bbb, #ddd); 37 | background: linear-gradient(top, #bbb, #ddd); 38 | */ 39 | /* 40 | -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.1); 41 | -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.1); 42 | box-shadow: inset 0 2px 4px rgba(0,0,0,0.1); 43 | */ 44 | -webkit-border-radius: 8px; 45 | -moz-border-radius: 8px; 46 | border-radius: 8px; 47 | 48 | border: 1px solid #aaa; 49 | height: 4px; 50 | } 51 | 52 | .slider > .highlight-track { 53 | background-color: #8DCA09; 54 | /* 55 | background: -webkit-linear-gradient(top, #8DCA09, #72A307); 56 | background: -moz-linear-gradient(top, #8DCA09, #72A307); 57 | background: linear-gradient(top, #8DCA09, #72A307); 58 | */ 59 | border-color: #496805; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /www/drzamirface.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utkarshtandon/GMCP-Tracker-Python-Implementation/285b0a9fd8d5e25022ae96c82142b72511301450/www/drzamirface.jpg -------------------------------------------------------------------------------- /www/gmcpweb.css: -------------------------------------------------------------------------------- 1 | #header{ 2 | font-family:bebas; 3 | font-weight: 50; 4 | color: red; 5 | font-size:83px; 6 | 7 | } 8 | /* 9 | html { 10 | background-image: url('back3.jpg'); 11 | background-repeat: no-repeat; 12 | background-attachment: fixed; 13 | background-position: center; 14 | background-size: 2000px; 15 | 16 | } 17 | */ 18 | @font-face { 19 | font-family: bebas; 20 | src: url(BebasNeue-webfont.woff); 21 | } 22 | 23 | @font-face { 24 | font-family: "OpenSans-Light"; 25 | src: url("OpenSans-Light.eot"), 26 | url("OpenSans-Light.svg"), 27 | url("OpenSans-Light.ttf"), 28 | url("OpenSans-Light.woff"); 29 | } 30 | #instruct{ 31 | font-family:"OpenSans-Light","OpenSans-Regular"; 32 | color:white; 33 | font-size:20px; 34 | width:50%; 35 | line-height: 30px; 36 | text-shadow: 1px 1px black; 37 | 38 | } 39 | 40 | #upload{ 41 | height:50px; 42 | width:300px; 43 | background-color:#2D9CFC; 44 | border-radius: 25px; 45 | margin-top:15px; 46 | border: 1px solid #2D9CFC; 47 | } 48 | 49 | #about{ 50 | color:#00FFB7; 51 | } 52 | 53 | #contact{ 54 | color:#FFBC47; 55 | } 56 | 57 | #u1{ 58 | width:90px; 59 | border: 1px solid #00FFB7; 60 | border-radius: 25px; 61 | left:70%; 62 | height:28px; 63 | position:fixed; 64 | margin-top:-50px; 65 | } 66 | 67 | .choose{ 68 | width:250px; 69 | border: 1px solid black; 70 | background-color:white; 71 | border-radius: 25px; 72 | height:35px; 73 | margin-top:15px; 74 | } 75 | 76 | .choose:hover{ 77 | background-color: #F72100; 78 | border: 1px solid black; 79 | } 80 | 81 | #choosetext{ 82 | color:black; 83 | font-family: "OpenSans-Light"; 84 | font-size: 13px; 85 | margin-top:8px; 86 | } 87 | 88 | .choose:hover #choosetext{ 89 | color:white; 90 | } 91 | 92 | 93 | 94 | #u1:hover { 95 | background-color: #00FFB7;; 96 | border: 1px solid #00FFB7;; 97 | } 98 | 99 | #u1:hover #about { 100 | color:white; 101 | } 102 | 103 | #u2{ 104 | width:110px; 105 | border: 1px solid #FFBC47; 106 | 107 | border-radius: 25px; 108 | left:78%; 109 | height:28px; 110 | position:fixed; 111 | margin-top:-50px; 112 | } 113 | 114 | #u2:hover { 115 | background-color: #FFBC47;; 116 | border: 1px solid #FFBC47;; 117 | } 118 | 119 | #u2:hover #contact { 120 | color:white; 121 | } 122 | 123 | 124 | 125 | 126 | #uploadtext{ 127 | font-family:bebas; 128 | font-weight: 50; 129 | color: white; 130 | font-size:26px; 131 | margin-top:11px; 132 | } 133 | 134 | #upload:hover { 135 | background-color: #16D90F; 136 | border: 1px solid #16D90F; 137 | } 138 | 139 | #upload:hover #uploadtext { 140 | color:white; 141 | } 142 | 143 | #txt_name{ 144 | width:250px; 145 | height:30px; 146 | border-radius: 10px; 147 | margin-top: 15px; 148 | border: 1px solid #B0B0B0; 149 | font-family:"HelveticaNeue-Light","OpenSans-Regular","OpenSans-Light"; 150 | color:black; 151 | font-size:16px; 152 | padding-left:15px; 153 | padding-right:15px; 154 | display: block; 155 | } 156 | 157 | #txt_name:focus, input:focus{ 158 | outline: 0; 159 | } 160 | 161 | #ajaxP{ 162 | font-family:"HelveticaNeue-Light","OpenSans-Regular","OpenSans-Light"; 163 | color:black; 164 | font-size:15px; 165 | width:30%; 166 | } 167 | 168 | #framebeg{ 169 | margin-top:30px; 170 | display:inline-block; 171 | font-family:"OpenSans-Regular","OpenSans-Light"; 172 | color:black; 173 | font-size:15px; 174 | line-height: 30px; 175 | } 176 | 177 | .centered-and-cropped { object-fit: cover } 178 | 179 | #frameinput{ 180 | display: inline-block; 181 | width:35px; 182 | height:30px; 183 | border-radius: 10px; 184 | margin-top: 15px; 185 | border: 1px solid #B0B0B0; 186 | font-family:"HelveticaNeue-Light","OpenSans-Regular","OpenSans-Light"; 187 | color:black; 188 | font-size:16px; 189 | padding-left:5px; 190 | padding-right:5px; 191 | margin-left: 5px; 192 | } 193 | 194 | #frameinput1{ 195 | display: inline-block; 196 | width:35px; 197 | height:30px; 198 | border-radius: 10px; 199 | margin-top: 15px; 200 | border: 1px solid #B0B0B0; 201 | font-family:"HelveticaNeue-Light","OpenSans-Regular","OpenSans-Light"; 202 | color:black; 203 | font-size:16px; 204 | padding-left:5px; 205 | padding-right:5px; 206 | margin-left: 5px; 207 | } 208 | #empty{ 209 | display: block; 210 | margin-top: -20px; 211 | } 212 | #step{ 213 | margin-top: -20px; 214 | display:inline-block; 215 | font-family:"OpenSans-Regular","OpenSans-Light"; 216 | color:black; 217 | font-size:15px; 218 | line-height: 30px; 219 | } 220 | 221 | #stepinput{ 222 | display: inline-block; 223 | width:25px; 224 | height:30px; 225 | margin-left: 5px; 226 | border-radius: 10px; 227 | margin-top: 15px; 228 | border: 1px solid #B0B0B0; 229 | font-family:"HelveticaNeue-Light","OpenSans-Regular","OpenSans-Light"; 230 | color:black; 231 | font-size:16px; 232 | padding-left:5px; 233 | padding-right:5px; 234 | } 235 | 236 | #cost{ 237 | font-family:"OpenSans-Regular","OpenSans-Light"; 238 | color:black; 239 | font-size:18px; 240 | line-height: 30px; 241 | display: block; 242 | } 243 | 244 | #motion{ 245 | padding-right:5px; 246 | display:inline-block; 247 | font-family:"OpenSans-Regular","OpenSans-Light"; 248 | color:black; 249 | font-size:16px; 250 | line-height: 30px; 251 | } 252 | 253 | #my-input{ 254 | display:inline-block; 255 | } 256 | 257 | #appearance{ 258 | display:inline-block; 259 | font-family:"OpenSans-Regular","OpenSans-Light"; 260 | color:black; 261 | font-size:10px; 262 | line-height: 30px; 263 | } 264 | 265 | #email{ 266 | display:inline-block; 267 | font-family:"OpenSans-Regular","OpenSans-Light"; 268 | color:white; 269 | font-size:16px; 270 | line-height: 30px; 271 | text-shadow: 1px 1px black; 272 | } 273 | 274 | #emailinput{ 275 | display: inline-block; 276 | width:175px; 277 | height:30px; 278 | margin-left: 5px; 279 | border-radius: 10px; 280 | margin-top: 15px; 281 | border: 1px solid #B0B0B0; 282 | font-family:"HelveticaNeue-Light","OpenSans-Regular","OpenSans-Light"; 283 | color:black; 284 | font-size:16px; 285 | padding-left:5px; 286 | padding-right:5px; 287 | } 288 | 289 | #tab{ 290 | width:150px; 291 | height:26px; 292 | border-radius: 5px; 293 | background-color:white; 294 | display:inline-block; 295 | opacity:0.7; 296 | margin-top:5px; 297 | } 298 | #tab:hover{ 299 | opacity:1; 300 | } 301 | -------------------------------------------------------------------------------- /www/js/simple-slider.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | jQuery Simple Slider 3 | 4 | Copyright (c) 2012 James Smith (http://loopj.com) 5 | 6 | Licensed under the MIT license (http://mit-license.org/) 7 | ### 8 | 9 | (($, window) -> 10 | 11 | # 12 | # Main slider class 13 | # 14 | 15 | class SimpleSlider 16 | # Build a slider object. 17 | # Exposed via el.numericalSlider(options) 18 | constructor: (@input, options) -> 19 | # Load in the settings 20 | @defaultOptions = 21 | animate: true 22 | snapMid: false 23 | classPrefix: null 24 | classSuffix: null 25 | theme: null 26 | highlight: false 27 | 28 | @settings = $.extend({}, @defaultOptions, options) 29 | @settings.classSuffix = "-#{@settings.theme}" if @settings.theme 30 | 31 | # Hide the original input 32 | @input.hide() 33 | 34 | # Create the slider canvas 35 | @slider = $("
") 36 | .addClass("slider"+(@settings.classSuffix || "")) 37 | .css 38 | position: "relative" 39 | userSelect: "none" 40 | boxSizing: "border-box" 41 | .insertBefore @input 42 | @slider.attr("id", @input.attr("id") + "-slider") if @input.attr("id") 43 | 44 | @track = @createDivElement("track") 45 | .css 46 | width: "100%" 47 | 48 | if @settings.highlight 49 | # Create the highlighting track on top of the track 50 | @highlightTrack = @createDivElement("highlight-track") 51 | .css 52 | width: "0" 53 | 54 | # Create the slider drag target 55 | @dragger = @createDivElement("dragger") 56 | 57 | # Adjust dimensions now elements are in the DOM 58 | @slider.css 59 | minHeight: @dragger.outerHeight() 60 | marginLeft: @dragger.outerWidth()/2 61 | marginRight: @dragger.outerWidth()/2 62 | 63 | @track.css 64 | marginTop: @track.outerHeight()/-2 65 | 66 | if @settings.highlight 67 | @highlightTrack.css 68 | marginTop: @track.outerHeight()/-2 69 | 70 | @dragger.css 71 | marginTop: @dragger.outerHeight()/-2 72 | marginLeft: @dragger.outerWidth()/-2 73 | 74 | # Hook up drag/drop mouse events 75 | @track 76 | .mousedown (e) => 77 | @trackEvent(e) 78 | 79 | if @settings.highlight 80 | @highlightTrack 81 | .mousedown (e) => 82 | @trackEvent(e) 83 | 84 | @dragger 85 | .mousedown (e) => 86 | return unless e.which == 1 87 | 88 | # We've started moving 89 | @dragging = true 90 | @dragger.addClass "dragging" 91 | 92 | # Update the slider position 93 | @domDrag(e.pageX, e.pageY) 94 | 95 | false 96 | 97 | $("body") 98 | .mousemove (e) => 99 | if @dragging 100 | # Update the slider position 101 | @domDrag(e.pageX, e.pageY) 102 | 103 | # Always show a pointer when dragging 104 | $("body").css cursor: "pointer" 105 | 106 | 107 | .mouseup (e) => 108 | if @dragging 109 | # Finished dragging 110 | @dragging = false 111 | @dragger.removeClass "dragging" 112 | 113 | # Revert the cursor 114 | $("body").css cursor: "auto" 115 | 116 | # Set slider initial position 117 | @pagePos = 0 118 | 119 | # Fill in initial slider value 120 | if @input.val() == "" 121 | @value = @getRange().min 122 | @input.val(@value) 123 | else 124 | @value = @nearestValidValue(@input.val()) 125 | 126 | @setSliderPositionFromValue(@value) 127 | 128 | # We are ready to go 129 | ratio = @valueToRatio(@value) 130 | @input.trigger "slider:ready", 131 | value: @value 132 | ratio: ratio 133 | position: ratio * @slider.outerWidth() 134 | el: @slider 135 | 136 | # Create the basis of the track-div(s) 137 | createDivElement: (classname) -> 138 | item = $("
") 139 | .addClass(classname) 140 | .css 141 | position: "absolute" 142 | top: "50%" 143 | userSelect: "none" 144 | cursor: "pointer" 145 | .appendTo @slider 146 | return item 147 | 148 | 149 | # Set the ratio (value between 0 and 1) of the slider. 150 | # Exposed via el.slider("setRatio", ratio) 151 | setRatio: (ratio) -> 152 | # Range-check the ratio 153 | ratio = Math.min(1, ratio) 154 | ratio = Math.max(0, ratio) 155 | 156 | # Work out the value 157 | value = @ratioToValue(ratio) 158 | 159 | # Update the position of the slider on the screen 160 | @setSliderPositionFromValue(value) 161 | 162 | # Trigger value changed events 163 | @valueChanged(value, ratio, "setRatio") 164 | 165 | # Set the value of the slider 166 | # Exposed via el.slider("setValue", value) 167 | setValue: (value) -> 168 | # Snap value to nearest step or allowedValue 169 | value = @nearestValidValue(value) 170 | 171 | # Work out the ratio 172 | ratio = @valueToRatio(value) 173 | 174 | # Update the position of the slider on the screen 175 | @setSliderPositionFromValue(value) 176 | 177 | # Trigger value changed events 178 | @valueChanged(value, ratio, "setValue") 179 | 180 | # Respond to an event on a track 181 | trackEvent: (e) -> 182 | return unless e.which == 1 183 | 184 | @domDrag(e.pageX, e.pageY, true) 185 | @dragging = true 186 | false 187 | 188 | # Respond to a dom drag event 189 | domDrag: (pageX, pageY, animate=false) -> 190 | # Normalize position within allowed range 191 | pagePos = pageX - @slider.offset().left 192 | pagePos = Math.min(@slider.outerWidth(), pagePos) 193 | pagePos = Math.max(0, pagePos) 194 | 195 | # If the element position has changed, do stuff 196 | if @pagePos != pagePos 197 | @pagePos = pagePos 198 | 199 | # Set the percentage value of the slider 200 | ratio = pagePos / @slider.outerWidth() 201 | 202 | # Trigger value changed events 203 | value = @ratioToValue(ratio) 204 | @valueChanged(value, ratio, "domDrag") 205 | 206 | # Update the position of the slider on the screen 207 | if @settings.snap 208 | @setSliderPositionFromValue(value, animate) 209 | else 210 | @setSliderPosition(pagePos, animate) 211 | 212 | # Set the slider position given a slider canvas position 213 | setSliderPosition: (position, animate=false) -> 214 | if animate and @settings.animate 215 | @dragger.animate left: position, 200 216 | @highlightTrack.animate width: position, 200 if @settings.highlight 217 | else 218 | @dragger.css left: position 219 | @highlightTrack.css width: position if @settings.highlight 220 | 221 | # Set the slider position given a value 222 | setSliderPositionFromValue: (value, animate=false) -> 223 | # Get the slide ratio from the value 224 | ratio = @valueToRatio(value) 225 | 226 | # Set the slider position 227 | @setSliderPosition(ratio * @slider.outerWidth(), animate) 228 | 229 | # Get the valid range of values 230 | getRange: -> 231 | if @settings.allowedValues 232 | min: Math.min(@settings.allowedValues...) 233 | max: Math.max(@settings.allowedValues...) 234 | else if @settings.range 235 | min: parseFloat(@settings.range[0]) 236 | max: parseFloat(@settings.range[1]) 237 | else 238 | min: 0 239 | max: 1 240 | 241 | # Find the nearest valid value, checking allowedValues and step settings 242 | nearestValidValue: (rawValue) -> 243 | range = @getRange() 244 | 245 | # Range-check the value 246 | rawValue = Math.min(range.max, rawValue) 247 | rawValue = Math.max(range.min, rawValue) 248 | 249 | # Apply allowedValues or step settings 250 | if @settings.allowedValues 251 | closest = null 252 | $.each @settings.allowedValues, -> 253 | if closest == null || Math.abs(this - rawValue) < Math.abs(closest - rawValue) 254 | closest = this 255 | 256 | return closest 257 | else if @settings.step 258 | maxSteps = (range.max - range.min) / @settings.step 259 | steps = Math.floor((rawValue - range.min) / @settings.step) 260 | steps += 1 if (rawValue - range.min) % @settings.step > @settings.step / 2 and steps < maxSteps 261 | 262 | return steps * @settings.step + range.min 263 | else 264 | return rawValue 265 | 266 | # Convert a value to a ratio 267 | valueToRatio: (value) -> 268 | if @settings.equalSteps 269 | # Get slider ratio for equal-step 270 | for allowedVal, idx in @settings.allowedValues 271 | if !closest? || Math.abs(allowedVal - value) < Math.abs(closest - value) 272 | closest = allowedVal 273 | closestIdx = idx 274 | 275 | if @settings.snapMid 276 | (closestIdx+0.5)/@settings.allowedValues.length 277 | else 278 | (closestIdx)/(@settings.allowedValues.length - 1) 279 | 280 | else 281 | # Get slider ratio for continuous values 282 | range = @getRange() 283 | (value - range.min) / (range.max - range.min) 284 | 285 | # Convert a ratio to a valid value 286 | ratioToValue: (ratio) -> 287 | if @settings.equalSteps 288 | steps = @settings.allowedValues.length 289 | step = Math.round(ratio * steps - 0.5) 290 | idx = Math.min(step, @settings.allowedValues.length - 1) 291 | 292 | @settings.allowedValues[idx] 293 | else 294 | range = @getRange() 295 | rawValue = ratio * (range.max - range.min) + range.min 296 | 297 | @nearestValidValue(rawValue) 298 | 299 | # Trigger value changed events 300 | valueChanged: (value, ratio, trigger) -> 301 | return if value.toString() == @value.toString() 302 | 303 | # Save the new value 304 | @value = value 305 | 306 | # Construct event data and fire event 307 | eventData = 308 | value: value 309 | ratio: ratio 310 | position: ratio * @slider.outerWidth() 311 | trigger: trigger 312 | el: @slider 313 | 314 | @input 315 | .val(value) 316 | .trigger($.Event("change", eventData)) 317 | .trigger("slider:changed", eventData) 318 | 319 | 320 | # 321 | # Expose as jQuery Plugin 322 | # 323 | 324 | $.extend $.fn, simpleSlider: (settingsOrMethod, params...) -> 325 | publicMethods = ["setRatio", "setValue"] 326 | 327 | $(this).each -> 328 | if settingsOrMethod and settingsOrMethod in publicMethods 329 | obj = $(this).data("slider-object") 330 | 331 | obj[settingsOrMethod].apply(obj, params) 332 | else 333 | settings = settingsOrMethod 334 | $(this).data "slider-object", new SimpleSlider($(this), settings) 335 | 336 | 337 | # 338 | # Attach unobtrusive JS hooks 339 | # 340 | 341 | $ -> 342 | $("[data-slider]").each -> 343 | $el = $(this) 344 | 345 | # Build options object from data attributes 346 | settings = {} 347 | 348 | allowedValues = $el.data "slider-values" 349 | settings.allowedValues = (parseFloat(x) for x in allowedValues.split(",")) if allowedValues 350 | settings.range = $el.data("slider-range").split(",") if $el.data("slider-range") 351 | settings.step = $el.data("slider-step") if $el.data("slider-step") 352 | settings.snap = $el.data("slider-snap") 353 | settings.equalSteps = $el.data("slider-equal-steps") 354 | settings.theme = $el.data("slider-theme") if $el.data("slider-theme") 355 | settings.highlight = $el.data("slider-highlight") if $el.attr("data-slider-highlight") 356 | settings.animate = $el.data("slider-animate") if $el.data("slider-animate")? 357 | 358 | # Activate the plugin 359 | $el.simpleSlider settings 360 | 361 | ) @jQuery or @Zepto, this 362 | -------------------------------------------------------------------------------- /www/js/simple-slider.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Simple Slider: Unobtrusive Numerical Slider 3 | * Version 1.0.0 4 | * 5 | * Copyright (c) 2014 James Smith (http://loopj.com) 6 | * 7 | * Licensed under the MIT license (http://mit-license.org/) 8 | * 9 | */ 10 | 11 | var __slice=[].slice,__indexOf=[].indexOf||function(e){for(var t=0,n=this.length;t").addClass("slider"+(this.settings.classSuffix||"")).css({position:"relative",userSelect:"none",boxSizing:"border-box"}).insertBefore(this.input),this.input.attr("id")&&this.slider.attr("id",this.input.attr("id")+"-slider"),this.track=this.createDivElement("track").css({width:"100%"}),this.settings.highlight&&(this.highlightTrack=this.createDivElement("highlight-track").css({width:"0"})),this.dragger=this.createDivElement("dragger"),this.slider.css({minHeight:this.dragger.outerHeight(),marginLeft:this.dragger.outerWidth()/2,marginRight:this.dragger.outerWidth()/2}),this.track.css({marginTop:this.track.outerHeight()/-2}),this.settings.highlight&&this.highlightTrack.css({marginTop:this.track.outerHeight()/-2}),this.dragger.css({marginTop:this.dragger.outerHeight()/-2,marginLeft:this.dragger.outerWidth()/-2}),this.track.mousedown(function(e){return i.trackEvent(e)}),this.settings.highlight&&this.highlightTrack.mousedown(function(e){return i.trackEvent(e)}),this.dragger.mousedown(function(e){if(e.which!==1)return;return i.dragging=!0,i.dragger.addClass("dragging"),i.domDrag(e.pageX,e.pageY),!1}),e("body").mousemove(function(t){if(i.dragging)return i.domDrag(t.pageX,t.pageY),e("body").css({cursor:"pointer"})}).mouseup(function(t){if(i.dragging)return i.dragging=!1,i.dragger.removeClass("dragging"),e("body").css({cursor:"auto"})}),this.pagePos=0,this.input.val()===""?(this.value=this.getRange().min,this.input.val(this.value)):this.value=this.nearestValidValue(this.input.val()),this.setSliderPositionFromValue(this.value),r=this.valueToRatio(this.value),this.input.trigger("slider:ready",{value:this.value,ratio:r,position:r*this.slider.outerWidth(),el:this.slider})}return t.prototype.createDivElement=function(t){var n;return n=e("
").addClass(t).css({position:"absolute",top:"50%",userSelect:"none",cursor:"pointer"}).appendTo(this.slider),n},t.prototype.setRatio=function(e){var t;return e=Math.min(1,e),e=Math.max(0,e),t=this.ratioToValue(e),this.setSliderPositionFromValue(t),this.valueChanged(t,e,"setRatio")},t.prototype.setValue=function(e){var t;return e=this.nearestValidValue(e),t=this.valueToRatio(e),this.setSliderPositionFromValue(e),this.valueChanged(e,t,"setValue")},t.prototype.trackEvent=function(e){if(e.which!==1)return;return this.domDrag(e.pageX,e.pageY,!0),this.dragging=!0,!1},t.prototype.domDrag=function(e,t,n){var r,i,s;n==null&&(n=!1),r=e-this.slider.offset().left,r=Math.min(this.slider.outerWidth(),r),r=Math.max(0,r);if(this.pagePos!==r)return this.pagePos=r,i=r/this.slider.outerWidth(),s=this.ratioToValue(i),this.valueChanged(s,i,"domDrag"),this.settings.snap?this.setSliderPositionFromValue(s,n):this.setSliderPosition(r,n)},t.prototype.setSliderPosition=function(e,t){t==null&&(t=!1);if(t&&this.settings.animate){this.dragger.animate({left:e},200);if(this.settings.highlight)return this.highlightTrack.animate({width:e},200)}else{this.dragger.css({left:e});if(this.settings.highlight)return this.highlightTrack.css({width:e})}},t.prototype.setSliderPositionFromValue=function(e,t){var n;return t==null&&(t=!1),n=this.valueToRatio(e),this.setSliderPosition(n*this.slider.outerWidth(),t)},t.prototype.getRange=function(){return this.settings.allowedValues?{min:Math.min.apply(Math,this.settings.allowedValues),max:Math.max.apply(Math,this.settings.allowedValues)}:this.settings.range?{min:parseFloat(this.settings.range[0]),max:parseFloat(this.settings.range[1])}:{min:0,max:1}},t.prototype.nearestValidValue=function(t){var n,r,i,s;return i=this.getRange(),t=Math.min(i.max,t),t=Math.max(i.min,t),this.settings.allowedValues?(n=null,e.each(this.settings.allowedValues,function(){if(n===null||Math.abs(this-t)this.settings.step/2&&s=0?(s=e(this).data("slider-object"),s[i].apply(s,t)):(o=i,e(this).data("slider-object",new n(e(this),o)))})}}),e(function(){return e("[data-slider]").each(function(){var t,n,r,i;return t=e(this),r={},n=t.data("slider-values"),n&&(r.allowedValues=function(){var e,t,r,s;r=n.split(","),s=[];for(e=0,t=r.length;e