File size: 18,520 Bytes
310ce48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
<!doctype html>
<!--
  File: evaluation.html
  Author: Amey Thakur
  GitHub: https://github.com/Amey-Thakur
  Repository: https://github.com/Amey-Thakur/GESTURE-FX
  Release Date: September 1 2026
  License: MIT

  Tech Stack: HTML5, CSS3, TypeScript (ES2022)

  Description:
  Measures the palm-flip detector against a corpus with exact ground truth, and
  prints the result.

  Why this page exists
  --------------------
  The quantity that matters for a frame-synchronous detector is the error
  between the frame on which the gesture physically occurred and the frame the
  detector reports. That quantity cannot be measured from recorded footage,
  because the true crossing frame is not observable in a video: an annotator
  watching a hand rotate can identify the edge-on frame only to within the few
  frames over which the hand looks edge-on, which is the same order as the error
  being measured.

  The corpus is therefore generated rather than filmed. A rigid hand is rotated
  about its own long axis by a known angle at a known rate, projected, and
  perturbed by noise of a stated magnitude. The instant the rotation passes
  ninety degrees is then known exactly, and the detector's report can be
  compared against it.

  What this measures and what it does not
  ---------------------------------------
  It measures the detector: the criterion, the gating conditions, and the
  arithmetic that recovers the causal instant. It does not measure the landmark
  estimator, which is modelled here as unbiased noise of a fixed magnitude and
  is in reality neither unbiased nor of fixed magnitude. A real hand also
  deforms as it turns, which a rigid model does not.

  The near-miss classes exist because a detector that fires on everything scores
  perfectly on the flip class alone. Each of them is a movement that shares part
  of a flip's signature and must not be reported as one.

  Run it by opening this page. It runs the same modules the application runs.
