Phoenix Detection — YOLO26s 화재·사람 탐지 (전처리 유무 비교)
화재 현장에서 불(fire) 과 사람(person) 을 탐지하는 YOLO26s 모델 두 개입니다.
같은 데이터셋·같은 하이퍼파라미터로 학습했고, 입력 이미지 전처리 유무만 다릅니다.
| baseline/ | filtered/ |
|---|
| 학습 이미지 | Roboflow 원본 | 디헤이즈 + CLAHE 적용본 |
| 추론 시 전처리 | 불필요 | 필수 (아래 참조) |
| 용도 | 대조군 | 연무·저대비 환경 대응 |
성능 (test split, 71 images / 94 instances)
| 모델 | P | R | mAP@50 | mAP@50-95 |
|---|
| baseline | 0.967 | 0.967 | 0.982 | 0.702 |
| filtered | 0.983 | 0.980 | 0.994 | 0.715 |
클래스별 (mAP@50 / mAP@50-95):
| 클래스 | baseline | filtered |
|---|
| fire | 0.971 / 0.616 | 0.995 / 0.634 |
| person | 0.994 / 0.788 | 0.992 / 0.796 |
전처리본이 모든 종합 지표에서 앞서고, 특히 fire 클래스의 mAP@50 이 0.971 → 0.995 로 오릅니다.
다만 test 셋이 71장뿐이라 이 차이를 통계적으로 유의하다고 단정하기는 어렵습니다.
경향의 근거로만 보시고, 판단이 중요한 용도라면 더 큰 셋에서 재확인하세요.
각 폴더의 results.csv(에폭별 전체 곡선), results.png, confusion_matrix_normalized.png,
BoxPR_curve.png 로 학습 과정을 확인할 수 있습니다. 표의 수치는 각 모델의 best 체크포인트를
test split 에서 재평가한 값입니다.
사용법
baseline
1from ultralytics import YOLO
2from huggingface_hub import hf_hub_download
3
4w = hf_hub_download("albitro/phoenix_detection", "baseline/best.pt")
5model = YOLO(w)
6
7results = model("frame.jpg")
8results[0].show()
filtered — 전처리를 반드시 거쳐야 합니다
이 가중치는 전처리된 픽셀로 학습되었습니다. 원본 이미지를 그대로 넣으면 학습/추론 분포가
어긋나 성능이 떨어집니다. 학습에 쓴 것과 동일한 파이프라인을 filtered/preprocess/ 에
함께 올려두었습니다 (opencv-python, numpy 만 있으면 동작하며 ROS 의존성 없음).
1import cv2
2from ultralytics import YOLO
3from huggingface_hub import snapshot_download
4
5repo = snapshot_download("albitro/phoenix_detection")
6
7import sys; sys.path.insert(0, f"{repo}/filtered")
8from preprocess import build_default_pipeline
9
10pipe = build_default_pipeline() # filter_params.json 의 값 그대로
11model = YOLO(f"{repo}/filtered/best.pt")
12
13bgr = cv2.imread("frame.jpg") # BGR, uint8
14results = model(pipe.process(bgr))
15results[0].show()
pipe.process() 는 BGR uint8 을 받아 BGR uint8 을 돌려줍니다. 비디오 스트림에서는
pipe 를 한 번만 만들어 재사용하세요 (프레임마다 새로 만들 필요 없음).
전처리 파이프라인
mode="full" — 감마 보정 → Dark Channel Prior 디헤이즈(guided filter refinement) → CLAHE.
전체 파라미터는 filtered/filter_params.json 에 있고 preprocess.DEFAULTS 와 일치합니다.
주요 값: omega=0.95, t0=0.1, patch=15, scale=0.25, a_max=0.92,
clahe_clip=2.0, clahe_tile=8, gamma=1.0.
데이터셋
Roboflow Universe — -ssifa/it-t82tu v1
(CC BY 4.0). 640×480, 2 클래스, train 307 / valid 94 / test 71.
filtered 데이터셋은 원본에 전처리를 적용한 사본입니다. 분할 멤버십·파일명·라벨이 원본과
완전히 동일하고 픽셀값만 다릅니다 — 디헤이즈와 CLAHE 는 화소값 변환이라 바운딩박스가
움직이지 않기 때문입니다. 두 모델의 차이가 전처리 효과인지 분할 운인지 헷갈리지 않도록
의도적으로 이렇게 맞췄습니다. 재압축 손실이 전처리 조건에만 얹히는 것을 피하려고 사본은
PNG 무손실로 저장했습니다.
데이터셋 자체는 이 레포에 포함돼 있지 않습니다. 클래스 정의는 data.yaml 참조.
학습 설정
두 모델 공통입니다. 전체는 각 폴더의 args.yaml 에 있습니다.
| |
|---|
| base | yolo26s.pt (COCO pretrained) |
| epochs | 100 (baseline best @79, filtered best @95) |
| imgsz | 640 |
| batch | 16 |
| optimizer | auto |
| seed | 0 |
| device | Intel Arc B580 (XPU), PyTorch 2.13.0+xpu |
| ultralytics | 8.4.117 |
한계
- 작은 데이터셋 (총 472장). 촬영 환경이 학습 데이터와 다르면 일반화가 떨어질 수 있습니다.
- test 셋 71장 기준의 비교라 두 모델 간 차이의 신뢰구간이 넓습니다.
fire 의 mAP@50-95 가 0.63 수준입니다. 탐지 여부(mAP@50 0.995)는 신뢰할 만하지만
불꽃 경계의 박스 정밀도는 그만큼 높지 않습니다 — 불꽃은 경계가 모호한 대상입니다.
- 안전이 걸린 용도에 단독 판단 근거로 쓰지 마세요. 사람의 확인을 거치는 경보 보조로만 쓰세요.
라이선스
가중치는 Ultralytics YOLO 에서 파생되어 AGPL-3.0 을 따릅니다. 네트워크 서비스로 배포할
경우 소스 공개 의무가 따라옵니다. 상용 용도라면 Ultralytics 엔터프라이즈 라이선스를 확인하세요.
학습 데이터셋은 CC BY 4.0 입니다.