Last Updated on 27/11/2025 by Eran Feit
YOLOv8 small object detection sits at the intersection of two big needs in modern computer vision: real-time performance and the ability to reliably detect tiny targets in busy, high-resolution scenes. While classic detectors can easily find large, clear objects, they often struggle when cars become just a few pixels wide in a traffic camera, or when tiny drones and pests appear in aerial images. YOLOv8 brings a fast and accurate baseline for detection, and when it is tuned specifically for small objects, it becomes a powerful tool for real-world applications.
Small objects are hard because they occupy a very small portion of the image and get heavily downsampled as they move through the convolutional layers of a network. In remote sensing, UAV imagery, or surveillance scenarios, this means that people, vehicles, and other targets can almost disappear in the deeper layers of a model, leading to missed detections and low confidence scores. Recent research on YOLOv8 variants for aerial and remote-sensing imagery shows just how much care is needed to recover those tiny targets and keep mean average precision high.
To make YOLOv8 small object detection practical, developers combine the native multi-scale design of YOLOv8 with additional strategies such as higher input resolutions, improved feature fusion, attention mechanisms, and sliced or tiled inference. Libraries like SAHI (Slicing Aided Hyper Inference) focus exactly on this problem: they cut large images into overlapping patches, run detection on each patch, and then merge the results, effectively giving small objects more pixels and more attention from the model.
The result is a workflow where YOLOv8 remains fast and easy to use, but suddenly becomes far more reliable in scenarios that used to be “blind spots”: distant pedestrians on a highway, clusters of vehicles in a city from a drone, or densely packed pests on leaves in an agricultural field. With the right configuration and a sliced-inference pipeline, YOLOv8 small object detection can move from a nice demo to a production-ready component in traffic analytics, smart farming, security monitoring, and many other domains.

Why YOLOv8 small object detection is so important today
The main goal of YOLOv8 small object detection is to accurately find and label very small targets in large or complex images without sacrificing real-time performance. In many practical systems, the most critical objects are also the smallest: a pedestrian far from the camera in an ADAS system, a tiny UAV in a wide sky, or insects scattered across high-resolution crop images. Missing these targets is not just a minor accuracy issue; it can break an entire application. Making YOLOv8 sensitive to these small patterns while keeping latency low is therefore a key requirement for real deployments.
At a high level, YOLOv8 is built around three main blocks: a backbone that extracts visual features, a neck that fuses multi-scale information, and a head that predicts bounding boxes and class scores. This architecture is designed to capture objects at different sizes by aggregating features at multiple resolutions. YOLOv8 also introduces improvements over earlier YOLO versions, such as an anchor-free head and optimized feature fusion, which help it adapt better to diverse object scales and complex backgrounds.
However, even with a strong architecture, standard full-image inference has limits when objects shrink below a certain size. Downsampling and pooling can compress a tiny car or drone into just a handful of activations, making it easy for the network to ignore. That is where sliced inference comes in. SAHI extends the pipeline by splitting the original image into overlapping tiles, running YOLO on each tile at a higher effective resolution, and then mapping all predictions back to the original coordinates. This technique gives small objects more pixels and clearer context, which significantly boosts their detection accuracy without needing to retrain the core model.
In practice, a YOLOv8 small object detection workflow often means loading a pretrained YOLOv8 model, wrapping it with SAHI’s sliced inference utilities, and tuning parameters such as slice size, overlap ratio, and confidence thresholds. The heavy lifting—running detection on each patch and merging duplicate boxes—is handled automatically by the library. This allows you to focus on dataset choice, evaluation metrics, and visualization rather than manually implementing tiling logic yourself. It also scales well: the same approach can be reused across different domains, from traffic analytics to agriculture or marine monitoring, wherever small objects play an outsized role.

