Python부터 Rust까지, Ultralytics YOLO에서 이미지 타일링으로 소형 객체 감지하기
이미지 타일링이 YOLO의 소형 객체 감지에 도움이 되는 경우와 비용을 살펴보고, SAHI 없이 Python 또는 Rust에서 내장 타일 추론을 실행하는 방법을 알아보세요.
Onuralp Sezer13 분 읽기
일반 사진에서는 잘 작동하는 감지기가 드론 영상에 있는 사람 대부분을 놓치는 이유는 무엇일까요? 대개 객체를 원래 크기로 본 적이 없기 때문입니다. 기본값인 imgsz=640에서 Ultralytics YOLO는 모델이 프레임을 살펴보기 전에 1920 x 1080 프레임을 세 번 축소하므로, 키가 15픽셀인 보행자는 약 5픽셀로 작아집니다.
이미지 타일링은 전체 해상도 이미지의 중첩 윈도우에서 모델을 실행하고 결과를 병합해 소형 객체의 세부 정보를 보존할 수 있습니다. 문서에 수록된 VisDrone 프레임 하나에서 Ultralytics YOLO26s의 감지 수는 35개에서 161개로 늘었습니다. 그 대가로 프레임당 처리량이 늘어납니다. 이미지 하나 대신 타일 입력 8개를 처리합니다.
이제 배포 환경의 양쪽 모두에서 타일링을 기본 지원합니다. Python 패키지는 11월 6일 Ultralytics 8.4.204부터 tile 인수를 제공하고, Rust 크레이트는 11월 9일 Ultralytics Inference 0.0.57에서 --tile 플래그를 추가했습니다. 이 가이드에서는 타일링이 소형 객체를 복구하는 경우와 비용, 각 환경에서 실행하는 방법을 다룹니다.
리사이즈로 인해 소형 객체가 가려집니다#
소형 객체 감지가 어려운 이유는 간단합니다. 객체가 가진 픽셀 수에는 한계가 있습니다. 객체 감지 모델은 객체당 몇 개 안 되는 픽셀로부터 형태를 학습합니다. 전체 프레임의 긴 변을 640픽셀로 축소하면 멀리 있는 사람, 차량, 결함은 네트워크가 텍스처와 노이즈로부터 구분할 수 있는 크기보다 작아집니다.
이 문제는 항공 영상, 위성 이미지 분석, 광각 교통·보안 카메라, 고해상도 검사 사진에서 특히 두드러집니다. VisDrone은 널리 사용되는 공개 항공 벤치마크입니다. 문서에 따르면 프레임에서 크기가 수십 픽셀에 불과한 객체들이 밀집해 있고 서로 많이 가려져 있습니다.
타일링은 해당 픽셀을 보존합니다. tile을 모델 입력 크기로 설정하면, 축소된 프레임을 한 번 처리하는 대신 모델이 여러 윈도우를 원본 해상도로 살펴봅니다. 이 방식은 SAHI 논문에서 슬라이싱 지원 하이퍼 추론이라고 부르는 방법으로, 저자들은 VisDrone 및 xView 항공 데이터셋에서 평가했습니다.
고해상도 타일링 가이드에 따르면 기본 신뢰도 임계값에서 1920 x 1080 VisDrone 프레임에 YOLO26s를 적용했을 때, 전체 이미지에 imgsz=640을 사용하면 35개, tile=640를 사용하면 먼 곳의 보행자, 자전거 이용자, 자동차를 포함해 161개를 감지합니다. 가이드에서는 두 이미지를 나란히 보여 줍니다. 이 수치는 예측 개수이지 점수가 산출된 평가 결과가 아닙니다. 두 개수 모두 같은 가중치로 얻었으며, 타일링은 각 윈도우에서 보이는 문맥도 바꿨습니다.

