| <!DOCTYPE html>
|
| <html lang="en">
|
| <head>
|
| <meta charset="UTF-8">
|
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| <title>🤖 AI Object Scanner</title>
|
|
|
|
|
| <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js"></script>
|
| <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd"></script>
|
|
|
| <style>
|
|
|
| body {
|
| background-color: #0d1117;
|
| color: #00f3ff;
|
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| display: flex;
|
| flex-direction: column;
|
| align-items: center;
|
| min-height: 100vh;
|
| margin: 0;
|
| padding: 20px;
|
| }
|
|
|
| h1 {
|
| text-shadow: 0 0 15px #00f3ff;
|
| letter-spacing: 2px;
|
| margin-bottom: 5px;
|
| }
|
|
|
| p {
|
| color: #ccc;
|
| margin-bottom: 20px;
|
| }
|
|
|
|
|
| .cam-container {
|
| position: relative;
|
| border: 3px solid #333;
|
| border-radius: 10px;
|
| overflow: hidden;
|
| box-shadow: 0 0 30px rgba(0, 243, 255, 0.2);
|
| background: #000;
|
| min-width: 640px;
|
| min-height: 480px;
|
| display: flex;
|
| justify-content: center;
|
| align-items: center;
|
| }
|
|
|
| video {
|
| display: block;
|
| width: 640px;
|
| height: 480px;
|
| }
|
|
|
|
|
| #box-overlay {
|
| position: absolute;
|
| top: 0;
|
| left: 0;
|
| width: 100%;
|
| height: 100%;
|
| pointer-events: none;
|
| }
|
|
|
|
|
| .detection-box {
|
| position: absolute;
|
| border: 2px solid #00f3ff;
|
| background-color: rgba(0, 243, 255, 0.1);
|
| z-index: 10;
|
| }
|
|
|
| .detection-label {
|
| position: absolute;
|
| top: -25px;
|
| left: 0;
|
| background-color: #00f3ff;
|
| color: #000;
|
| padding: 2px 8px;
|
| font-size: 14px;
|
| font-weight: bold;
|
| }
|
|
|
| button {
|
| background-color: #00f3ff;
|
| color: #000;
|
| border: none;
|
| padding: 15px 40px;
|
| font-size: 1.2rem;
|
| font-weight: bold;
|
| cursor: pointer;
|
| border-radius: 50px;
|
| margin-top: 20px;
|
| transition: transform 0.2s;
|
| }
|
|
|
| button:hover {
|
| transform: scale(1.05);
|
| box-shadow: 0 0 20px #00f3ff;
|
| }
|
|
|
| button:disabled {
|
| background-color: #555;
|
| color: #888;
|
| cursor: wait;
|
| transform: none;
|
| box-shadow: none;
|
| }
|
|
|
| .status {
|
| font-family: monospace;
|
| font-size: 1.2rem;
|
| margin-top: 10px;
|
| }
|
| </style>
|
| </head>
|
| <body>
|
|
|
| <h1>🤖 AI Vision Lab</h1>
|
| <p>Hold objects up to the camera (cellphone, cup, book, person) to scan them.</p>
|
|
|
| <div class="cam-container">
|
|
|
| <video id="webcam" autoplay muted playsinline></video>
|
|
|
| <div id="box-overlay"></div>
|
| </div>
|
|
|
| <div class="status" id="statusText">⏳ Initializing Systems...</div>
|
|
|
| <button id="startBtn" onclick="enableCam()" disabled>Please Wait...</button>
|
|
|
| <script>
|
|
|
|
|
| const video = document.getElementById('webcam');
|
| const overlay = document.getElementById('box-overlay');
|
| const startBtn = document.getElementById('startBtn');
|
| const statusText = document.getElementById('statusText');
|
|
|
| let model = undefined;
|
|
|
|
|
|
|
| cocoSsd.load().then(function (loadedModel) {
|
| model = loadedModel;
|
| statusText.innerText = "✅ System Ready";
|
| startBtn.disabled = false;
|
| startBtn.innerText = "🔴 Activate Scanner";
|
| });
|
|
|
|
|
| function enableCam() {
|
| if (!model) {
|
| return;
|
| }
|
|
|
|
|
| startBtn.style.display = 'none';
|
| statusText.innerText = "👀 Scanning...";
|
|
|
|
|
| const constraints = {
|
| video: { width: 640, height: 480 }
|
| };
|
|
|
| navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
|
| video.srcObject = stream;
|
|
|
| video.addEventListener('loadeddata', predictWebcam);
|
| });
|
| }
|
|
|
|
|
| function predictWebcam() {
|
|
|
| model.detect(video).then(function (predictions) {
|
|
|
|
|
| overlay.innerHTML = '';
|
|
|
|
|
| for (let n = 0; n < predictions.length; n++) {
|
|
|
|
|
| if (predictions[n].score > 0.66) {
|
|
|
|
|
| const p = document.createElement('div');
|
| p.classList.add('detection-box');
|
|
|
|
|
|
|
| const x = predictions[n].bbox[0];
|
| const y = predictions[n].bbox[1];
|
| const width = predictions[n].bbox[2];
|
| const height = predictions[n].bbox[3];
|
|
|
|
|
| p.style.left = x + 'px';
|
| p.style.top = y + 'px';
|
| p.style.width = width + 'px';
|
| p.style.height = height + 'px';
|
|
|
|
|
| const label = document.createElement('span');
|
| label.classList.add('detection-label');
|
| label.innerText = predictions[n].class.toUpperCase() + ' ' + Math.round(parseFloat(predictions[n].score) * 100) + '%';
|
|
|
|
|
| p.appendChild(label);
|
| overlay.appendChild(p);
|
| }
|
| }
|
|
|
|
|
| window.requestAnimationFrame(predictWebcam);
|
| });
|
| }
|
| </script>
|
| </body>
|
| </html>
|
|
|