Getting hands-on with YOLOv8 small object detection
This tutorial is all about turning the theory of YOLOv8 small object detection into a simple, repeatable Python script you can actually run.
Instead of starting from a huge framework, the code focuses on a single, clear use case: detecting cars and other objects in an image where some targets are relatively small or far from the camera.
The goal is to show you how to set up the environment, load a pretrained YOLOv8 model, combine it with SAHI, and visually compare “normal” detection to sliced inference on the same image.
The code begins with the practical foundations: creating a dedicated Conda environment, installing PyTorch with CUDA support, and then adding the ultralytics and sahi libraries.
This makes the script self-contained and easy to debug, because all dependencies live in a clean environment tailored for object detection work.
Once the environment is ready, the script downloads the YOLOv8 medium model, so you can start experimenting without training your own network.
From there, the tutorial walks through a straightforward inference pipeline.
An input image is loaded with OpenCV, resized to a more manageable scale, and passed once through YOLOv8 for a standard “full image” prediction.
You see how easy it is to run model(img) and get annotated results that already detect cars and other visible objects.
This part of the code sets a baseline: what YOLOv8 can do on its own, without any special tricks for small objects.
The second half of the script introduces SAHI and its sliced prediction workflow.
Instead of feeding the entire image at once, the code uses get_sliced_prediction to cut the image into overlapping tiles, run YOLOv8 on each tile, and then merge all predictions back together.
This effectively zooms in on small objects, giving them more pixels and a better chance to be detected.
You then loop over the resulting bounding boxes, draw them with OpenCV, and display a side-by-side comparison of the simple YOLOv8 output versus the YOLOv8+SAHI output.
The final result is a compact tutorial script that shows, in a very visual way, how sliced inference can significantly improve YOLOv8 small object detection on real images.
Link to the video tutorial : https://youtu.be/e0nsRGwd82s
You can download the code here : https://eranfeit.lemonsqueezy.com/buy/e102b217-e1a1-4a35-aabe-88eb8ddaf685 or here : https://ko-fi.com/s/44116d7409
Link to medium users : https://medium.com/@feitgemel/how-to-detect-small-objects-with-yolov8-and-sahi-67702073c612
You can follow my blog here : https://eranfeit.net/blog/
Want to get started with Computer Vision or take your skills to the next level ?
If you’re just beginning, I recommend this step-by-step course designed to introduce you to the foundations of Computer Vision – Complete Computer Vision Bootcamp With PyTorch & TensorFlow
If you’re already experienced and looking for more advanced techniques, check out this deep-dive course – Modern Computer Vision GPT, PyTorch, Keras, OpenCV4
How to Detect Small Objects with YOLOv8 and SAHI
YOLOv8 small object detection becomes really interesting when you move from “big and obvious” objects to tiny cars, people, or drones that occupy just a few pixels in a large image.
In those cases, even a strong detector can miss targets simply because there is not enough detail after downsampling.
This tutorial shows a practical way to handle that problem by combining YOLOv8 with SAHI (Slicing Aided Hyper Inference).
You will first run a simple YOLOv8 prediction on a full image and then use SAHI to slice the same image into overlapping tiles, detect objects on each tile, and merge the results.
The code walks through the full pipeline: creating a clean Conda environment, installing PyTorch with CUDA, adding YOLOv8 and SAHI, downloading a pretrained YOLOv8 model, and finally drawing bounding boxes with OpenCV.
By the end of this post you will have a clear, copy-paste friendly script that visually compares plain YOLOv8 detection against a YOLOv8+SAHI sliced setup for small object detection.
Setting up the environment for YOLOv8 and SAHI
Before writing any Python, it is best to isolate the project in its own Conda environment.
This keeps your YOLOv8 small object detection experiments clean, reproducible, and independent from other projects on the same machine.
In this first block you will create and activate a Conda environment, check that CUDA is available, install a CUDA-enabled PyTorch stack, and then add the Ultralytics YOLOv8 and SAHI libraries.
Once this is done, you are ready to run the rest of the tutorial code on GPU or CPU without version conflicts.
### Create a new Conda environment dedicated to YOLOv8 small object detection with SAHI.
conda create --name yolo8_sahi python=3.8
### Activate the environment so that all packages are installed in an isolated space.
conda activate yolo8_sahi
### Check that the NVIDIA CUDA compiler is available and confirm the installed CUDA toolkit version.
nvcc --version
### Install PyTorch, Torchvision, and Torchaudio with CUDA 11.8 support from the official PyTorch and NVIDIA channels.
conda install pytorch==2.1.1 torchvision==0.16.1 torchaudio==2.1.1 pytorch-cuda=11.8 -c pytorch -c nvidia
### Install the Ultralytics package that provides the YOLOv8 implementation used in this tutorial.
pip install ultralytics==8.1.0
### Install the SAHI library, which adds sliced inference for better small object detection.
pip install sahi
After running these commands you have a clean environment configured for YOLOv8 small object detection with SAHI.
If anything breaks later, you can simply recreate the same environment with these few lines.
Loading YOLOv8, preparing the image, and configuring SAHI
Now that the environment is ready, the next step is to load the required libraries, download a pretrained YOLOv8 model, and prepare the input image.
In this tutorial, the target is to detect cars and other objects in an image where some of them are relatively small or far away from the camera.
The code below imports OpenCV, SAHI utilities, and the YOLO class from Ultralytics.
It then points to a local image, sets the model path, downloads the YOLOv8m weights if they are not already present, and wraps the model in a SAHI AutoDetectionModel configured with a confidence threshold and device selection.
Finally, it loads the original image with OpenCV, scales it down to a more manageable size, and keeps a resized copy ready for the next steps.
Here is our test image :

