Refuse to detect faces on a proxy too small to find one
Detection was run on whatever proxy the caller happened to have. A small one does not fail -- the image is letterboxed into the detector's 640px input at any size -- so it comes back with almost nothing, and the caller then writes a face_index row saying the photograph was examined. That row is the damage. Nothing distinguishes it from "examined properly, no faces in this one", so the image is never looked at again. The measurement, on the reference library of 23,531 images. Runs against a 1024-edge proxy: 0.078 faces per image, 90% of them finding nothing at all. Runs against 2048 or better: 1.82. To rule out the obvious objection that small proxies just come from small photographs, the same comparison restricted to DNGs -- 1,592 of them averaging 21 MB against 7,724 averaging 23 MB, so the same kind of file in the same library -- gives 0.078 against 1.82 again. Twenty-three fold, on identical source material, identical weights, identical options. So the floor goes in the detector rather than in either sweep, because both of them, the example tool and any future job handler are equally entitled to get this wrong, and there is one place that sees every attempt. It is 1025, not 1024, and the odd-looking number is the point: 1024 is exactly ThumbSize::Large, the tier proxies are stored at and the tier one of the two sweeps was detecting on. A floor that admitted 1024 would admit precisely the population this exists to exclude. Written as a minimum rather than a maximum so the test at each call site is `edge < MIN_DETECT_EDGE` with no boundary left to get wrong. ProxyTooSmall is its own error variant rather than an empty result because the caller has to tell it apart from a failure: nothing is wrong with the image or the model, and the answer is to go and find better pixels, not to retry these ones. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,31 @@ pub mod embedding;
|
||||
pub mod naming;
|
||||
pub mod neighbours;
|
||||
|
||||
/// Smallest proxy long edge detection will accept, in pixels.
|
||||
///
|
||||
/// # Why this exists, and why it is 1025 rather than 1024
|
||||
///
|
||||
/// A proxy is letterboxed into the detector's 640px input whatever size it
|
||||
/// arrives at, so a small one does not fail — it silently finds almost
|
||||
/// nothing, and the
|
||||
/// caller records a run marker saying the image was examined. That marker is
|
||||
/// the damage: it is indistinguishable from "examined properly, no faces
|
||||
/// here", so the photograph is never looked at again.
|
||||
///
|
||||
/// The number is not a guess. Measured over a 23,500 image library, detection
|
||||
/// against a 1024-edge proxy returned **0.078 faces per image**; the same
|
||||
/// files — DNGs, 21 MB against 23 MB, so the same photographs in every respect
|
||||
/// that matters — returned **1.82** against a proxy of 2048 or better. A
|
||||
/// twenty-three fold difference, on identical source material and identical
|
||||
/// weights. Ninety percent of the 1024-edge runs found nothing at all.
|
||||
///
|
||||
/// 1024 is exactly `dr_thumbs::ThumbSize::Large`, the tier a proxy is stored
|
||||
/// at, and it was the tier one of the two sweeps detected on. So the floor has
|
||||
/// to *exclude* 1024 rather than admit it, and the constant is one past it:
|
||||
/// `edge < MIN_DETECT_EDGE` is then the whole test, with no off-by-one left at
|
||||
/// the call sites to get wrong.
|
||||
pub const MIN_DETECT_EDGE: u32 = 1025;
|
||||
|
||||
pub use align::{warp, Aligned112, Similarity, ALIGNED_EDGE, ARCFACE_TEMPLATE};
|
||||
pub use assign::{identity_shares, RIVAL_FLOOR, TOP_MATCHES};
|
||||
pub use calibrate::{Calibration, Pairs, ReliabilityBand};
|
||||
@@ -80,6 +105,14 @@ pub enum FaceError {
|
||||
|
||||
#[error("image buffer is {got} floats, expected {expected} (RGB, three per pixel)")]
|
||||
ImageShape { expected: usize, got: usize },
|
||||
|
||||
/// The proxy is too small to detect on, so nothing was attempted.
|
||||
///
|
||||
/// A distinct variant because the caller must treat it differently from a
|
||||
/// failure: nothing is wrong with the image or the model, and the right
|
||||
/// response is to find better pixels rather than to retry these.
|
||||
#[error("proxy long edge is {edge}px, below the {needed}px detection floor")]
|
||||
ProxyTooSmall { edge: u32, needed: u32 },
|
||||
}
|
||||
|
||||
/// Install tract as `ort`'s backend.
|
||||
|
||||
Reference in New Issue
Block a user