File size: 2,592 Bytes
8f78c90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bc97233
8f78c90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bc97233
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import os
import cv2
import numpy as np
import supervision as sv
from huggingface_hub import hf_hub_download
from ultralytics import YOLOE

# Hugging Face space model details
HF_TOKEN = os.environ.get("HF_TOKEN")
REPO_ID = "imtk/knee-landmarks"

# Download the ROI model weights
print("Downloading model...")
roi_model_path = hf_hub_download(
    repo_id=REPO_ID,
    filename="roi_model/weights/best.pt",
    token=HF_TOKEN
)
print(f"ROI Model downloaded to: {roi_model_path}")

roi_model = YOLOE(roi_model_path)
roi_model.fuse()

def predict_rois(image):
    if image is None:
        return None, [], {}
    
    # Convert Gradio RGB image to BGR for model prediction
    img_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    
    # Predict ROIs
    results = roi_model.predict(img_bgr, conf=0.05)[0]
    detections = sv.Detections.from_ultralytics(results)
    
    rois = {}
    for xyxy, _, conf, class_id, _, class_name_dict in detections:
        shape_name = str(class_name_dict["class_name"])
        pt1 = (int(xyxy[0]), int(xyxy[1]))
        pt2 = (int(xyxy[2]), int(xyxy[3]))
        
        # Crop the region from original RGB image
        roi = image[pt1[1]:pt2[1], pt1[0]:pt2[0]]
        if roi.size == 0:
            continue
            
        area = abs(xyxy[0] - xyxy[2]) * abs(xyxy[1] - xyxy[3])
        
        # If class exists, keep the one with higher confidence
        if shape_name in rois:
            if rois[shape_name]["conf"] > conf:
                continue
                
        rois[shape_name] = {
            "minx": xyxy[0],
            "miny": xyxy[1],
            "maxx": xyxy[2],
            "maxy": xyxy[3],
            "box": (pt1, pt2),
            "img": roi,
            "conf": conf,
            "area": area,
        }
    
    # Draw annotations on the original image
    annotated_img = image.copy()
    gallery_items = []
    
    for name, data in rois.items():
        pt1, pt2 = data["box"]
        
        if name.endswith("L"):
            color = (255, 0, 0)  # Red
        else:
            color = (0, 0, 255)  # Blue
        
        # Draw box on annotated image
        cv2.rectangle(annotated_img, pt1, pt2, color, 3)
        # Put text label
        cv2.putText(
            annotated_img,
            f"{name} ({data['conf']:.2f})",
            (pt1[0], max(pt1[1] - 10, 20)),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.8,
            color,
            2
        )
        
        # Add cropped ROI to gallery
        gallery_items.append((data["img"], name))

    return annotated_img, gallery_items, rois