### Import OpenCV so we can load images, resize them, draw bounding boxes, and display windows.
import cv2
### Import the AutoDetectionModel wrapper from SAHI to connect YOLOv8 with sliced inference.
from sahi import AutoDetectionModel
### Import the get_sliced_prediction helper to run SAHI’s tiled small object detection.
from sahi.predict import get_sliced_prediction
### Import a convenience function that downloads the YOLOv8m model weights if needed.
from sahi.utils.yolov8 import download_yolov8m_model
### Import the YOLO class from Ultralytics so we can run standard YOLOv8 inference.
from ultralytics import YOLO
### Define the path to the input image that contains cars and other objects we want to detect.
img_path = "Best-Object-Detection-models/Yolo-V8/yolov8-sahi-Detect-Objects/cars.jpg"
### Define the filename of the YOLOv8 model we plan to use.
model_path = "yolov8m.pt"
### Build the full path where the YOLOv8 model file will be stored locally.
yolov8_model_path = f'models/{model_path}'
### Download the YOLOv8m model weights into the models folder if they are not already there.
download_yolov8m_model(yolov8_model_path)
### Create a SAHI AutoDetectionModel that wraps the YOLOv8 model for sliced small object detection.
detection_model = AutoDetectionModel.from_pretrained(
model_type='yolov8',
model_path=yolov8_model_path,
confidence_threshold=0.6,
device='cpu'
)
### Load the original image from disk using OpenCV.
img_original = cv2.imread(img_path)
### Define the desired scaling percentage to shrink the image for faster experiments.
scale_precent = 30
### Compute the new width based on the original width and the chosen scale percentage.
w = int(img_original.shape[1] * scale_precent / 100)
### Compute the new height based on the original height and the chosen scale percentage.
h = int(img_original.shape[0] * scale_precent / 100)
### Pack the resized width and height into a dimension tuple for OpenCV.
dim = (w, h)
### Resize the original image to the new dimensions using an interpolation method suited for shrinking.
img_original = cv2.resize(img_original, dim, interpolation=cv2.INTER_AREA)
At this point you have a resized image in memory and a YOLOv8 model that can be used both for simple full-image prediction and for SAHI-powered sliced inference.
The confidence threshold and device can easily be adjusted later if you move from CPU to GPU or want stricter filtering of low probability detections.
Running YOLOv8 and SAHI to get predictions
In this part we focus on the actual detection step.
First, we run a simple YOLOv8 inference on the resized image to get a baseline prediction.
Then we apply SAHI’s sliced inference on a copy of the same image and convert the resulting objects into two simple Python lists: one for bounding box coordinates and one for class names.
These lists will be used in the next part to draw bounding boxes and labels on the image.
### Make a copy of the resized image that will be used for the plain YOLOv8 prediction.
img2 = img_original.copy()
### Load the YOLOv8 model from the local model file so we can run standard object detection.
model = YOLO(model_path)
### Run YOLOv8 inference on the image copy with a confidence threshold of 0.6.
results = model(img2, conf=0.6)
### Convert the first YOLOv8 result into an annotated frame with bounding boxes and labels.
annotated_frame = results[0].plot()
### Make another copy of the resized image that will be used for YOLOv8 + SAHI sliced inference.
img = img_original.copy()
### Run SAHI sliced prediction on the image using the wrapped YOLOv8 detection model.
results = get_sliced_prediction(
img,
detection_model,
slice_height=512,
slice_width=512,
overlap_height_ratio=0.2,
overlap_width_ratio=0.2
)
### Extract the list of individual object predictions produced by SAHI.
object_predicition_list = results.object_prediction_list
### Prepare an empty list to store bounding box coordinates for each detected object.
boxes_list = []
### Prepare an empty list to store the class names for each detected object.
clss_list = []
### Loop over each object prediction in the SAHI result.
for ind, _ in enumerate(object_predicition_list):
### Extract the bounding box coordinates (min x, min y, max x, max y) for the current prediction.
boxes = (
object_predicition_list[ind].bbox.minx,
object_predicition_list[ind].bbox.miny,
object_predicition_list[ind].bbox.maxx,
object_predicition_list[ind].bbox.maxy
)
### Extract the category name (class label) for the current prediction.
clss = object_predicition_list[ind].category.name
### Append the bounding box coordinates to the list of boxes.
boxes_list.append(boxes)
### Append the class name to the list of class labels.
clss_list.append(clss)
### Print the list of detected class names to the console for a quick sanity check.
print(clss_list)
After this block finishes, you already have detections from both plain YOLOv8 and YOLOv8+SAHI.
The boxes_list and clss_list variables hold everything you need to visualize and compare small object detections in a clear way.
Drawing bounding boxes and visualizing the results
Now that we have the predictions collected, this part is all about visualization.
We loop over each bounding box and class label, draw a colored rectangle and a solid label background, and put readable text on top with OpenCV.
Finally, we open two windows: one for the SAHI-enhanced detections and one for the simple YOLOv8 output, so you can see how much sliced inference helps with small objects.
### Loop over each bounding box and its corresponding class name together.
for box, cls in zip(boxes_list, clss_list):
### Unpack the bounding box coordinates into separate variables.
x1, y1, x2, y2 = box
### Draw a rectangle around the detected object on the SAHI image copy.
cv2.rectangle(img, (int(x1), int(y1)), (int(x2), int(y2)), (56, 56, 255), 2)
### Convert the class label to a string so it can be drawn on the image.
label = str(cls)
### Measure the size of the text in pixels so we can reserve space for a solid label background.
t_size = cv2.getTextSize(label, 0, fontScale=0.6, thickness=1)[0]
### Draw a filled rectangle above the bounding box to use as a background for the label text.
cv2.rectangle(
img,
(int(x1), int(y1) - t_size[1] - 3),
(int(x1) + t_size[0], int(y1) + 3),
(56, 56, 255),
-1
)
### Put the class label text on top of the colored rectangle using a readable font.
cv2.putText(
img,
label,
(int(x1), int(y1) - 2),
cv2.FONT_HERSHEY_SIMPLEX,
0.7,
[255, 255, 255],
thickness=2,
lineType=cv2.LINE_AA
)
### Open a window that shows the YOLOv8 + SAHI sliced inference result with all drawn boxes and labels.
cv2.imshow("Yolo V8 SAHI", img)
### Open another window that shows the simple YOLOv8 prediction without SAHI for comparison.
cv2.imshow("Yolo V8 Simple prediction", annotated_frame)
### Wait indefinitely for a key press so you have time to inspect the detection windows.
cv2.waitKey(0)
### Close all OpenCV windows gracefully after a key is pressed.
cv2.destroyAllWindows()
After running this block, you will see a clear visual comparison between the two approaches.
If your scene contains many small or distant objects, the YOLOv8+SAHI window should reveal detections that were missing or less accurate in the simple YOLOv8 view.
The result :

