--- title: Hemocytometer Ground Truth emoji: ๐ŸŽฏ colorFrom: blue colorTo: yellow sdk: gradio sdk_version: 5.35.0 app_file: app.py pinned: false --- # Hemocytometer ground truth Annotation tool for building ground-truth counts of the 4ร—4 hemocytometer block. Two tabs: **Single image** and **4 squares**. ## Single image 1. **Upload** one photo. 2. **Click the 4 corners** of the 4ร—4 block (any order). Drag a handle to adjust it. 3. **Segment.** The block is warped to an upright square (โ‰ค1024 px) and segmented with the fine-tuned hemocytometer Cellpose-SAM model. 4. **Correct the count** (see below). ## 4 squares 1. **Upload** the four square images at once. They are sorted by filename into Square 1โ€“4. 2. **Set each block:** click its 4 corners, or press **โŒ– Auto** and click the block centre to auto-detect the grid. Drag any handle to adjust. 3. **Segment all 4.** One GPU call per square, as in the main counter. The time from the click until all four squares are ready to annotate is recorded (end-to-end), along with the server's own time. 4. **Correct each square** on the large canvas below. Switch squares with the buttons or keys **1โ€“4**; edits on each square are kept when you switch. 5. **Copy the results row** (or **Copy with header** the first time) and paste it into a spreadsheet. Columns: `timestamp, files, model_sq1, corrected_sq1, โ€ฆ model_sq4, corrected_sq4, mean_corrected, seg_time_s, server_time_s, min_size_px`. *Model* is what Cellpose counted (after min size and exclusion); *corrected* is your ground truth. The table also shows the count error, (model โˆ’ corrected) / corrected. ## Correcting the count - click a cell โ†’ remove it (false positive); click again โ†’ restore - click empty space โ†’ add a dot (false negative) - click a dot โ†’ delete it - **Shift+click** โ†’ always add a dot, even on top of a cell (e.g. two cells merged into one mask) - **Ctrl+Z / Ctrl+Shift+Z** undo / redo ยท **Space** (hold) hide outlines ยท **F** fit - mouse wheel zooms, drag pans The total is the count of detected objects, minus objects below the min size, minus objects touching the left or bottom 1% exclusion zones, minus removed, plus added dots. Everything after segmentation runs in the browser, so clicks are instant. The page keeps nothing: copy the results row (or write the count down) before uploading the next image. ## Files `app.py` (server), `gt_canvas.js` (annotation canvas), `corner_canvas.js` (4-corner canvases in the 4-squares tab), `grid_seeded.py` (grid auto-detection, a copy of the main app's), `requirements.txt`. Set hardware to **ZeroGPU** in the Space settings. To use local weights instead of the Hub file, set `CPCC_LOCAL_MODEL=/path/to/weights.npy`.