PJDEMO / templates /detect3.html
oriqqqqqqat
PJCOMMIT
3d7eadf
<!-- ลบออกอัตโนมัติ -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lesion Detection</title>
<link rel="stylesheet" href="{{ url_for('static', path='css/detect.css') }}">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Thai:wght@100;200;300;400;500;600;700&display=swap"
rel="stylesheet">
<link rel="icon" type="image/x-icon" href="{{ url_for('static', path='image/production.png') }}">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
<style>
:root {
--primary-color: #1da2e0;
--secondary-color: #c8e5fa;
}
body {
box-sizing: border-box;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
font-family: 'IBM Plex Sans Thai', sans-serif;
min-height: 100vh;
}
.loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); z-index: 1060; display: flex; justify-content: center; align-items: center; }
.spinner-container { color: white; }
.spinner { animation: rotate 2s linear infinite; width: 50px; height: 50px; }
.path { stroke: #93d3f4; stroke-linecap: round; animation: dash 1.5s ease-in-out infinite; }
@keyframes rotate { 100% { transform: rotate(360deg); } }
@keyframes dash {
0% { stroke-dasharray: 1, 150; stroke-dashoffset: 0; }
50% { stroke-dasharray: 90, 150; stroke-dashoffset: -35; }
100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124; }
}
#symptomTextArea::placeholder {
color: #adb5bd;
opacity: 1;
}
.background-color {
background-color: #f8f9fa; /* สีพื้นหลังอ่อนๆ */
}
.footer {
margin-top: auto; /* ดัน footer ไปอยู่ด้านล่างสุด */
}
</style>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<img src="{{ url_for('static', path='image/Logo.png') }}" alt="Logo" class="img-fluid logo"
style="max-width: 100px; height: auto;" />
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link active" href="/detect">ตรวจจับรอยโรค</a></li>
</ul>
</div>
</div>
</nav>
<!-- Detection Section -->
<div class="detect-section flex-grow-1 background-color">
<div class="container py-4">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="input-card shadow-lg p-4 bg-white rounded-3">
<h2 class="text-center mb-4 fw-bold">ตรวจจับรอยโรคในช่องปาก</h2>
<form id="sectionForm" method="post" enctype="multipart/form-data" action="/uploaded">
<div class="mb-4">
<label for="file" class="form-label fs-5">อัปโหลดรูปภาพ</label>
<input class="form-control" type="file" id="file" name="file" required accept="image/*">
</div>
<div>
<p class="fs-5">ประวัติ/อาการผู้ป่วย</p>
<p class="text-muted small">โปรดเลือกจากรายการ หรือพิมพ์เพิ่มเติม (หากไม่เลือกหรือพิมพ์ ระบบจะบันทึกว่า “ไม่มีอาการผิดปกติ” โดยอัตโนมัติ)</p>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-check mb-1"><input class="form-check-input symptom-checkbox" type="checkbox" id="check6" name="checkboxes" value="noSymptoms"><label class="form-check-label" for="check6">ไม่มีอาการผิดปกติ</label></div>
<div class="form-check mb-1"><input class="form-check-input symptom-checkbox" type="checkbox" id="check1" name="checkboxes" value="drinkAlcohol"><label class="form-check-label" for="check1">ดื่มเครื่องดื่มแอลกอฮอล์</label></div>
<div class="form-check mb-1"><input class="form-check-input symptom-checkbox" type="checkbox" id="check2" name="checkboxes" value="smoking"><label class="form-check-label" for="check2">สูบบุหรี่</label></div>
<div class="form-check mb-1"><input class="form-check-input symptom-checkbox" type="checkbox" id="check3" name="checkboxes" value="chewBetelNut"><label class="form-check-label" for="check3">เคี้ยวหมาก</label></div>
</div>
<div class="col-md-6">
<div class="form-check mb-1"><input class="form-check-input symptom-checkbox" type="checkbox" id="check4" name="checkboxes" value="eatSpicyFood"><label class="form-check-label" for="check4">รับประทานอาหารเผ็ดแล้วรู้สึกระคายเคือง</label></div>
<div class="form-check mb-1"><input class="form-check-input symptom-checkbox" type="checkbox" id="check5" name="checkboxes" value="wipeOff"><label class="form-check-label" for="check5">คราบขาวที่สามารถลอกออก</label></div>
<div class="form-check mb-1"><input class="form-check-input symptom-checkbox" type="checkbox" id="check7" name="checkboxes" value="alwaysHurts"><label class="form-check-label" for="check7">มีอาการเจ็บหรือระคายเคืองตลอดเวลา</label></div>
</div>
</div>
<div class="mt-4">
<label for="symptomTextArea" class="form-label">รายละเอียดอาการเพิ่มเติม:</label>
<textarea class="form-control" id="symptomTextArea" name="symptom_text" rows="4" placeholder="เช่น มีอาการปวดเป็นบางครั้ง, เป็นมานาน 2 สัปดาห์ ..."></textarea>
</div>
<div class="mt-4 d-flex justify-content-center">
<button class="button" type="submit">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- Loader Section -->
<div id="loading" class="loading-overlay d-none">
<div class="spinner-container text-center">
<svg class="spinner" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="4"></circle>
</svg>
<p class="mt-2">กำลังประมวลผล, กรุณารอสักครู่...</p>
</div>
</div>
<!-- ===== Result Modal ===== -->
{% if image_b64_data %}
<div class="modal fade" id="outputModal" tabindex="-1">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">ผลการตรวจจับรอยโรค</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row g-3">
<div class="col-lg-8">
<div class="row">
<div class="col-md-6 text-center mb-2">
<h6>ภาพต้นฉบับ</h6>
<img src="data:image/jpeg;base64, {{ image_b64_data }}" alt="Original Image" class="img-fluid rounded shadow-sm">
</div>
<div class="col-md-6 text-center">
<h6 class="d-inline-block">Grad-CAM Heatmap</h6>
<i class="bi bi-info-circle-fill ms-1 info-icon"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="Grad-CAM Heatmap แสดงถึงความสนใจของโมเดล โดยพื้นที่สีแดงคือบริเวณที่โมเดลให้ความสำคัญสูงสุดในการตัดสินใจ"></i>
<img src="data:image/jpeg;base64, {{ gradcam_b64_data }}" alt="Grad-CAM Heatmap" class="img-fluid rounded shadow-sm">
</div>
</div>
</div>
<div class="col-lg-4 d-flex align-items-center">
<div class="w-100">
<h4 class="mb-3">ผลการวิเคราะห์</h4>
<p class="fs-6">ผลการวิเคราะห์รอยโรคจากภาพร่วมกับประวัติผู้ป่วย:</p>
<div class="alert alert-primary" role="alert">
<h5 class="alert-heading">ประเภทรอยโรคที่คาดการณ์:</h5>
<p class="fs-4 fw-bold mb-0">{{ name_out }}</p>
</div>
<div class="alert alert-danger" role="alert">
<h5 class="alert-heading">โอกาสเป็นรอยโรค:</h5>
<p class="fs-4 fw-bold mb-0">{{ eva_output }} %</p>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">ปิด</button>
</div>
</div>
</div>
</div>
{% endif %}
<footer class="footer bg-dark text-white p-4 text-center">
&copy; 2025 MYCompany. All Rights Reserved.
</footer>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
// ส่วนจัดการ Loader
const form = document.getElementById('sectionForm');
const loadingOverlay = document.getElementById('loading');
if (form) {
form.addEventListener('submit', function () {
// ตรวจสอบว่าฟอร์ม valid ก่อนแสดง loader
if (form.checkValidity()) {
loadingOverlay.classList.remove('d-none');
}
});
}
// ส่วนจัดการ Modal แสดงผล
const outputModalElement = document.getElementById('outputModal');
if (outputModalElement) {
const outputModal = new bootstrap.Modal(outputModalElement);
outputModal.show();
}
// ส่วนจัดการ Checkbox "ไม่มีอาการผิดปกติ"
const noSymptomsCheckbox = document.getElementById('check6');
const otherCheckboxes = document.querySelectorAll('.symptom-checkbox:not(#check6)');
if (noSymptomsCheckbox) {
noSymptomsCheckbox.addEventListener('change', function() {
if (this.checked) {
otherCheckboxes.forEach(checkbox => {
// ยกเว้นกลุ่มพฤติกรรมเสี่ยง
if (!['check1', 'check2', 'check3'].includes(checkbox.id)) {
checkbox.checked = false;
checkbox.disabled = true;
}
});
} else {
otherCheckboxes.forEach(checkbox => {
checkbox.disabled = false;
});
}
});
}
});
</script>
</body>
</html>