Capture-quality check
Every walk gets a capture check at the top of its results. It says how the walk was filmed and warns when the footage is likely to give poor counts.
What it measures
- Resolution of the source.
- Sharpness: the variance of the Laplacian on each frame with its long side resized to 1024 px, so clips of any resolution share one scale. It reports the median and the 10th percentile over frames.
- Fruit size: the short side of each fruit box at the same 1024 px scale, as p10, median, and p90.
- Share without ripeness: fruit whose crop was too small to score.
Warnings and thresholds
| Warning | Fires when | What to do |
|---|---|---|
| Too far | The median fruit is under 29 px, or half or more of the fruit have no ripeness | Move closer, or record at 4K |
| Too close | The 90th percentile fruit is over 60 px | Step back. One large tomato can get several boxes |
| Blurry | The median sharpness is under 300, or the 10th percentile is under 300 on three or more frames | Walk slower, hold the phone steady, clean the lens |
The size warnings need at least 5 fruit on the walk. Too far and too close never fire together. When the median says too far but the large fruit say too close, too close wins: close up, the detector adds small boxes on parts of large tomatoes, and those pull the median down.
Where the thresholds come from
- 29 px is the smallest fruit whose padded crop reaches the 32 px the ripeness head scores.
- 60 px at the 90th percentile comes from frames measured one by one. On 60 close-range 4K phone frames it flags 40. Scoring drops boxes on those frames whose short side is under 15% of the 90th percentile, mostly pieces of one large tomato, which takes their count from 61% high to 31% high. The other 20 phone frames stay under the limit because their small boxes pull the 90th percentile down. Scoring also drops boxes under 35% of the 90th percentile on a frame under the limit when at least 12% of its boxes overlap a box 2.5 times their area and the 90th percentile is at least 2.2 times the median. That takes those 20 frames from 158% high to 100% high. It changes no drone frame, test walk frame or example photo, and on the aisle set it keeps every labelled fruit it found before. On a public aisle set it flags 5 of 146 frames, all of them close shots. It flags none of 35 drone frames, 12 frames from a 960×540 walk, or the 4 example photos. The median does not work here: extra boxes on parts of large tomatoes pull it down to about 25 px on the close frames.
- 300 sits below sharp public sets (10th percentile 555 to 764) and above a soft example photo (178).
Live check while filming
The same thresholds also run live. Film a walk in the app sends one frame about once a second and shows one verdict with a plain instruction, before you walk and while you record (see Filming a walk).
| Verdict | Shows when |
|---|---|
| Move closer | The frame would get the too far warning: median fruit under 29 px, or half or more of the fruit too small for ripeness |
| Step back | The frame would get the too close warning: 90th percentile fruit over 60 px |
| Hold steady | The frame's sharpness is under 300 |
| No fruit in view | Fewer than 5 fruit, too few to judge the distance |
| Good | None of these |
Distance comes first: a frame that is both too far and blurry says move closer. Only the fruit detector runs on the frame, so the check answers in under a second. It does not score ripeness, keeps no copy of the frame, and never counts as a walk. The share too small for ripeness is judged at the resolution you record, so a 4K recording counts more fruit as large enough than the smaller preview frame would.
One frame can differ from the whole walk. The capture check on the uploaded walk stays the final word.
In the API
The same block is in the observation result as quality, with resolution, sharpness, fruit_px (whose detections counts boxes over all scored frames, not fruit; count is an old name for it and will be removed), without_ripeness, thresholds, and a warnings list of {code, message}. The codes are too_far, too_close, and blurry.
The live check is POST /api/capture/check with an organization key. Send one JPEG as the form field frame, at most 2 MB and 4096 px on its long side, and optionally source_long_side, the long side of the recording in pixels. It returns verdict (move_closer, move_back, hold_steady, good, or no_fruit), advice, fruit_count, median_fruit_px, p90_fruit_px, too_small_for_ripeness, sharpness, and thresholds. Each key may check once a second with a burst of three. Faster checks get 429 with a Retry-After header.