PJDEMO / templates /detect.html
oriqqqqqqat
modifytemplate
a5e2a63
<!DOCTYPE html>
<html lang="th">
<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">
<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 { font-family:'IBM Plex Sans Thai',sans-serif; display:flex; flex-direction:column; min-height:100vh; }
.background-color { background-color:#f8f9fa; }
/* Loader */
.loading-overlay {
position:fixed; top:0; left:0; width:100%; height:100%;
background:rgba(0,0,0,0.7); z-index:2000;
display:flex; justify-content:center; align-items:center;
}
.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; }
}
</style>
</head>
<body>
<!-- Navbar -->
<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') }}" class="img-fluid" style="max-width:100px;">
</a>
<button class="navbar-toggler" 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>
<!-- Form 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">
{% if error %}
<div class="alert alert-danger text-center">{{ error }}</div>
{% endif %}
<h2 class="text-center mb-4 fw-bold">ตรวจจับรอยโรคในช่องปาก</h2>
<form id="sectionForm" method="post" enctype="multipart/form-data" action="/uploaded">
<!-- Upload image -->
<div class="mb-4">
<label class="form-label fs-5">อัปโหลดรูปภาพ</label>
<input class="form-control" type="file" name="file" required accept="image/*">
</div>
<p class="fs-5">ประวัติ/อาการผู้ป่วย</p>
<p class="text-muted small">เลือกจากรายการ หรือกรอกเพิ่ม (ถ้าไม่เลือก = ไม่มีอาการ)</p>
<div class="row">
<!-- Left -->
<div class="col-md-6">
<div class="form-check mb-1">
<input class="form-check-input symptom-checkbox" id="check6" type="checkbox" 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" name="checkboxes" value="drinkAlcohol">
<label class="form-check-label">ดื่มเครื่องดื่มแอลกอฮอล์</label>
</div>
<div class="form-check mb-1">
<input class="form-check-input symptom-checkbox" type="checkbox" name="checkboxes" value="smoking">
<label class="form-check-label">สูบบุหรี่</label>
</div>
<div class="form-check mb-1">
<input class="form-check-input symptom-checkbox" type="checkbox" name="checkboxes" value="chewBetelNut">
<label class="form-check-label">เคี้ยวหมาก</label>
</div>
</div>
<!-- Right -->
<div class="col-md-6">
<div class="form-check mb-1">
<input class="form-check-input symptom-checkbox" type="checkbox" name="checkboxes" value="eatSpicyFood">
<label class="form-check-label">รับประทานอาหารเผ็ดแล้วรู้สึกระคายเคือง</label>
</div>
<div class="form-check mb-1">
<input class="form-check-input symptom-checkbox" type="checkbox" name="checkboxes" value="wipeOff">
<label class="form-check-label">คราบขาวที่สามารถลอกออก</label>
</div>
<div class="form-check mb-1">
<input class="form-check-input symptom-checkbox" type="checkbox" name="checkboxes" value="alwaysHurts">
<label class="form-check-label">เจ็บหรือแสบตลอดเวลา</label>
</div>
</div>
</div>
<!-- Additional symptoms -->
<div class="mt-4">
<label class="form-label">รายละเอียดอาการเพิ่มเติม:</label>
<textarea class="form-control" id="symptomTextArea" name="symptom_text" rows="4"
placeholder="เช่น มีอาการปวดเป็นบางครั้ง, เป็นมานาน 2 สัปดาห์ ..."></textarea>
</div>
<!-- Cloudflare Turnstile -->
<div class="cf-turnstile mt-4 mb-3"
data-sitekey="0x4AAAAAACEfyPjr3pfV21Mm"
data-callback="onTurnstileSuccess">
</div>
<input type="hidden" id="turnstile-token" name="cf-turnstile-response">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script>
function onTurnstileSuccess(token) {
document.getElementById("turnstile-token").value = token;
}
</script>
<!-- Submit -->
<div class="mt-4 d-flex justify-content-center">
<button class="button btn btn-primary px-4" type="submit">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- Loader -->
<div id="loading" class="loading-overlay d-none">
<div class="text-center text-white">
<svg class="spinner" 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>
<!-- Modal Results -->
{% 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 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">
<h6>ภาพต้นฉบับ</h6>
<img src="data:image/jpeg;base64, {{ image_b64_data }}"
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"
data-bs-toggle="tooltip"
title="พื้นที่สีแดงคือบริเวณที่โมเดลใช้ตัดสินใจมากที่สุด"></i>
<img src="data:image/jpeg;base64, {{ gradcam_b64_data }}"
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>
<div class="alert alert-primary">
<h5>ประเภทรอยโรค:</h5>
<p class="fs-4 fw-bold">{{ name_out }}</p>
</div>
<div class="alert alert-danger">
<h5>ความมั่นใจ:</h5>
<p class="fs-4 fw-bold">{{ eva_output }}%</p>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<a href="/detect" class="btn btn-secondary">ตรวจใหม่</a>
</div>
</div>
</div>
</div>
{% endif %}
<footer class="footer bg-dark text-white p-4 text-center mt-auto">
© 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', () => {
const form = document.getElementById('sectionForm');
const loadingOverlay = document.getElementById('loading');
form.addEventListener('submit', () => {
if (form.checkValidity()) loadingOverlay.classList.remove('d-none');
});
const modalElement = document.getElementById('outputModal');
if (modalElement) new bootstrap.Modal(modalElement).show();
const noSymptoms = document.getElementById('check6');
const other = document.querySelectorAll('.symptom-checkbox:not(#check6)');
noSymptoms.addEventListener('change', function() {
if (this.checked) {
other.forEach(cb => {
if (!['check1','check2','check3'].includes(cb.id)) {
cb.checked = false;
cb.disabled = true;
}
});
} else {
other.forEach(cb => cb.disabled = false);
}
});
});
</script>
</body>
</html>