-->
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>GESTURE-FX &middot; Detector Evaluation</title>

    <meta name="description"
        content="The GESTURE-FX palm-flip detector, evaluated in your browser against a seeded synthetic corpus where the crossing time is known exactly. 95.0 per cent detected, 0 false positives in 240 near-miss sequences, 6.7 ms mean localisation error. Runs the shipped modules, so the figures are reproduced rather than reported.">
    <meta name="author" content="Amey Thakur">
    <meta name="keywords"
        content="gesture detection evaluation, palm flip detection, hand gesture benchmark, temporal localisation error, false positive rate, zero crossing detection, reproducible evaluation, browser computer vision, MediaPipe, GESTURE-FX, Amey Thakur">

    <link rel="canonical" href="https://amey-thakur.github.io/GESTURE-FX/evaluation.html">

    <meta property="og:type" content="article">
    <meta property="og:site_name" content="GESTURE-FX">
    <meta property="og:title" content="GESTURE-FX &middot; Detector Evaluation">
    <meta property="og:description"
        content="95.0 per cent of palm flips detected, 0 false positives in 240 near-miss sequences, 6.7 ms mean localisation error. Reproduced in your own browser against the shipped modules.">
    <meta property="og:url" content="https://amey-thakur.github.io/GESTURE-FX/evaluation.html">
    <meta property="og:image" content="https://amey-thakur.github.io/GESTURE-FX/social-preview.png">

    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:title" content="GESTURE-FX &middot; Detector Evaluation">
    <meta name="twitter:description"
        content="95.0 per cent of palm flips detected, 0 false positives in 240 near-miss sequences, 6.7 ms mean localisation error. Reproduced in your own browser.">
    <meta name="twitter:image" content="https://amey-thakur.github.io/GESTURE-FX/social-preview.png">

    <script type="application/ld+json">
    {
            "@context": "https://schema.org",
            "@type": "Dataset",
            "name": "GESTURE-FX palm-flip detector evaluation",
            "description": "The GESTURE-FX palm-flip detector, evaluated in your browser against a seeded synthetic corpus where the crossing time is known exactly. 95.0 per cent detected, 0 false positives in 240 near-miss sequences, 6.7 ms mean localisation error. Runs the shipped modules, so the figures are reproduced rather than reported.",
            "url": "https://amey-thakur.github.io/GESTURE-FX/evaluation.html",
            "license": "https://opensource.org/licenses/MIT",
            "isAccessibleForFree": true,
            "creator": {
                    "@type": "Person",
                    "name": "Amey Thakur",
                    "url": "https://github.com/Amey-Thakur",
                    "identifier": "https://orcid.org/0000-0001-5644-1575"
            },
            "citation": {
                "@type": "ScholarlyArticle",
                "name": "Frame-Synchronous Hand Gesture Detection by Projected Winding Order",
                "author": {
                    "@type": "Person",
                    "name": "Amey Thakur",
                    "@id": "https://orcid.org/0000-0001-5644-1575"
                },
                "identifier": "https://doi.org/10.48550/arXiv.2609.13269",
                "url": "https://arxiv.org/abs/2609.13269"
            },
            "measurementTechnique": "Seeded synthetic landmark corpus with exact ground-truth crossing times, evaluated against the shipped detector modules",
            "variableMeasured": [
                    {
                            "@type": "PropertyValue",
                            "name": "Detection rate",
                            "value": "95.0",
                            "unitText": "percent"
                    },
                    {
                            "@type": "PropertyValue",
                            "name": "False positives",
                            "value": "0",
                            "description": "across 240 near-miss sequences"
                    },
                    {
                            "@type": "PropertyValue",
                            "name": "Mean localisation error",
                            "value": "6.7",
                            "unitText": "ms"
                    },
                    {
                            "@type": "PropertyValue",
                            "name": "Median localisation error",
                            "value": "4.0",
                            "unitText": "ms"
                    }
            ],
            "isPartOf": "https://amey-thakur.github.io/GESTURE-FX/"
    }
    </script>

    <link rel="icon" type="image/svg+xml" href="/assets/favicon-CpSTbO1N.svg">

    <style>
        /*
         * base.css fixes the application shell to the viewport and lets only its
         * overlays scroll, which is correct for a camera interface and wrong for
         * a document. This page is a document, so it takes its height from its
         * content and scrolls in the ordinary way.
         *
         * The override wins on specificity rather than on order, and that is
         * deliberate. The bundler hoists the built stylesheet into a link tag
         * immediately before the closing head tag, which places it after this
         * block however the source is written. An override that relied on
         * coming last therefore worked in development and was silently
         * discarded in the build. :root matches the same html element and adds
         * a class-level component, so these two selectors outrank the plain
         * element selectors in base.css wherever either sheet ends up.
         */
        html:root,
        html:root > body {
            height: auto;
            min-height: 100%;
            overflow: visible;
        }


        /* --- Masthead ---------------------------------------------------- */

        .masthead {
            display: flex;
            align-items: center;
            gap: var(--space-3);
            padding-bottom: var(--space-5);
            border-bottom: 1px solid var(--line-subtle);
        }

        .masthead__mark {
            width: 34px;
            height: 34px;
        }

        .masthead__name {
            font-family: var(--font-display);
            font-size: var(--text-sm);
            font-weight: 700;
            letter-spacing: var(--tracking-caps);
            text-transform: uppercase;
            color: var(--text-strong);
        }

        .masthead__links {
            margin-left: auto;
            display: flex;
            flex-wrap: wrap;
            gap: var(--space-2);
        }

        .badge {
            display: inline-flex;
            align-items: center;
            min-height: 28px;
            padding: 0 var(--space-3);

            border: 1px solid var(--line);
            border-radius: var(--radius-pill);

            font-size: var(--text-xs);
            font-weight: 600;
            letter-spacing: 0.02em;
            color: var(--text-secondary);
            text-decoration: none;

            transition:
                border-color var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out);
        }

        a.badge:hover {
            border-color: var(--line-strong);
            color: var(--text-strong);
        }

        .badge--accent {
            border-color: transparent;
            background: var(--brand-gradient);
            color: var(--on-accent);
        }

        .lede {
            font-size: var(--text-base);
            color: var(--text-primary);
        }

        /* --- Alerts ------------------------------------------------------- */

        /*
         * The same five kinds the repository's documents use, so a reader who
         * has read those recognises the weight of each without a legend. The
         * colour carries the left edge and the label; the body stays readable
         * text rather than coloured text on a coloured field.
         */
        .alert {
            margin: var(--space-5) 0;
            padding: var(--space-3) var(--space-4);

            border: 1px solid var(--line-subtle);
            border-left: 3px solid var(--line-strong);
            border-radius: var(--radius-sm);
            background-color: var(--ink-850);
        }

        .alert p {
            margin: 0;
        }

        .alert p + p {
            margin-top: var(--space-2);
        }

        .alert__label {
            display: block;
            margin-bottom: var(--space-1);

            font-size: var(--text-xs);
            font-weight: 700;
            letter-spacing: var(--tracking-caps);
            text-transform: uppercase;
        }

        .alert--note { border-left-color: var(--cyan-400); }
        .alert--note .alert__label { color: var(--cyan-300); }

        .alert--tip { border-left-color: var(--success); }
        .alert--tip .alert__label { color: var(--success); }

        .alert--important { border-left-color: var(--magenta-400); }
        .alert--important .alert__label { color: var(--magenta-300); }

        .alert--warning { border-left-color: var(--warning); }
        .alert--warning .alert__label { color: var(--warning); }

        /* --- Colophon ------------------------------------------------------ */

        .colophon {
            margin-top: var(--space-8);
            padding-top: var(--space-5);
            border-top: 1px solid var(--line-subtle);

            display: flex;
            flex-wrap: wrap;
            align-items: center;
            gap: var(--space-3);

            font-size: var(--text-xs);
            color: var(--text-muted);
        }

        .colophon a {
            color: var(--text-secondary);
        }

        @media (max-width: 620px) {
            .masthead {
                flex-wrap: wrap;
            }

            .masthead__links {
                margin-left: 0;
                width: 100%;
            }
        }

        .sheet {
            max-width: 940px;
            margin: 0 auto;
            padding: var(--space-8) var(--space-5) var(--space-9);
        }

        h1 {
            font-family: var(--font-display);
            font-size: var(--text-2xl);
            margin-bottom: var(--space-3);
        }

        h2 {
            font-family: var(--font-display);
            font-size: var(--text-xs);
            font-weight: 700;
            letter-spacing: var(--tracking-caps);
            text-transform: uppercase;
            color: var(--text-muted);
            margin: var(--space-7) 0 var(--space-3);
        }

        /*
         * No measure cap. A paragraph set to 68 characters beside a table set to
         * the full sheet gives the column two different widths and a ragged
         * right edge against every rule. The sheet itself is the measure.
         */
        p {
            color: var(--text-secondary);
            font-size: var(--text-sm);
            line-height: var(--leading-relaxed, 1.7);
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: var(--space-3);
            font-size: var(--text-sm);
        }

        th, td {
            padding: var(--space-3) var(--space-4);
            text-align: left;
            border-bottom: 1px solid var(--line-subtle);
        }

        th {
            font-size: var(--text-xs);
            letter-spacing: var(--tracking-caps);
            text-transform: uppercase;
            color: var(--text-muted);
        }

        td.figure {
            font-variant-numeric: tabular-nums;
            color: var(--text-strong);
            text-align: right;
        }

        th.figure {
            text-align: right;
        }

        /*
         * Four columns and a sheet's padding do not both fit a phone: the
         * results table held the page 19px wider than the screen, so the whole
         * page slid sideways. The padding is what gives way, because the
         * figures are the reason the table is here.
         */
        @media (max-width: 520px) {
            th,
            td {
                padding: var(--space-2);
            }
        }

        .verdict {
            margin-top: var(--space-6);
            padding: var(--space-4) var(--space-5);
            border-radius: var(--radius-md);
            background-color: var(--ink-850);
            font-size: var(--text-sm);
            color: var(--text-primary);
        }

        code {
            font-family: ui-monospace, monospace;
            font-size: 0.92em;
            color: var(--accent-text);
        }
    </style>
  <script type="module" crossorigin src="/assets/evaluation-BVUXiaFT.js"></script>
  <link rel="modulepreload" crossorigin href="/assets/index-CAvColh3.js">
  <link rel="stylesheet" crossorigin href="/assets/base-C38wIWi-.css">