두 번째 1920 x 1080 VisDrone 검증 프레임. 기본 신뢰도에서 YOLO26s는 전체 프레임을 imgsz=640으로 처리할 때 8개, tile=640으로 처리할 때 128개를 감지합니다. 도로 부분을 자른 이미지이며, 클래스 레이블 없이 바운딩 박스만 표시합니다.
타일링은 윈도우마다 모델 입력을 하나씩 추가합니다#
가이드에서는 윈도우 구성을 구체적으로 정의합니다. 윈도우는 기본 20% 겹치며, 마지막 행과 열은 이미지 경계에 맞춰 정렬되므로 가장자리 윈도우는 더 많이 겹칠 수 있습니다. 이미지가 윈도우보다 작으면 전체 이미지를 하나의 윈도우로 처리합니다.
따라서 비용을 쉽게 예측할 수 있습니다. tile=640에서 1920 x 1080 프레임은 가로 4개, 세로 2개로 총 8개 윈도우를 처리합니다. tile=1280에서 3840 x 2160 프레임도 8개를 처리합니다. 3840 x 2160 프레임에 동일한 20% 규칙을 적용하고 tile=640를 사용하면 가로 8개, 세로 4개로 총 32개 윈도우가 만들어집니다. 따라서 4K 프레임에서 윈도우 크기를 절반으로 줄이면 타일 입력 수는 네 배가 됩니다.

1920 x 1080 프레임에서 tile=640으로 사용하는 8개 윈도우: 열은 x = 0, 512, 1024, 1280에서 시작하고 행은 y = 0, 440에서 시작합니다. 음영 영역은 두 개 이상의 윈도우에서 보입니다.
배치 처리 방식에 따라 이러한 입력이 모델에 전달되는 방식이 달라집니다. Python에서는 batch으로 추론 호출 한 번에 모델을 함께 통과하는 윈도우 수를 설정하고, Rust 크레이트에서는 동적 배치 내보내기 모델에 --batch을 사용해 동일하게 설정합니다. 배치 처리는 처리량을 높일 수 있지만, 하드웨어에서 지연 시간을 측정해야 합니다. Ultralytics YOLO를 사용한 배치 추론 가이드에서 그 이유를 설명합니다.
소형 객체에 더 많은 픽셀을 할당하는 다른 방법과 타일링을 비교하면 다음과 같습니다.
| 접근 방식 | 1920 x 1080 프레임의 모델 입력 | 모델이 보는 내용 | 가장 적합한 경우 |
|---|---|---|---|
전체 이미지, imgsz=640 | 1 | 프레임을 3배 축소 | 리사이즈 후에도 객체가 선명하게 보임 |
전체 이미지, imgsz=1280 | 입력 1개, 640 대비 연산량 약 4배 | 프레임을 1.5배 축소 | 메모리와 지연 시간이 허용하는 더 큰 입력 |
tile=True 및 imgsz=640 | 8 | 원본 해상도의 640픽셀 윈도우 | 모델 입력보다 몇 배 더 큰 이미지 |
tile=400 및 imgsz=640 | 8개 초과 | 640픽셀로 확대된 윈도우 | 원본 해상도에서도 너비가 몇 픽셀에 불과한 객체 |
각 타일은 일반 크기의 모델 입력이므로, 타일링을 사용하면 imgsz을 높이지 않고도 매우 큰 이미지를 처리할 수 있습니다. 마스크와 깊이 맵처럼 원본 크기로 출력되는 결과에는 여전히 원본 이미지 크기에 비례하는 메모리가 필요하며, max_det은 유지되는 인스턴스 마스크의 수를 제한합니다.
타일링이 도움이 되는 경우와 방해가 되는 경우#
객체가 프레임에 비해 작고 프레임이 모델 입력보다 훨씬 클 때 타일링이 효과적입니다. 드론·위성 영상, 항공 교통, 군중, 광각으로 촬영한 소매 매대, 보드나 패널 전체를 촬영한 비전 검사 이미지가 여기에 해당합니다.
객체가 클 때는 성능에 악영향을 줍니다. 프레임의 절반을 차지하는 트럭은 윈도우에 일부만 보일 수 있으며, 가이드에서는 이 점을 분명히 설명합니다. 객체가 겹치는 영역보다 크면 어떤 윈도우에도 전체가 보이지 않아 객체가 분할될 수 있고, 병합으로 서로 분리된 조각을 합칠 수는 없습니다. 또한 전역 문맥이 사라지므로, 타일별 출력이 이미지 전체에서 일치하지 않을 수 있는 분류와 깊이 추정에서 특히 문제가 됩니다.
윈도우를 더 작게 설정하면 또 다른 절충이 생깁니다. 400픽셀 윈도우를 640픽셀로 확대하면 너비가 몇 픽셀에 불과한 객체를 처리하는 데 도움이 되지만, 배경의 복잡한 요소도 함께 확대되어 오탐으로 이어질 수 있습니다. 자체 검증 세트에서 타일 크기를 두세 가지 비교하고 정밀도와 재현율을 모두 살펴보세요.
타일을 하나의 결과로 다시 병합하는 방법#
각 윈도우는 윈도우 좌표계로 자체 예측을 생성합니다. 타일링은 예측을 원본 이미지 좌표로 매핑하고 원본 이미지마다 Results 객체 하나를 반환하므로, result.boxes을 읽는 후속 코드는 수정 없이 작동합니다.
겹치는 영역에서는 경계 부근의 객체가 두 번 감지될 수 있습니다. 감지의 경우 iou, agnostic_nms, max_det 설정을 사용한 비최대 억제로 중복을 제거하므로, NMS IoU 임계값 조정 가이드를 타일 출력에 그대로 적용할 수 있습니다. 한 윈도우 경계에 잘린 박스는 다른 윈도우에서 객체가 경계에 걸리지 않은 상태로 보이고 유지된 박스가 해당 객체를 덮으면 제거되므로, 경계에서는 더 완전한 예측이 남습니다. 더 나은 일치 결과가 없는 잘린 박스는 유지됩니다.

