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.io.DataOutputStream; 012import java.io.File; 013import java.io.FileOutputStream; 014import java.io.IOException; 015import java.io.PrintWriter; 016import java.util.ArrayList; 017import java.util.List; 018import java.util.SortedMap; 019import java.util.TreeMap; 020 021/** 022 * A table storing features per frame 023 * 024 * @author Stan Birchfield 025 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 026 */ 027public class FeatureTable { 028 /** 029 * The table of features 030 */ 031 public SortedMap<Integer, List<Feature>> features; 032 033 /** 034 * The number of features 035 */ 036 public int nFeatures; 037 038 /********************************************************************* 039 * KLTCreateFeatureTable 040 * @param nFeatures 041 * 042 */ 043 public FeatureTable(int nFeatures) { 044 features = new TreeMap<Integer, List<Feature>>(); 045 this.nFeatures = nFeatures; 046 } 047 048 /** 049 * Store a list of features for the given frame number 050 * @param fl 051 * @param frame 052 */ 053 public void storeFeatureList(FeatureList fl, int frame) { 054 ArrayList<Feature> list = new ArrayList<Feature>(fl.features.length); 055 056 for (Feature f : fl.features) 057 list.add(f.clone()); 058 059 features.put(frame, list); 060 } 061 062 /** 063 * Convert to a string representation. 064 * @param fmt 065 * @param comments 066 * @return the string representation. 067 */ 068 public String toString(String fmt, boolean comments) { 069 String [] setup = IOUtils.setupTxtFormat(fmt); 070 String format = setup[0]; 071 String type = setup[1]; 072 073 String s = IOUtils.getHeader(format, IOUtils.StructureType.FEATURE_TABLE, features.size(), nFeatures, comments); 074 075 for (int j = 0 ; j < nFeatures; j++) { 076 s += String.format("%7d | ", j); 077 for (int i = 0 ; i < features.size(); i++) 078 s += features.get(i).get(j).toString(format, type); 079 s += "\n"; 080 } 081 082 return s; 083 } 084 085 @Override 086 public String toString() { 087 return toString("%3d", false); 088 } 089 090 /** 091 * Write feature table to a file. 092 * @param fname 093 * @param fmt 094 * @throws IOException 095 */ 096 public void writeFeatureTable(File fname, String fmt) throws IOException 097 { 098 if (fmt != null) { /* text file or stderr */ 099 if (fname != null) { 100 PrintWriter bw = new PrintWriter(new FileOutputStream(fname)); 101 bw.write(toString(fmt, true)); 102 bw.close(); 103 } else { 104 System.out.print(toString(fmt, false)); 105 } 106 } else { /* binary file */ 107 DataOutputStream dos = new DataOutputStream(new FileOutputStream(fname)); 108 109 dos.write(IOUtils.binheader_ft.getBytes("US-ASCII")); 110 dos.writeInt(features.size()); 111 dos.writeInt(nFeatures); 112 113 for (int j = 0 ; j < nFeatures ; j++) { 114 for (int i = 0 ; i < features.size() ; i++) { 115 features.get(j).get(i).writeFeatureBin(dos); 116 } 117 } 118 119 dos.close(); 120 } 121 } 122} 123