</head>

<body>
    <main class="sheet">
        <header class="masthead">
            <img class="masthead__mark" src="data:image/svg+xml,%3c!--%20File:%20favicon.svg%20Author:%20Amey%20Thakur%20GitHub:%20https://github.com/Amey-Thakur%20Repository:%20https://github.com/Amey-Thakur/GESTURE-FX%20Release%20Date:%20August%2031%202026%20License:%20MIT%20Tech%20Stack:%20SVG%20Description:%20The%20application%20mark:%20a%20viewfinder%20frame%20separated%20into%20its%20colour%20channels.%20It%20is%20a%20literal%20picture%20of%20what%20the%20software%20does,%20and%20it%20is%20legible%20at%2016px%20because%20it%20resolves%20to%20three%20coloured%20strokes%20rather%20than%20to%20detail.%20--%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2064%2064'%20role='img'%20aria-label='GESTURE-FX'%3e%3crect%20width='64'%20height='64'%20rx='14'%20fill='%2306070A'/%3e%3cg%20fill='none'%20stroke-width='3.5'%20stroke-linejoin='round'%3e%3crect%20x='16.5'%20y='16.5'%20width='31'%20height='31'%20rx='8'%20stroke='%232EE0FB'%20transform='translate(-3.5%20-3.5)'/%3e%3crect%20x='16.5'%20y='16.5'%20width='31'%20height='31'%20rx='8'%20stroke='%23FF4D9D'%20transform='translate(3.5%203.5)'/%3e%3crect%20x='16.5'%20y='16.5'%20width='31'%20height='31'%20rx='8'%20stroke='%23F2F5FA'/%3e%3c/g%3e%3c/svg%3e" alt="" width="34" height="34">
            <span class="masthead__name">Gesture&#8209;FX</span>

            <nav class="masthead__links" aria-label="Elsewhere">
                <a class="badge badge--accent" href="./">Open the application</a>
                <a class="badge" href="https://github.com/Amey-Thakur/GESTURE-FX">Repository</a>
                <a class="badge" href="https://github.com/Amey-Thakur/GESTURE-FX/blob/main/docs/GESTURES.md">The derivation</a>
                <a class="badge" href="https://github.com/Amey-Thakur/GESTURE-FX/blob/main/LICENSE">MIT</a>
            </nav>
        </header>

        <h1>Palm-flip detector: measured error</h1>

        <p class="lede">
            A rigid hand is rotated about its own long axis by a known angle at a known
            rate, projected orthographically and perturbed by landmark noise. The instant
            the rotation passes ninety degrees is therefore known exactly, and the
            detector's report is compared against it.
        </p>

        <div class="alert alert--note">
            <span class="alert__label">Nothing here is precomputed</span>
            <p>
                The figures below were produced in this tab, just now, by the same modules
                the application runs. Reload the page and they are computed again. The
                corpus is seeded, so the numbers are reproducible rather than merely
                repeatable.
            </p>
        </div>

        <div data-role="report">Running…</div>

        <footer class="colophon">
            <span>
                Built by
                <a href="https://github.com/Amey-Thakur">Amey Thakur</a>.
                Open source under the MIT licence.
            </span>
            <span style="margin-left:auto">
                <a href="./">Application</a>
                &nbsp;&middot;&nbsp;
                <a href="https://github.com/Amey-Thakur/GESTURE-FX">Source</a>
                &nbsp;&middot;&nbsp;
                <a href="https://orcid.org/0000-0001-5644-1575">ORCID</a>
            </span>
        </footer>
    </main>

</body>

</html>