| | <!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>
|
| |
|