같은 프레임에서 y = 640 경계 처리를 설명한 그림입니다. 청록색 박스는 위쪽 행 윈도우의 아래쪽 경계에서 잘렸고, 자홍색 박스는 아래쪽 행 윈도우에서 나왔습니다. 오른쪽 패널은 병합 후 차량마다 더 완전한 박스 하나가 유지된 결과를 보여 줍니다.
Ultralytics YOLO의 각 작업은 고유한 방식으로 결과를 병합합니다.
- 감지, 분할, 포즈 및 OBB는 박스, 마스크, 키포인트 또는 회전 박스를 원본 좌표로 복원하고 박스 선택을 적용하며, OBB에는 회전 NMS를 적용합니다.
- 시맨틱 분할은 클래스 맵을 이어 붙이고 윈도우가 겹치는 영역에서는 중앙에 가장 가까운 타일을 선택합니다.
- 깊이 추정은 겹치는 깊이 맵을 병합하며 각 타일의 중앙에 가까울수록 가중치를 높입니다.
- 분류는 타일 확률의 평균을 계산합니다.
Python 파이프라인은 YOLO-World, YOLOE, RT-DETR, FastSAM 예측에도 타일링을 적용합니다. SAM은 자체 크롭 파이프라인을 사용하며 tile을 지원하지 않습니다.
tile 인수를 사용한 Python 타일 추론#
타일링을 사용하려면 Ultralytics 8.4.204 이상이 필요하며 추가 패키지는 필요하지 않습니다. predict 모드에서 tile=True을 전달하면 imgsz를 윈도우 크기로 사용하고, 정수를 전달하면 윈도우 크기를 별도로 지정합니다.
from ultralytics import YOLO
model = YOLO("yolo26s.pt")
# 기준선: 프레임을 640픽셀로 축소해 한 번 처리
full = model.predict("intersection.jpg", imgsz=640)
# 타일 처리: 원본 해상도의 640픽셀 윈도우를 배치당 8개 처리
tiled = model.predict("intersection.jpg", imgsz=640, tile=640, batch=8)
print(len(full[0].boxes), len(tiled[0].boxes))CLI에서도 yolo predict model=yolo26s.pt source=large-image.tif tile=640 imgsz=640 batch=8을 사용하면 같은 인수를 적용할 수 있습니다. 동영상에서는 메모리 사용량을 제한하기 위해 stream=True을 전달하세요. track 모드에서는 병합된 예측을 대상으로 프레임마다 트래커를 한 번 실행합니다.
타일링은 예측에만 사용하는 기능이 아닙니다. 이미지가 imgsz보다 훨씬 크다면 학습과 검증에도 동일한 설정을 사용하세요.
model.train(data="aerial.yaml", tile=True, imgsz=640)을 사용해 타일로 학습합니다. 레이블은 각 윈도우에 맞춰 잘리고, 원래 박스 면적의 10% 미만만 남는 인스턴스는 제거되며, 비어 있는 윈도우는 음성 예제로 유지됩니다.model.val(data="aerial.yaml", tile=True, imgsz=640)을 사용해 병합된 결과로 검증합니다. 예측은 원본 주석과 비교해 점수를 계산하기 전에 병합되므로, mAP는 실제 배포 시의 성능을 반영합니다.- 학습 시 타일을 섞어 사용하고 같은 대용량 이미지를 여러 번 디코딩하지 않도록
cache="ram"으로 대용량 원본을 캐시합니다. - 타일 모델을 사용하기 전에 동일한 검증 분할에서 전체 이미지 기준선과 비교합니다. 소형 객체의 점수를 높이는 방법은 소형 객체 mAP 체크리스트를 참조하세요.
타일 학습을 사용하면 모델은 타일 예측 시 접하게 될 크기의 객체를 학습합니다. 드론 감지 데이터셋 가이드에서는 4K 프레임을 사용해 학습, 타일링, 평가 전체 과정을 안내합니다.
내보낸 모델에도 타일링을 적용할 수 있습니다. 타일링은 Python 예측 파이프라인에서 실행되므로, ONNX 또는 TensorRT로 내보낸 모델은 일반 입력 그래프를 유지하며, 고정된 내보내기 배치 크기와 마지막 불완전 배치를 포함해 YOLO("yolo26s.onnx").predict(source, tile=640)도 정상적으로 작동합니다.

