feat: 초기 프로젝트 구조 추가
This commit is contained in:
59
ai/detector.py
Normal file
59
ai/detector.py
Normal file
@@ -0,0 +1,59 @@
|
||||
# AI 추론 — YOLOv8 기반 불량(스크래치/이물/흑점/변형) 검출
|
||||
import os
|
||||
import numpy as np
|
||||
|
||||
from utils.path_helper import BASE_PATH
|
||||
|
||||
|
||||
class Detector:
|
||||
class_names = ["스크래치", "이물", "흑점", "변형"]
|
||||
|
||||
def __init__(self):
|
||||
self._model = None
|
||||
self.model_path = None
|
||||
|
||||
def load_model(self, model_path: str) -> bool:
|
||||
if model_path and not os.path.isabs(model_path):
|
||||
model_path = os.path.join(BASE_PATH, model_path)
|
||||
try:
|
||||
from ultralytics import YOLO # 지연 로딩 — 앱 시작 시 torch DLL 오류 방지
|
||||
self._model = YOLO(model_path)
|
||||
self.model_path = model_path
|
||||
print(f"[AI] 모델 로드 성공: {model_path}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"[AI] 모델 로드 실패: {e}")
|
||||
self._model = None
|
||||
return False
|
||||
|
||||
def is_loaded(self) -> bool:
|
||||
return self._model is not None
|
||||
|
||||
def detect(self, image: np.ndarray) -> list:
|
||||
"""
|
||||
image: numpy array (BGR)
|
||||
반환: [{"class_id": int, "class_name": str,
|
||||
"confidence": float, "bbox": [x1,y1,x2,y2]}, ...]
|
||||
"""
|
||||
if self._model is None:
|
||||
return []
|
||||
try:
|
||||
results = self._model(image, verbose=False)
|
||||
detections = []
|
||||
for result in results:
|
||||
for box in result.boxes:
|
||||
class_id = int(box.cls[0])
|
||||
detections.append({
|
||||
"class_id": class_id,
|
||||
"class_name": (
|
||||
self.class_names[class_id]
|
||||
if class_id < len(self.class_names)
|
||||
else str(class_id)
|
||||
),
|
||||
"confidence": float(box.conf[0]),
|
||||
"bbox": box.xyxy[0].tolist(),
|
||||
})
|
||||
return detections
|
||||
except Exception as e:
|
||||
print(f"[AI] 추론 오류: {e}")
|
||||
return []
|
||||
Reference in New Issue
Block a user