001/**
002 * This source code file is part of a direct port of Stan Birchfield's implementation
003 * of a Kanade-Lucas-Tomasi feature tracker. The original implementation can be found
004 * here: http://www.ces.clemson.edu/~stb/klt/
005 *
006 * As per the original code, the source code is in the public domain, available
007 * for both commercial and non-commercial use.
008 */
009package org.openimaj.video.tracking.klt;
010
011import java.util.ArrayList;
012import java.util.List;
013import java.util.Map;
014import java.util.TreeMap;
015
016/**
017 * The history of a set of tracked features through time
018 * 
019 * @author Stan Birchfield
020 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
021 */
022public class FeatureHistory {
023        Map<Integer, List<List<Feature>>> history = new TreeMap<Integer, List<List<Feature>>>();
024        
025        /**
026         * The feature history. Each element is a list over time.
027         */
028        public List<Feature> [] currentState;
029        
030        /**
031         * Default constructor with given number of features
032         * @param nFeatures
033         */
034        @SuppressWarnings("unchecked")
035        public FeatureHistory(int nFeatures) {
036                currentState = new List[nFeatures];
037        }
038        
039        /**
040         * Record a list of features at a given time
041         * @param fl
042         * @param frame
043         */
044        public void record(FeatureList fl, int frame) {
045                for (int i=0; i<fl.features.length; i++) {
046                        Feature f = fl.features[i];
047                        
048                        if (f.val>=0) {
049                                //was tracked
050                                if (currentState[i] == null) {
051                                        List<Feature> ff = new ArrayList<Feature>();
052                                        List<List<Feature>> hist;
053                                        if (history.containsKey(frame)) {
054                                                hist = history.get(frame);
055                                        } else {
056                                                hist = new ArrayList<List<Feature>>();
057                                                history.put(frame, hist);
058                                        }
059                                        hist.add(ff);
060                                        currentState[i] = ff;
061                                }
062                                if (currentState[i].size() == 0 || !currentState[i].get(currentState[i].size()-1).equals(f))
063                                        currentState[i].add(f.clone());
064                        } else {
065                                //was lost
066                                currentState[i] = null;
067                        }
068                }
069        }
070        
071        @Override
072        public String toString() {
073                String s = "FeatureHistory[\n";
074                for (int startframe : history.keySet()) {
075                        List<List<Feature>> tracks = history.get(startframe);
076                        s += "Starting frame: " + startframe + ":\n";
077                        for (int i=0; i<tracks.size(); i++) {
078                                s += "\t" + i +" " + tracks.get(i) + "\n";
079                        }
080                }
081                return s+"]";
082        }
083}