lokesh341's picture
Update services/operations_maintenance/crack_detection.py
b9160f0 verified
import cv2
import numpy as np
from typing import List, Tuple, Dict, Any
def detect_cracks_and_holes(frame: np.ndarray) -> Tuple[List[Dict[str, Any]], np.ndarray]:
"""
Detect cracks and holes in the frame using edge detection and contour analysis.
Args:
frame: Input frame as a numpy array.
Returns:
Tuple of (list of detections, annotated frame).
"""
# Convert to grayscale
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Apply Gaussian blur to reduce noise
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# Edge detection using Canny
edges = cv2.Canny(blurred, 50, 150)
# Dilate edges to connect nearby edges
kernel = np.ones((3, 3), np.uint8)
dilated = cv2.dilate(edges, kernel, iterations=1)
# Find contours
contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
detections = []
for i, contour in enumerate(contours):
# Calculate the area of the contour
area = cv2.contourArea(contour)
if area < 100: # Ignore small contours
continue
# Get bounding box
x, y, w, h = cv2.boundingRect(contour)
x_min, y_min, x_max, y_max = x, y, x + w, y + h
# Determine if it's a crack or hole based on shape and area
perimeter = cv2.arcLength(contour, True)
circularity = 4 * np.pi * area / (perimeter * perimeter) if perimeter > 0 else 0
# Classify as hole if more circular, crack if elongated
dtype = "hole" if circularity > 0.5 else "crack"
label = f"{dtype.capitalize()} {i+1}"
# Determine severity based on area
severity = "Severe" if area > 1000 else "Moderate" if area > 500 else "Mild"
detections.append({
"box": [x_min, y_min, x_max, y_max],
"label": label,
"type": dtype,
"severity": severity
})
return detections, frame