AI연구회
경남ICT협회 AI 연구 모임
작은 물체 감지는 비디오 피드나 이미지에서 작은 물체를 정확하게 식별하는 것을 목표로 하는 컴퓨터 비전 문제입니다. 물체 자체가 반드시 작을 필요는 없습니다. 예를 들어, 작은 물체 감지는 항공 컴퓨터 비전에서 매우 중요하며, 각 개별 물체가 사진 크기에 비해 작더라도 물체를 정확하게 식별할 수 있어야 합니다.
컴퓨터 비전 파이프라인에는 작은 물체를 감지하기 위한 최적화를 할 수 있는 두 단계가 있습니다.
두 단계 모두 최적화하여 감지 성능을 개선할 수 있습니다.
이 가이드에서는 두 단계 모두에서 최적화를 수행하는 방법을 안내합니다.
공공 항공 해상 데이터세트 에서 드론이 위에서 본 작은 물체
작은 물체를 효과적으로 식별하는 방법에 대해 이야기하기 전에 대답해야 할 근본적인 질문이 하나 있습니다. 애초에 이미지나 비디오에서 작은 물체를 찾는 것이 왜 그렇게 어려운가요?
작은 물체 문제는 전 세계적으로 물체 감지 모델을 괴롭히고 있습니다. 구매하지 않습니까? 최신 최신 모델 YOLOv3 , EfficientDet 및 YOLOv4 에 대한 COCO 평가 결과를 확인하세요 .
최신 모델을 보려면 AP_S, AP_M, AP_L을 확인하세요. 작은 물체는 어렵다! ( 인용하다 )
예를 들어 EfficientDet 에서 작은 물체의 평균 정밀도(mAP )는 12%에 불과하며, 큰 물체의 AP는 51%입니다. 거의 5배 정도 차이가 나네요!
그렇다면 작은 물체를 감지하는 것이 왜 그렇게 어려울까?
모든 것은 모델에 달려 있습니다. 객체 감지 모델은 합성곱 레이어에서 픽셀을 집계하여 특징을 형성합니다.
PP-YOLO 의 객체 감지를 위한 기능 집계
그리고 네트워크의 마지막에는 손실 함수를 기반으로 예측이 이루어지며, 이 손실 함수는 예측과 실제 결과의 차이를 기반으로 픽셀 전체에서 합산됩니다.
YOLO의 손실 함수
기준 진실 상자가 크지 않으면 학습이 진행되는 동안 신호가 작아집니다.
또한 작은 물체에는 데이터 라벨링 오류가 있을 가능성이 가장 높으며 식별이 생략될 수 있습니다.
경험적으로나 이론적으로 작은 물체는 단단합니다.
번화한 거리, 도시의 드론 영상, 수평선 근처의 파도를 타는 서퍼 등 순진하게 실행되는 객체 감지 모델은 종종 좋지 않은 결과를 낳습니다. 주된 이유는 더 큰 물체에 대해 훈련된 모델이 작은 세부 사항을 놓치기 때문입니다.
yolov8s-640은 거의 아무것도 감지하지 못합니다!
이를 해결하려면 yolov8s-1280 과 같은 고해상도 이미지에서 학습된 모델 을 사용할 수 있습니다 . 그러나 이 문제에 대한 우리의 접근 방식 은 InferenceSlicer 입니다 .
이 글에서는 그 사용 방법을 설명하고 두 가지 최신 기능을 강조하겠습니다.
전체 장면에서 모델을 실행하는 대신 모델을 InferenceSlicer더 작은 부분(슬라이스)으로 분할하고 각 부분에서 모델을 실행한 다음 결과를 함께 연결합니다. 일반적으로 이는 SAHI 로 알려져 있습니다 .
InferenceSlicer
사용은 InferenceSlicer간단합니다.
import supervision as sv from inference import get_model model = get_model(model_id="yolov8m-640") image = cv2.imread(<SOURCE_IMAGE_PATH>) def callback(image_slice: np.ndarray) -> sv.Detections: results = model.infer(image_slice)[0] return sv.Detections.from_inference(results) slicer = sv.InferenceSlicer(callback=callback) detections = slicer(image)
결과를 보려면 이미지에 주석을 달면 됩니다.
annotated_frame = sv.BoundingBoxAnnotator().annotate( scene=image.copy(), detections=detections )
InferenceSlicer를 사용한 yolov8s-640의 성과가 훨씬 더 좋았습니다.
시간이 훨씬 오래 걸렸지만 모델은 물 속에 있는 모든 사람을 감지했습니다.
우리가 실행한 코드는 다음과 같습니다.
import supervision as sv from inference import get_model import cv2 image = cv2.imread("beach.jpg") model = get_model("yolov8s-640") def slicer_callback(slice: np.ndarray) -> sv.Detections: result = model.infer(slice)[0] detections = sv.Detections.from_inference(result) return detections slicer = sv.InferenceSlicer( callback=slicer_callback, slice_wh=(512, 512), overlap_ratio_wh=(0.4, 0.4), overlap_filter_strategy=sv.OverlapFilter.NONE ) detections = slicer(image) annotated_frame = sv.BoundingBoxAnnotator().annotate( scene=image.copy(), detections=detections )
이 모든 매개변수는 무엇입니까? 더 자세히 살펴보겠습니다.
slice_wh
overlap_ratio_wh
(0, 0)
(0.2, 0.2)
callback
np.ndarray
sv.Detections
cv2.imread
thread_workers
1
overlap_filter_strategy
iou_threshold
특성상 일부 모델은 여러 개의 중첩 감지를 생성합니다. 설정 overlap_ratio_wh도 기여합니다. 이전 해변 예에서는 575개의 탐지로 끝났지만 실제 개수는 280에 가깝습니다. 어떻게 도달합니까?
해변의 예에서는 겹치는 부분을 보기 어렵기 때문에 간단한 이미지를 분석해 보겠습니다. 로 다음을 감지했다고 가정합니다 overlap_filter_strategy = sv.OverlapFilter.NONE. 모든 탐지 항목을 볼 수 있지만 개선의 여지가 있습니다.
overlap_filter_strategy = sv.OverlapFilter.NONE
앞 차량과 밴에서 중복되는 영역이 여러 개 감지되었습니다.
기본적으로 비최대 억제InferenceSlicer (NMS)를 수행하여 일부 감지를 억제합니다. 요점은 상당한 중복이 있는 감지가 발견될 때마다 가장 높은 신뢰도를 가진 감지를 유지하고 다른 감지는 삭제한다는 것입니다. 매개변수를 설정하여 이를 제어할 수 있습니다. 값이 낮을수록 더 많은 감지가 삭제됩니다.InferenceSlieriou_threshold
InferenceSlieriou_threshold
관심이 있으시다면 Piotr가 NumPy를 사용한 Non-Max Suppression 에 대한 심층 분석을 작성했습니다 .
자동차에서 중복 감지는 삭제되었습니다! 하지만 밴에서도 하나 삭제되었습니다.
에서는 supervision v0.21.0더 많은 필터링 전략을 도입했습니다. 을 설정하면 overlap_filter_strategy이제 필터링을 수행하지 않거나 NMM ( non-max-merge )을 수행할 수 있습니다.
supervision v0.21.0
설정하여 사용하실 수 있습니다 overlap_filter_strategy = sv.OverlapFilter.NON_MAX_MERGE.
overlap_filter_strategy = sv.OverlapFilter.NON_MAX_MERGE
Non-Max 병합은 Non-Max 억제와 매우 유사합니다. 먼저, IOU를 계산하고 임계값과 비교하여 어떤 기능이 크게 겹치는지 확인합니다. 그러나 가장 자신 있는 기능만 남기고 모두 버리는 대신 기능을 점진적으로 병합합니다. 알고리즘은 다음과 같습니다.
마지막으로, 감지된 객체를 둘러싼 상자가 표시됩니다.
자동차에서는 Non-max-merge가 비슷한 성능을 보였지만 밴에서는 더 나은 감지 성능을 보였습니다.
우리의 조언은 다음과 같습니다. 사용 사례와 다양한 InferenceSlicer매개변수를 실험해 보세요.
InferenceSlicer먼저, 모든 객체를 감지할 수 없는 표준 접근 방식인지 확인하세요 .
그렇지 않은 경우 InferenceSlicer기본 매개변수를 사용하여 시작하십시오. 계속해서 결과를 설정 slice_wh하고 overlap_ratio_wh미세 조정하세요.
마지막으로, 탐지 중복을 확인합니다. 대부분의 경우 기본값이 overlap_filter_strategy잘 작동합니다. 그렇지 않으면 .을 사용하여 실험합니다 . ! sv.OverlapFilter.NON_MAX_MERGE를 설정하는 것을 잊지 마세요 .iou_threshold
sv.OverlapFilter.NON_MAX_MERGE
오버랩 처리 전략
기사에서는 탐지와 상자에 대해 언급했지만 이후에는 supervision v0.21.0분할과 마스크를 사용하여 이를 빠르게 수행할 수 있습니다! 필요한 것은 분할 모델뿐입니다. 예 yolov8s-seg-640:
yolov8s-seg-640
import supervision as sv from inference import get_model model = get_model(model_id="yolov8s-seg-640") image = cv2.imread(<SOURCE_IMAGE_PATH>) def callback(image_slice: np.ndarray) -> sv.Detections: results = model.infer(image_slice)[0] return sv.Detections.from_inference(results) slicer = sv.InferenceSlicer(callback=callback) detections = slicer(image)
마스크를 보려면 다른 주석 작성 도구를 사용해야 합니다!
annotated_frame = sv.MaskAnnotator().annotate( scene=image.copy(), detections=detections )
AI 생성 이미지에 대한 실행은 다음과 같습니다.
InferenceSlicer의 결함에 주목하세요. 사람이 크면 시점에 가까워도 완전히 감지되지 않습니다.
보기는 어렵지만 InferenceSlicer로 생성된 해변 이미지의 분할은 다음과 같습니다.
yolov8s-seg-640을 사용하여 해변의 InferenceSlicer 출력을 매우 확대한 그림
Roboflow의 Inference Slicer는 이미지를 작은 세그먼트로 분할하고 각 부분에서 선택한 모델을 실행한 다음 결과를 하나로 묶습니다. 겹치는 결과가 있는 경우 Slicer는 overlap_filter_strategy선택한 항목에 따라 자동으로 처리합니다. 최근에는 세분화와도 작동합니다!
다음에 작은 물건을 다루는 데 어려움을 겪는다면, 한번 시도해 보세요!
이제 문제를 이해하고 해결 방법에 대해 논의할 준비가 되었습니다. 작은 객체에 대한 모델 성능을 향상하려면 다음 기술을 권장합니다.
해상도, 해상도, 해상도... 그것은 모두 해상도 에 관한 것입니다 .
매우 작은 물체는 경계 상자 내에 단지 몇 개의 픽셀만 포함할 수 있습니다. 즉, 감지기가 작은 상자에서 형성할 수 있는 특징의 풍부함을 높이기 위해 이미지의 해상도를 높이는 것이 매우 중요합니다.
따라서 가능하면 최대한 높은 해상도의 이미지를 촬영하는 것이 좋습니다.
이미지가 더 높은 해상도 로 되면 모델의 입력 해상도를 확장할 수 있습니다. 경고: 이렇게 하면 훈련하는 데 더 오래 걸리는 대형 모델이 생성되고 배포를 시작할 때 추론 속도가 느려집니다. 성능과 속도의 적절한 균형을 찾기 위해 실험을 실행해야 할 수도 있습니다.
YOLOv4 훈련 튜토리얼 에서 설정 파일에서 이미지 크기를 변경하여 입력 해상도를 쉽게 확장할 수 있습니다 .
[net] batch=64 subdivisions=36 width={YOUR RESOLUTION WIDTH HERE} height={YOUR RESOLUTION HEIGHT HERE} channels=3 momentum=0.949 decay=0.0005 angle=0 saturation = 1.5 exposure = 1.5 hue = .1 learning_rate=0.001 burn_in=1000 max_batches=6000 policy=steps steps=4800.0,5400.0 scales=.1,.1
훈련 명령에서 이미지 크기 매개변수를 변경하여 YOLOv5를 훈련하는 방법에 대한 튜토리얼 에서 입력 해상도를 쉽게 조정할 수도 있습니다 .
!python train.py --img {YOUR RESOLUTON SIZE HERE} --batch 16 --epochs 10 --data '../data.yaml' --cfg ./models/custom_yolov5s.yaml --weights '' --name yolov5s_results --cache
참고: 훈련 데이터의 최대 해상도까지만 개선된 결과를 볼 수 있습니다.
작은 이미지를 감지하는 또 다른 훌륭한 전략은 전처리 단계로 이미지를 타일링하는 것입니다. 타일링을 사용하면 작은 물체에 대한 감지기를 효과적으로 확대할 수 있지만 빠른 추론을 실행하는 데 필요한 작은 입력 해상도를 유지할 수 있습니다.
Roboflow 의 전처리 단계로 이미지 타일링
훈련 중에 타일링을 사용하는 경우 추론 시 이미지도 타일링해야 한다는 점을 기억하는 것이 중요합니다.
훈련 중에 타일링을 사용한 경우 더 정확한 결과를 얻으려면 추론 중에도 타일링을 사용해야 합니다 . 추론 중에 객체가 훈련 중에 있던 크기와 비슷하도록 확대된 관점을 유지하고 싶기 때문입니다.
다음은 항공 사진을 통해 자동차를 감지하도록 훈련된 모델의 예입니다. 모델은 원본 이미지의 작은 크기와 큰 크기를 고려하여 자동차를 더 잘 인식하기 위해 타일링으로 훈련되었지만 추론 시 타일링을 사용하지 않으면 차량의 크기에 더 가깝기 때문에 자동차 대신 건물 및 기타 큰 형상을 감지하게 됩니다. 훈련 중에 감지하려고 시도한 개체입니다.
추론 시 타일링 없이 오류가 발생하기 쉬운 결과(제공: CHUTTERSNAP )
아래에서는 추론을 실행하기 전에 이미지에 타일링을 적용했습니다. 이를 통해 이미지의 일부를 확대하여 자동차를 더 크게 만들고 모델에서 쉽게 감지할 수 있습니다.
추론 시 타일링으로 결과 개선(제공: CHUTTERSNAP )
데이터 증대는 기본 데이터세트에서 새로운 이미지를 생성합니다. 이는 모델이 훈련 세트에 과적합되는 것을 방지하는 데 매우 유용할 수 있습니다 .
특히 작은 객체 감지에 유용한 증강에는 무작위 자르기 , 무작위 회전 , 모자이크 증강이 있습니다 .
앵커 박스는 모델이 예측하는 것을 학습하는 전형적인 경계 박스입니다. 즉, 앵커 박스는 사전 설정될 수 있으며 때로는 훈련 데이터에 대해 최적이 아닐 수 있습니다. 이러한 박스를 현재 작업에 맞게 사용자 정의하는 것이 좋습니다. 다행히도 YOLOv5 모델 아키텍처는 사용자 정의 데이터를 기반으로 자동으로 이를 수행합니다. 해야 할 일은 훈련을 시작하는 것뿐입니다.
Analyzing anchors... anchors/target = 4.66, Best Possible Recall (BPR) = 0.9675. Attempting to generate improved anchors, please wait... WARNING: Extremely small objects found. 35 of 1664 labels are < 3 pixels in width or height. Running kmeans for 9 anchors on 1664 points... thr=0.25: 0.9477 best possible recall, 4.95 anchors past thr n=9, img_size=416, metric_all=0.317/0.665-mean/best, past_thr=0.465-mean: 18,24, 65,37, 35,68, 46,135, 152,54, 99,109, 66,218, 220,128, 169,228 Evolving anchors with Genetic Algorithm: fitness = 0.6825: 100%|██████████| 1000/1000 [00:00<00:00, 1081.71it/s] thr=0.25: 0.9627 best possible recall, 5.32 anchors past thr n=9, img_size=416, metric_all=0.338/0.688-mean/best, past_thr=0.476-mean: 13,20, 41,32, 26,55, 46,72, 122,57, 86,102, 58,152, 161,120, 165,204
클래스 관리란 데이터 세트의 품질을 개선하는 중요한 기술입니다. 다른 클래스와 상당히 겹치는 클래스가 있는 경우 데이터 세트에서 이 클래스를 필터링해야 합니다. 그리고 데이터 세트의 작은 개체가 감지할 가치가 없다고 판단하여 제거하고 싶을 수도 있습니다. Roboflow Pro 의 일부인 고급 데이터 세트 상태 확인을 사용하면 이러한 모든 문제를 빠르게 식별할 수 있습니다 .
Roboflow의 온톨로지 관리 도구를 통해 클래스 생략 및 클래스 이름 변경이 모두 가능합니다 .
작은 물체를 제대로 감지하는 것은 정말 어려운 일입니다. 이 글에서는 작은 물체 감지기를 개선하기 위한 몇 가지 전략을 논의했습니다. 즉, 다음과 같습니다.
(Linas Kondrackis가 작성한 게시물에서)
기업 홍보를 위한 확실한 방법협회 홈페이지에 회사정보를 보강해 보세요.