Skip to course content
Free computer vision course

Computer Vision and Multimodal AI

Unit 08.04: Small objects, and why they are hard

Small objects are hard for a mechanical reason that precedes any modelling one.

The resize destroys them first

Three object sizes in a full-resolution image, and their size after a standard resize to 224 pixels.

The code computes both.

IMAGE = (1920, 1080)
OBJECTS = [("carton", 400, 300), ("label", 60, 40), ("barcode", 30, 12)]

print(f"{'object':10} {'pixels':>10} {'% of image':>11} {'after 224px resize':>20}")
for name, w, h in OBJECTS:
    area = w * h
    share = area / (IMAGE[0] * IMAGE[1])
    scale = 224 / IMAGE[0]
    print(f"{name:10} {area:>10,} {share:>10.3%} {w * scale:>9.1f} x {h * scale:.1f} px")

print("\nthe barcode is under 4x2 pixels after a standard resize")

# Small objects are hard for a mechanical reason before any modelling one: the
# resize that makes the image fit the network has already destroyed them.
# Detecting small objects means tiling the image, not tuning the detector.

The barcode is under four pixels by two after the resize. There is nothing left for a detector to find, however good it is - the information was removed by the preprocessing.

The remedy is architectural rather than model-scale: tile the image and run the detector on each tile at native resolution, then merge. Bigger models do not help.

The mistake this prevents

The mistake is responding to poor small-object performance by training longer or using a larger backbone. Measure the object's size in pixels after the resize first - if it is a handful of pixels, the problem is upstream of the model entirely.

Takeaway

Compute your smallest target's size in pixels after the resize. Under a few pixels, tiling is the answer and a larger model is not.