-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstack_evaluation.html
More file actions
415 lines (389 loc) · 31.2 KB
/
Copy pathstack_evaluation.html
File metadata and controls
415 lines (389 loc) · 31.2 KB
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
<title>Classroom Stack Audit</title>
<style>
:root{
--ground:#F1F2EF; --surface:#FFFFFF; --surface-2:#E9EBE7;
--ink:#171B20; --ink-2:#3A424A; --muted:#616A72; --rule:#D2D6D0;
--accent:#1F6656; --accent-soft:#DCE9E5;
--ok:#2C6B3E; --ok-soft:#DCE9DE;
--warn:#8C5410; --warn-soft:#F0E6D6;
--crit:#95291F; --crit-soft:#F0DDDA;
--mono:ui-monospace,"SFMono-Regular","Cascadia Mono",Menlo,Consolas,"Liberation Mono",monospace;
--serif:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,"Times New Roman",serif;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--ground:#0F1317; --surface:#161B21; --surface-2:#1D242B;
--ink:#E3E8EB; --ink-2:#B7C0C7; --muted:#8A949C; --rule:#2A323A;
--accent:#4FB098; --accent-soft:#16302B;
--ok:#63B074; --ok-soft:#172A1D;
--warn:#C99248; --warn-soft:#2C2317;
--crit:#D0685C; --crit-soft:#2E1B18;
}
}
:root[data-theme="dark"]{
--ground:#0F1317; --surface:#161B21; --surface-2:#1D242B;
--ink:#E3E8EB; --ink-2:#B7C0C7; --muted:#8A949C; --rule:#2A323A;
--accent:#4FB098; --accent-soft:#16302B;
--ok:#63B074; --ok-soft:#172A1D;
--warn:#C99248; --warn-soft:#2C2317;
--crit:#D0685C; --crit-soft:#2E1B18;
}
*{box-sizing:border-box}
body{
background:var(--ground); color:var(--ink);
font-family:var(--serif); font-size:17px; line-height:1.62;
margin:0; padding:0 24px 96px;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1080px;margin:0 auto}
.col{max-width:68ch}
h1,h2,h3,h4,.eyebrow,.chip,th,.mono,code,td.n{font-family:var(--mono)}
.eyebrow{
font-size:11px; letter-spacing:.16em; text-transform:uppercase;
color:var(--accent); font-weight:600; margin:0 0 10px;
}
header{padding:72px 0 40px;border-bottom:2px solid var(--ink)}
h1{font-size:clamp(30px,4.4vw,46px);line-height:1.08;margin:0 0 18px;letter-spacing:-.02em;text-wrap:balance;font-weight:700}
.standfirst{font-size:20px;line-height:1.5;color:var(--ink-2);margin:0;max-width:60ch}
.meta{display:flex;flex-wrap:wrap;gap:8px 28px;margin-top:28px;font-family:var(--mono);font-size:12px;color:var(--muted)}
.meta b{color:var(--ink-2);font-weight:600}
h2{font-size:13px;letter-spacing:.14em;text-transform:uppercase;margin:0;color:var(--accent);font-weight:700}
section{padding:56px 0;border-bottom:1px solid var(--rule)}
.sec-head{display:grid;grid-template-columns:44px 1fr;gap:20px;align-items:baseline;margin-bottom:28px}
.sec-num{font-family:var(--mono);font-size:13px;color:var(--muted);font-variant-numeric:tabular-nums;font-weight:600}
h3{font-size:26px;line-height:1.2;margin:6px 0 0;letter-spacing:-.01em;text-wrap:balance;font-weight:700}
h4{font-size:15px;margin:32px 0 10px;letter-spacing:.01em;font-weight:700}
p{margin:0 0 16px}
.lede{font-size:18.5px;color:var(--ink-2)}
ul,ol{margin:0 0 18px;padding-left:22px}
li{margin-bottom:9px}
strong{font-weight:700}
code{background:var(--surface-2);padding:.12em .4em;border-radius:3px;font-size:.85em;color:var(--ink)}
a{color:var(--accent);text-decoration-thickness:1px;text-underline-offset:2px}
.scroll{overflow-x:auto;margin:24px 0;border:1px solid var(--rule);background:var(--surface);border-radius:2px}
table{border-collapse:collapse;width:100%;font-size:13.5px;font-family:var(--mono);min-width:600px}
th{
text-align:left;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
color:var(--muted);font-weight:600;padding:12px 14px;
border-bottom:1px solid var(--ink-2);white-space:nowrap;background:var(--surface-2);
}
td{padding:11px 14px;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
td.n{text-align:right;font-variant-numeric:tabular-nums;color:var(--ink)}
tbody tr:last-child td{border-bottom:none}
.chip{
display:inline-block;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
font-weight:700;padding:3px 8px;border-radius:2px;white-space:nowrap;
}
.c-keep{background:var(--ok-soft);color:var(--ok)}
.c-rev{background:var(--warn-soft);color:var(--warn)}
.c-rep{background:var(--crit-soft);color:var(--crit)}
.c-add{background:var(--accent-soft);color:var(--accent)}
.c-cut{background:var(--surface-2);color:var(--muted)}
.stage{
background:var(--surface);border:1px solid var(--rule);border-radius:2px;
padding:22px 24px;margin-bottom:14px;
}
.stage-top{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin-bottom:6px}
.stage-id{font-family:var(--mono);font-size:11px;color:var(--muted);font-weight:600;letter-spacing:.08em}
.stage h4{margin:0;font-size:17px;flex:1;min-width:220px}
.stage p{font-size:15.5px;margin-bottom:12px}
.stage p:last-child{margin-bottom:0}
.stage ul{font-size:15.5px;margin-bottom:12px}
.callout{
border-left:3px solid var(--accent);background:var(--accent-soft);
padding:18px 22px;margin:24px 0;border-radius:0 2px 2px 0;
}
.callout p:last-child{margin-bottom:0}
.callout .eyebrow{margin-bottom:6px}
.crit-callout{border-left-color:var(--crit);background:var(--crit-soft)}
.crit-callout .eyebrow{color:var(--crit)}
.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;margin:24px 0}
.card{background:var(--surface);border:1px solid var(--rule);padding:20px 22px;border-radius:2px}
.card .eyebrow{margin-bottom:8px}
.card p{font-size:15px;margin-bottom:0}
.big{font-family:var(--mono);font-size:30px;font-weight:700;color:var(--ink);line-height:1;margin:0 0 8px;font-variant-numeric:tabular-nums}
.finding{display:grid;grid-template-columns:32px 1fr;gap:18px;padding:22px 0;border-bottom:1px solid var(--rule)}
.finding:last-child{border-bottom:none}
.finding .n{font-family:var(--mono);font-size:12px;color:var(--crit);font-weight:700;padding-top:5px;font-variant-numeric:tabular-nums}
.finding h4{margin:0 0 8px;font-size:17px}
.finding p{font-size:15.5px;margin-bottom:0}
footer{padding:48px 0 0;color:var(--muted);font-family:var(--mono);font-size:12px;line-height:1.7}
footer a{color:var(--accent)}
@media (max-width:640px){
body{font-size:16px;padding:0 18px 64px}
.sec-head{grid-template-columns:1fr;gap:2px}
.finding{grid-template-columns:1fr;gap:4px}
header{padding:48px 0 32px}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
</style>
<div class="wrap">
<header>
<p class="eyebrow">Project Classroom · Problem Statement 2</p>
<h1>Stack Audit Against the Measured Footage</h1>
<p class="standfirst">Every layer of the proposed architecture, evaluated against what the dataset actually contains — measured, not assumed — and against what the published literature has proven on comparable problems.</p>
<div class="meta">
<span><b>Scope</b> PRD v2.1, 6 source files, 4 camera views</span>
<span><b>Footage</b> 18.3 min total</span>
<span><b>Date</b> 18 Aug 2026</span>
</div>
</header>
<section>
<div class="sec-head">
<span class="sec-num">01</span>
<div><h2>Ground truth</h2><h3>What the dataset actually is</h3></div>
</div>
<div class="col">
<p class="lede">Every recommendation below derives from these numbers. They were measured off the files with PyAV, not taken from the PRD.</p>
</div>
<div class="scroll">
<table>
<thead><tr>
<th>File</th><th>Codec</th><th>Resolution</th><th>FPS</th><th>Duration</th><th>Mbps</th><th>VFR</th><th>MV/frame</th>
</tr></thead>
<tbody>
<tr><td>01 · mobile phone</td><td>h264</td><td>1280×720</td><td class="n">25.0</td><td class="n">131 s</td><td class="n">1.95</td><td>no</td><td class="n">3649</td></tr>
<tr><td>02 · mobile phone</td><td>h264</td><td>1280×720</td><td class="n">25.0</td><td class="n">212 s</td><td class="n">1.95</td><td>no</td><td class="n">3621</td></tr>
<tr><td>03 · mobile usage</td><td>mpeg4</td><td>1280×720</td><td class="n">12.1</td><td class="n">282 s</td><td class="n">1.87</td><td><b>yes</b></td><td class="n">3594</td></tr>
<tr><td>04 · candidate talking</td><td>h264</td><td>640×480</td><td class="n">8.0</td><td class="n">143 s</td><td class="n">0.24</td><td>no</td><td class="n">1290</td></tr>
<tr><td>05 · reception crowd</td><td>mpeg4</td><td>1280×720</td><td class="n">25.0</td><td class="n">241 s</td><td class="n">10.53</td><td><b>yes</b></td><td class="n">3584</td></tr>
<tr><td>Seat 12 · paper</td><td>mpeg4</td><td>1280×720</td><td class="n">25.0</td><td class="n">88 s</td><td class="n">1.75</td><td><b>yes</b></td><td class="n">3575</td></tr>
</tbody>
</table>
</div>
<div class="grid2">
<div class="card">
<p class="eyebrow">Phone footprint</p>
<p class="big">~30×20 px</p>
<p>Measured on a near-camera seat in file 03. Motion-blurred, no screen glow, no rectangle geometry. Far seats are smaller.</p>
</div>
<div class="card">
<p class="eyebrow">Compression</p>
<p class="big">0.08 bpp</p>
<p>1.9 Mbps at 720p25. Block artifacts are guaranteed and will register as motion.</p>
</div>
<div class="card">
<p class="eyebrow">Motion vectors</p>
<p class="big">6 / 6 files</p>
<p>Present in every file including MPEG-4, at 16×16 block granularity. I and P frames only, no B-frames.</p>
</div>
<div class="card">
<p class="eyebrow">Total footage</p>
<p class="big">18.3 min</p>
<p>Across 4 camera views and 4 dates spanning 2025–2026. All pre-cut incident clips.</p>
</div>
</div>
</section>
<section>
<div class="sec-head">
<span class="sec-num">02</span>
<div><h2>Findings</h2><h3>Six things that change the plan</h3></div>
</div>
<div class="finding">
<span class="n">01</span>
<div>
<h4>The clips are already the events</h4>
<p>Every file is a pre-cut incident. PS2's entire premise — surfacing a handful of relevant windows from hours of continuous recording — cannot be demonstrated or validated on this data, because there is no negative time. Your event-recall and false-events-per-hour metrics have nothing to measure against. This is the single biggest gap, and it is a data problem, not an engineering one.</p>
</div>
</div>
<div class="finding">
<span class="n">02</span>
<div>
<h4>It is a computer-based test centre, not a paper exam hall</h4>
<p>Every seat has a live monitor, keyboard and mouse. The PRD is written throughout for seated candidates writing on paper. Two consequences dominate: <strong>every screen is a continuous motion source</strong>, and <strong>typing means every seat has a high, constant hand-motion baseline</strong> — so the signal-to-noise ratio for "unusual hand movement" is far worse than the PRD's quiet-baseline model assumes.</p>
</div>
</div>
<div class="finding">
<span class="n">03</span>
<div>
<h4>720p, not 1080p — and one file is 640×480 at 8 fps</h4>
<p>PRD §8.1 specifies "one recorded 1080p classroom video". Nothing in the dataset is 1080p. File 04 at 8 fps is below the sampling rate needed to characterise hand gestures at all. Every pixel-footprint and throughput claim in the document needs recomputing at 720p.</p>
</div>
</div>
<div class="finding">
<span class="n">04</span>
<div>
<h4>Variable frame rate confirmed on half the files</h4>
<p>PRD §14 lists VFR as a hypothetical edge case. It is real here — three of six files have irregular PTS deltas. Any code indexing by frame number will silently misreport timestamps, which corrupts the evidence provenance that FR-19 requires. Presentation timestamps are mandatory from the first line of code.</p>
</div>
</div>
<div class="finding">
<span class="n">05</span>
<div>
<h4>Burned-in timestamp overlays change every second</h4>
<p>Every file carries a date/time overlay that updates once per second, plus a static camera label. That is a guaranteed, perfectly periodic motion blob in a fixed screen region — it will trigger on every single frame interval unless masked during calibration. The PRD never mentions it.</p>
</div>
</div>
<div class="finding">
<span class="n">06</span>
<div>
<h4>Four camera views across four dates — validation splits are possible</h4>
<p>The only good news in this section. Camera 04, Camera 12 and the two screenshot views are distinct rooms recorded on 30-05-2025, 12-04-2025, 02-06-2026 and 15-07-2026. That gives you a genuine leave-one-room-out split, which §10.1 requires and which most teams cannot honestly produce.</p>
</div>
</div>
<div class="callout crit-callout">
<p class="eyebrow">Unanticipated false-motion sources in this specific footage</p>
<p>Live monitors displaying exam content · per-second timestamp overlay · plastic-wrapped chairs producing specular highlights · glass partitions and a wall mirror reflecting people and monitors from adjacent rooms · standing invigilators and reception traffic crossing frame. The PRD's environmental-motion model (§3.3) anticipates fans and curtains, which are <em>periodic</em>. Screen content is aperiodic, so the periodicity score will not suppress it. This needs a dedicated masking layer.</p>
</div>
</section>
<section>
<div class="sec-head">
<span class="sec-num">03</span>
<div><h2>Pipeline</h2><h3>Stage-by-stage verdict</h3></div>
</div>
<div class="col">
<p class="lede">Ten stages, in strict execution order. Each carries a verdict: keep as specified, revise, replace, add, or cut.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 0</span><h4>Ingest & decode</h4><span class="chip c-rep">Replace</span></div>
<p>The PRD makes DeepStream NVDEC the ingest layer. DeepStream 9.1 ships for Ubuntu x86, Jetson and ARM SBSA only — <strong>Windows is not supported</strong>, confirmed against the platform table. A second, subtler risk: three of your files are MPEG-4 Part 2, and NVDEC hardware support for that codec is inconsistent on recent architectures, so even on Linux half your dataset may fall back to software decode.</p>
<p><strong>Do instead:</strong> PyAV/FFmpeg as the decode layer with optional NVDEC acceleration, behind a config flag. Parse presentation timestamps, never frame indices. Validate codec, rate and PTS monotonicity at import, per FR-02 — which this dataset will actually exercise.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 1</span><h4>Motion estimation</h4><span class="chip c-rev">Revise</span></div>
<p>Rejecting MOG2 is <strong>correct and well-supported</strong> — on the CDnet 2014 change-detection benchmark, MOG2 is consistently beaten by SuBSENSE, PAWCS and FgSegNet-v2. The PRD is right to refuse it as the primary layer.</p>
<p>But replacing it with NVOF everywhere is the wrong trade. Pass 1 runs over 100% of frames; everything downstream runs over roughly 1%. NVOF gives 4×4 blocks against codec MV's 16×16 — genuinely 16× denser — but the coarse field is sufficient to <em>gate</em>, and it is already in the bitstream. Empirically confirmed on your files: ~3,600 vectors per frame, present in all six, MPEG-4 included.</p>
<p><strong>Do instead — three tiers:</strong> codec motion vectors across the whole recording as the cheap gate; NVOF or <code>cv2.DISOpticalFlow</code> on candidate windows for sub-pixel quality; dense flow only on disputed events. This keeps every §5.2 feature, cuts whole-video cost by a large factor, and demotes DeepStream from load-bearing to optional.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 2</span><h4>Calibration</h4><span class="chip c-add">Extend</span></div>
<p>The §5.1 calibration design is sound, and easier here than anticipated: <strong>seats carry physical numbered placards</strong> visible in frame (18–24, 61, 13, and Devanagari ३४५७ on one camera). Anchor seat IDs to those and your attribution is auditable by eye.</p>
<p><strong>Add three mask layers the PRD lacks:</strong> a per-seat <em>screen region</em> sub-polygon excluding each monitor; a global <em>overlay mask</em> for the burned-in timestamp; and a <em>reflection mask</em> for glass partitions, the mirror and the window. Also split each seat into screen / desk / torso zones rather than the PRD's desk-versus-upper-body pair — the screen zone must be excluded from motion scoring entirely.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 3</span><h4>Motion features</h4><span class="chip c-rev">Revise</span></div>
<p>The §5.2 feature list — robust median and percentile magnitudes, directional coherence, area ratio, residual after global compensation, periodicity, duration, repetition, neighbour correlation — is a good, defensible set. Per-seat temporal median/MAD normalisation is the right robust statistic and needs no change.</p>
<p><strong>What is missing is the typing baseline.</strong> In a CBT hall every occupied seat produces continuous hand motion at the keyboard. Add a per-seat <em>activity-class baseline</em> that models the typing regime explicitly, so scoring measures deviation from "actively typing", not deviation from "still". Without this, every working candidate looks like an event and every idle one looks quiet.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 4</span><h4>Event boundaries</h4><span class="chip c-keep">Keep</span></div>
<p>The §5.3 hysteresis state machine is the strongest single piece of engineering in the PRD. Dual start/stop thresholds with a cooling state is the standard, well-founded solution — the same Schmitt-trigger structure used in voice activity detection and shot-boundary detection, and exactly what DVR-Scan implements for surveillance. Rejecting PySceneDetect as the segmenter is correct; it detects cuts, not activity.</p>
<p><strong>Two additions:</strong> a maximum event duration that forces a split, and per-seat independent state machines so simultaneous events in different seats never merge. Score it with temporal IoU and fragmentation rate, consistent with the temporal-action-detection literature.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 5</span><h4>Object detection</h4><span class="chip c-rev">Revise</span></div>
<p>D-FINE is a sound primary choice — 54.0 AP on COCO val2017, rising to 57.1 with Objects365 pretraining, and D-FINE-M beats RT-DETRv2-M at 49.9. The published numbers support the PRD's ranking.</p>
<p><strong>But the tiling strategy needs correcting.</strong> SAHI's documented gains (+6.8 to +14.5 AP) come from aerial imagery where the frame vastly exceeds the network input. Your frame is 1280×720 against a 640 input — barely a 2× downscale, so slicing the full frame buys little. The right move is the opposite: <strong>crop each seat ROI at native resolution and upscale into the detector</strong>. A 200×200 seat crop fed to a 640 input is 3× supersampling, which is where the recall on a 30-pixel object actually comes from.</p>
<p>The generic COCO detector held as backup will not work for phones at this scale. Keep it for the person class only, which is what it is good for.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 6</span><h4>Phone versus chit/paper</h4><span class="chip c-rep">Reframe</span></div>
<p>You asked specifically whether implementations exist. They do — a YOLO model on the Roboflow cellphone dataset, and several published classroom systems — but every one operates at webcam or near-field range. The most relevant published CCTV result compares YOLOv5, v6 and v7 on classroom cheating classes and reports <strong>43%, 37% and 51% accuracy</strong>. That is the honest state of the art on this exact problem, and it is not a number a detector-first strategy improves on with 18 minutes of data.</p>
<p>At 30×20 px, motion-blurred, at 0.08 bits per pixel, phone-versus-dark-object discrimination sits at or below the reliability floor. The PRD's abstention rule (§6.1) is the correct response and should be kept exactly as written.</p>
<p><strong>The stronger signal is behavioural, not appearance-based.</strong> The dominant pattern visible in your own footage is sustained downward head pitch with hand dwell in the lap region — a phone held below the desk. That is measurable from pose and motion at this resolution, whereas the object is not. Classify the behaviour; treat the object as corroboration that raises confidence when present and is absent otherwise. This is also precisely what §3.1's evidence-fusion philosophy already argues for — the PRD's <em>effort allocation</em> simply contradicts its own thesis.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 7</span><h4>Pose</h4><span class="chip c-keep">Keep</span></div>
<p>RTMO is well chosen: 73.2 AP on CrowdPose, state of the art among one-stage methods, and specifically strong on the medium and hard occlusion splits — which is what booth partitions and chair backs produce here. Foreground candidates in your footage are 150–350 px tall, comfortably within range; back rows will degrade.</p>
<p>Two constraints to honour. Wrist keypoints are unreliable exactly when hands go below the desk, which is the interesting case — mask them and let the absence itself be evidence. And head pitch, the signal that matters most for the lap-phone pattern, is recoverable from the nose-to-shoulder vertical offset in COCO-17 without any head-pose model.</p>
<p>Use <code>rtmlib</code> rather than full MMPose — same weights, ONNXRuntime only, and it avoids compiling <code>mmcv</code>.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 8</span><h4>Tracking</h4><span class="chip c-cut">Reduce</span></div>
<p>Seats are fixed, candidates are seated for the duration, and seat polygons carry identity. The tracking problem in this footage is close to trivial, and the mandated NvDCF versus Deep OC-SORT A/B in §13.3 is effort spent on a solved sub-problem. NvDCF also requires DeepStream, which Stage 0 removes.</p>
<p><strong>Do instead:</strong> ByteTrack via Supervision, reconciled to seats. Keep the seat-reconciliation layer — the PRD is right that it, not the tracker, is the identity source. Cut the A/B to a roadmap line.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 9</span><h4>Event scoring</h4><span class="chip c-rev">Revise</span></div>
<p>The §5.4 additive score with exposed contributing factors is a good design for explainability. The problem is the PRD says weights are "learned or tuned on a held-out validation set" — with 18 minutes of footage and a handful of events, fitting weights will overfit immediately.</p>
<p><strong>Do instead:</strong> hand-set the weights with documented rationale, publish them in the UI, and validate <em>rank ordering</em> rather than absolute calibration. Report Precision@K, which is what a reviewer actually experiences. The principled alternative — weakly supervised anomaly ranking under multiple-instance learning, as Cheatomaly formulates it and as UCF-Crime methods reach ~91 AP on — becomes available only once you have hours of weakly labelled footage. Note it as the roadmap and do not attempt it now.</p>
</div>
<div class="stage">
<div class="stage-top"><span class="stage-id">STAGE 10</span><h4>Visual verifier</h4><span class="chip c-keep">Keep</span></div>
<p>The Gemma verifier design is sound: contact sheet of selected frames, constrained JSON schema, no authority to create or delete events. Enforce the schema with a GBNF grammar in llama.cpp rather than prompting and hoping — that turns the ≥95% valid-output acceptance criterion into a structural guarantee.</p>
<p>One expectation to reset: at 30 px the VLM will not reliably identify the phone either. Its value here is describing <em>posture and interaction</em> — head down, hand below desk, sustained over N seconds — and flagging uncertainty. Prompt it for that, not for object identification.</p>
</div>
</section>
<section>
<div class="sec-head">
<span class="sec-num">04</span>
<div><h2>Benchmarks</h2><h3>What the literature has actually proven</h3></div>
</div>
<div class="col">
<p class="lede">Published results on comparable problems, as calibration for what is claimable.</p>
</div>
<div class="scroll">
<table>
<thead><tr><th>Result</th><th>Benchmark</th><th>Number</th><th>Bearing on this project</th></tr></thead>
<tbody>
<tr><td>D-FINE-L</td><td>COCO val2017</td><td class="n">54.0 AP</td><td>57.1 with Objects365 pretrain; supports it as primary detector</td></tr>
<tr><td>D-FINE-M vs RT-DETRv2-M</td><td>COCO val2017</td><td class="n">> 49.9 AP</td><td>Ranking in §6.1 is correct; the A/B is confirmatory, not decisive</td></tr>
<tr><td>RTMO-l</td><td>CrowdPose</td><td class="n">73.2 AP</td><td>One-stage SOTA, strongest on hard/occluded splits — matches this footage</td></tr>
<tr><td>SAHI slicing</td><td>VisDrone / xView</td><td class="n">+6.8–14.5 AP</td><td>Gains come from frames far larger than input; limited at 720p</td></tr>
<tr><td>YOLOv5 / v6 / v7</td><td>Classroom cheating</td><td class="n">43 / 37 / 51%</td><td><strong>The realistic ceiling</strong> for appearance-only cheating detection on CCTV</td></tr>
<tr><td>MOG2</td><td>CDnet 2014</td><td class="n">below SOTA</td><td>Beaten by SuBSENSE, PAWCS, FgSegNet-v2 — rejection justified</td></tr>
<tr><td>Weakly supervised VAD</td><td>UCF-Crime</td><td class="n">~91 AP</td><td>Coarser task, hours of data; the roadmap target, not a Phase-1 goal</td></tr>
</tbody>
</table>
</div>
<div class="callout">
<p class="eyebrow">Read this row carefully</p>
<p>Published classroom cheating detection tops out near <strong>51% accuracy</strong>. Any claim above that needs extraordinary evidence, and §13.4 already forbids presenting unmeasured claims as achieved. Positioning the system as evidence prioritisation rather than detection is not just ethically safer — it is the only framing the numbers support.</p>
</div>
</section>
<section>
<div class="sec-head">
<span class="sec-num">05</span>
<div><h2>Data</h2><h3>Closing the 18-minute gap</h3></div>
</div>
<div class="col">
<p>Finding 01 is the blocking problem: with only pre-cut incident clips, the segmentation layer — the part PS2 actually scores — has nothing to be validated against. Three moves, in order of value.</p>
<p><strong>Request raw continuous recordings.</strong> Even two or three uncut hours from one camera changes the project more than any model swap. This should be asked for today.</p>
<p><strong>Build a synthetic long-form test video.</strong> Concatenate the existing clips with extended quiet footage from the same cameras, recording exact insertion timestamps as ground truth. This produces a multi-hour recording with known event times, and lets you measure event recall, temporal IoU, fragmentation and false-events-per-hour honestly, using only what you already have. It is the highest-leverage thing you can build this week.</p>
<p><strong>Annotate temporally before annotating boxes.</strong> Event-level labels — start, end, seat, type, visibility — take hours and validate the segmentation layer. Box-level labels take days and validate a detector whose ceiling is already known to be low. Do them in that order.</p>
</div>
</section>
<section>
<div class="sec-head">
<span class="sec-num">06</span>
<div><h2>Compute</h2><h3>Fitting the cascade to one GPU</h3></div>
</div>
<div class="col">
<p>You specified strictly sequential execution, compute-bound rather than time-bound. That constraint is compatible with every recommendation above, and the cascade is designed for it — each stage releases its workspace before the next loads.</p>
</div>
<div class="scroll">
<table>
<thead><tr><th>Pass</th><th>Coverage</th><th>Resident model</th><th>Device</th></tr></thead>
<tbody>
<tr><td>1 · Motion scan</td><td>100% of frames</td><td>none</td><td>CPU (decode-bound)</td></tr>
<tr><td>2 · Segmentation</td><td>metadata only</td><td>none</td><td>CPU, near-instant</td></tr>
<tr><td>3 · Detection</td><td>candidate crops</td><td>D-FINE</td><td>GPU, load → run → free</td></tr>
<tr><td>4 · Pose</td><td>candidate clips</td><td>RTMO</td><td>GPU, load → run → free</td></tr>
<tr><td>5 · Verification</td><td>ambiguous events only</td><td>Gemma 4 E2B/E4B</td><td>GPU or CPU, last</td></tr>
</tbody>
</table>
</div>
<div class="col">
<p>Passes 1 and 2 need no GPU at all, which means <strong>the PS2 deliverable is fully demonstrable before any model is loaded</strong>. That is the property that makes the unknown deployment hardware survivable: build 1 through 4 first, and the target machine becomes an accelerator rather than a dependency.</p>
</div>
</section>
<section style="border-bottom:none">
<div class="sec-head">
<span class="sec-num">07</span>
<div><h2>Actions</h2><h3>Concrete edits to the PRD</h3></div>
</div>
<div class="col">
<ol>
<li><strong>§11, §12</strong> — demote DeepStream from primary pipeline to optional accelerator; document the Windows constraint.</li>
<li><strong>§8.1, FR-04, §22</strong> — replace "1080p" with 720p and "NVOF" with "hardware or codec-derived motion vectors" so your acceptance criteria are satisfiable.</li>
<li><strong>§5.1</strong> — add screen-region, overlay and reflection masks to calibration.</li>
<li><strong>§5.2</strong> — add the per-seat typing-activity baseline.</li>
<li><strong>§5.4</strong> — change weights from "learned" to hand-set and documented; score on Precision@K.</li>
<li><strong>§6.1</strong> — replace full-frame slicing with native-resolution seat-crop supersampling.</li>
<li><strong>§13.3</strong> — cut three of four mandatory A/Bs; keep only the detector comparison.</li>
<li><strong>§6.2</strong> — cut Multi-HMR2 and SAT-HMR to roadmap.</li>
<li><strong>§14</strong> — promote VFR from hypothetical edge case to confirmed dataset property.</li>
<li><strong>§24</strong> — fix the dead <code>/Users/atharvadeo/Desktop/</code> path before submission.</li>
<li><strong>New section</strong> — CBT-centre scene model: monitors, typing baseline, reflections, standing staff.</li>
</ol>
</div>
<div class="callout">
<p class="eyebrow">The one-sentence version</p>
<p>The architecture is sound and the model choices are defensible; what needs to change is that the effort is pointed at object detection, where this footage cannot support a strong claim, instead of at motion-grounded event segmentation, where it can — and where PS2 assigns the marks.</p>
</div>
</section>
<footer>
<p>Measurements taken 18 Aug 2026 with PyAV 18.1.0 against six source files in <code>D:\DrishtiAI</code>. Benchmark figures from the D-FINE (ICLR 2025), RTMO (CVPR 2024), SAHI, CDnet 2014 and UCF-Crime literature, and from published classroom-cheating CCTV results. Platform support verified against the NVIDIA DeepStream 9.1 documentation.</p>
<p>Model and detector claims are cited from published benchmarks and have not been reproduced on this dataset. Per PRD §13.4, none of them are presentation-safe until measured end to end here.</p>
</footer>
</div>