sai4444's picture
initial commit
1e08de6
<!DOCTYPE html>
<html>
<head>
<title>YOLOv8 Object Detection</title>
<style>
body {
background-color: #000;
color: #fff;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
h1 {
color: #00ffcc;
text-align: center;
margin-top: 20px;
}
.main {
display: flex;
justify-content: space-between;
padding: 20px;
}
.left-panel {
width: 40%;
padding: 20px;
}
.right-panel {
width: 60%;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
min-height: 500px;
border-left: 2px solid #444;
}
input[type="file"] {
margin: 10px 0;
font-size: 16px;
border-radius: 6px;
width: 100%;
}
button {
margin: 10px 0;
padding: 10px 18px;
font-size: 16px;
border: none;
border-radius: 6px;
cursor: pointer;
width: 100%;
background-color: #00ffcc;
color: #000;
font-weight: bold;
}
button:hover {
background-color: #00ccaa;
}
h3 {
color: #ffcc00;
}
.zoomable {
transition: transform 0.2s ease;
border: 2px solid #00ffcc;
cursor: zoom-in;
max-width: 100%;
max-height: 500px;
}
.zoomed {
transform: scale(1.5);
cursor: zoom-out;
}
.tooltip {
position: relative;
display: inline-block;
margin-top: 20px;
}
.tooltip .tooltiptext {
visibility: hidden;
background-color: #333;
color: #fff;
text-align: center;
padding: 5px 8px;
border-radius: 4px;
position: absolute;
z-index: 1;
bottom: 110%;
left: 50%;
transform: translateX(-50%);
opacity: 0;
transition: opacity 0.3s;
font-size: 14px;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
video {
margin-top: 20px;
max-width: 100%;
}
/* Loader styling */
.loading-container {
text-align: center;
font-weight: bold;
font-size: 18px;
}
.loading-text {
margin-bottom: 10px;
color: #ffcc00;
}
.progress-bar {
width: 250px;
height: 8px;
background-color: #444;
border-radius: 10px;
overflow: hidden;
margin: 0 auto;
}
.progress {
width: 0%;
height: 100%;
background-color: #00ffcc;
animation: load-bar 1.5s infinite;
}
@keyframes load-bar {
0% { width: 0%; }
50% { width: 100%; }
100% { width: 0%; }
}
</style>
</head>
<body>
<h1>YOLOv8 Object Detection</h1>
<div class="main">
<!-- Left Panel -->
<div class="left-panel">
<form id="imageForm" action="/detect-image" method="post" enctype="multipart/form-data">
<h3>Image Detection</h3>
<input type="file" name="image" accept="image/*" required>
<button type="submit">Detect Image</button>
</form>
<h3>Video Detection</h3>
<input type="file" id="videoInput" accept="video/*" required>
<button onclick="uploadVideo()">Detect Video</button>
<h3>Real-Time Detection</h3>
<p style="color: gray;">🚀 Real-Time detection feature launching soon...</p>
</div>
<!-- Right Panel / Result Placeholder -->
<div class="right-panel" id="responseContainer">
<div id="loadingMsg" class="loading-container" style="display: none;">
<div class="loading-text">Processing... Please wait</div>
<div class="progress-bar"><div class="progress"></div></div>
</div>
<div class="tooltip" id="imageOutput" style="display: none;">
<span class="tooltiptext">Detected Image</span>
<img id="resultImage" class="zoomable" alt="Detected Image" />
</div>
<div class="tooltip" id="videoOutput" style="display: none;">
<span class="tooltiptext">Detected Video</span>
<video id="resultVideo" class="zoomable" controls autoplay muted></video>
</div>
</div>
</div>
<script>
// Zoom toggle
document.addEventListener("click", function (e) {
if (e.target.classList.contains("zoomable")) {
e.target.classList.toggle("zoomed");
}
});
function resetResponseView() {
const loadingMsg = document.getElementById("loadingMsg");
const progress = document.querySelector(".progress");
// Reset animation
progress.style.animation = "none";
void progress.offsetWidth;
progress.style.animation = "load-bar 1.5s infinite";
loadingMsg.style.display = "block";
document.getElementById("imageOutput").style.display = "none";
document.getElementById("videoOutput").style.display = "none";
document.getElementById("resultImage").src = "";
document.getElementById("resultVideo").src = "";
}
// Image Detection Handler
document.getElementById("imageForm").addEventListener("submit", async function (e) {
e.preventDefault();
const formData = new FormData(this);
resetResponseView();
try {
const response = await fetch("/detect-image", {
method: "POST",
body: formData
});
if (!response.ok) {
alert("Image detection failed.");
return;
}
const blob = await response.blob();
const imageUrl = URL.createObjectURL(blob);
document.getElementById("resultImage").src = imageUrl;
document.getElementById("imageOutput").style.display = "inline-block";
} catch (error) {
alert("Error detecting image.");
console.error(error);
} finally {
document.getElementById("loadingMsg").style.display = "none";
}
});
// Video Detection Handler
async function uploadVideo() {
const input = document.getElementById("videoInput");
const file = input.files[0];
if (!file) {
alert("Please select a video file.");
return;
}
resetResponseView();
const formData = new FormData();
formData.append("video", file);
try {
const response = await fetch("/detect-video", {
method: "POST",
body: formData,
});
if (!response.ok) {
alert("Video detection failed.");
return;
}
const blob = await response.blob();
const videoUrl = URL.createObjectURL(blob);
const videoElement = document.getElementById("resultVideo");
videoElement.src = videoUrl;
videoElement.load();
videoElement.play();
document.getElementById("videoOutput").style.display = "inline-block";
} catch (error) {
console.error("Upload error:", error);
alert("An error occurred during video upload.");
} finally {
document.getElementById("loadingMsg").style.display = "none";
}
}
</script>
</body>
</html>