RavindranadhM's picture
Deploy manufacturing monitoring system
201b13c verified
Raw
History Blame Contribute Delete
3.3 kB
from ultralytics import YOLO
import cv2
import numpy as np
from core.config import settings
from core.logger import logger
class DefectInspector:
"""
Handles model inference and defect extraction.
"""
def __init__(self, model_path: str):
self.model = YOLO(model_path)
logger.info(f"Model loaded from: {model_path}")
def inspect_image(self, image: np.ndarray):
"""
Run inference and extract defect information.
"""
try:
results = self.model(
image,
conf=settings.CONF_THRESHOLD,
imgsz=settings.IMAGE_SIZE,
verbose=False
)
result = results[0]
defects = []
if result.masks is None:
return defects
masks = result.masks.data.cpu().numpy()
classes = result.boxes.cls.cpu().numpy()
confidences = result.boxes.conf.cpu().numpy()
height, width = image.shape[:2]
image_area = height * width
for i, (mask, cls_id) in enumerate(zip(masks, classes)):
confidence = float(confidences[i])
if confidence < settings.SECONDARY_CONF_THRESHOLD:
continue
# -------------------------
# MASK PROCESSING
# -------------------------
mask = cv2.resize(mask, (width, height))
mask = (mask > 0.3).astype("uint8") * 255
kernel = np.ones((3, 3), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
# -------------------------
# CONTOUR EXTRACTION
# -------------------------
contours, _ = cv2.findContours(
mask,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE
)
if not contours:
continue
# ✅ PICK LARGEST CONTOUR (FIX)
largest_contour = max(contours, key=cv2.contourArea)
# Optional smoothing
epsilon = 0.01 * cv2.arcLength(largest_contour, True)
largest_contour = cv2.approxPolyDP(largest_contour, epsilon, True)
cnt = largest_contour
area = cv2.contourArea(cnt)
if area < settings.MIN_DEFECT_AREA:
continue
x, y, w, h = cv2.boundingRect(cnt)
length = max(w, h)
width_def = min(w, h)
area_ratio = area / image_area
if area_ratio > settings.MAX_AREA_RATIO:
continue
defects.append({
"class_id": int(cls_id),
"confidence": confidence,
"area_pixels": float(area),
"length_pixels": float(length),
"width_pixels": float(width_def),
"area_ratio": float(area_ratio),
"bbox": (x, y, w, h),
"contour": cnt
})
return defects
except Exception as e:
logger.error(f"Inference failed: {e}")
return []