Spaces:
Running
Running
| from typing import Tuple | |
| import cv2 | |
| import numpy as np | |
| from models import FingerQualityResult | |
| class Visualizer: | |
| def draw_axis(img, center, vec, length, color, thickness=2): | |
| x0, y0 = center | |
| x1 = int(x0 + length * vec[0]) | |
| y1 = int(y0 + length * vec[1]) | |
| cv2.arrowedLine(img, (x0, y0), (x1, y1), color, thickness, tipLength=0.2) | |
| def draw_debug( | |
| img: np.ndarray, | |
| contour: np.ndarray, | |
| bbox: Tuple[int, int, int, int], | |
| angle_deg: float, | |
| result: FingerQualityResult | |
| ) -> np.ndarray: | |
| out = img.copy() | |
| x, y, w_box, h_box = bbox | |
| cv2.rectangle(out, (x, y), (x + w_box, y + h_box), (0, 255, 0), 2) | |
| cv2.drawContours(out, [contour], -1, (255, 0, 0), 2) | |
| pts = contour.reshape(-1, 2).astype(np.float64) | |
| mean, eigenvectors, _ = cv2.PCACompute2(pts, mean=np.empty(0)) | |
| center = (int(mean[0, 0]), int(mean[0, 1])) | |
| main_vec = eigenvectors[0] | |
| Visualizer.draw_axis(out, center, main_vec, length=80, color=(0, 0, 255), thickness=2) | |
| text_lines = [ | |
| f"Blur: {result.blur_score:.1f} ({'OK' if result.blur_pass else 'BAD'})", | |
| f"Illum: {result.illumination_score:.1f} ({'OK' if result.illumination_pass else 'BAD'})", | |
| f"Coverage: {result.coverage_ratio*100:.1f}% ({'OK' if result.coverage_pass else 'BAD'})", | |
| f"Angle: {angle_deg:.1f} deg ({'OK' if result.orientation_pass else 'BAD'})", | |
| f"Quality: {result.quality_score:.2f} ({'PASS' if result.overall_pass else 'FAIL'})", | |
| ] | |
| y0 = 25 | |
| for line in text_lines: | |
| color = (0, 255, 0) if ("OK" in line or "PASS" in line) else (0, 0, 255) | |
| cv2.putText(out, line, (10, y0), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2, cv2.LINE_AA) | |
| y0 += 22 | |
| return out | |