GESTURE-FX / evaluation.html
ameythakur's picture
Gesture FX
310ce48
Raw History Blame Contribute Delete
18.5 kB
<!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>