Ultralytics Platform의 VisDrone 데이터셋은 자체 데이터에 레이블을 지정하기 전에 타일 크기를 테스트할 수 있는 준비된 벤치마크입니다.
먼저 공개 데이터에서 타일 크기를 시험하려면 Ultralytics Platform의 VisDrone 데이터셋으로 시작하세요. 기준선과 함께 타일 실행을 추적하려면 Platform 학습 대화상자에서 Local Training 명령을 복사하고, project를 기준선의 Platform 프로젝트로 설정한 다음, tile=True을 추가해 타일 실행의 메트릭을 해당 프로젝트로 전송하세요.
새로운 --tile 플래그를 사용한 Rust 타일 추론#
Ultralytics Inference는 Rust 크레이트이자 CLI로, 추론 시 Python 런타임 없이 내보낸 ONNX 모델을 ONNX Runtime으로 실행하고 OpenVINO IR 모델을 기본 방식으로 실행합니다. 서버, 컨테이너, CPU, CUDA, TensorRT, CoreML, OpenVINO 및 기타 실행 공급자를 사용하는 엣지 디바이스를 대상으로 합니다. 버전 0.0.57은 기본 20% 윈도우 겹침, 원본 이미지 좌표로 결과 매핑, 클래스별 중복 제거 등 Python과 동일한 타일링 방식을 제공합니다.

