Browse files

Removed scala nature.

  • Loading branch information...
1 parent 8fa136d commit c3c7e4f00a553605a4301d18a3a2b1e21b92904a @ushadow committed Nov 5, 2012
View
1 .classpath
@@ -4,7 +4,6 @@
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
- <classpathentry kind="con" path="ch.epfl.lamp.sdt.launching.SCALA_CONTAINER"/>
<classpathentry kind="lib" path="lib/javacpp.jar"/>
<classpathentry kind="lib" path="lib/javacv-linux-x86_64.jar"/>
<classpathentry kind="lib" path="lib/javacv.jar"/>
View
9 .project
@@ -11,14 +11,13 @@
</arguments>
</buildCommand>
<buildCommand>
- <name>ch.epfl.lamp.sdt.core.scalabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>com.aptana.ruby.core.rubynature</nature>
- <nature>ch.epfl.lamp.sdt.core.scalanature</nature>
</natures>
</projectDescription>
View
2 src/edu/mit/yingyin/tabletop/apps/CheckerboardTestAppController.java
@@ -82,7 +82,7 @@ public CheckerboardTestAppController() {
BufferedImage image = ImageIO.read(new File(IMAGE_FILE_NAME));
heController = new HandEventsController(image,
new Dimension(TABLETOP_WIDTH, TABLETOP_HEIGHT));
- engine = new HandTrackingEngine(OPENNI_CONFIG_FILE, CALIB_FILE,
+ engine = HandTrackingEngine.initInstance(OPENNI_CONFIG_FILE, CALIB_FILE,
EnvConstants.DEFAULT_MAX_DEPTH);
packetController = new ProcessPacketController(engine.depthWidth(),
engine.depthHeight(), null);
View
27 src/edu/mit/yingyin/tabletop/apps/HandTrackingApp.scala
@@ -1,27 +0,0 @@
-package edu.mit.yingyin.tabletop.apps {
-import edu.mit.yingyin.tabletop.models.HandTrackingEngine
-import org.apache.commons.cli.OptionBuilder
-import edu.mit.yingyin.util.CommandLineOptions
-import edu.mit.yingyin.tabletop.models.EnvConstants
-
-object HandTrackingApp {
- def main(args:Array[String]) = {
- // Parse command line arguments.
- OptionBuilder.withArgName("main direction")
- OptionBuilder.withLongOpt("dir")
- OptionBuilder.hasArg
- OptionBuilder.withDescription("The main directory for input and output. " +
- "The configuration file should be in <dir>/config/folder." +
- "The default dir is the current directory.")
- val mainDirOpt = OptionBuilder.create("d")
- CommandLineOptions.addOption(mainDirOpt)
- CommandLineOptions.parse(args)
- val mainDir = CommandLineOptions.getOptionValue("d", "./")
-
- val openniConfigFile = mainDir + "config/config.xml"
- val calibrationFile = mainDir + "data/calibration/calibration.txt"
-
- val engine = new HandTrackingEngine(openniConfigFile, calibrationFile,
- EnvConstants.DEFAULT_MAX_DEPTH)
- }
-}}
View
2 src/edu/mit/yingyin/tabletop/apps/HandTrackingAppController.java
@@ -158,7 +158,7 @@ public HandTrackingAppController(String mainDir) {
displayOn = false;
try {
- engine = new HandTrackingEngine(openniConfigFile, calibrationFile,
+ engine = HandTrackingEngine.initInstance(openniConfigFile, calibrationFile,
maxDepth);
} catch (GeneralException ge) {
logger.info("OpenNI config file = " + openniConfigFile);
View
1 src/edu/mit/yingyin/tabletop/models/Background.java
@@ -302,6 +302,7 @@ private void computeAvgDiff() {
* as the depth array.
*/
private void depthToImage(int[] depthRawData, IplImage image) {
+ // No scaling.
CvUtil.intToFloatIplImage(depthRawData,image, 1);
}
View
4 src/edu/mit/yingyin/tabletop/models/ForelimbFeatureDetector.java
@@ -24,7 +24,7 @@
import edu.mit.yingyin.util.CvUtil;
import edu.mit.yingyin.util.Geometry;
import edu.mit.yingyin.util.Matrix;
-import edu.mit.yingyin.util.Vector2fUtil;
+import edu.mit.yingyin.util.VectorUtil;
/**
* A detector for forelimb features including fingertip positions.
@@ -93,7 +93,7 @@ public void extractFingertipsConvexityDefects(ProcessPacket packet) {
defect2.depth_point().y() - defect2.start().y());
float distance2 = CvUtil.distance2(defect1.depth_point(),
defect2.depth_point());
- if (Vector2fUtil.angle(v1, v2) <= FINGERTIP_ANGLE &&
+ if (VectorUtil.angle(v1, v2) <= FINGERTIP_ANGLE &&
distance2 >= FINGERTIP_WIDTH_THRESHOLD) {
int mx = (defect1.end().x() + defect2.start().x()) / 2;
int my = (defect1.end().y() + defect2.start().y()) / 2;
View
6 src/edu/mit/yingyin/tabletop/models/FullOpenNIDevice.java
@@ -16,6 +16,7 @@
import org.OpenNI.OutArg;
import org.OpenNI.Player;
import org.OpenNI.PlayerSeekOrigin;
+import org.OpenNI.Point3D;
import org.OpenNI.ScriptNode;
import org.OpenNI.StatusException;
@@ -200,6 +201,11 @@ public void seekFrameBy(int diff) throws StatusException {
player.seekToFrame(depthGen, PlayerSeekOrigin.CURRENT, diff);
}
+ public Point3D[] convertProjectiveToRealWorld(Point3D[] points)
+ throws StatusException {
+ return depthGen.convertProjectiveToRealWorld(points);
+ }
+
private void updateMetaData() {
if (depthGen.isDataNew())
depthMD = depthGen.getMetaData();
View
9 src/edu/mit/yingyin/tabletop/models/HandAnalyzer.java
@@ -58,7 +58,6 @@
*/
private static final int BG_INIT_FRAMES = BG_INGNORE_FRAMES + 40;
-
private static final float BG_DIFF_LSCALE = 6;
private static final float BG_DIFF_HSCALE = 15;
@@ -102,6 +101,9 @@ public HandAnalyzer(int width, int height, int maxDepth) {
ffd = new ForelimbFeatureDetector(width, height);
}
+ /**
+ * @return true if background is initialized.
+ */
public boolean isBgInitialized() {
return background.isInitialized();
}
@@ -110,15 +112,15 @@ public FloatBuffer aveBg() {
return background.avgBuffer();
}
- public int aveBgWidth() {
+ public int aveBgWidthStep() {
return background.avgBufferWidthStep();
}
public FloatBuffer diffBg() {
return background.diffBuffer();
}
- public int diffBgWidth() {
+ public int diffBgWidthStep() {
return background.diffBufferWidthStep();
}
@@ -142,7 +144,6 @@ public void analyzeData(ProcessPacket packet) {
} else if (packet.depthFrameID == BG_INIT_FRAMES) {
background.createModelsFromStats((float) BG_DIFF_LSCALE,
(float) BG_DIFF_HSCALE);
- Table.instance().init(background);
logger.info(background.stats());
}
View
12 src/edu/mit/yingyin/tabletop/models/HandTracker.java
@@ -1,5 +1,6 @@
package edu.mit.yingyin.tabletop.models;
+import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -52,9 +53,6 @@ public String toString() {
private List<IHandEventListener> listeners =
new ArrayList<IHandEventListener>();
- /**
- * Reference to the table.
- */
private Table table;
/** Counts the duration of contact or noncontact. */
private int pressedCounter = 0, releasedCounter = 0;
@@ -63,10 +61,16 @@ public String toString() {
private CalibModel calibExample;
public HandTracker(CalibModel calibExample) {
- table = Table.instance();
this.calibExample = calibExample;
}
+ public boolean isTableInitialized() { return table != null; }
+
+ public void initTable(FloatBuffer avg, FloatBuffer diff, int avgWidthStep,
+ int diffWidthStep, int width, int height) {
+ table = new Table(avg, diff, avgWidthStep, diffWidthStep, width, height);
+ }
+
/**
* Updates forelimbs information and generates events.
* @param forelimbs information for all the forelimbs detected.
View
55 src/edu/mit/yingyin/tabletop/models/HandTrackingEngine.java
@@ -6,6 +6,8 @@
import java.util.logging.Logger;
import org.OpenNI.GeneralException;
+import org.OpenNI.Point3D;
+import org.OpenNI.StatusException;
import edu.mit.yingyin.calib.CalibModel;
import edu.mit.yingyin.image.ImageConvertUtils;
@@ -27,6 +29,10 @@
public void fingerPressed(List<FingerEvent> feList);
}
+ private static HandTrackingEngine instance;
+ private static String openniConfigFile, calibrationFile;
+ private static int maxDepth;
+
private static Logger logger = Logger.getLogger(
HandTrackingEngine.class.getName());
@@ -38,14 +44,41 @@
private HandAnalyzer analyzer;
/**
+ * Initialize and returns the instance of <code>HandTrackingEngine</code>.
+ * @param _openniConfigFile
+ * @param _calibrationFile
+ * @param _maxDepth
+ * @return
+ * @throws GeneralException
+ */
+ public static HandTrackingEngine initInstance(String _openniConfigFile,
+ String _calibrationFile, int _maxDepth) throws GeneralException {
+ openniConfigFile = _openniConfigFile;
+ calibrationFile = _calibrationFile;
+ maxDepth = _maxDepth;
+ return instance();
+ }
+
+ public static HandTrackingEngine instance() throws GeneralException {
+ if (openniConfigFile == null) {
+ logger.severe("HandTrackingEngine is not initialized");
+ System.exit(-1);
+ }
+ if (instance == null)
+ instance = new HandTrackingEngine(openniConfigFile, calibrationFile,
+ maxDepth);
+ return instance;
+ }
+
+ /**
* Creates a new <code>HandTrackingEngine</code>.
*
* @param openniConfigFile
* @param calibrationFile
* @param maxDepth
* @throws GeneralException
*/
- public HandTrackingEngine(String openniConfigFile,
+ private HandTrackingEngine(String openniConfigFile,
String calibrationFile, int maxDepth) throws GeneralException {
openni = new FullOpenNIDevice(openniConfigFile);
@@ -99,6 +132,11 @@ public void step() {
analyzer.analyzeData(packet);
+ if (!tracker.isTableInitialized() && analyzer.isBgInitialized()) {
+ tracker.initTable(analyzer.aveBg(), analyzer.diffBg(),
+ analyzer.aveBgWidthStep(), analyzer.diffBgWidthStep(), depthWidth,
+ depthHeight);
+ }
tracker.update(packet.forelimbs, packet.depthFrameID);
}
@@ -115,14 +153,25 @@ public FloatBuffer aveBg() {
}
public int aveBgWidth() {
- return analyzer.aveBgWidth();
+ return analyzer.aveBgWidthStep();
}
public FloatBuffer diffBg() {
return analyzer.diffBg();
}
public int diffBgWidth() {
- return analyzer.diffBgWidth();
+ return analyzer.diffBgWidthStep();
+ }
+
+ public Point3D[] convertProjectiveToRealWorld(Point3D[] points) {
+ Point3D[] converted = null;
+ try {
+ converted = openni.convertProjectiveToRealWorld(points);
+ } catch (StatusException se) {
+ logger.severe(se.getMessage());
+ System.exit(-1);
+ }
+ return converted;
}
}
View
2 src/edu/mit/yingyin/tabletop/models/ProcessPacket.java
@@ -47,7 +47,7 @@ public void release() {
}
/**
- * Integer array of raw depth values from Kinect.
+ * Integer array of raw depth values in mm from Kinect.
*/
public int[] depthRawData;
public IplImage depthImage8U;
View
98 src/edu/mit/yingyin/tabletop/models/Table.java
@@ -1,30 +1,38 @@
package edu.mit.yingyin.tabletop.models;
+import static com.googlecode.javacv.cpp.opencv_core.CV_32FC3;
+import static com.googlecode.javacv.cpp.opencv_imgproc.CV_DIST_L2;
+import static com.googlecode.javacv.cpp.opencv_imgproc.cvFitLine;
+
import java.nio.FloatBuffer;
+import java.util.logging.Logger;
+
+import javax.vecmath.Vector3f;
+
+import org.OpenNI.GeneralException;
+import org.OpenNI.Point3D;
+
+import com.googlecode.javacv.cpp.opencv_core.CvMat;
+
+import edu.mit.yingyin.util.VectorUtil;
/**
- * Model of the table.
+ * Model of a tabletop.
* @author yingyin
*
*/
public class Table {
+ private static final Logger logger = Logger.getLogger(Table.class.getName());
private static final int DIFF_SCALE = 5;
- static private Table table;
-
/**
- * Average depth and depth difference scaled between 0 and 1.
+ * Average depth and depth difference in mm.
*/
private FloatBuffer avg, diff;
- private int avgWidthStep, diffWidthStep;
+ private int avgWidthStep, diffWidthStep, width, height;
private boolean initialized = false;
+ private Vector3f surfaceNormal;
- public static Table instance() {
- if (table == null)
- table = new Table();
- return table;
- }
-
/**
* Initializes the table statistics.
* @param avg
@@ -33,18 +41,22 @@ public static Table instance() {
* @param diffWidthStep
* @param scale used to scale the depth value.
*/
- public void init(FloatBuffer avg, FloatBuffer diff, int avgWidthStep,
- int diffWidthStep) {
+ public Table(FloatBuffer avg, FloatBuffer diff, int avgWidthStep,
+ int diffWidthStep, int width, int height) {
this.avg = avg;
this.diff = diff;
this.avgWidthStep = avgWidthStep;
this.diffWidthStep = diffWidthStep;
+ this.width = width;
+ this.height = height;
+ computeSurfaceNormal();
initialized = true;
}
- public void init(Background background) {
- init(background.avgBuffer(), background.diffBuffer(),
- background.avgBufferWidthStep(), background.diffBufferWidthStep());
+ public Table(Background background) {
+ this(background.avgBuffer(), background.diffBuffer(),
+ background.avgBufferWidthStep(), background.diffBufferWidthStep(),
+ background.width(), background.height());
}
/**
@@ -85,5 +97,57 @@ private float diffAt(int x, int y) {
return diff.get(y * diffWidthStep + x);
}
- private Table() {}
+ private void computeSurfaceNormal() {
+ HandTrackingEngine engine = null;
+ try {
+ engine = HandTrackingEngine.instance();
+ } catch (GeneralException ge) {
+ logger.severe(ge.getMessage());
+ System.exit(-1);
+ }
+ Point3D[] points = new Point3D[width];
+ int h = height / 2;
+ int startIndex = h * avgWidthStep;
+ for (int i = 0; i < width; i++) {
+ float depth = avg.get(startIndex + i);
+ points[i] = new Point3D(i, h, depth);
+ }
+
+ Point3D[] converted = engine.convertProjectiveToRealWorld(points);
+ // projective = image coordinate space ((0,0) is top left corner of the
+ // image)
+ CvMat pointMat = CvMat.create(1, width, CV_32FC3);
+ for (int i = 0; i < converted.length; i++) {
+ pointMat.put(i * 3, converted[i].getX());
+ pointMat.put(i * 3 + 1, converted[i].getY());
+ pointMat.put(i * 3 + 2, converted[i].getZ());
+ }
+
+ float[] hline = new float[6];
+ cvFitLine(pointMat, CV_DIST_L2, 0, 0.001, 0.001, hline);
+ pointMat.release();
+
+ int w = width / 2;
+ points = new Point3D[height];
+ for (int i = 0; i < height; i++) {
+ points[i] = new Point3D(w, i, avg.get(avgWidthStep * i + w));
+ }
+
+ converted = engine.convertProjectiveToRealWorld(points);
+ pointMat = CvMat.create(1, height, CV_32FC3);
+ for (int i = 0; i < converted.length; i++) {
+ pointMat.put(i * 3, converted[i].getX());
+ pointMat.put(i * 3 + 1, converted[i].getY());
+ pointMat.put(i * 3 + 2, converted[i].getZ());
+ }
+
+ float[] vline = new float[6];
+ cvFitLine(pointMat, CV_DIST_L2, 0, 0.001, 0.001, vline);
+ pointMat.release();
+
+ Vector3f v1 = new Vector3f(hline[0], hline[1], hline[2]);
+ Vector3f v2 = new Vector3f(vline[0], vline[1], vline[3]);
+ surfaceNormal = VectorUtil.cross(v1, v2);
+ logger.info("surface normal = " + surfaceNormal);
+ }
}
View
3 src/edu/mit/yingyin/util/CommandLineOptions.java
@@ -3,7 +3,6 @@
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
-import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
@@ -12,7 +11,7 @@
private static CommandLineParser parser = new GnuParser();
private static CommandLine line;
- public static void addOption(Option option) {
+ public static void addOption(org.apache.commons.cli.Option option) {
options.addOption(option);
}
View
20 src/edu/mit/yingyin/util/Vector2fUtil.java → src/edu/mit/yingyin/util/VectorUtil.java
@@ -3,13 +3,14 @@
import javax.vecmath.Point2f;
import javax.vecmath.Tuple2f;
import javax.vecmath.Vector2f;
+import javax.vecmath.Vector3f;
/**
- * Utility class for 2D vector math.
+ * Utility class for 2D and 3D vector math.
* @author yingyin
*
*/
-public class Vector2fUtil {
+public class VectorUtil {
private static float EPS = (float)1e-5;
public static float dot(Vector2f a, Vector2f b) {
@@ -20,6 +21,11 @@ public static float cross(Vector2f a, Vector2f b) {
return a.x * b.y - a.y * b.x;
}
+ public static Vector3f cross(Vector3f a, Vector3f b) {
+ return new Vector3f(a.y * b.z - a.z * b.y, -a.x * b.z + a.z * b.x,
+ a.x * b.y - a.y * b.x);
+ }
+
public static float lengthSquared(Tuple2f a) {
float dx = a.x;
float dy = a.y;
@@ -33,9 +39,9 @@ public static float lengthSquared(Tuple2f a) {
* @return
*/
public static float angle(Vector2f a, Vector2f b) {
- float denom = (float)Math.sqrt(Vector2fUtil.lengthSquared(a) *
- Vector2fUtil.lengthSquared(b));
- float result = Vector2fUtil.dot(a, b) / denom;
+ float denom = (float)Math.sqrt(VectorUtil.lengthSquared(a) *
+ VectorUtil.lengthSquared(b));
+ float result = VectorUtil.dot(a, b) / denom;
return (float)Math.acos(result);
}
@@ -57,10 +63,10 @@ public static Point2f intersection(Point2f a, Point2f b, Point2f c, Point2f d)
ac.sub(c, a);
cd.sub(d, c);
ab.sub(b, a);
- float cp = Vector2fUtil.cross(ab, cd);
+ float cp = VectorUtil.cross(ab, cd);
if (cp < EPS && cp > -EPS)
return null;
- float s = Vector2fUtil.cross(ac, cd) / cp;
+ float s = VectorUtil.cross(ac, cd) / cp;
result.scaleAdd(s, ab, a);
return result;
}
View
4 test/edu/mit/yingyin/tabletop/models/HandTrackingEngineTest.java
@@ -13,8 +13,8 @@
@Test
public void testStep() {
try {
- HandTrackingEngine engine = new HandTrackingEngine(OPENNI_CONFIG_FILE,
- CALIB_FILE, MAX_DEPTH);
+ HandTrackingEngine engine = HandTrackingEngine.initInstance(
+ OPENNI_CONFIG_FILE, CALIB_FILE, MAX_DEPTH);
engine.step();
} catch (GeneralException ge) {
ge.printStackTrace();
View
3 test/edu/mit/yingyin/tabletop/models/TableTest.java
@@ -15,7 +15,6 @@
@Test
public void testTableContact() {
- Table table = Table.instance();
FloatBuffer avg = DirectBufferUtil.allocateFloatBuffer(WIDTH * HEIGHT);
FloatBuffer diff = DirectBufferUtil.allocateFloatBuffer(WIDTH * HEIGHT);
avg.rewind();
@@ -25,7 +24,7 @@ public void testTableContact() {
while(diff.remaining() > 0)
diff.put(1);
- table.init(avg, diff, WIDTH, WIDTH);
+ Table table = new Table(avg, diff, WIDTH, WIDTH, WIDTH, HEIGHT);
assertTrue(table.isInContact(0, 0, 1));
assertTrue(table.isInContact(0, 1, (float)1.9));
assertTrue(table.isInContact(1, 1, (float)0.1));

0 comments on commit c3c7e4f

Please sign in to comment.