File size: 7,379 Bytes
43721ce a900d50 43721ce a900d50 b1bab45 a900d50 88c76bc 0602cd9 a900d50 b1bab45 a900d50 b1bab45 a900d50 b1bab45 a900d50 0602cd9 88c76bc a900d50 dea2bbd 3cf72b4 b1bab45 3cf72b4 a900d50 3cf72b4 a900d50 3cf72b4 a900d50 b1bab45 a900d50 b1bab45 a900d50 b1bab45 |
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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
import gradio as gr
import torch
import cv2
import numpy as np
from preprocess import unsharp_masking
import time
from sklearn.cluster import KMeans
import os
device = "cuda" if torch.cuda.is_available() else "cpu"
# Função para ordenar e pré-processar a imagem de entrada
def ordenar_e_preprocessar_imagem(img, modelo):
ori = img.copy()
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
h, w = img.shape
img_out = preprocessar_imagem(img, modelo)
return img_out, h, w, img, ori
# Função para pré-processar a imagem com base no modelo selecionado
def preprocessar_imagem(img, modelo='SE-RegUNet 4GF'):
# Redimensionar a imagem para 512x512
img = cv2.resize(img, (512, 512))
# Aplicar a máscara de nitidez à imagem
img = unsharp_masking(img).astype(np.uint8)
# Função auxiliar para normalizar a imagem
def normalizar_imagem(img):
return np.float32((img - img.min()) / (img.max() - img.min() + 1e-6))
if modelo == 'AngioNet' or modelo == 'UNet3+':
img = normalizar_imagem(img)
img_out = np.expand_dims(img, axis=0)
elif modelo == 'SE-RegUNet 4GF':
clahe1 = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
clahe2 = cv2.createCLAHE(clipLimit=8.0, tileGridSize=(8, 8))
image1 = clahe1.apply(img)
image2 = clahe2.apply(img)
img = normalizar_imagem(img)
image1 = normalizar_imagem(image1)
image2 = normalizar_imagem(image2)
img_out = np.stack((img, image1, image2), axis=0)
else:
clahe1 = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
image1 = clahe1.apply(img)
image1 = normalizar_imagem(image1)
img_out = np.stack((image1,) * 3, axis=0)
return img_out
import os
# Caminho absoluto para a pasta de salvamento
caminho_salvar_resultado = "/Segmento_de_Angio_Coronariana_v5/Salvar Resultado"
# Função para processar a imagem de entrada
def processar_imagem_de_entrada(img, modelo, pipe, salvar_resultado=False):
try:
# Faça uma cópia da imagem original
img = img.copy()
# Coloque o modelo na GPU (se disponível) e configure-o para modo de avaliação
pipe = pipe.to(device).eval()
# Registre o tempo de início
start = time.time()
# Pré-processe a imagem e obtenha informações de dimensão
img, h, w, ori_gray, ori = ordenar_e_preprocessar_imagem(img, modelo)
# Converta a imagem para o formato esperado pelo modelo e coloque-a na GPU
img = torch.FloatTensor(img).unsqueeze(0).to(device)
# Realize a inferência do modelo sem gradientes
with torch.no_grad():
if modelo == 'AngioNet':
img = torch.cat([img, img], dim=0)
logit = np.round(torch.softmax(pipe.forward(img), dim=1).detach().cpu().numpy()[0, 0]).astype(np.uint8)
# Calcule o tempo decorrido
spent = time.time() - start
spent = f"{spent:.3f} segundos"
# Redimensione o resultado, se necessário
if h != 512 or w != 512:
logit = cv2.resize(logit, (h, w))
# Converta o resultado para um formato booleano
logit = logit.astype(bool)
# Crie uma cópia da imagem original para saída e aplique a máscara
img_out = ori.copy()
img_out[logit, 0] = 255
# Salve o resultado em um arquivo se a opção estiver ativada
if salvar_resultado:
nome_arquivo = os.path.join(caminho_salvar_resultado, f'resultado_{int(time.time())}.png')
cv2.imwrite(nome_arquivo, img_out)
return spent, img_out
except Exception as e:
# Em caso de erro, retorne uma mensagem de erro
return str(e), None
# Carregar modelos pré-treinados
models = {
'SE-RegUNet 4GF': torch.jit.load('./model/SERegUNet4GF.pt'),
'SE-RegUNet 16GF': torch.jit.load('./model/SERegUNet16GF.pt'),
'AngioNet': torch.jit.load('./model/AngioNet.pt'),
'EffUNet++ B5': torch.jit.load('./model/EffUNetppb5.pt'),
'Reg-SA-UNet++': torch.jit.load('./model/RegSAUnetpp.pt'),
'UNet3+': torch.jit.load('./model/UNet3plus.pt'),
}
from scipy.spatial import distance
from scipy.ndimage import label
import numpy as np
import numpy as np
import cv2
from sklearn.cluster import KMeans
def processar_imagem_de_entrada_wrapper(img, modelo, salvar_resultado=False, nome_arquivo=None):
model = models[modelo]
resultado, img_out = processar_imagem_de_entrada(img, modelo, model)
# Resto do código permanece inalterado
kmeans = KMeans(n_clusters=2, random_state=0)
flattened_img = img_out[:, :, 0].reshape((-1, 1))
kmeans.fit(flattened_img)
labels = kmeans.labels_
cluster_centers = kmeans.cluster_centers_
# Extração de características dos clusters
num_clusters = len(cluster_centers)
cluster_features = []
for i in range(num_clusters):
cluster_mask = labels == i # Create a boolean mask for the cluster
# Calcular área do cluster
area = np.sum(cluster_mask)
if area == 0: # Skip empty clusters
continue
# Calcular forma do cluster usando a relação entre área e perímetro
contours, _ = cv2.findContours(np.uint8(cluster_mask), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if len(contours) > 0:
perimeter = cv2.arcLength(contours[0], True)
compactness = 4 * np.pi * area / (perimeter ** 2)
cluster_features.append({'area': area, 'compactness': compactness})
# Decidir se há doença com base nas características dos clusters
has_disease_flag = any(feature['area'] >= 200 and feature['compactness'] < 0.3 for feature in cluster_features)
# Formatar o indicador de doença como uma string
if has_disease_flag:
status_doenca = "Sim"
explanation = "A máquina detectou uma possível doença nos vasos sanguíneos."
else:
status_doenca = "Não"
explanation = "A máquina não detectou nenhuma doença nos vasos sanguíneos."
return resultado, img_out, status_doenca, explanation, f"{num_analises} análises realizadas"
# Inicializar a contagem de análises
num_analises = 0
# Criar a interface Gradio
my_app = gr.Interface(
fn=processar_imagem_de_entrada_wrapper,
inputs=[
gr.inputs.Image(label="Angiograma:", shape=(512, 512)),
gr.inputs.Dropdown(['SE-RegUNet 4GF','SE-RegUNet 16GF', 'AngioNet', 'EffUNet++ B5', 'Reg-SA-UNet++', 'UNet3+'], label='Modelo', default='SE-RegUNet 4GF'),
gr.inputs.Checkbox(label="Salvar Resultado"),
],
outputs=[
gr.outputs.Label(label="Tempo decorrido"),
gr.outputs.Image(type="numpy", label="Imagem de Saída"),
gr.outputs.Label(label="Possui Doença?"),
gr.outputs.Label(label="Explicação"),
gr.outputs.Label(label="Análises Realizadas"),
],
title="Segmentação de Angiograma Coronariano",
description="Esta aplicação segmenta angiogramas coronarianos usando modelos de segmentação pré-treinados.",
theme="default",
layout="vertical",
allow_flagging=False,
)
# Iniciar a interface Gradio
my_app.launch() |