├── README.md ├── haarcascade_frontalface_default.xml ├── index.html └── js ├── opencv.js └── utils.js /README.md: -------------------------------------------------------------------------------- 1 | # face-detection-opencv-js 2 | 3 | 4 | To test this copy or clone all the files with same directory structure and serve from the directory where 'index.html' file is located. 5 | 6 | e.g: 7 | 8 | $ python -m http.server 9 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Opencv JS 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 64 | -------------------------------------------------------------------------------- /js/utils.js: -------------------------------------------------------------------------------- 1 | function Utils(errorOutputId) { // eslint-disable-line no-unused-vars 2 | let self = this; 3 | this.errorOutput = document.getElementById(errorOutputId); 4 | 5 | const OPENCV_URL = 'opencv.js'; 6 | this.loadOpenCv = function(onloadCallback) { 7 | let script = document.createElement('script'); 8 | script.setAttribute('async', ''); 9 | script.setAttribute('type', 'text/javascript'); 10 | script.addEventListener('load', () => { 11 | if (cv.getBuildInformation) 12 | { 13 | console.log(cv.getBuildInformation()); 14 | onloadCallback(); 15 | } 16 | else 17 | { 18 | // WASM 19 | cv['onRuntimeInitialized']=()=>{ 20 | console.log(cv.getBuildInformation()); 21 | onloadCallback(); 22 | } 23 | } 24 | }); 25 | script.addEventListener('error', () => { 26 | self.printError('Failed to load ' + OPENCV_URL); 27 | }); 28 | script.src = OPENCV_URL; 29 | let node = document.getElementsByTagName('script')[0]; 30 | node.parentNode.insertBefore(script, node); 31 | }; 32 | 33 | this.createFileFromUrl = function(path, url, callback) { 34 | let request = new XMLHttpRequest(); 35 | request.open('GET', url, true); 36 | request.responseType = 'arraybuffer'; 37 | request.onload = function(ev) { 38 | if (request.readyState === 4) { 39 | if (request.status === 200) { 40 | let data = new Uint8Array(request.response); 41 | cv.FS_createDataFile('/', path, data, true, false, false); 42 | callback(); 43 | } else { 44 | self.printError('Failed to load ' + url + ' status: ' + request.status); 45 | } 46 | } 47 | }; 48 | request.send(); 49 | }; 50 | 51 | this.loadImageToCanvas = function(url, cavansId) { 52 | let canvas = document.getElementById(cavansId); 53 | let ctx = canvas.getContext('2d'); 54 | let img = new Image(); 55 | img.crossOrigin = 'anonymous'; 56 | img.onload = function() { 57 | canvas.width = img.width; 58 | canvas.height = img.height; 59 | ctx.drawImage(img, 0, 0, img.width, img.height); 60 | }; 61 | img.src = url; 62 | }; 63 | 64 | this.executeCode = function(textAreaId) { 65 | try { 66 | this.clearError(); 67 | let code = document.getElementById(textAreaId).value; 68 | eval(code); 69 | } catch (err) { 70 | this.printError(err); 71 | } 72 | }; 73 | 74 | this.clearError = function() { 75 | this.errorOutput.innerHTML = ''; 76 | }; 77 | 78 | this.printError = function(err) { 79 | if (typeof err === 'undefined') { 80 | err = ''; 81 | } else if (typeof err === 'number') { 82 | if (!isNaN(err)) { 83 | if (typeof cv !== 'undefined') { 84 | err = 'Exception: ' + cv.exceptionFromPtr(err).msg; 85 | } 86 | } 87 | } else if (typeof err === 'string') { 88 | let ptr = Number(err.split(' ')[0]); 89 | if (!isNaN(ptr)) { 90 | if (typeof cv !== 'undefined') { 91 | err = 'Exception: ' + cv.exceptionFromPtr(ptr).msg; 92 | } 93 | } 94 | } else if (err instanceof Error) { 95 | err = err.stack.replace(/\n/g, '
'); 96 | } 97 | this.errorOutput.innerHTML = err; 98 | }; 99 | 100 | this.loadCode = function(scriptId, textAreaId) { 101 | let scriptNode = document.getElementById(scriptId); 102 | let textArea = document.getElementById(textAreaId); 103 | if (scriptNode.type !== 'text/code-snippet') { 104 | throw Error('Unknown code snippet type'); 105 | } 106 | textArea.value = scriptNode.text.replace(/^\n/, ''); 107 | }; 108 | 109 | this.addFileInputHandler = function(fileInputId, canvasId) { 110 | let inputElement = document.getElementById(fileInputId); 111 | inputElement.addEventListener('change', (e) => { 112 | let files = e.target.files; 113 | if (files.length > 0) { 114 | let imgUrl = URL.createObjectURL(files[0]); 115 | self.loadImageToCanvas(imgUrl, canvasId); 116 | } 117 | }, false); 118 | }; 119 | 120 | function onVideoCanPlay() { 121 | if (self.onCameraStartedCallback) { 122 | self.onCameraStartedCallback(self.stream, self.video); 123 | } 124 | }; 125 | 126 | this.startCamera = function(resolution, callback, videoId) { 127 | const constraints = { 128 | 'qvga': {width: {exact: 320}, height: {exact: 240}}, 129 | 'vga': {width: {exact: 640}, height: {exact: 480}}}; 130 | let video = document.getElementById(videoId); 131 | if (!video) { 132 | video = document.createElement('video'); 133 | } 134 | 135 | let videoConstraint = constraints[resolution]; 136 | if (!videoConstraint) { 137 | videoConstraint = true; 138 | } 139 | 140 | navigator.mediaDevices.getUserMedia({video: videoConstraint, audio: false}) 141 | .then(function(stream) { 142 | video.srcObject = stream; 143 | video.play(); 144 | self.video = video; 145 | self.stream = stream; 146 | self.onCameraStartedCallback = callback; 147 | video.addEventListener('canplay', onVideoCanPlay, false); 148 | }) 149 | .catch(function(err) { 150 | self.printError('Camera Error: ' + err.name + ' ' + err.message); 151 | }); 152 | }; 153 | 154 | this.stopCamera = function() { 155 | if (this.video) { 156 | this.video.pause(); 157 | this.video.srcObject = null; 158 | this.video.removeEventListener('canplay', onVideoCanPlay); 159 | } 160 | if (this.stream) { 161 | this.stream.getVideoTracks()[0].stop(); 162 | } 163 | }; 164 | }; 165 | --------------------------------------------------------------------------------