-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.html
346 lines (284 loc) · 10.8 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
<!--
A Pen created at CodePen.io. You can find this one at https://codepen.io/ace-subido/pen/Cuiep.
Using default Bootstrap 3.0, here's a short CSS snippet to style your login form.
-->
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>SkeptCha: Login </title>
<link rel='stylesheet prefetch' href='http://netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css'>
<link rel="stylesheet" href="css/style.css">
<script type="text/javascript" src="drawCanvas.js"></script>
<script type="text/javascript" src="sketchDebugger.js"></script>
<script type="text/javascript" src="SketchRecTools.js"></script>
<script type="text/javascript" src="shortStraw.js"></script>
<!-- <script type="text/javascript" src="pdollar.js"></script> -->
<script type="text/javascript" src="triangleRecognizer.js"></script>
</head>
<body onload="start()" background="wallpaper.jpg">
<div class="wrapper">
<form class="form-signin">
<h2 class="form-signin-heading">Please login</h2>
<input type="text" class="form-control" name="username" placeholder="Username" required="" autofocus="" />
<br>
<input type="password" class="form-control" name="password" placeholder="Password" required=""/>
<label class="checkbox">
<input type="checkbox" value="remember-me" id="rememberMe" name="rememberMe"> Remember me
</label>
<div>
<p id="failureNotice">Please draw the given shape :)</p>
</div>
<div>
<canvas id="drawCanvas" class="canvaslook" width="200" height="200" ></canvas>
</div>
<div>
<canvas id="viewCanvas" class="canvasView" width="200" height="200" ></canvas>
</div>
<!-- Buttons Section -->
<div>
<input type="button" value="Clear" class="btn btn-sm btn-default" id="btn" onclick="clearButton(drawCanvas, drawContext);">
<input type="button" value="Undo" class="btn btn-sm btn-default" id="btn" onclick="undoButton(drawCanvas, drawContext);">
<input type="button" value="reSkeptCha" class="btn btn-sm btn-default" id="btn" onclick="start()">
<input type="button" value="Validate" class="btn btn-sm btn-default" id="btn" onclick="validateSkeptCha()">
</div>
<button class="btn btn-lg btn-primary btn-block" type="button" id="loginButton" disabled onclick="login()">Login</button>
</form>
</div>
<script type="text/javascript">
function start(){
loadSkeptCha();
initDrawing();
document.getElementById("loginButton").disabled = true;
}
var recognizing = "Dummy"; // Current interpretation of sketch
var indexFile; // File Storing Sketch Ids for a particular Interpretation
var localSketch = readJson('Data/Others/defaultSketch.json');
var responseTime = Date.now();
function loadSkeptCha() {
// get the canvas and its context
viewCanvas = document.getElementById('viewCanvas');
if (viewCanvas.getContext) {
viewContext = viewCanvas.getContext('2d');
}
clearCanvas(viewCanvas, viewContext);
// Select Random Interpretation
var totalInterpretations = 1;
var choose = Math.floor(totalInterpretations * Math.random());
switch(choose) {
case 0:
default: // Triangle
indexFile = readJson('Data/Triangle.json');
// console.log(indexFile);
var localId = indexFile[Math.floor(indexFile.length * Math.random())];
// console.log(localId);
if (localId) {
localSketch = readJson('Data/Sketch_Triangle/' + localId + '.json');
}
}
console.log("Loaded sketch:")
console.log(localSketch)
// Add Backgroung image and display sketch
var ref_image = new Image();
ref_image.src = 'Data/background/bkgRef'+ Math.floor(5 * Math.random()) +'.jpg';
ref_image.onload = function() {
viewContext.drawImage(ref_image, 0, 0);
var strokeColor = '#afafaf';
displaySketchInContext(localSketch, strokeColor, viewContext)
};
recognizing = localSketch.shapes[0].interpretation;
log("New SkeptCha Loaded");
// Start calculating response time
responseTime = Date.now();
}
function validateSkeptCha() {
responseTime = Date.now() - responseTime;
log("SkeptCha Validation requested: User Response Time " + responseTime + " ms.");
drawCanvas = document.getElementById('drawCanvas');
if (drawCanvas.getContext) {
drawContext = drawCanvas.getContext('2d');
}
var sketch = getSkeptCha(drawCanvas, recognizing);
// console.log(sketch);
if (!sketch) {
responseTime = Date.now();
log("User trying to validate Empty Sketch");
// Show Notification - Cannot validate empty sketch.. Please draw the given image.
}
// Template Matching
var matching = matchSkeptCha(sketch, localSketch);
log("Matching Score: " + matching);
var SamplingDist = SketchRecTools.determineResampleSpacing(sketch);
var resampledSketch = SketchRecTools.resampleByDistance(sketch, SamplingDist);
console.log("Resampled Sketch");
console.log(resampledSketch);
var result = false;
//Select appropriate recognizer as per the interpretation being recognized
result = TriangleRecognizer.validate(resampledSketch, SamplingDist);
// ToDo Add response Time as a metric
if(result || (150 < matching && matching < 550)) {
console.log("SkeptCha Validation Pass");
log("SkeptCha Validation Pass");
document.getElementById("loginButton").disabled = false;
saveSketch(sketch);
} else {
//TODO reduce confidence level of displayed sketch and save the drawn sketch to otherSketches folder
document.getElementById("failureNotice").innerHTML = "SkeptCha validation fail :( Please try again...";
console.log("SkeptCha Validation Fail");
log("SkeptCha Validation Fail");
start()
}
return result;
}
/**
* Retrieve the currently drawn sketch from the canvas without clearing it
* @param {Object} canvas - The draw canvas.
*/
function getSkeptCha(canvas, interpretation) {
// get the sketch's strokes and validate
var strokes = DrawCanvasData.strokes;
if (strokes.length == 0){
// console.log("Cannot validate empty sketch. Please draw the given image.");
return;
}
// get the sketch's interpretation
if (interpretation === "") {
interpretation = "none";
}
// get the sketch's domain(s)
var domainString = "SkeptCha";
// parse the domains into an array
var domainString = domainString.replace(/ /g, ''); // removes whitespace
var domain = domainString.split(",");
// Set up sketch object
var id = generateUuidv4();
// get the sketch's first time
var firstTime = strokes[0].points[0].time;
// create the sketch's shapes object
var shape = {};
shape.subElements = [];
for (var i = 0; i < strokes.length; i++) {
var stroke = strokes[i];
shape.subElements.push(stroke.id);
}
shape.time = firstTime;
shape.interpretation = interpretation;
shape.confidence = "1.0";
// id, time, domain, strokes, shapes
var sketch = {};
sketch.id = id;
sketch.time = firstTime;
sketch.domain = domainString.split(",");;
sketch.canvasWidth = Number.parseInt(canvas.width);;
sketch.canvasHeight = Number.parseInt(canvas.height);;
sketch.strokes = strokes;
sketch.shapes = [shape];
return sketch;
}
var NumPoints = 100;
var Origin = {x: 0, y: 0};
// Template Matching using P-dollar algorithm
function matchSkeptCha(sketch, template) {
sketch = SketchRecTools.resampleByCount(sketch, NumPoints);
template = SketchRecTools.resampleByCount(template, NumPoints);
sketch = SketchRecTools.scaleProportional(sketch, 200);
template = SketchRecTools.scaleProportional(template, 200);
sketch = SketchRecTools.translateToPoint(sketch, Origin);
template = SketchRecTools.translateToPoint(template, Origin);
var pointsA = [];
var pointsB = [];
for (var i=0; i< sketch.strokes.length; i++) {
pointsA.push.apply(pointsA, sketch.strokes[i].points);
}
for (var i=0; i< template.strokes.length; i++) {
pointsB.push.apply(pointsB, template.strokes[i].points);
}
console.log("pointsA", pointsA);
console.log("pointsB", pointsB);
var diffLen = pointsA.length - pointsB.length;
// console.log(pointsA.length);
// console.log(pointsB.length);
// console.log(diffLen);
if (diffLen > 0) {
pointsA.splice(-1*diffLen, diffLen);
} else if (diffLen < 0) {
pointsB.splice(diffLen, -1*diffLen);
}
// console.log("pointsA", pointsA);
// console.log("pointsB", pointsB);
var score = GreedyCloudMatch(pointsA, pointsB);
console.log("Matching Score", score);
return score;
}
function GreedyCloudMatch(pointsA, pointsB)
{
var e = 0.50;
var step = Math.floor(Math.pow(pointsA.length, 1 - e));
var min = +Infinity;
for (var i = 0; i < pointsA.length; i += step) {
var d1 = CloudDistance(pointsA, pointsB, i);
var d2 = CloudDistance(pointsB, pointsA, i);
min = Math.min(min, Math.min(d1, d2)); // min3
}
return min;
}
function CloudDistance(pts1, pts2, start)
{
var matched = new Array(pts1.length); // pts1.length == pts2.length
for (var k = 0; k < pts1.length; k++)
matched[k] = false;
var sum = 0;
var i = start;
do
{
var index = -1;
var min = +Infinity;
for (var j = 0; j < matched.length; j++)
{
if (!matched[j]) {
var d = SketchRecTools.calculateDistance(pts1[i].x, pts1[i].y, pts2[j].x, pts2[j].y);
if (d < min) {
min = d;
index = j;
}
}
}
matched[index] = true;
var weight = 1 - ((i - start + pts1.length) % pts1.length) / pts1.length;
sum += weight * min;
i = (i + 1) % pts1.length;
} while (i != start);
return sum;
}
function readJson(fileName) {
var contents;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
contents = JSON.parse(this.response);
}
};
xhttp.open("GET", fileName, false);
xhttp.send();
return contents;
}
function saveSketch(sketch) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000/saveSkeptCha", false);
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
var data = JSON.stringify(sketch);
xhr.send(data);
}
function log(event) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000/log", false);
xhr.setRequestHeader("Content-Type", "text/plain; charset=UTF-8");
xhr.send(event);
}
function login(){
log("User Logged in to the system");
window.location.href = "success.html";
}
</script>
</body>
</html>