Repository navigation
Add the eval page (contracts section 3), checked against OpenCV and the runner - #20
Open
06pratyush wants to merge 4 commits into
Open
06pratyush wants to merge 4 commits into
06pratyush wants to merge 4 commits into
Conversation
app/eval.html gives eval/run_detect.py the app's own decoding, detection, masking and encoding, as docs/contracts.md, section 3 defines them: decode(url), detectFaces(image, options), render(image, masks) and info(). The page has the app's Content Security Policy. npm run dev serves it, and the deployed build leaves it out (Vite builds only index.html). render() encodes exactly as the app saves: the drawing moves out of main.ts into paint() in mask.ts, which the page and render() both call, and render() rounds the given masks outward to whole pixels and clips them with maskFor(mask, 0, ...), as section 2 says. tests/app/eval-page.spec.ts drives the page on the dev server as the runner does. On the test photo the face matches OpenCV's FaceDetectorYN on the same model within 0.5 px and 0.0005 of score, with the same 15 boxes at 0.05 or more, in Chromium, Firefox and WebKit. Swapping the colour channels makes it fail (the face is still found, with its box 93 px lower and 2 boxes instead of 15), a regression the privacy tests would miss. It also checks render(), info(), and that no eval code is in app/dist. Run against the page, Shashwat's run_detect.py and score.py give the same face on the photo as stored and turned 90 degrees, both fully covered and found, with no false masks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… on a knife-edge The eval-page test now also serves the photo stored turned with EXIF Orientation 8, as run_detect.py serves turned images, and checks it decodes upright with the face within 2 px of OpenCV's. The box count is compared at score 0.10 (7 boxes; the lowest scores 0.1037), not at 0.05, where one box sat 0.0003 above the cut and OpenCV's own count differs by an edge box. The dev server's webServer allows 180 s, for a cold model download. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the review of the eval page: - info().modelSha256 is now the SHA-256 of the model as loaded, which detect.ts records when it reads the file, not the expected constant. - window.solidMask appears once the model has loaded and compiled, so the runner's wait covers it and its first image is timed like the rest (on the stand-in run: max 395 ms against a median of 333 ms). - A page Vite reloaded because a file changed refuses to start, so a run fails instead of going on under code that changed mid-run. - npm run dev keeps port 5173 (strictPort), where the eval docs say the page is. The OpenCV boxes now come from tests/reference/opencv_yunet.py, which writes opencv_yunet.txt with OpenCV pinned (4.13.0.92); the test reads that file and compares all 7 boxes scoring 0.10 or more, not just the count. The 0.5 px bound applies in Chromium, the runner's browser; Firefox and WebKit get 2 px, since WebKit on macOS decodes JPEG with ImageIO. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The eval page that
docs/contracts.md, section 3 asks of the app, soeval/run_detect.py(#10) can run the real detector instead of the stub.What is in it
app/eval.htmlandapp/src/eval.tssetwindow.solidMask:decode(url): fetch, then the app's owndecode()(createImageBitmapwithimageOrientation: "from-image").detectFaces(image, options): the app'sdetect.ts.render(image, masks): draws the given masks (already padded) and encodes exactly as the app saves. The drawing moves out ofmain.tsintopaint()inmask.ts, which the page andrender()both call.render()rounds each mask outward to whole pixels and clips it withmaskFor(mask, 0, …), as section 2 (v0.2) says. With the app's own masks, its file is byte-identical to the app's savedmasked-1.jpgin all three engines.info():{ ortVersion: "1.30.0", backend: "wasm", threads: 1, modelSha256 }.modelSha256is the hash of the model as loaded:detect.tsnow records it when it reads the file.window.solidMaskappears once the model has loaded and compiled, so the runner's wait covers it and its first image is timed like the rest.npm run devserves the page at http://localhost:5173/eval.html, the addresseval/README.mdgives, and now fails rather than move if 5173 is taken. The page has the app's Content Security Policy.index.html, and a test checks that no eval code is inapp/dist.Tests
tests/app/eval-page.spec.tsdrives the page on the dev server, as the runner does (the image served on the page's own origin, the runner's options), in Chromium, Firefox and WebKit.Golden detection. The 7 boxes scoring 0.10 or more must match OpenCV 4.13's
FaceDetectorYNon the same model:The reference comes from
tests/reference/opencv_yunet.py, with OpenCV pinned, and its output is committed, so you can rerun it. Swapping the colour channels makes the test fail: the face is still found, 93 px lower, so the privacy suite wouldn't notice. Nothing guarded the equivalence with OpenCV before; the review of the eval PRs flagged this.A photo stored turned, with the EXIF Orientation 8 the runner adds for Rotation 90, decodes upright with the face within 2 px.
render()andinfo().render()covers the face and writes a file with nothing but the picture, andinfo()returns exactly the expected values.A reloaded page refuses to start.
Playwright now starts the dev server too (port 4402), next to the static server for the production build.
Checked with the eval code
I ran
eval/run_detect.py --page http://127.0.0.1:5173/eval.htmlandeval/score.pyon a two-image stand-in manifest made from the public-domain test photo, one copy as stored and one stored turned 90°. No Open Images image was used.wasmand 1 thread.For Shashwat
run_detect.pycould also stop when the page navigates mid-run (page.on('framenavigated')). The page now refuses to start after a reload, so the run fails on its next image anyway, but the runner would then say why.--tilesand--model yolo5facestill stop atdetectFaces, which supports only the single setting and YuNet so far. Tiling comes next, for part B's tiled setting./code-reviewand two independent reviewers looked at this before I opened it, and all their findings are fixed.🤖 Generated with Claude Code