diff options
author | Yang Li <liyang@google.com> | 2009-05-27 18:19:04 -0700 |
---|---|---|
committer | Yang Li <liyang@google.com> | 2009-05-27 18:19:04 -0700 |
commit | 58b359041a29418876f12d37a7082ece9f8a38a4 (patch) | |
tree | 1bcdc590cc499afe5328b5b96276ee8a44fa85a1 | |
parent | b082ceefdc877bda2159a8d66d854576e0511d15 (diff) | |
download | frameworks_base-58b359041a29418876f12d37a7082ece9f8a38a4.zip frameworks_base-58b359041a29418876f12d37a7082ece9f8a38a4.tar.gz frameworks_base-58b359041a29418876f12d37a7082ece9f8a38a4.tar.bz2 |
Bug fixes and performance improvements
- Added affine transform functions in GestureUtilities to remove Matrix
- Fixed a bug with Instance.createInstance
- Updated letter recognition file
-rw-r--r-- | core/java/android/gesture/GestureLibrary.java | 10 | ||||
-rw-r--r-- | core/java/android/gesture/GestureStroke.java | 11 | ||||
-rwxr-xr-x | core/java/android/gesture/GestureUtilities.java | 44 | ||||
-rwxr-xr-x | core/java/android/gesture/Instance.java | 32 | ||||
-rw-r--r-- | core/java/android/gesture/InstanceLearner.java | 9 | ||||
-rw-r--r-- | core/res/res/raw/latin_lowercase | bin | 28494 -> 28496 bytes |
6 files changed, 65 insertions, 41 deletions
diff --git a/core/java/android/gesture/GestureLibrary.java b/core/java/android/gesture/GestureLibrary.java index 1cf192e..9020d2b 100644 --- a/core/java/android/gesture/GestureLibrary.java +++ b/core/java/android/gesture/GestureLibrary.java @@ -136,7 +136,7 @@ public class GestureLibrary { * @return a list of predictions of possible entries for a given gesture */ public ArrayList<Prediction> recognize(Gesture gesture) { - Instance instance = Instance.createInstance(mSequenceType, gesture, null); + Instance instance = Instance.createInstance(mSequenceType, mOrientationStyle, gesture, null); return mClassifier.classify(mSequenceType, instance.vector); } @@ -156,7 +156,7 @@ public class GestureLibrary { mNamedGestures.put(entryName, gestures); } gestures.add(gesture); - mClassifier.addInstance(Instance.createInstance(mSequenceType, gesture, entryName)); + mClassifier.addInstance(Instance.createInstance(mSequenceType, mOrientationStyle, gesture, entryName)); mChanged = true; } @@ -337,10 +337,14 @@ public class GestureLibrary { for (int j = 0; j < gestureCount; j++) { final Gesture gesture = Gesture.deserialize(in); gestures.add(gesture); - classifier.addInstance(Instance.createInstance(mSequenceType, gesture, name)); + classifier.addInstance(Instance.createInstance(mSequenceType, mOrientationStyle, gesture, name)); } namedGestures.put(name, gestures); } } + + Learner getLearner() { + return mClassifier; + } } diff --git a/core/java/android/gesture/GestureStroke.java b/core/java/android/gesture/GestureStroke.java index 0d7bc2d..90faaed 100644 --- a/core/java/android/gesture/GestureStroke.java +++ b/core/java/android/gesture/GestureStroke.java @@ -17,7 +17,6 @@ package android.gesture; import android.graphics.Canvas; -import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; @@ -147,10 +146,12 @@ public class GestureStroke { final float[] pts = GestureUtilities.temporalSampling(this, numSample); final RectF rect = boundingBox; - final Matrix matrix = new Matrix(); - matrix.setTranslate(-rect.left, -rect.top); - matrix.postScale(width / rect.width(), height / rect.height()); - matrix.mapPoints(pts); + GestureUtilities.translate(pts, -rect.left, -rect.top); + + float sx = width / rect.width(); + float sy = height / rect.height(); + float scale = sx > sy ? sy : sx; + GestureUtilities.scale(pts, scale, scale); float mX = 0; float mY = 0; diff --git a/core/java/android/gesture/GestureUtilities.java b/core/java/android/gesture/GestureUtilities.java index 4a3144c..3e8a3c8 100755 --- a/core/java/android/gesture/GestureUtilities.java +++ b/core/java/android/gesture/GestureUtilities.java @@ -17,7 +17,6 @@ package android.gesture; import android.graphics.RectF; -import android.graphics.Matrix; import android.util.Log; import java.util.ArrayList; @@ -380,22 +379,17 @@ final class GestureUtilities { } static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) { - Matrix tr = new Matrix(); - tr.setTranslate(-centroid[0], -centroid[1]); - tr.mapPoints(points); + translate(points, -centroid[0], -centroid[1]); double[][] array = computeCoVariance(points); double[] targetVector = computeOrientation(array); float angle; if (targetVector[0] == 0 && targetVector[1] == 0) { - angle = -90; + angle = (float) -Math.PI/2; } else { // -PI<alpha<PI angle = (float) Math.atan2(targetVector[1], targetVector[0]); - angle = (float) (180 * angle / Math.PI); - Matrix trans = new Matrix(); - trans.setRotate(-angle); - trans.mapPoints(points); + rotate(points, -angle); } float minx = Float.MAX_VALUE; @@ -446,4 +440,36 @@ final class GestureUtilities { } return targetVector; } + + + static float[] rotate(float[] points, double angle) { + double cos = Math.cos(angle); + double sin = Math.sin(angle); + int size = points.length; + for (int i = 0; i < size; i += 2) { + float x = (float) (points[i] * cos - points[i + 1] * sin); + float y = (float) (points[i] * sin + points[i + 1] * cos); + points[i] = x; + points[i + 1] = y; + } + return points; + } + + static float[] translate(float[] points, float dx, float dy) { + int size = points.length; + for (int i = 0; i < size; i += 2) { + points[i] += dx; + points[i + 1] += dy; + } + return points; + } + + static float[] scale(float[] points, float sx, float sy) { + int size = points.length; + for (int i = 0; i < size; i += 2) { + points[i] *= sx; + points[i + 1] *= sy; + } + return points; + } } diff --git a/core/java/android/gesture/Instance.java b/core/java/android/gesture/Instance.java index 7922fab..9ac0a96 100755 --- a/core/java/android/gesture/Instance.java +++ b/core/java/android/gesture/Instance.java @@ -16,7 +16,6 @@ package android.gesture; -import android.graphics.Matrix; /** * An instance represents a sample if the label is available or a query if the @@ -28,7 +27,9 @@ class Instance { private static final int PATCH_SAMPLE_SIZE = 16; private final static float[] ORIENTATIONS = { - 0, 45, 90, 135, 180, -0, -45, -90, -135, -180 + 0, (float) (Math.PI / 4), (float) (Math.PI / 2), (float) (Math.PI * 3 / 4), + (float) Math.PI, -0, (float) (-Math.PI / 4), (float) (-Math.PI / 2), + (float) (-Math.PI * 3 / 4), (float) -Math.PI }; // the feature vector @@ -39,13 +40,13 @@ class Instance { // the id of the instance final long id; - + private Instance(long id, float[] sample, String sampleName) { this.id = id; vector = sample; label = sampleName; } - + private void normalize() { float[] sample = vector; float sum = 0; @@ -55,7 +56,7 @@ class Instance { sum += sample[i] * sample[i]; } - float magnitude = (float) Math.sqrt(sum); + float magnitude = (float)Math.sqrt(sum); for (int i = 0; i < size; i++) { sample[i] /= magnitude; } @@ -68,11 +69,11 @@ class Instance { * @param label * @return the instance */ - static Instance createInstance(int samplingType, Gesture gesture, String label) { + static Instance createInstance(int sequenceType, int orientationType, Gesture gesture, String label) { float[] pts; Instance instance; - if (samplingType == GestureLibrary.SEQUENCE_SENSITIVE) { - pts = temporalSampler(samplingType, gesture); + if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) { + pts = temporalSampler(orientationType, gesture); instance = new Instance(gesture.getID(), pts, label); instance.normalize(); } else { @@ -81,20 +82,19 @@ class Instance { } return instance; } - + private static float[] spatialSampler(Gesture gesture) { return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE); } - private static float[] temporalSampler(int samplingType, Gesture gesture) { + private static float[] temporalSampler(int orientationType, Gesture gesture) { float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0), SEQUENCE_SAMPLE_SIZE); float[] center = GestureUtilities.computeCentroid(pts); - float orientation = (float) Math.atan2(pts[1] - center[1], pts[0] - center[0]); - orientation *= 180 / Math.PI; + float orientation = (float)Math.atan2(pts[1] - center[1], pts[0] - center[0]); float adjustment = -orientation; - if (samplingType == GestureLibrary.ORIENTATION_SENSITIVE) { + if (orientationType == GestureLibrary.ORIENTATION_SENSITIVE) { int count = ORIENTATIONS.length; for (int i = 0; i < count; i++) { float delta = ORIENTATIONS[i] - orientation; @@ -104,10 +104,8 @@ class Instance { } } - Matrix m = new Matrix(); - m.setTranslate(-center[0], -center[1]); - m.postRotate(adjustment); - m.mapPoints(pts); + GestureUtilities.translate(pts, -center[0], -center[1]); + GestureUtilities.rotate(pts, adjustment); return pts; } diff --git a/core/java/android/gesture/InstanceLearner.java b/core/java/android/gesture/InstanceLearner.java index 1739cdc..b6feb64 100644 --- a/core/java/android/gesture/InstanceLearner.java +++ b/core/java/android/gesture/InstanceLearner.java @@ -16,14 +16,9 @@ package android.gesture; -import android.util.Config; -import android.util.Log; -import static android.gesture.GestureConstants.*; - import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.Iterator; import java.util.TreeMap; /** @@ -32,7 +27,7 @@ import java.util.TreeMap; class InstanceLearner extends Learner { @Override - ArrayList<Prediction> classify(int gestureType, float[] vector) { + ArrayList<Prediction> classify(int sequenceType, float[] vector) { ArrayList<Prediction> predictions = new ArrayList<Prediction>(); ArrayList<Instance> instances = getInstances(); int count = instances.size(); @@ -43,7 +38,7 @@ class InstanceLearner extends Learner { continue; } double distance; - if (gestureType == GestureLibrary.SEQUENCE_SENSITIVE) { + if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) { distance = GestureUtilities.cosineDistance(sample.vector, vector); } else { distance = GestureUtilities.squaredEuclideanDistance(sample.vector, vector); diff --git a/core/res/res/raw/latin_lowercase b/core/res/res/raw/latin_lowercase Binary files differindex 17cfaf0..443d5f8 100644 --- a/core/res/res/raw/latin_lowercase +++ b/core/res/res/raw/latin_lowercase |