from pathlib import Path
from ultralytics import YOLOE
p = Path.home() / "Downloads"
f = p / "boxes.jpg"
model = YOLOE("yoloe-11l-seg.pt") # Large segmentation model
names = [
"box",
"bin",
"handtruck",
"person",
"garage door",
"forklift",
"pallet",
"",
] # other classes that might be in the image to help separate detections
model.set_classes(names, model.get_text_pe(names))
results = model.predict(f, iou=0.11, conf=0.06)
results[0].show(masks=True, labels=False)
Ryan’s question gets to the core of it: with one fixed 2D RGB view, even perfect Ultralytics YOLO detection can only count boxes that are at least partly visible. Fully hidden boxes are not recoverable from a single image, so the first step is defining whether you want a visible-box count or an estimated total-stack count.
Burhan’s YOLOE result is a solid front end, but the counting logic has to sit on top of it. In practice, the most reliable setup here is segmentation + homography + layout prior: rectify the pallet/camera plane, segment visible box faces, then fit a grid using known box size and pallet dimensions to infer missing occluded slots. For cropped boxes, use a strict ROI rule, like counting only boxes whose centroid is inside the pallet region, and flag edge cases as uncertain.
If you have video instead of a single frame, tracking across frames helps a lot since a box partially hidden in one frame may be clearer in another. For new experiments, I’d test Ultralytics YOLO26-seg or obb, but the biggest gain here usually comes from geometry constraints, not just switching models.
If the box size and pallet pattern are consistent, this is very workable. If they vary a lot, exact total count from one view will stay inherently ambiguous.