The uWave: Accelerometer-based Gesture Recognition project from the Rice Efficient Computing Group inspired me to build a small real time HTML based signature identification with JavaScript. Actually gestures have not that much incommon with drawn handwriting, but I wanted to test dynamic-time-warping on signatures. I am not sure if there is a real usecase for a signature identification in web applications, but it was fun to build this kind of prototyp. Feedback is welcome.
Please note this small application tries to identify just simple signatures. The path, the speed and the size of the drawn signature are very important. For example a circle clockwise is not the same as a circle anticlockwise.
Just make your signature, any symbol or an other doodle on the first square (violet). Afterwards try to draw the same thing again on the second square (cyan). A simple example to start is a triangle for example. There is a maximum pause of one second between strokes in the signature. The application will think it is beginning a new signature if the pause between strokes is longer than one second.
We have now both signatures in one rectangle. The white strokes symbolize the path of the dynamic time warping.
The following explanation will ignore the painting from the signatures on canvas. More important are the data preparation and evaluation.
First we are recording the touch with the events touchstart
, touchmove
and
touchend
or the mouse movements with mousedown
, mousemove
and
mouseup
. Important are the x
and the y
coordinates of the events relative to
the left upper corner of the green rectangle. The signature is finished if the user stops painting for more than 1
second between strokes.
We need to normalize the signatures to making sure that a signature in the left upper corner is the same as a
signature in the right corner. We just collect all x
values of a signature and calculate the average
value. Every x
value in the signature will be reduced by this average value. We do the same with the
y
values.
// data is an array of arrays with the x coordinate in 0 and y in 1
function prepareSignature(data) {
var xMean = 0;
var yMean = 0;
var diffData = [];
for (var i = 0; i < data.length; i++) {
xMean = xMean + data[i][0];
yMean = yMean + data[i][1];
}
xMean = xMean / data.length;
yMean = yMean / data.length;
for (var i = 0; i < data.length; i++) {
diffData[i] = [data[i][0] - xMean, data[i][1] - yMean];
}
return diffData;
}
The application will start comparing if both rectangles have signatures. That can be done with the following lines
of code. The distance function that is injected into the DynamicTimeWarping
calculates just the
euclidian distance between two points in a two-dimensional space.
var dtw = new DynamicTimeWarping(sig1, sig2, function (a, b) {
var xDiff = a[0] - b[0];
var yDiff = a[1] - b[1];
return diff = Math.sqrt(xDiff * xDiff + yDiff * yDiff);
});
var result = dtw.getDistance();
The result itself also needs to be normalized. We just divide the result by the length of the dynamic time warping
path. Afterwards the result will be compared with an upper bound that was estimated by experience. In my case it was
the the average between height and width of the rectangle divided by 15
.
var path = dtw.getPath();
var result = result / path.length;
Here some example signatures and their distances.