System designExplainer

Non square YOLO training: image size, rect mode and ONNX export

Train YOLO on non square images at the native 1920 × 480: rect mode, no gray padding, and an ONNX export that holds the input size at [480, 1920].

LumaSpec Vision10 min read Share on LinkedIn

On this page 10 sections
  1. 01The decision: train the native rectangle when the sides divide by 32
  2. 02What rect mode changes, and what the square default does
  3. 03Worked example: a 1920 × 480 px strip dataset, rect on versus off
  4. 04The .pt checkpoint has no input size
  5. 05Export the ONNX at [480, 1920]
  6. 06Size the rectangle from the pixels the defect needs
  7. 07Run the exported model on the line
  8. 08Checks before you ship the model
  9. 09When the square default is still the right call
  10. 10Questions

Long, thin images are normal in machine vision: label strips, EL panels, conveyor crops, barcode bands. YOLO training defaults to a square canvas. Padding a 1920 × 480 strip into a square therefore spends most of every batch on gray pixels that carry no defect information. This guide gives you the rule that decides it: when a rectangle trains natively with zero padding, which numbers must divide by the 32-pixel stride, and how to export an ONNX file that keeps the strip's shape end to end. It is written for engineers wiring object detection into a production vision system.

The decision: train the native rectangle when the sides divide by 32

Commit to the native rectangle when three things hold: every image shares one shape, both sides divide by 32 with no remainder, and the aspect ratio is long enough that a square canvas would waste real pixels. For a 1920 × 480 dataset all three hold — 1920 ÷ 32 = 60 and 480 ÷ 32 = 15. Rect mode then trains the strip at its own size and the letterbox has nothing to add.

The 32 is the detector's stride: the total downsampling between the input image and the coarsest detection grid on a standard YOLO head. Feature grids have to align to it. A side that is not a multiple of 32 gets rounded up, and the difference comes back as gray padding. Hand the trainer sides that are already multiples and rounding never runs.

valid side = 32 × k (k = 1, 2, 3, …) square pad fraction = 1 − short side ÷ long side

Pick every side from the 32-times table — 160, 320, 480, 512, 640, 1024 and 1920 all qualify — and choose the pair that fits your pixels, not a default. If a single view with a handful of classes can be trained and run on the device itself, a smart camera ends the question before it starts; this guide is for the runs you keep on a PC.

What rect mode changes, and what the square default does

With rect off, the letterbox scales each image so its long side fills a square canvas, then pads the short side with gray until the tensor is square. On a 4:1 strip that padding is three quarters of every image. None of it carries information.

With rect enabled, the trainer sorts the dataset by aspect ratio and packs each batch into one rectangle that fits its images, padded only out to stride multiples. A single-shape dataset therefore lands in batches of one identical rectangle — here 480 × 1920 — with no padding anywhere.

You do not have to take that on faith. The trainer writes train-batch images into the runs/train folder: strips sitting edge to edge mean zero padding; gray bars along the top and bottom mean the square letterbox is still in play. The matching mechanics at inference — input dimensions and padding — are laid out in object detector input dimensions: height, width, and padding.

Worked example: a 1920 × 480 px strip dataset, rect on versus off

The case is your own dataset: strips of 1920 px × 480 px (4:1), trained on a standard YOLO head with a documented stride of 32 px, once with rect enabled and once with the square default. The canvas rule is the square letterbox when rect is off, and the batch's own rectangle when rect is on.

Divisibility first: 1920 ÷ 32 = 60 and 480 ÷ 32 = 15, so both sides are stride-valid and nothing is forced to round.

Rect on: the batch tensor is 480 × 1920 px = 921,600 px, padding 0 px.

Rect off: the letterbox fills a square canvas of 1920 px × 1920 px = 3,686,400 px. The strip occupies 1920 × 480 px, so 1920 − 480 = 1440 px of height turns gray, split evenly top and bottom. The gray area is 3,686,400 − 921,600 = 2,764,800 px, and 2,764,800 ÷ 3,686,400 = 0.75 — exactly 75% of every image is padding. Compute per image is 3,686,400 ÷ 921,600 = 4.0× the strip's pixels, bought for no extra information.

