Detector trainers assume square inputs, and machine-vision frames rarely are. A fixed ROI on an area scan camera hands you 1024 × 320 strips; a moving web hands you captures a few thousand pixels wide. Pass the trainer a two-value imgsz such as [1024, 320] and it trains at 1024 square anyway, so the rectangle looks ignored. The fix is a choice between three settings: square training with letterboxed inference, rect=True training on the native rectangle, or tiling wide strips into squares. Each has a pixel and memory cost you can compute before the first epoch, and the arithmetic below settles it for a 3.2:1 dataset.
What imgsz accepts during training
Training reads one integer: the long-side target. YOLOv8 and YOLO11 trainers keep 1024 from your [1024, 320] and letterbox every frame into a 1024 × 1024 tensor. The long side scales to target, the short side fills with a neutral gray band, and nothing stretches — content geometry survives, only the canvas is square.
Both sides of anything the network sees must be a multiple of the stride, 32. Your strip already qualifies: 1024 = 32 × 32 and 320 = 32 × 10. The rectangle is legal network geometry; the square canvas is simply the trainer's default packing, kept because the default augmentation needs that canvas.
The cost of the packing is pure padding:
The waste depends only on the aspect ratio. At 3.2:1 you lose 704 / 1024 = 68.75% of every tensor to gray, whether you train at 1024 or at 640.
How rect=True builds rectangular batches
rect=True replaces the square loader with a batch builder that sorts frames by aspect ratio and pads each batch to one shared rectangle instead of a square. On a uniform dataset — every frame the same fixed ROI — every batch lands on exactly 1024 × 320: zero padding, native pixel scale, defects exactly the size you annotated them.
The price is fixed: rect training disables mosaic augmentation, because the two loaders are incompatible by construction. That is why the standard recommendation is to leave rect off unless memory forces it.
Why mosaic usually earns its padding
Mosaic stitches four frames onto one square canvas at the target size. In a single step the model sees objects at four scales and in neighbor combinations no real frame would show it. On sparse datasets — aerial imagery is the published case — it is reported as the strongest augmentation in the stack, lifting accuracy exactly where inspection data is thin.
The gray padding it forces is dead compute, not lost accuracy. The band carries no objects and the detector reads it as background. The square default therefore trades multiply-adds you do not need for an augmentation you do. When mosaic is off, put the diversity back with horizontal flips, scale jitter, and synthetic exposure augmentation for realistic camera images so brightness drift does not blind the model.
Worked example: 1024 × 320 frames with 6-pixel defects
Inputs:
- Frame size: 1024 × 320 px (width × height), one fixed ROI; aspect 1024 / 320 = 3.2.
- Smallest feature that must be found: 6 px across on native frames, measured on the annotated images.
- Candidate square sides: 1024 px and 640 px, both multiples of 32.
- Memory ceiling: whatever batch the GPU holds at 1024 square.
The 4 px detection floor below comes from the same pixel-count logic that sizes the camera itself; camera resolution for defect detection works it from the sensor side.
The frames can be a crop from a 12 MP USB3 area scan camera:
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
That sensor sends 4000 × 3000 frames over USB3 at 30 fps. A fixed inspection ROI then crops each one down to the 1024 × 320 strip you annotate, and the crop is what the dataset stores.
Square at 1024:
- pad rows = 1024 − 320 = 704, split into 352 rows top and bottom
- waste = 704 / 1024 = 68.75%
- tensor pixels = 1024 × 1024 = 1,048,576 against 327,680 of content
- the 6 px defect stays 6 px — comfortable against the 4 px floor
Square at 640:
- scale = 640 / 1024 = 0.625
- the strip becomes 640 × 200 (320 × 0.625 = 200); pad = 640 − 200 = 440 rows; waste = 440 / 640 = 68.75%, unchanged
- the defect becomes 6 × 0.625 = 3.75 px — below the floor, so 640 is out
rect at 1024:
- every batch is exactly 1024 × 320 = 327,680 px, no padding, defect 6 px, mosaic off
- pixels per frame drop by 1,048,576 / 327,680 = 3.2×, so activation memory and step time fall by roughly 3× — a first-order estimate, since memory tracks pixel count. A card that held batch 8 at the square holds about 25 at the rectangle (8 × 3.2 = 25.6)
Decision, by threshold: the 6 px feature forbids downscaling, so 640 is rejected on pixels, not preference. If the GPU holds 1024-square batches, train square with mosaic and letterbox at inference — the default and the best-accuracy path. If it does not, set imgsz=1024 with rect=True and replace mosaic with flips, scale jitter and exposure augmentation. Had the smallest feature been 10 px or larger, the arithmetic flips: 10 × 0.625 = 6.25 px survives 640, and the smaller square with mosaic on is usually the better accuracy per training hour.
If the ROI itself is still an open decision, size the camera first:
Letterboxing at inference
Prediction letterboxes whatever you feed it: scale to the target, pad the short side with the same gray, never stretch. Run the model at imgsz=1024 and your strip reaches the network at native scale inside a 1024 × 1024 tensor — exactly the packing the square-trained model learned, gray bands included. Validation needs no help: it batches frames by aspect ratio on its own, so metrics come from letterboxed rectangles however you trained.
Two rules hold the pipeline together. First, identical letterbox logic on both sides — same scaling, same fill, no stretching anywhere. Second, feed the network the original pixels: resize inside your pipeline from the raw frame, never from an already-scaled preview, and start from the raw camera buffer rather than a rendered copy.
The head is also fully convolutional, so a deployment can feed the unpadded 1024 × 320 tensor directly — both sides divide by 32 — and skip the padding compute, provided the scaling and fill match training. That saving is the same two-thirds of the tensor the square trainer wasted.
Choosing the setting
| Path | Setting | Mosaic | Tensor waste | Pick it when |
|---|---|---|---|---|
| Square, letterbox at inference | imgsz=1024 | on | 69% | Default: memory holds the square batch |
| Rectangular batches | imgsz=1024, rect=True | off | none | Memory-bound and small features need native scale |
| Smaller square | imgsz=640 | on | 69% | Smallest feature 10 px native or larger (10 px becomes 6.25 px) |
| Tiled squares | crop with overlap at least the largest object | on | none | Strips around 3000 × 350 and wider |
For a uniform 1024 × 320 ROI the order of preference is: square 1024 with mosaic; rect at 1024 when memory says no; 640 square only when the pixel budget allows it; tiling when the strip is a web capture thousands of pixels wide.
The camera side of a 3.2:1 dataset
Wide training sets have three usual sources: a fixed ROI cropped from an area scan camera (the case above), an area scan camera run in line-scan mode over a moving web, and true line scan cameras whose frames are long strips — grain sorting with a line scan camera is a worked instance of the last. Training geometry does not care which source; the pixel budget does, because a web strip's height is the line height while its width grows with the capture.
For wider webs and for models that must run on the device, two parts fit:
- Sensor format
- APS-H
- Lens mount
- F-mount
- Interface
- USB 2.0
- Resolution
- 6-10 MP
The MV-CH250-25TC-F-NF is a 25 MP 10GigE camera on an F-mount, suited to wide fields at high frame counts. The LS-SMC-0017 is an 8.8 MP smart camera with a C-mount and a global shutter that runs inference beside the sensor; its letterbox must match training exactly, because there is no second chance to resize on the device. Wide sensors also raise the lens question — the image circle has to cover the format — so machine vision lenses belong in the same decision. The camera finder filters by sensor format and mount, and the configurator walks the chain with the lens attached.
GigE, USB3, 10GigE and CoaXPress
1,287 models · from $149.00When the usual answer is wrong
- Aspect ratios beyond about 4:1. A 3000 × 350 web capture (aspect ≈ 8.6) pads about 88% of every square tensor, and mosaic stitches four nearly empty strips that teach little. Tile, or use rect.
- Thin datasets. A few hundred frames is exactly where mosaic's four-image stitching adds scene diversity you cannot annotate; switching it off hurts most here.
- Mixed ROIs. If the dataset mixes aspect ratios — the ROI changed mid-project — rect batches go ragged and per-batch padding returns. Re-crop everything to one ROI, or train square.
- Pre-scaled images. Frames saved already resized bake in interpolation and can alias small features away before training sees them; antialiasing when you downsample or warp images covers what that costs. Store native frames and resize in the loader.
Checklist before the first epoch
- Both frame sides are multiples of the stride, 32.
- One ROI for the entire dataset; mixed ratios defeat rect batching.
- Smallest feature at least 4 px after scaling — at a 640 square that needs 6.4 px native (4 / 0.625).
- Letterbox in both training and inference: same scale, same gray fill, never a stretch.
- Mosaic on unless you chose rect; if rect, add flips, scale jitter and exposure augmentation.
- Read the mAP from the aspect-batched validation logs, not from square preview renders.
- Store native frames; resize only inside the pipeline.
If camera, ROI and lens are still open decisions, start from the guides hub and lock the pixel budget before the first annotation. Questions about a specific strip geometry go to our team through the contact page.
Questions
Does the trainer stretch 1024 × 320 frames to fill the square?
No. The loader scales the long side to imgsz and pads the short side with a neutral gray band — at 1024 that is 352 rows above and 352 below the content. Circles stay circles and object sizes stay true. If your frames look stretched, your own preprocessing is doing it; the trainer never distorts content to fill the canvas.
Why does rect=True switch mosaic off?
Mosaic builds one square canvas at imgsz and stitches four random frames onto it, then trains on the composite. The rect loader instead packs each batch into a shared rectangle near native aspect, so the square canvas mosaic needs does not exist and the loader disables it. You keep native scale and lose the four-scale scene diversity — that is the whole trade.
Is tiling wide frames into squares a real alternative?
Yes, and for strips around 3000 × 350 it is often the best one. Crop overlapping squares, keep every crop that contains an object, and set the overlap to at least your largest object so nothing is cut in half at a tile edge; merge overlapping detections at inference. You keep square training, mosaic augmentation and native pixel scale all at once.
The 1024 square will not fit in memory — what now?
First try imgsz=1024 with rect=True: batches train at 1024 × 320, 327,680 pixels per frame instead of 1,048,576, and memory falls by roughly the same 3.2 factor. Drop to a 640 square only if the smallest feature survives: everything scales by 0.625 there, so a 6 px defect becomes 3.75 px (too small) and a 10 px defect becomes 6.25 px (fine).
Do validation and prediction need square inputs too?
No. Validation groups frames by aspect ratio and scores letterboxed rectangles on its own. Prediction letterboxes what you feed it — scale to target, gray fill, no stretch — so a 1024 × 320 frame runs inside a 1024 square, or as the bare rectangle in a deployment that feeds tensors directly, since both sides divide by 32. Keep the letterbox identical on both sides of training.


