Point an off-the-shelf object detector at a drone photo of a marina and it will tell you there are five boats. There are dozens. The model isn't bad; the pipeline throws the boats away before the model ever sees them.

The resize problem

Most real-time detectors, YOLO and its relatives included, are trained and run at around 640×640 pixels. A 3613×2400 aerial photo gets shrunk by a factor of about 5.6 to fit. A boat that was 30 pixels long becomes about 5 pixels long, which is below what the network can reliably pick out. The same thing happens to background people in crowd shots and to cars in parking lot photos.

Sliced inference

The fix is to stop shrinking the image and look at it in pieces instead:

  1. Cut the image into overlapping tiles at full resolution, 640 px with about 20% overlap.
  2. Run the detector on every tile, plus one pass on the whole downscaled image so large objects that span tiles are still found.
  3. Shift each tile's boxes back into full-image coordinates.
  4. Merge duplicates. Plain IoU-based non-max suppression is not enough, because an object cut by a tile edge produces a partial box that barely overlaps the full one. Matching on intersection-over-smaller-box as well as IoU joins those fragments into one object.

Results

I ran the same YOLOX-S model on three public photos from Wikimedia Commons, once as a single pass and once tiled:

Photo Single pass Tiled
Aerial marina, 3613×2400 5 boats 91 boats
Festival crowd, 3586×2981 18 people 105 people
Parking lot, 2304×2304 18 cars 31 cars

These are detector outputs, not hand-checked counts, but the gap is the point: most of what the single pass missed was simply too small after resizing.

The trade-off

Tiling costs compute. The marina photo needs 35 tiles, so it runs 36 inferences instead of one. Two knobs keep that under control:

  • Only tile images that are meaningfully larger than the model's input. I start at about 1.5× the tile size.
  • Cap the number of tiles per image, and enlarge the tiles when the cap is hit.

When tiling isn't enough

  • Very dense crowds with heavily overlapping heads need density-estimation models, not detectors.
  • Straight-down satellite views of tiny objects need a model trained on overhead imagery; COCO-trained detectors expect side and oblique views.
  • Tiling finds more objects, and more false positives. Raise the confidence threshold or filter to the classes you need.

Try it

If you want to build this yourself, SAHI is a good Python starting point.

If you'd rather pass in image URLs and get counts, boxes and annotated previews back, I packaged this pipeline as Object Counter, priced per image. You can run the same three photos from this post:

Photo credits, all via Wikimedia Commons: aerial marina by GPlantam, CC BY-SA 4.0; festival crowd by Anthony O'Neil, CC BY-SA 2.0; parking lot by Tony Webster, CC BY 2.0. The cover image adapts the marina photo with detection boxes and labels and is shared under CC BY-SA 4.0.