The decision rides on the pad fraction, 1 − short ÷ long: 0.75 at 4:1, 0.50 at 2:1, 0.25 at 4:3. Past about half, rect wins outright — at 4:1 it is not close.

rect enabled square default
Batch tensor (height × width) 480 × 1920 px 1920 × 1920 px
Pixels per image 921,600 px 3,686,400 px
Gray padding per image 0 px 2,764,800 px (75%)
Compute per image 1.0× 4.0×
Fit one shape, stride-valid sides, aspect past about 2:1 mixed shapes, near-square images

Check it on the train-batch images: the rect run shows strips edge to edge; the square run shows the gray bands.

The .pt checkpoint has no input size

A best.pt file stores weights, not an input shape. A YOLO detector is fully convolutional, so the same weights run at any stride-compatible size, and the size is supplied where you use the model: in the predict call for a quick check, in the export call for deployment. Asking for 'the .pt in 1920 × 480' has no answer because the file never carried a size to change.

That is also your fastest sanity check: predict with the .pt on a native 1920 × 480 frame and look at the boxes before any export exists.

Export the ONNX at [480, 1920]

Export takes its own imgsz, in height × width order — so this dataset exports at [480, 1920], not [1920, 480]. The call reads model.export(format='onnx', imgsz=[480, 1920]), and the written graph records the input as 1 × 3 × 480 × 1920 in the usual batch, channels, height, width order. Read the input tensor's dimensions back from the .onnx once it is written — every runtime prints them when it loads a model.

Leave imgsz out of the export and it falls back to the 640 × 640 default square, quietly reintroducing the padding you just removed from training. Pass the same imgsz to predict when you compare the two models, so both see identical frames.

Reported issues have made non-square ONNX inputs easy to mishandle, so close the loop with a smoke test: run the exported file on a native 1920 × 480 frame and confirm the boxes match the .pt's on the same frame. For the wider path from an exported model to a line decision, the ONNX anomaly detection inference walkthrough covers the same export-to-verdict route.

Size the rectangle from the pixels the defect needs

Work backwards from the smallest feature that must be detected: the working rule is at least 3 px across it for a detector to fire, more when you measure. A 60 mm wide strip across 1920 px gives 1920 ÷ 60 = 32 px/mm, so a 0.1 mm crack spans 0.1 × 32 = 3.2 px — right at the floor. A 0.05 mm crack at the same scale is 1.6 px and will not be seen. That arithmetic, not the 4:1 shape alone, sets the width. The shape then tells you what a square canvas would waste. The camera resolution guide for defect detection develops the full pixel rule, and the calculator below runs it on your own defect size.

Camera resolution for the smallest feature
Units
Pixels needed
–
Sensor size
– MP
Smallest sensor that fits
–
Pixel on the part
– mm
Pixels across the feature, that sensor
–

Pixels needed = field / feature × pixels per feature on each axis (field incl. margin). The lens must resolve the pixels too: Nyquist = 1000 / (2 × pixel µm) lp/mm.

Find cameras with enough pixels Open the full calculator

Then set the camera ROI to the strip you actually inspect and the training size follows the optics: an area scan camera with a 12 MP global shutter leaves room around a 0.92 MP strip ROI for a second inspection region. The camera finder filters by resolution, shutter and interface.

Area scan camerasHikrobot MV-CH120-11UC 12 MP Area Scan Camera, USB3, IMX304, High-speed version, ColorMV-CH120-11UC
Sensor format
1.1"
Lens mount
C-mount
Interface
USB3
Resolution
12 MP
$2,339.00 · quotedView and quoteBuild a system with it

Run the exported model on the line

The exported rectangle runs wherever an ONNX runtime lives, and on a line that is usually a vision controller: camera links, light channels and inference in one box, with no desktop in the cabinet. Feeding it is a frame loop on the acquisition side — the continuous camera acquisition mode guide shows the loop pattern. Latency tracks the pixel count too: at 480 × 1920 the network processes 0.92 MP per frame, where a padded square export would push 3.69 MP — roughly four times the work per frame for the same boxes.

