├── .gitignore ├── README.md ├── index.html ├── style.css └── video.js /.gitignore: -------------------------------------------------------------------------------- 1 | hs -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🤖 ai-object-detection 2 | ## 👋 About this project 3 | This is a web AI object detection. You can use it in your web browser. This web application uses the camera of your device to detect objects. 4 | 5 | ## ⚙️ Features 6 | 7 | - ✅ Toggle switch to turn AI on or off 8 | - ✅ Range slider to control frame rate 9 | 10 | ## 🖼️ Images 11 | preview-combined 12 | 13 | ## 💪 Try it 14 | If you are not convinced yet just try it out here: https://woody.pizza/tensorflow/object-detection/ 15 | 16 | ## 🌐 Multiple browser support 17 | Probably this will work with the most browsers, but here is a list which browsers I have tested: 18 | 19 | | Browser | supported | 20 | |:-----------------:|:---------:| 21 | | Firefox | ✅ | 22 | | Chrome | ✅ | 23 | | Edge | ✅ | 24 | | Internet Explorer | ❌ | 25 | 26 | | Mobile Browser | supported | 27 | |:--------------:|:---------:| 28 | | Firefox | ✅ | 29 | | Chrome | ✅ | 30 | 31 | ## ✌️ Credits 32 | - [Materialize](https://materializecss.com/) 33 | - [ml5js](https://ml5js.org/) 34 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AI object detection 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Loading...

15 | 16 | 17 |

18 | 19 |

20 | 21 | 22 | 23 | 33 | 34 | 35 | 36 | 41 | 42 |
AI: 24 |
25 | 31 |
32 |
FPS: 37 |

38 | 39 |

40 |
43 | 44 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | body { 2 | text-align: center; 3 | } 4 | 5 | video { 6 | width: 0px; 7 | height: 0px; 8 | } 9 | 10 | table { 11 | width: auto; 12 | margin: auto; 13 | } 14 | 15 | tr, 16 | td { 17 | border: 0px; 18 | text-align: center; 19 | } -------------------------------------------------------------------------------- /video.js: -------------------------------------------------------------------------------- 1 | document.getElementById("ai").addEventListener("change", toggleAi) 2 | document.getElementById("fps").addEventListener("input", changeFps) 3 | 4 | const video = document.getElementById("video"); 5 | const c1 = document.getElementById('c1'); 6 | const ctx1 = c1.getContext('2d'); 7 | var cameraAvailable = false; 8 | var aiEnabled = false; 9 | var fps = 16; 10 | 11 | /* Setting up the constraint */ 12 | var facingMode = "environment"; // Can be 'user' or 'environment' to access back or front camera (NEAT!) 13 | var constraints = { 14 | audio: false, 15 | video: { 16 | facingMode: facingMode 17 | } 18 | }; 19 | 20 | /* Stream it to video element */ 21 | camera(); 22 | function camera() { 23 | if (!cameraAvailable) { 24 | console.log("camera") 25 | navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { 26 | cameraAvailable = true; 27 | video.srcObject = stream; 28 | }).catch(function (err) { 29 | cameraAvailable = false; 30 | if (modelIsLoaded) { 31 | if (err.name === "NotAllowedError") { 32 | document.getElementById("loadingText").innerText = "Waiting for camera permission"; 33 | } 34 | } 35 | setTimeout(camera, 1000); 36 | }); 37 | } 38 | } 39 | 40 | window.onload = function () { 41 | timerCallback(); 42 | } 43 | 44 | function timerCallback() { 45 | if (isReady()) { 46 | setResolution(); 47 | ctx1.drawImage(video, 0, 0, c1.width, c1.height); 48 | if (aiEnabled) { 49 | ai(); 50 | } 51 | } 52 | setTimeout(timerCallback, fps); 53 | } 54 | 55 | function isReady() { 56 | if (modelIsLoaded && cameraAvailable) { 57 | document.getElementById("loadingText").style.display = "none"; 58 | document.getElementById("ai").disabled = false; 59 | return true; 60 | } else { 61 | return false; 62 | } 63 | } 64 | 65 | function setResolution() { 66 | if (window.screen.width < video.videoWidth) { 67 | c1.width = window.screen.width * 0.9; 68 | let factor = c1.width / video.videoWidth; 69 | c1.height = video.videoHeight * factor; 70 | } else if (window.screen.height < video.videoHeight) { 71 | c1.height = window.screen.height * 0.50; 72 | let factor = c1.height / video.videoHeight; 73 | c1.width = video.videoWidth * factor; 74 | } 75 | else { 76 | c1.width = video.videoWidth; 77 | c1.height = video.videoHeight; 78 | } 79 | }; 80 | 81 | function toggleAi() { 82 | aiEnabled = document.getElementById("ai").checked; 83 | } 84 | 85 | function changeFps() { 86 | fps = 1000 / document.getElementById("fps").value; 87 | } 88 | 89 | function ai() { 90 | // Detect objects in the image element 91 | objectDetector.detect(c1, (err, results) => { 92 | console.log(results); // Will output bounding boxes of detected objects 93 | for (let index = 0; index < results.length; index++) { 94 | const element = results[index]; 95 | ctx1.font = "15px Arial"; 96 | ctx1.fillStyle = "red"; 97 | ctx1.fillText(element.label + " - " + (element.confidence * 100).toFixed(2) + "%", element.x + 10, element.y + 15); 98 | ctx1.beginPath(); 99 | ctx1.strokeStyle = "red"; 100 | ctx1.rect(element.x, element.y, element.width, element.height); 101 | ctx1.stroke(); 102 | console.log(element.label); 103 | } 104 | }); 105 | } --------------------------------------------------------------------------------