|
|
<!DOCTYPE html> |
|
|
<html lang="pt-BR"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>PulmoX - AI System</title> |
|
|
|
|
|
|
|
|
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png"> |
|
|
|
|
|
|
|
|
|
|
|
<style> |
|
|
body { |
|
|
font-family: sans-serif; |
|
|
background-color: #080808; |
|
|
color: #F5F5F5; |
|
|
margin: 0; |
|
|
padding: 0; |
|
|
display: flex; |
|
|
} |
|
|
.sidebar { |
|
|
width: 280px; |
|
|
min-height: 100vh; |
|
|
background-color: #181818; |
|
|
backdrop-filter: none; |
|
|
color: #F5F5F5; |
|
|
padding: 20px; |
|
|
box-sizing: border-box; |
|
|
flex-shrink: 0; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
} |
|
|
.sidebar-content { |
|
|
flex-grow: 1; |
|
|
} |
|
|
.sidebar-image { |
|
|
margin-top: auto; |
|
|
padding-top: 20px; |
|
|
text-align: left; |
|
|
} |
|
|
.sidebar-image img { |
|
|
max-width: 100%; |
|
|
height: auto; |
|
|
border-radius: 8px; |
|
|
} |
|
|
.sidebar-logo { |
|
|
text-align: left; |
|
|
padding: 20px 0 0 0; |
|
|
background-color: transparent; |
|
|
} |
|
|
.sidebar-menu { |
|
|
margin-top: 40px; |
|
|
margin-bottom: 20px; |
|
|
} |
|
|
.sidebar-menu a { |
|
|
display: block; |
|
|
color: #F5F5F5; |
|
|
text-decoration: none; |
|
|
padding: 15px 20px; |
|
|
margin: 5px -20px; |
|
|
font-size: 28px; |
|
|
font-family: sans-serif; |
|
|
font-weight: 700; |
|
|
transition: all 0.2s ease-in-out; |
|
|
bborder-radius: 0; 10px 0; |
|
|
} |
|
|
.sidebar-menu a:hover { |
|
|
background-color: #303030; |
|
|
color: #F5F5F5; |
|
|
box-shadow: none; |
|
|
} |
|
|
.sidebar-menu a.active { |
|
|
background-color: #303030; |
|
|
color: #F5F5F5; |
|
|
box-shadow: none; |
|
|
font-weight: bold; |
|
|
border-left: 3px solid #00C853; |
|
|
padding-left: 17px; |
|
|
} |
|
|
.main-content { |
|
|
flex-grow: 1; |
|
|
padding: 1rem 2rem; |
|
|
box-sizing: border-box; |
|
|
} |
|
|
.main-container { |
|
|
max-width: 700px; |
|
|
margin: 0 auto; |
|
|
} |
|
|
.image-placeholder { |
|
|
width: 100%; |
|
|
height: 520px; |
|
|
background-color: #181818; |
|
|
backdrop-filter: none; |
|
|
border-radius: 0; |
|
|
border: 1px solid #333333; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
margin-bottom: 1.5rem; |
|
|
font-size: 1.5rem; |
|
|
color: rgba(204, 204, 204, 0.6); |
|
|
overflow: hidden; |
|
|
} |
|
|
.image-placeholder img { |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
object-fit: contain; |
|
|
} |
|
|
.prediction-placeholder { |
|
|
min-height: 50px; |
|
|
margin-bottom: 1.5rem; |
|
|
padding: 10px 0; |
|
|
} |
|
|
.columns-container { |
|
|
display: flex; |
|
|
gap: 1rem; |
|
|
align-items: flex-start; |
|
|
} |
|
|
.column { |
|
|
flex: 1; |
|
|
} |
|
|
.button-style { |
|
|
border: 2px solid #F5F5F5; |
|
|
border-radius: 0; |
|
|
background-color: black; |
|
|
color: #F5F5F5; |
|
|
padding: 1.2rem 2rem; |
|
|
font-size: 20px; |
|
|
font-family: sans-serif; |
|
|
cursor: pointer; |
|
|
width: 100%; |
|
|
text-align: center; |
|
|
transition: all 0.2s ease-in-out; |
|
|
height: 100%; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
text-decoration: none; |
|
|
box-sizing: border-box; |
|
|
} |
|
|
.button-style:hover { |
|
|
background-color: #303030; |
|
|
border-color: #00C853; |
|
|
} |
|
|
.upload-label { |
|
|
display: block; |
|
|
cursor: pointer; |
|
|
} |
|
|
#file-upload-input { |
|
|
display: none; |
|
|
} |
|
|
.footer { |
|
|
text-align: left; |
|
|
padding: 1rem 20px; |
|
|
color: #aaa; |
|
|
font-size: 14px; |
|
|
line-height: 1.5; |
|
|
} |
|
|
.footer a { |
|
|
color: #00C853; !important; |
|
|
text-decoration: none !important; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="sidebar"> |
|
|
<div class="sidebar-logo"> |
|
|
<a href="index.html"><img src="pulmox_logo_v2.png" alt="PulmoX Logo" style="width: 220px; height: auto; margin-bottom: 20px;"></a> |
|
|
</div> |
|
|
<div class="sidebar-content"> |
|
|
|
|
|
<div class="sidebar-menu"> |
|
|
<a href="index.html">Sobre</a> |
|
|
<a href="ai_system.html" class="active">PulmoX</a> |
|
|
<a href="contact.html">Contato</a> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
</div> |
|
|
<div class="main-content"> |
|
|
<div class="main-container"> |
|
|
<div style="font-size:32px; font-weight:bold; margin-top:0px; line-height:1.2; margin-bottom: 1.5rem;"> |
|
|
Classificação de Doenças Pulmonares via IA |
|
|
</div> |
|
|
|
|
|
<div class="image-placeholder" id="image-placeholder"> |
|
|
<img src="doencas_pulmonares.jpg" alt="Imagem de Raio-X de Pulmão"> |
|
|
</div> |
|
|
<div class="prediction-placeholder"> |
|
|
<span style="color:white; font-size:32px;">Previsão:</span> |
|
|
<span id="prediction-result" style="color:#5dade2; font-size:32px;">Aguardando Ação</span> |
|
|
<span id="prediction-prob" style="color:white; font-size:32px;"></span> |
|
|
</div> |
|
|
<div class="columns-container"> |
|
|
<div class="column"> |
|
|
<button class="button-style" id="random-button">Raios-X Aleatórios</button> |
|
|
</div> |
|
|
<div class="column"> |
|
|
<input type="file" id="file-upload-input" accept=".png"> |
|
|
<label for="file-upload-input" class="upload-label"> |
|
|
<div class="button-style">Selecionar Arquivo</div> |
|
|
</label> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
<script> |
|
|
const resultElement = document.getElementById('prediction-result'); |
|
|
const probElement = document.getElementById('prediction-prob'); |
|
|
const imagePlaceholder = document.getElementById('image-placeholder'); |
|
|
const fileInput = document.getElementById('file-upload-input'); |
|
|
|
|
|
function updatePrediction(classe, prob, cor) { |
|
|
resultElement.textContent = classe; |
|
|
resultElement.style.color = cor; |
|
|
probElement.textContent = prob > 0 ? ` - ${prob}%` : ''; |
|
|
} |
|
|
|
|
|
function displayImage(file) { |
|
|
const reader = new FileReader(); |
|
|
reader.onload = function(e) { |
|
|
imagePlaceholder.innerHTML = `<img src="${e.target.result}" alt="Imagem de Raio-X">`; |
|
|
}; |
|
|
reader.readAsDataURL(file); |
|
|
} |
|
|
|
|
|
fileInput.addEventListener('change', function(event) { |
|
|
const file = event.target.files[0]; |
|
|
if (!file) return; |
|
|
|
|
|
displayImage(file); |
|
|
|
|
|
const formData = new FormData(); |
|
|
formData.append('file', file); |
|
|
|
|
|
updatePrediction('Processando...', 0, '#9ecbff'); |
|
|
|
|
|
fetch('/predict', { |
|
|
method: 'POST', |
|
|
body: formData |
|
|
}) |
|
|
.then(response => response.json()) |
|
|
.then(data => { |
|
|
if (data.error) { |
|
|
updatePrediction('Erro', 0, '#ff0000'); |
|
|
alert(`Erro na predição: ${data.error}`); |
|
|
return; |
|
|
} |
|
|
updatePrediction(data.classe, data.prob, data.cor); |
|
|
}) |
|
|
.catch(error => { |
|
|
console.error('Erro:', error); |
|
|
updatePrediction('Erro de Conexão', 0, '#ff0000'); |
|
|
alert('Erro ao conectar com o servidor de predição. Verifique se o servidor Flask está rodando.'); |
|
|
}); |
|
|
}); |
|
|
|
|
|
document.getElementById('random-button').addEventListener('click', function() { |
|
|
updatePrediction('Buscando Imagem...', 0, '#9ecbff'); |
|
|
|
|
|
fetch('/random_predict', { |
|
|
method: 'GET' |
|
|
}) |
|
|
.then(response => response.json()) |
|
|
.then(data => { |
|
|
if (data.error) { |
|
|
updatePrediction('Erro', 0, '#ff0000'); |
|
|
alert(`Erro ao buscar imagem: ${data.error}`); |
|
|
return; |
|
|
} |
|
|
|
|
|
const imgSource = `data:${data.image_mimetype};base64,${data.image_base64}`; |
|
|
imagePlaceholder.innerHTML = `<img src="${imgSource}" alt="Imagem de Raio-X Aleatória">`; |
|
|
|
|
|
updatePrediction(data.classe, data.prob, data.cor); |
|
|
}) |
|
|
.catch(error => { |
|
|
console.error('Erro:', error); |
|
|
updatePrediction('Erro de Conexão', 0, '#ff0000'); |
|
|
alert('Erro ao conectar com o servidor de predição. Verifique se o servidor Flask está rodando.'); |
|
|
}); |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |
|
|
|