Vision controllersHikrobot MV-VC2140-128G40-1T VC2100 Vision Controller, N97, 8GB+128G SSD+ 1THDDMV-VC2140-128G40-1T
LAN ports
3-4 LAN ports
USB 3 ports
2 USB 3 ports
Light outputs
4 built-in channels
Memory
8 GB
$1,679.00View partBuild a system with it

Size camera, controller and lighting in one pass with the system configurator, which starts from the parts you already have.

Checks before you ship the model

Run this list before the model goes near production:

  • Both sides divide by 32 — 60 × 32 and 15 × 32 for this strip — because the trainer rounds silently if you get it wrong.
  • The train-batch images in the runs/train folder show strips edge to edge with no gray bars.
  • The export call carried imgsz=[480, 1920], and the .onnx input tensor reads 1 × 3 × 480 × 1920.
  • One ONNX predict on a native 1920 × 480 frame reproduces the .pt's boxes on the same frame.
  • Latency is measured on the target controller at 480 × 1920, batch 1, not extrapolated from a square benchmark.

When the square default is still the right call

Rect mode is not automatic. Keep the square when the dataset mixes shapes: rect packs each batch by aspect ratio, so padding returns per batch and the benefit thins out. Two dominant shapes are better served by one model each, with frames routed by size at runtime. Keep it when the image is nearly square: the pad fraction is 20% at 5:4 and 25% at 4:3, small enough that the square default costs little.

Memory is the third boundary. A 921,600 px training image at a workable batch size can exhaust GPU memory — the pressure behind YOLO training crashes. The fix there is a smaller stride-valid rectangle such as 1280 × 320 (409,600 px, same 4:1), not a return to the square. The YOLO training segmentation fault guide walks that failure through. What not to do: shrink the rectangle below the pixels the defect needs just to fit a square default — 3 px across the smallest crack is the floor the width was chosen for.

The whole decision, then: divide by 32, enable rect, train, export at [480, 1920], and check the batch images and the graph input before the line sees the model. To move from rule to hardware, the camera finder and the configurator above narrow the camera, and a fanless industrial mini PC covers the runtime side of the cabinet. More systems-side guides sit under the systems topic, and we take strip drawings and defect lists through the contact page.

Questions

Does imgsz take height or width first when exporting ONNX?

Height first. The exported graph stores the input as [batch, channels, height, width], so a 1920 wide × 480 tall detector exports at [480, 1920] and the file reads 1 × 3 × 480 × 1920. Read the dimensions back from the .onnx input tensor instead of trusting the order you typed — some pre-processing code builds a width × height tuple, and that mismatch is a classic silent failure.

Can I train at 500 × 500 or another odd size?

Not at 500: each side must be a multiple of the 32-pixel stride, so the trainer rounds 500 up to 512 and pads the extra 12 pixels with gray. Choose 480 × 480 or 512 × 512 and the letterbox has nothing to add. The same applies to rectangles: 1919 × 480 trains as 1920 × 480 with a one-pixel gray column, so round the sides yourself.

Is 1920 × 480 too large for my training GPU?

Count pixels: 921,600 px per image is 2.25× the 409,600 px of a 640 × 640 square, so plan memory accordingly. If it runs out, drop to a stride-valid 4:1 rectangle: 1280 × 320 is 409,600 px, 1024 × 256 is 262,144 px and 640 × 160 is 102,400 px — or keep the size and cut the batch. Keeping the shape usually beats padding back to a square.

Do I have to retrain to change the input size?

No. A YOLO detector is fully convolutional: the same weights predict at any stride-compatible size, and the size lives in the predict or export call, not in the checkpoint. Retrain at the new size only if accuracy moves when you measure it on your own validation set — that decision belongs to your data, not to the file format.

Should I resize images before annotating them?

No. Annotate the native 1920 × 480 frames: labels are stored as normalized coordinates between 0 and 1, so they hold for any later letterbox or resize, while pre-shrinking throws away the detail you chose the size to keep. Export the annotation set once at native size and let the trainer do whatever scaling each run needs.