Conclusion
YOLOv8 small object detection is a powerful tool, but it truly shines when paired with the right inference strategy.
By combining YOLOv8 with SAHI, you move beyond simple full-image predictions and give your model a better view of tiny details that would otherwise be lost during downsampling.
In this tutorial you set up a dedicated Conda environment, installed GPU-ready PyTorch, and added both the Ultralytics and SAHI libraries.
You then downloaded a YOLOv8m model, wrapped it in SAHI’s AutoDetectionModel, and prepared an image that simulates a realistic scene where small objects matter.
The final comparison between plain YOLOv8 and YOLOv8+SAHI clearly shows how tiled inference can recover extra detections and sharpen bounding boxes on distant cars or other small targets.
This pattern is easy to extend.
You can plug in your own YOLOv8 weights trained on custom datasets, adjust slice sizes and overlaps to match your image resolution, and even move from single images to full video pipelines.
Once you are comfortable with this workflow, YOLOv8 plus SAHI becomes a reusable building block you can apply to traffic analysis, aerial mapping, smart agriculture, medical imaging, and any project where small objects carry big importance.
Connect :
☕ Buy me a coffee — https://ko-fi.com/eranfeit
🖥️ Email : feitgemel@gmail.com
🤝 Fiverr : https://www.fiverr.com/s/mB3Pbb
Enjoy,
Eran