예시 이미지입니다. Rust 크레이트가 목표로 하는 Python 런타임 없는 배포에 사용되는 도로변 카메라와 엣지 컴퓨터입니다.
팀은 ONNX Runtime CPU, OpenVINO CPU, GPU 및 NPU, CUDA, TensorRT 환경에서 이미지, 동영상, 웹캠을 대상으로 타일 출력을 Ultralytics Python과 비교했습니다. 감지, 분할, 시맨틱 분할, 깊이 추정, 분류, 포즈, OBB 모델을 모두 지원합니다.
CLI에서 윈도우 크기와 함께 --tile을 추가하거나, 플래그만 전달해 --imgsz을 사용하세요. 모델 내보내기는 Python에서 한 번만 수행하면 되며, 추론에는 Rust 바이너리만 필요합니다.
# One-time export in Python: a dynamic-batch ONNX model so several windows run per call
pip install -U "ultralytics[export-base]>=8.4.204"
yolo export model=yolo26s.pt format=onnx dynamic=True
# Install the Rust CLI
cargo install ultralytics-inference
# Tiled inference on a large image: 640-pixel windows, 8 per batch
ultralytics-inference predict --model yolo26s.onnx --source aerial.jpg --tile 640 --batch 8라이브러리로 사용할 때는 InferenceConfig에서 타일링을 한 번 설정하면 모든 predict 호출에 타일링이 적용됩니다. with_tile(0)는 추론 크기를 사용합니다.
use ultralytics_inference::{InferenceConfig, YOLOModel};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = InferenceConfig::new().with_tile(640);
let mut model = YOLOModel::load_with_config("yolo26s.onnx", config)?;
let results = model.predict("aerial.jpg")?;
if let Some(ref boxes) = results[0].boxes {
println!("{} detections", boxes.len());
}
Ok(())
}윈도우 간 중복 박스는 설정된 --iou에 따라 클래스별 NMS로 제거됩니다. 동일한 릴리스부터 기본값은 0.5로, Ultralytics 예측 기본값과 일치합니다. 윈도우마다 모델 입력이 추가되므로 타일링은 기본적으로 비활성화되어 있습니다. 세부 정보가 중요한 경우 활성화하고 대상 디바이스에서 추론 지연 시간을 측정한 다음 적합한 실행 공급자를 선택하세요. NVIDIA 하드웨어에서는 ONNX와 TensorRT 비교가 도움이 되며, NVIDIA Jetson 가이드에서는 디바이스 설정을 다룹니다.
SAHI 사용자는 내장 tile 인수로 전환할 수 있습니다#
이미지 슬라이싱에 SAHI 라이브러리를 사용하고 있다면, 내장 인수로 추가 패키지나 별도의 결과 형식 없이 Ultralytics 내에서 동일한 작업을 수행할 수 있습니다. SAHI 통합 가이드는 이제 tile을 사용하는 방식으로 대체되어 더 이상 권장되지 않습니다.
SAHI 스크립트를 이전하려면 대부분 인수만 변경하면 됩니다.
| SAHI | 내장 타일링 |
|---|---|
AutoDetectionModel.from_pretrained(model_type="ultralytics", ...) | YOLO("yolo26s.pt") |
get_sliced_prediction(image, model, slice_height=256, slice_width=256, ...) | model.predict(image, tile=256) |
overlap_height_ratio, overlap_width_ratio | 고정된 기본 20% 겹침, 이미지 경계에 맞춰 정렬되는 가장자리 윈도우 |
SAHI PredictionResult | 표준 Ultralytics Results |
윈도우는 정사각형이며, 겹침과 병합은 SAHI의 설정 가능한 후처리가 아니라 위에서 설명한 규칙을 따르므로 박스 결과는 비슷하지만 동일하지 않을 수 있습니다. 전환 후에는 검증 세트에서 임계값을 다시 확인하세요.
실질적인 차이는 통합에 있습니다. tile은 동일한 인수로 Ultralytics의 학습, 검증, 예측, 추적에 통합되고 표준 Results 객체를 반환하며 Rust 크레이트에서도 동일한 옵션을 제공합니다. 따라서 노트북에서 검증한 타일 크기를 엣지의 Rust 바이너리에서도 그대로 사용할 수 있습니다.
타일링을 활성화해야 하는 대상#
Ultralytics YOLO를 모델 입력보다 몇 배 큰 이미지에 적용하고 검증 결과에서 놓친 소형 객체가 확인된다면 타일링을 활성화하세요. 드론·위성 팀, 광각 카메라를 사용하는 교통·보안 통합업체, 보드·패널·매대 전체를 촬영하는 검사 팀이 여기에 해당합니다. Rust 사용자는 Python 런타임 없이 엣지 하드웨어에서 동일한 타일링 방식을 사용할 수 있습니다.
객체가 프레임에 비해 크거나, 더 큰 imgsz으로 한 번에 처리해 이미 객체를 복구할 수 있거나, 프레임당 여러 타일 입력으로 인해 지연 시간 예산을 초과한다면 타일링을 비활성화하세요. 어떤 경우든 동일한 검증 분할과 신뢰도 임계값에서 타일 결과와 전체 이미지 결과를 비교하고 재현율, 오탐, 지연 시간을 확인하세요. 추가 처리 비용을 감수할 만큼 이점이 있는 경우에만 타일링을 유지하세요.
Ultralytics Platform에서 이러한 비교를 한곳에서 진행할 수 있습니다. 자체 고해상도 이미지에 레이블을 지정하거나 VisDrone을 사용하고, 클라우드 GPU에서 전체 이미지 기준선을 학습한 다음 더 큰 imgsz로 또 다른 기준선을 학습하고, 자체 컴퓨터에서 실행한 타일 실험의 결과를 같은 프로젝트에 기록하세요. 고해상도 타일링 가이드에서는 타일링 옵션을 자세히 설명하고, Ultralytics Inference 문서에서는 Rust 배포를 다룹니다.
Python 패키지와 Rust 크레이트는 모두 AGPL-3.0 라이선스로 제공됩니다. 타일 감지를 폐쇄형 제품이나 고객에게 배송하는 엣지 디바이스에 적용하려는 경우, Ultralytics Enterprise License를 사용하면 약관에 따라 대상 Ultralytics 소프트웨어를 AGPL-3.0의 소스 공개 의무 없이 상업적으로 사용할 수 있습니다.
자주 묻는 질문
이미지 타일링은 큰 이미지를 겹치는 윈도우로 분할하고 각 윈도우에서 감지기를 실행한 뒤 박스를 원본 이미지에 다시 병합하는 방식입니다. 윈도우 크기가 모델 입력 크기와 같으면 전체 이미지를 리사이즈할 때 사라지는 픽셀을 소형 객체에 유지할 수 있습니다. Ultralytics YOLO의
tile인수는 기본 20% 겹침으로 이 작업을 수행하고 이미지마다 결과 하나를 반환합니다.먼저 리사이즈가 문제인지 확인하세요.
imgsz=640에서 객체가 몇 픽셀로 축소된다면 더 큰imgsz또는tile=True를 테스트하세요. 예측에 사용할 설정과 동일한 설정으로 학습해 모델이 배포 시 크기의 객체를 학습하게 하고, 크기 및 클래스별로 검증하세요. 타일링은 이미지가 모델 입력보다 몇 배 더 큰 경우에 적합합니다.윈도우마다 모델 입력이 하나씩 추가됩니다.
tile=640에서 1920 x 1080 프레임은 이미지 하나 대신 타일 입력 8개를 생성합니다. Python에서batch을 사용하거나 Rust에서 동적 배치 내보내기와 함께--batch를 사용해 여러 타일을 한 번의 배치 호출로 실행하면 처리량을 높일 수 있습니다. 대상 하드웨어에서 지연 시간을 측정하세요.아니요. Ultralytics 8.4.204부터 내장
tile인수로 추가 패키지 없이 슬라이스 추론을 처리할 수 있으며 학습, 검증, 추적에도 타일링을 적용할 수 있습니다. 문서의 SAHI 가이드는 이제tile을 사용하는 방식으로 대체되어 더 이상 권장되지 않습니다.예. Python에서는 내보낸 모델이 일반 입력 그래프를 유지하며 평소처럼
predict에tile을 전달합니다. Rust에서는 Ultralytics Inference 0.0.57이 CLI에--tile를,InferenceConfig에with_tile을 추가했으며, ONNX Runtime CPU, OpenVINO, CUDA, TensorRT에서 Python과 비교 검증했습니다.창 크기로
imgsz을 사용하는tile=True으로 시작합니다. 기본 해상도에서도 객체의 너비가 몇 픽셀에 불과한 경우에는imgsz=640과 함께tile=400와 같은 더 작은 창을 사용하고, 객체가 경계 부분에서 잘릴 우려가 있는 경우에는 더 큰 창을 사용합니다. 검증 세트에서 몇 가지 크기를 비교하면서 재현율과 오탐을 모두 확인합니다.
작성자
댓글
질문하거나 결과를 공유하거나 다른 사람을 도와주세요.










