|
import cv2 |
|
import numpy as np |
|
import matplotlib.pyplot as plt |
|
from ultralytics import YOLO |
|
import gradio as gr |
|
from matplotlib.patches import Rectangle |
|
from matplotlib.legend import Legend |
|
|
|
|
|
model = YOLO("model.pt") |
|
|
|
def process_image(image): |
|
|
|
img = np.array(image) |
|
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) |
|
|
|
|
|
results = model.predict(source=img, save=False) |
|
|
|
|
|
mask_info_list = [] |
|
|
|
|
|
for result in results: |
|
|
|
if result.masks is not None and len(result.masks.data) > 0: |
|
|
|
masks = result.masks.data.cpu().numpy() |
|
confidences = result.boxes.conf.cpu().numpy() |
|
classes = result.boxes.cls.cpu().numpy().astype(int) |
|
names = model.names |
|
|
|
|
|
confidences_norm = (confidences - confidences.min()) / (confidences.max() - confidences.min() + 1e-6) |
|
|
|
|
|
resized_masks = [] |
|
for mask in masks: |
|
mask_resized = cv2.resize(mask, (img.shape[1], img.shape[0]), interpolation=cv2.INTER_LINEAR) |
|
resized_masks.append(mask_resized) |
|
resized_masks = np.array(resized_masks) |
|
|
|
|
|
smoothed_masks = [] |
|
for mask in resized_masks: |
|
|
|
mask_uint8 = (mask * 255).astype(np.uint8) |
|
|
|
blurred_mask = cv2.GaussianBlur(mask_uint8, (7, 7), 0) |
|
|
|
mask_smoothed = blurred_mask.astype(np.float32) / 255.0 |
|
smoothed_masks.append(mask_smoothed) |
|
smoothed_masks = np.array(smoothed_masks) |
|
|
|
|
|
sorted_indices = np.argsort(-confidences) |
|
sorted_masks = smoothed_masks[sorted_indices] |
|
sorted_confidences = confidences[sorted_indices] |
|
sorted_confidences_norm = confidences_norm[sorted_indices] |
|
sorted_classes = classes[sorted_indices] |
|
|
|
|
|
colormap = plt.cm.get_cmap('viridis') |
|
|
|
|
|
mask_image = np.zeros_like(img, dtype=np.uint8) |
|
|
|
|
|
mask_indices = np.full((img.shape[0], img.shape[1]), -1, dtype=int) |
|
|
|
|
|
for idx_in_order, (idx, mask, conf_norm, conf, cls) in enumerate(zip(sorted_indices, sorted_masks, sorted_confidences_norm, sorted_confidences, sorted_classes)): |
|
mask_bool = mask > 0.5 |
|
|
|
update_mask = np.logical_and(mask_bool, mask_indices == -1) |
|
if not np.any(update_mask): |
|
continue |
|
mask_indices[update_mask] = idx |
|
|
|
|
|
color_rgb = colormap(conf_norm)[:3] |
|
color_rgb = [int(c * 255) for c in color_rgb] |
|
color_bgr = color_rgb[::-1] |
|
|
|
|
|
mask_info = { |
|
'mask_index': idx, |
|
'class': names[cls], |
|
'confidence': conf, |
|
'color_rgb': color_rgb, |
|
'color_bgr': color_bgr |
|
} |
|
mask_info_list.append(mask_info) |
|
|
|
|
|
for i in range(3): |
|
mask_image[:, :, i][update_mask] = color_bgr[i] |
|
|
|
|
|
alpha = 0.2 |
|
img_with_masks = cv2.addWeighted(img.astype(np.float32), 1, mask_image.astype(np.float32), alpha, 0).astype(np.uint8) |
|
|
|
else: |
|
|
|
img_with_masks = img.copy() |
|
print("No se detectaron máscaras en esta imagen.") |
|
|
|
|
|
img_with_masks_rgb = cv2.cvtColor(img_with_masks, cv2.COLOR_BGR2RGB) |
|
|
|
return img_with_masks_rgb |
|
|
|
|
|
iface = gr.Interface( |
|
fn=process_image, |
|
inputs=gr.Image(type="pil"), |
|
outputs=gr.Image(type="numpy"), |
|
title="Detección de Estenosis", |
|
description="Sube una imagen para detectar estenosis." |
|
) |
|
|
|
if __name__ == "__main__": |
|
iface.launch() |
|
|