Added non-uniform scaling for spatial sampling.
This commit is contained in:
@@ -27,7 +27,10 @@ import java.io.IOException;
|
||||
import static android.gesture.GestureConstants.*;
|
||||
|
||||
final class GestureUtilities {
|
||||
|
||||
|
||||
private static final float SCALING_THRESHOLD = 0.26f;
|
||||
private static final float NONUNIFORM_SCALE = (float) Math.sqrt(2);
|
||||
|
||||
private GestureUtilities() {
|
||||
}
|
||||
|
||||
@@ -46,63 +49,82 @@ final class GestureUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension) {
|
||||
static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension,
|
||||
boolean uniformScaling) {
|
||||
final float targetPatchSize = sampleMatrixDimension - 1; // edge inclusive
|
||||
float[] sample = new float[sampleMatrixDimension * sampleMatrixDimension];
|
||||
Arrays.fill(sample, 0);
|
||||
|
||||
RectF rect = gesture.getBoundingBox();
|
||||
float sx = targetPatchSize / rect.width();
|
||||
float sy = targetPatchSize / rect.height();
|
||||
float scale = sx < sy ? sx : sy;
|
||||
|
||||
final float gestureWidth = rect.width();
|
||||
final float gestureHeight = rect.height();
|
||||
float sx = targetPatchSize / gestureWidth;
|
||||
float sy = targetPatchSize / gestureHeight;
|
||||
|
||||
if (uniformScaling) {
|
||||
float scale = sx < sy ? sx : sy;
|
||||
sx = scale;
|
||||
sy = scale;
|
||||
} else {
|
||||
|
||||
float aspectRatio = gestureWidth / gestureHeight;
|
||||
if (aspectRatio > 1) {
|
||||
aspectRatio = 1 / aspectRatio;
|
||||
}
|
||||
if (aspectRatio < SCALING_THRESHOLD) {
|
||||
float scale = sx < sy ? sx : sy;
|
||||
sx = scale;
|
||||
sy = scale;
|
||||
} else {
|
||||
if (sx > sy) {
|
||||
float scale = sy * NONUNIFORM_SCALE;
|
||||
if (scale < sx) {
|
||||
sx = scale;
|
||||
}
|
||||
} else {
|
||||
float scale = sx * NONUNIFORM_SCALE;
|
||||
if (scale < sy) {
|
||||
sy = scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
float preDx = -rect.centerX();
|
||||
float preDy = -rect.centerY();
|
||||
float postDx = targetPatchSize / 2;
|
||||
float postDy = targetPatchSize / 2;
|
||||
|
||||
final ArrayList<GestureStroke> strokes = gesture.getStrokes();
|
||||
final int count = strokes.size();
|
||||
|
||||
int size;
|
||||
float xpos;
|
||||
float ypos;
|
||||
|
||||
for (int index = 0; index < count; index++) {
|
||||
final GestureStroke stroke = strokes.get(index);
|
||||
float[] strokepoints = stroke.points;
|
||||
size = strokepoints.length;
|
||||
|
||||
final float[] pts = new float[size];
|
||||
|
||||
for (int i = 0; i < size; i += 2) {
|
||||
pts[i] = (strokepoints[i] + preDx) * scale + postDx;
|
||||
pts[i + 1] = (strokepoints[i + 1] + preDy) * scale + postDy;
|
||||
pts[i] = (strokepoints[i] + preDx) * sx + postDx;
|
||||
pts[i + 1] = (strokepoints[i + 1] + preDy) * sy + postDy;
|
||||
}
|
||||
|
||||
float segmentEndX = -1;
|
||||
float segmentEndY = -1;
|
||||
|
||||
for (int i = 0; i < size; i += 2) {
|
||||
|
||||
float segmentStartX = pts[i] < 0 ? 0 : pts[i];
|
||||
float segmentStartY = pts[i + 1] < 0 ? 0 : pts[i + 1];
|
||||
|
||||
if (segmentStartX > targetPatchSize) {
|
||||
segmentStartX = targetPatchSize;
|
||||
}
|
||||
|
||||
if (segmentStartY > targetPatchSize) {
|
||||
segmentStartY = targetPatchSize;
|
||||
}
|
||||
|
||||
plot(segmentStartX, segmentStartY, sample, sampleMatrixDimension);
|
||||
|
||||
if (segmentEndX != -1) {
|
||||
// evaluate horizontally
|
||||
if (segmentEndX > segmentStartX) {
|
||||
xpos = (float) Math.ceil(segmentStartX);
|
||||
float slope = (segmentEndY - segmentStartY) / (segmentEndX - segmentStartX);
|
||||
float slope = (segmentEndY - segmentStartY) /
|
||||
(segmentEndX - segmentStartX);
|
||||
while (xpos < segmentEndX) {
|
||||
ypos = slope * (xpos - segmentStartX) + segmentStartY;
|
||||
plot(xpos, ypos, sample, sampleMatrixDimension);
|
||||
@@ -110,18 +132,19 @@ final class GestureUtilities {
|
||||
}
|
||||
} else if (segmentEndX < segmentStartX){
|
||||
xpos = (float) Math.ceil(segmentEndX);
|
||||
float slope = (segmentEndY - segmentStartY) / (segmentEndX - segmentStartX);
|
||||
float slope = (segmentEndY - segmentStartY) /
|
||||
(segmentEndX - segmentStartX);
|
||||
while (xpos < segmentStartX) {
|
||||
ypos = slope * (xpos - segmentStartX) + segmentStartY;
|
||||
plot(xpos, ypos, sample, sampleMatrixDimension);
|
||||
xpos++;
|
||||
}
|
||||
}
|
||||
|
||||
// evaluating vertically
|
||||
if (segmentEndY > segmentStartY) {
|
||||
ypos = (float) Math.ceil(segmentStartY);
|
||||
float invertSlope = (segmentEndX - segmentStartX) / (segmentEndY - segmentStartY);
|
||||
float invertSlope = (segmentEndX - segmentStartX) /
|
||||
(segmentEndY - segmentStartY);
|
||||
while (ypos < segmentEndY) {
|
||||
xpos = invertSlope * (ypos - segmentStartY) + segmentStartX;
|
||||
plot(xpos, ypos, sample, sampleMatrixDimension);
|
||||
@@ -129,7 +152,8 @@ final class GestureUtilities {
|
||||
}
|
||||
} else if (segmentEndY < segmentStartY) {
|
||||
ypos = (float) Math.ceil(segmentEndY);
|
||||
float invertSlope = (segmentEndX - segmentStartX) / (segmentEndY - segmentStartY);
|
||||
float invertSlope = (segmentEndX - segmentStartX) /
|
||||
(segmentEndY - segmentStartY);
|
||||
while (ypos < segmentStartY) {
|
||||
xpos = invertSlope * (ypos - segmentStartY) + segmentStartX;
|
||||
plot(xpos, ypos, sample, sampleMatrixDimension);
|
||||
@@ -137,13 +161,10 @@ final class GestureUtilities {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
segmentEndX = segmentStartX;
|
||||
segmentEndY = segmentStartY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
@@ -162,40 +183,44 @@ final class GestureUtilities {
|
||||
sample[index] = 1;
|
||||
}
|
||||
} else {
|
||||
double topLeft = Math.sqrt(Math.pow(xFloor - x, 2) + Math.pow(yFloor - y, 2));
|
||||
double topRight = Math.sqrt(Math.pow(xCeiling - x, 2) + Math.pow(yFloor - y, 2));
|
||||
double btmLeft = Math.sqrt(Math.pow(xFloor - x, 2) + Math.pow(yCeiling - y, 2));
|
||||
double btmRight = Math.sqrt(Math.pow(xCeiling - x, 2) + Math.pow(yCeiling - y, 2));
|
||||
double sum = topLeft + topRight + btmLeft + btmRight;
|
||||
final double xFloorSq = Math.pow(xFloor - x, 2);
|
||||
final double yFloorSq = Math.pow(yFloor - y, 2);
|
||||
final double xCeilingSq = Math.pow(xCeiling - x, 2);
|
||||
final double yCeilingSq = Math.pow(yCeiling - y, 2);
|
||||
float topLeft = (float) Math.sqrt(xFloorSq + yFloorSq);
|
||||
float topRight = (float) Math.sqrt(xCeilingSq + yFloorSq);
|
||||
float btmLeft = (float) Math.sqrt(xFloorSq + yCeilingSq);
|
||||
float btmRight = (float) Math.sqrt(xCeilingSq + yCeilingSq);
|
||||
float sum = topLeft + topRight + btmLeft + btmRight;
|
||||
|
||||
double value = topLeft / sum;
|
||||
float value = topLeft / sum;
|
||||
int index = yFloor * sampleSize + xFloor;
|
||||
if (value > sample[index]){
|
||||
sample[index] = (float) value;
|
||||
sample[index] = value;
|
||||
}
|
||||
|
||||
value = topRight / sum;
|
||||
index = yFloor * sampleSize + xCeiling;
|
||||
if (value > sample[index]){
|
||||
sample[index] = (float) value;
|
||||
sample[index] = value;
|
||||
}
|
||||
|
||||
value = btmLeft / sum;
|
||||
index = yCeiling * sampleSize + xFloor;
|
||||
if (value > sample[index]){
|
||||
sample[index] = (float) value;
|
||||
sample[index] = value;
|
||||
}
|
||||
|
||||
value = btmRight / sum;
|
||||
index = yCeiling * sampleSize + xCeiling;
|
||||
if (value > sample[index]){
|
||||
sample[index] = (float) value;
|
||||
sample[index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Featurize a stroke into a vector of a given number of elements
|
||||
* Featurizes a stroke into a vector of a given number of elements
|
||||
*
|
||||
* @param stroke
|
||||
* @param sampleSize
|
||||
|
||||
@@ -84,7 +84,7 @@ class Instance {
|
||||
}
|
||||
|
||||
private static float[] spatialSampler(Gesture gesture) {
|
||||
return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE);
|
||||
return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE, false);
|
||||
}
|
||||
|
||||
private static float[] temporalSampler(int orientationType, Gesture gesture) {
|
||||
|
||||
Reference in New Issue
Block a user