xDesCO / segmentation /model.py
tuannt
update_check_clinical_data
7650763
Raw History Blame Contribute Delete
1.61 kB
from ultralytics import YOLO
import cv2
import torch
BEST_WEIGHT = './segmentation/weights/oai_s_best4.pt'
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
def create_model(weight_path=None):
if weight_path:
return YOLO(weight_path)
else:
return YOLO(BEST_WEIGHT)
class Segmenter():
def __init__(self, weight_path=None):
self.model = create_model(weight_path).to(DEVICE)
def segment(self, img):
"""
input: image (H, W, C)
output: mask (H, W) with femur is 1 and tibia is 2
"""
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
eimg = cv2.equalizeHist(img)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
eimg = clahe.apply(eimg)
eimg = cv2.cvtColor(eimg, cv2.COLOR_GRAY2RGB)
res = self.model(eimg, verbose=False)
result = res[0]
if result.masks is None or result.boxes is None:
raise ValueError("Segmentation failed: no mask/object detected.")
masks = result.masks.data
classes = result.boxes.cls
if masks is None or len(masks) < 2 or len(classes) < 2:
raise ValueError("Segmentation failed: need at least 2 detected objects (femur and tibia).")
mask = torch.zeros_like(masks[0])
n = min(len(masks), len(classes))
for i in range(n):
class_value = int(classes[i].item()) + 1
mask = torch.where(masks[i] > 0.5, torch.tensor(float(class_value), device=mask.device), mask)
mask = mask.cpu().numpy()
return mask