137 lines
4.8 KiB
Python
137 lines
4.8 KiB
Python
import cv2
|
|
import numpy as np
|
|
import logging
|
|
from pathlib import Path
|
|
from ultralytics import YOLO
|
|
from exceptions import ModelLoadError, DetectionError, ImageProcessingError
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class MemoryDetector:
|
|
def __init__(self, model_path, confidence_threshold=0.3, image_size=416):
|
|
self.model_path = model_path
|
|
self.confidence_threshold = confidence_threshold
|
|
self.image_size = image_size
|
|
self.model = None
|
|
self._load_model()
|
|
|
|
def _load_model(self):
|
|
"""Load YOLO model with error handling."""
|
|
try:
|
|
if not Path(self.model_path).exists():
|
|
raise FileNotFoundError(f"Model file not found: {self.model_path}")
|
|
|
|
logger.info(f"Loading model from {self.model_path}")
|
|
self.model = YOLO(self.model_path)
|
|
logger.info("Model loaded successfully")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to load model: {e}")
|
|
raise ModelLoadError(f"Model loading failed: {str(e)}")
|
|
|
|
def detect_from_bytes(self, image_bytes):
|
|
"""Detect memory modules from image bytes."""
|
|
try:
|
|
# Decode image
|
|
nparr = np.frombuffer(image_bytes, np.uint8)
|
|
image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
|
|
|
|
if image is None:
|
|
raise ImageProcessingError("Could not decode image")
|
|
|
|
return self._perform_detection(image)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Detection from bytes failed: {e}")
|
|
raise DetectionError(f"Detection failed: {str(e)}")
|
|
|
|
def detect_from_file(self, file_path):
|
|
"""Detect memory modules from image file."""
|
|
try:
|
|
if not Path(file_path).exists():
|
|
raise FileNotFoundError(f"Image file not found: {file_path}")
|
|
|
|
image = cv2.imread(str(file_path))
|
|
if image is None:
|
|
raise ImageProcessingError("Could not load image file")
|
|
|
|
return self._perform_detection(image)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Detection from file failed: {e}")
|
|
raise DetectionError(f"Detection failed: {str(e)}")
|
|
|
|
def _perform_detection(self, image):
|
|
"""Perform detection on image."""
|
|
try:
|
|
logger.info("Running detection")
|
|
|
|
# Run inference
|
|
results = self.model.predict(
|
|
image,
|
|
imgsz=self.image_size,
|
|
conf=self.confidence_threshold,
|
|
verbose=False
|
|
)
|
|
|
|
# Extract detections
|
|
detections = self._extract_detections(results[0])
|
|
|
|
# Create annotated image
|
|
annotated_image = self._draw_boxes(image, detections)
|
|
|
|
logger.info(f"Detection completed: {len(detections)} objects found")
|
|
|
|
return {
|
|
'detections': detections,
|
|
'annotated_image': annotated_image,
|
|
'detection_count': len(detections)
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Detection processing failed: {e}")
|
|
raise DetectionError(f"Detection processing failed: {str(e)}")
|
|
|
|
def _extract_detections(self, result):
|
|
"""Extract detection results."""
|
|
detections = []
|
|
|
|
if result.boxes is not None:
|
|
boxes = result.boxes.xyxy.cpu().numpy()
|
|
confidences = result.boxes.conf.cpu().numpy()
|
|
classes = result.boxes.cls.cpu().numpy() if result.boxes.cls is not None else None
|
|
|
|
for i, (box, conf) in enumerate(zip(boxes, confidences)):
|
|
detection = {
|
|
'box': [float(coord) for coord in box], # [x1, y1, x2, y2]
|
|
'confidence': float(conf),
|
|
'class': int(classes[i]) if classes is not None else 0
|
|
}
|
|
detections.append(detection)
|
|
|
|
return detections
|
|
|
|
def _draw_boxes(self, image, detections):
|
|
"""Draw bounding boxes on image."""
|
|
annotated = image.copy()
|
|
|
|
for detection in detections:
|
|
box = detection['box']
|
|
confidence = detection['confidence']
|
|
|
|
# Extract coordinates
|
|
x1, y1, x2, y2 = map(int, box)
|
|
|
|
# Draw bounding box
|
|
cv2.rectangle(annotated, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
|
|
|
# Draw confidence score
|
|
label = f"Memory: {confidence:.2f}"
|
|
cv2.putText(
|
|
annotated, label, (x1, y1 - 10),
|
|
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1
|
|
)
|
|
|
|
return annotated
|