CalibrationEngine.java

00001 package edu.stanford.hci.r3.pattern.calibrate;
00002 
00003 import java.io.File;
00004 import java.util.List;
00005 
00006 import javax.swing.JFileChooser;
00007 
00008 import edu.stanford.hci.r3.PaperToolkit;
00009 import edu.stanford.hci.r3.pattern.coordinates.PageAddress;
00010 import edu.stanford.hci.r3.pen.ink.Ink;
00011 import edu.stanford.hci.r3.pen.ink.InkStroke;
00012 import edu.stanford.hci.r3.util.DebugUtils;
00013 import edu.stanford.hci.r3.util.files.FileUtils;
00014 
00026 public class CalibrationEngine {
00027 
00035         public static void main(String[] args) {
00036                 PaperToolkit.initializeLookAndFeel();
00037 
00038                 // display file chooser
00039                 JFileChooser chooser = FileUtils.createNewFileChooser(new String[] { "xml" });
00040                 chooser.setCurrentDirectory(new File("data/calibration/"));
00041                 chooser.setMultiSelectionEnabled(true);
00042                 int result = chooser.showDialog(null, "Align Two XML Files");
00043 
00044                 // load two ink objects
00045                 if (result == JFileChooser.APPROVE_OPTION) {
00046                         File[] selectedFiles = chooser.getSelectedFiles();
00047                         if (selectedFiles.length < 2) {
00048                                 DebugUtils.println("Please select at least two XML files...");
00049                         } else {
00050 
00051                                 File streamed = null;
00052                                 File batched = null;
00053 
00054                                 for (File f : selectedFiles) {
00055                                         final String fileName = f.getName();
00056                                         if (streamed == null && fileName.contains("streamed")) {
00057                                                 // look for the streamed file
00058                                                 streamed = f;
00059                                         }
00060                                         if (batched == null && fileName.contains("batched")) {
00061                                                 // look for the batched file
00062                                                 batched = f;
00063                                         }
00064 
00065                                         if ((streamed != null) && (batched != null)) {
00066                                                 // once we have both... align them using this class
00067                                                 new CalibrationEngine().alignInkStrokes(new Ink(streamed), new Ink(batched));
00068                                         }
00069                                 }
00070                         }
00071                 }
00072         }
00073 
00078         public void alignInkStrokes(Ink streamedInk, Ink batchedInk) {
00079                 final int numStreamedStrokes = streamedInk.getNumStrokes();
00080                 final int numBatchedStrokes = batchedInk.getNumStrokes();
00081 
00082                 if (numStreamedStrokes != numBatchedStrokes) {
00083                         DebugUtils
00084                                         .println("The number of strokes do not match. We will try our best to align the two...");
00085                 }
00086 
00087                 DebugUtils.println(numStreamedStrokes + " streamed strokes.");
00088                 DebugUtils.println(numBatchedStrokes + " batched strokes.");
00089 
00090                 final List<InkStroke> streamedStrokes = streamedInk.getStrokes();
00091                 final List<InkStroke> batchedStrokes = batchedInk.getStrokes();
00092 
00093                 final PageAddress bPageAddress = batchedInk.getSourcePageAddress();
00094 
00095                 double avgMillisBehind = 0;
00096                 double numSamples = 0;
00097 
00098                 for (int i = 0; i < streamedStrokes.size(); i++) {
00099                         DebugUtils.println("Aligning Stroke");
00100                         InkStroke sStroke = streamedStrokes.get(i);
00101                         InkStroke bStroke = batchedStrokes.get(i);
00102 
00103                         int[] sForceSamples = sStroke.getForceSamples();
00104                         int[] bForceSamples = bStroke.getForceSamples();
00105 
00106                         long[] sTimeSamples = sStroke.getTimeSamples();
00107                         long[] bTimeSamples = bStroke.getTimeSamples();
00108 
00109                         double[] sSamplesX = sStroke.getXSamples();
00110                         double[] bSamplesX = bStroke.getXSamples();
00111 
00112                         double[] sSamplesY = sStroke.getYSamples();
00113                         double[] bSamplesY = bStroke.getYSamples();
00114 
00115                         for (int j = 0; j < sForceSamples.length; j++) {
00116                                 if (sForceSamples[j] == bForceSamples[j]) {
00117                                         final double millisBehind = (sTimeSamples[j] - bTimeSamples[j]);
00118                                         final String behindOrAhead = getBehindOrAheadString(millisBehind);
00119 
00120                                         final double currStreamedX = sSamplesX[j];
00121                                         final double currStreamedY = sSamplesY[j];
00122                                         final double currBatchedY = bSamplesY[j];
00123                                         final double currBatchedX = bSamplesX[j];
00124                                         
00125                                         DebugUtils.println("Streamed: " + currStreamedX + ", " + currStreamedY + " <--> "
00126                                                         + currBatchedX + ", " + currBatchedY + " on page " + bPageAddress
00127                                                         + " with the Pen's Clock" + behindOrAhead + "by " + Math.abs(millisBehind)
00128                                                         + " milliseconds.");
00129 
00130                                         // an incremental averaging...
00131                                         numSamples++;
00132                                         avgMillisBehind = (avgMillisBehind * ((numSamples - 1) / numSamples))
00133                                                         + (millisBehind / numSamples);
00134                                         // DebugUtils.println("Average: " + avgMillisBehind);
00135 
00136                                         final double offsetX = currStreamedX - currBatchedX;
00137                                         final double offsetY = currStreamedY - currBatchedY;
00138                                         
00139                                         DebugUtils.println(offsetX + " " + offsetY);
00140 
00141                                 }
00142                         }
00143                 }
00144 
00145                 DebugUtils.println("After " + numSamples + " samples, we find that the Pen's Clock is"
00146                                 + getBehindOrAheadString(avgMillisBehind) + "by " + Math.abs(avgMillisBehind)
00147                                 + " milliseconds, on average.");
00148         }
00149 
00154         private String getBehindOrAheadString(double millisBehind) {
00155                 String behindOrAhead = (millisBehind < 0) ? " ahead " : " behind ";
00156                 return behindOrAhead;
00157         }
00158 }

Generated on Sat Apr 14 18:21:33 2007 for R3 Paper Toolkit by  doxygen 1.4.7