|
import cv2 |
|
import numpy as np |
|
import matplotlib.pyplot as plt |
|
from ultralytics import YOLO |
|
import gradio as gr |
|
from matplotlib.patches import Patch |
|
|
|
|
|
model = YOLO("model.pt") |
|
|
|
def process_image(image): |
|
|
|
img_rgb = np.array(image) |
|
img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR) |
|
|
|
|
|
results = model.predict(source=img_bgr, save=False) |
|
|
|
|
|
mask_info_list = [] |
|
|
|
|
|
mask_image = np.zeros_like(img_bgr, dtype=np.uint8) |
|
|
|
|
|
max_confidence_map = np.zeros((img_bgr.shape[0], img_bgr.shape[1]), dtype=np.float32) |
|
|
|
|
|
colormap = plt.cm.get_cmap('tab20') |
|
|
|
|
|
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_bgr.shape[1], img_bgr.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] |
|
|
|
|
|
for idx_in_order, (mask, conf_norm, conf, cls) in enumerate( |
|
zip(sorted_masks, sorted_confidences_norm, sorted_confidences, sorted_classes)): |
|
|
|
|
|
color = colormap(idx_in_order % colormap.N)[:3] |
|
color_rgb = [int(c * 255) for c in color] |
|
color_bgr = color_rgb[::-1] |
|
|
|
|
|
mask_binary = mask > 0.5 |
|
|
|
|
|
update_pixels = mask_binary & (sorted_confidences[idx_in_order] > max_confidence_map) |
|
|
|
|
|
for i in range(3): |
|
mask_image[:, :, i][update_pixels] = color_bgr[i] |
|
max_confidence_map[update_pixels] = sorted_confidences[idx_in_order] |
|
|
|
|
|
mask_info = { |
|
'class': names[cls], |
|
'confidence': sorted_confidences[idx_in_order], |
|
'color_rgb': color_rgb |
|
} |
|
mask_info_list.append(mask_info) |
|
|
|
|
|
alpha = 0.4 |
|
img_with_masks = cv2.addWeighted(img_bgr.astype(np.float32), 1, mask_image.astype(np.float32), alpha, 0).astype(np.uint8) |
|
|
|
|
|
img_with_masks_rgb = cv2.cvtColor(img_with_masks, cv2.COLOR_BGR2RGB) |
|
|
|
|
|
fig, ax = plt.subplots(figsize=(10, 10)) |
|
ax.imshow(img_with_masks_rgb) |
|
ax.axis('off') |
|
|
|
|
|
if mask_info_list: |
|
handles = [] |
|
labels = [] |
|
|
|
seen = set() |
|
for mask_info in mask_info_list: |
|
label = f"{mask_info['class']} - Confianza: {mask_info['confidence']:.2f}" |
|
if label not in seen: |
|
seen.add(label) |
|
color_rgb_normalized = np.array(mask_info['color_rgb']) / 255 |
|
patch = Patch(facecolor=color_rgb_normalized) |
|
handles.append(patch) |
|
labels.append(label) |
|
|
|
|
|
ax.legend(handles, labels, loc='upper right', bbox_to_anchor=(1.15, 1)) |
|
|
|
plt.tight_layout() |
|
|
|
|
|
fig.canvas.draw() |
|
img_figure = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8) |
|
img_figure = img_figure.reshape(fig.canvas.get_width_height()[::-1] + (3,)) |
|
|
|
plt.close(fig) |
|
|
|
return img_figure |
|
|
|
|
|
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() |
|
|