fix(preprocess): use INTER_AREA when downscaling images for model input#2519
Draft
patricknihranz wants to merge 1 commit into
Draft
fix(preprocess): use INTER_AREA when downscaling images for model input#2519patricknihranz wants to merge 1 commit into
patricknihranz wants to merge 1 commit into
Conversation
The model's built-in resize ('Stretch to' and the 'Fit ... edges in'
letterbox path) called cv2.resize / F.interpolate without specifying an
interpolation method, defaulting to bilinear. Bilinear point-samples a
2x2 neighborhood and aliases on large downscales, eroding thin,
low-contrast features (e.g. embossed serial-number text) and causing
silently missed detections on high-resolution inputs.
Select INTER_AREA (and antialias=True on the torch path) when the target
is smaller than the source, which averages over the full source region;
keep bilinear when upscaling, where INTER_AREA degenerates to nearest.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
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.
What
Selects
cv2.INTER_AREA(andantialias=Trueon the PyTorch path) instead of the implicit bilinear default when the model's preprocessing resize is shrinking an image to the network input size. Applies to both resize modes:Stretch to—inference/core/models/roboflow.pyFit (black/white/grey edges) in— viaresize_image_keeping_aspect_ratioininference/core/utils/preprocess.pyUpscaling keeps bilinear (
INTER_AREAdegenerates toward nearest-neighbor when enlarging).Why
The resize calls passed no
interpolationargument, so OpenCV defaulted toINTER_LINEAR(bilinear). Bilinear samples only a 2×2 neighborhood per output pixel, so on large downscales (e.g. a 3120×4160 image → 640×640, ~6.5× per axis) it point-samples and aliases — high-frequency detail like thin, low-contrast embossed text is discarded rather than averaged in.INTER_AREAintegrates over the entire source region each output pixel covers, acting as a proper anti-aliasing filter.This surfaced on a customer (GE Vernova) serial-number OCR model: sending a full-resolution image silently dropped one of two detection regions, while resizing first with
INTER_AREA(via theimage_preprocessingworkflow block, which already usesINTER_AREA) recovered both. The Models-page UI "worked" only incidentally — it downsamples to 1536×2048 before inference, reducing the final downscale ratio and thus the aliasing.Impact / risk
image_preprocessingblock (INTER_AREA) and, likely, dataset-generation preprocessing — reducing train/serve skew. Open question for reviewers: please confirm the interpolation used during version generation so inference matches it exactly.Repro (customer A/B, model
serialnumber-001/15, same image)INTER_AREAresize → 640×640 → modelINTER_AREA-to-640 vs bilinear-to-640Out of scope (follow-ups)
antialiasflag only applies tomode="bilinear"/"bicubic"— fine here, but worth a guard if modes are ever made configurable.Fit within,Fill (with center crop) in, andFit (reflect edges) insilently fall back toFit (black edges) ininroboflow.py.Test plan
INTER_AREAchosen when target < source andINTER_LINEARwhen target ≥ source, for bothStretch toand the letterbox path.🤖 Generated with Claude Code