Training does not consume your frames at camera resolution. The YOLO loader letterboxes every image down to imgsz before the network sees a pixel, so imgsz — not the sensor — decides both your epoch time and how many pixels your smallest object keeps. Set it from the annotations, not from the camera. The working rule: scale the frames so the smallest labeled box stays at or above about 32 × 32 pixels, then spend the compute you save on batch size. For 1920 × 1080 footage with 50–60 px boxes, that lands on imgsz=1280 — every object above the floor, each epoch at about 44% of the 1920 cost, and inference on the original 1920 stream unchanged.
What imgsz does to a frame
A YOLO detection model consumes a square tensor of imgsz × imgsz pixels, and the loader builds it by letterboxing: scale the frame until its longest side equals imgsz, center the result on a gray canvas, pad the remainder. A 1920 × 1080 frame trained at imgsz=1280 enters the network as a 1280 × 720 image centered on a 1280 × 1280 canvas, with 280 px of padding above and below. What that padding does to coordinates and aspect ratio is its own subject: what letterbox padding does to a 16:9 image.
Two consequences drive everything that follows. Native resolution matters only through the scale factor imgsz ÷ long side — one number that sets the resized pixel size of every object. And imgsz must be a multiple of 32, the largest stride in the detection neck, which is why the practical values step in 32s: 640, 1280, 1920. Nothing about a 1920-wide source makes imgsz=1920 necessary; the annotations decide, because they carry the object pixel sizes. If the 44% padding of a widescreen frame bothers you, rect mode trains on a stride-aligned rectangle instead of a square — the trade is compared in non-square image size in YOLO training: rect vs square.
The 32-pixel floor for small objects
The finest prediction grid advances 8 pixels per cell (stride 8), so the head needs an object spanning several cells before it can place a confident box. The working floor is 32 × 32 px after the resize: below it, the downscale has averaged away the features the head reads, and recall on that size band collapses. Keep the smallest labeled box at 32 px or more after the resize, and design to 35–40 px, because mosaic crops, HSV shifts and blur each cost a little effective sharpness.
Pixels at the floor are where accuracy lives. A widely cited 2019 study of aerial imagery measured a 13–36% improvement in small-object average precision when the effective ground sample distance was halved, with much smaller gains from further increases. Doubling the pixels on your smallest object buys recall; pixels beyond the floor mostly buy epoch time you did not need to spend.
The formula: imgsz from the smallest box
One line connects the annotation statistic to the training size:
Round up to the next multiple of 32, and cap the result at the native long side: past a scale of 1.0 the loader interpolates pixels the sensor never captured, so the extra tensor is compute spent on data that carries no new information.
- Measure smallest_box_px from the annotation files at native resolution — resized previews shift every box. The same per-image discipline used to annotate images for YOLO training applies here.
- Compute imgsz_min and round up to the next multiple of 32.
- Check the margin: the smallest box should land at 35–40 px after the resize. At 32–33 px, step up one multiple or oversample the class.
- If imgsz_min exceeds the native long side, stop — the frame is the wrong unit of analysis. Tile it or change the optics, as the next sections work through.
For 50 px boxes on a 1920 long side: imgsz_min = 32 × 1920 / 50 = 1228.8. The next multiple of 32 is 1248, which holds the box at 50 × 1248 / 1920 = 32.5 px — at the floor with nothing left for augmentation. One step up, imgsz=1280, holds it at 50 × 1280 / 1920 = 33.3 px and is the value most tooling and pretrained detection weights are tuned around. Take 1280.
Worked example: 1920 × 1080 frames with 50–60 px boxes
Take a dataset of 100,000 native 1920 × 1080 frames whose boxes run 50–60 px on the long side. Three candidate imgsz values:
| imgsz | scale = imgsz / 1920 | 50 px box becomes | 60 px box becomes | Tensor pixels | Verdict |
|---|---|---|---|---|---|
| 640 | 0.333 | 17 px | 20 px | 409,600 | Below the floor — misses the class |
| 1280 | 0.667 | 33 px | 40 px | 1,638,400 | Clears the floor with margin |
| 1920 | 1.000 | 50 px | 60 px | 3,686,400 | Clears it, at 2.25× the compute |
The arithmetic: scale = 1280 / 1920 = 0.667, so 50 × 0.667 = 33 px and 60 × 0.667 = 40 px. Tensor pixels are imgsz squared: 640² = 409,600, 1280² = 1,638,400, 1920² = 3,686,400. The compute ratio of 1920 to 1280 is (1920 / 1280)² = 2.25.
Epoch time follows the pixel count. If a 1920 epoch runs 5 hours at the batch your GPUs allow, the same epoch at 1280 costs 5 × 0.444 = 2.2 hours. Over 300 epochs that is 1500 hours — about 62 days — against about 670 hours, or 28 days. Batch size widens the gap: memory per image also scales with imgsz², so a run that batches 4 at 1920 typically batches 8 or more at 1280 on the same hardware, which raises utilization and cuts optimizer steps per epoch.
The 16:9 shape adds waste at a square imgsz. The frame fills 1280 × 720 = 921,600 of the 1,638,400 canvas pixels, so 44% of every batch is padding. Rect mode resizes to about 1280 × 736 — a 942,080-pixel canvas — trimming roughly 42% of the padded compute per image.
Inference: frames of a different size
Deployment resolution is decoupled from training resolution. The inference loader letterboxes frames to the training imgsz automatically: a 1920 × 1080 stream into a 1280-trained model is detected at 1280 and written out at 1920 × 1080, with box coordinates mapped back through the stored scale and padding. A training size below the camera's native size therefore costs nothing at deployment.
Do not raise the inference size to match the camera. The model was tuned on 1280-letterboxed inputs; feeding it 1920 shifts the input distribution and usually drops accuracy. Keep training and inference imgsz identical, and when boxes appear in the wrong place after export, check that the preprocessing size and the export size agree — the common cause is covered in the inference image size mismatch fix.
The same logic holds on a smart camera: the device runs the deployed model at its trained size. Settle imgsz during training, before hardware, then match the camera's resolution class to the object sizes you measured.
When the fix is optics, not imgsz
If imgsz_min exceeds the native long side, the sensor never captured the pixels in the first place — no imgsz recovers them. That result is the formula telling you the frame is the wrong unit. The machine-vision answer is more pixels on the object: shorten the working distance, narrow the field of view, or move to a higher-resolution sensor.
Put numbers on it. A 2 mm defect that must span 32 px needs 32 / 2 = 16 px per mm of field. Across a 200 mm field of view that is 3200 px of sensor width. A 2.5 MP-class sensor at about 2000 px covers 125 mm at that density — not 200 mm — so you either narrow the field to 125 mm or step up to a 12 MP sensor near 4000 px wide. The calculator below runs this chain from object size to sensor pixels:
The sensor classes differ exactly where the arithmetic says they must: the MV-CU020-90GC resolves 2.5 MP. The MV-CH120-11UC resolves 12 MP on a 1.1" sensor.
- Sensor format
- 1/1.7"
- Lens mount
- C-mount
- Sensor format
- 1.1"
- Lens mount
- C-mount
For the wider framing of that choice — sensor, lens and the object sizes that drive both — see how to choose a camera for object detection.
When tiling beats a bigger imgsz
When many small objects share a large scene — imgsz_min well above your normal training size but below the native long side — tiling restores effective scale without a giant tensor. A 3840 × 2160 frame at imgsz=1280 runs at scale 0.333; split into four 1920 × 1080 tiles, each tile trains at 1280 with scale 0.667, doubling the pixels on every object. Four tile tensors cost the same total pixels as one full-frame 2560 pass (4 × 1280² = 2560²), but each is a 1280 image your loader, memory and augmentation handle comfortably, and inference runs tile-wise with the same math. For reference, the full-frame alternative gets expensive fast: (3840 / 1280)² = 9× the compute of a 1280 tensor per image. The thresholds and stitching workflow live in tiled inference: confidence and IoU thresholds for small objects.
Checks before the 300-epoch run
- Smallest-box statistic computed from the annotation files at native resolution, across train and validation — a preview resize shifts every number.
- imgsz is a multiple of 32, at or above imgsz_min, and at or below the native long side.
- The smallest box lands at 32 px or more after the resize; 35–40 px for the class that matters most.
- Padding below about 45% of the canvas, or rect mode on.
- Batch raised until GPU memory is the limit again — a smaller imgsz at the old batch wastes half the win.
- Dataset kept at native resolution on disk; imgsz is a loader setting, and pre-resized copies buy nothing, as argued in downscale images after capture.
- If sources mix native sizes, treat them as mixed-resolution training data so the floor holds for every source, not just the 1080p majority.
- A 20–30-epoch subset run at the candidate imgsz against 1920, scoring average precision on the small-box subset only; parity within a point or two is the expected outcome once the floor holds.
The decision, restated once: imgsz is bought with the smallest object, not with the sensor. Compute 32 × long side ÷ smallest box, round up to a multiple of 32, keep 35–40 px of margin, and spend the savings on batch size — for the 1920 × 1080 case with 50–60 px boxes, that is imgsz=1280. If the arithmetic points at the sensor instead, the area scan cameras page and the camera finder filter by resolution and sensor format, and the configurator pairs the sensor with a lens that puts the pixels where the defect lands. More on the training side of the pipeline in the systems guides.
Questions
Does imgsz have to match my camera's native resolution?
No. The loader letterboxes every frame to imgsz at both training and inference, whatever the source size. Native resolution only sets the scale factor imgsz divided by the long side, which fixes the pixel size of your smallest object. Keep the files at native resolution on disk so that scale factor stays exact, and choose imgsz from the box statistics instead.
What happens if I train at 1280 and deploy on a 1920 × 1080 stream?
Frames are resized to 1280 automatically before detection, and results are written back in original 1920 × 1080 coordinates; the saved video keeps its native size. Leave the inference size at the training value — raising it to match the camera shifts the input distribution and typically costs accuracy. If boxes land in the wrong place after export, check that preprocessing and export sizes agree.
Why 32 pixels, and is the floor exact?
It is a working floor with an architectural basis: the finest detection grid advances 8 pixels per cell, so a 32 px object spans about four cells — enough signal for the head to place a box. Below that, resize blur leaves too little to localize. Treat 32 px as the minimum and design to 35–40 px so augmentation does not push samples under it.
Is the default imgsz=640 ever the right choice?
When the arithmetic clears it: a 640-trained model keeps 32 px on any object whose native box is at least one-twentieth of the frame's long side — 96 px on a 1920 frame, 48 px on a 960 frame. Check 640 divided by your long side against the smallest box before trusting the default; 1080p footage with 50 px objects fails it.
Should I resize my dataset to 1280 first to save disk and time?
No. Training compute depends on imgsz, not file size, so pre-resizing saves nothing and locks you out of a different imgsz later, tiling, or measurement from the original pixels. Disk is the cheaper resource: keep native-resolution files and let the loader do the letterbox each epoch. If storage is tight, archive the originals and keep a manifest of their sizes.

