Build a Vanilla Javascript Project to Implement Realtime Motion Face Detection Using Webcam in Browser Using HTML5 Full Project For Beginners

 

 

 

index.html

 

 

<!DOCTYPE html>
<html>
	<head>
		<title>Webcam motion detection</title>
		<style>
			#webCamWindow {
	border: 1px solid #000;
	width: 640px;
	height:  480px;
	position: absolute;
	top: 0;
	opacity: 1;
	left: 0;	
}

#canvas {
	position: absolute;
	opacity: 1;
	top: 0;
	left: 0;
	width: 640px;
	height:  480px;
}

#movement {
	position: absolute;
	top: 0;
	left: 0;
	border: 1px solid red;
	background: rgba(255,0,0,0.3);
}
		</style>
	</head>
	<body>
		<video id="webCamWindow" autoplay></video>
		<div id="movement"></div>
		
		<script>
			MotionDetector = {};
		</script>
		<script>
			/**
 *
 * @project        Motion Detection in JS
 * @file           WebCamCapture.js
 * @description    Interfaces with the web cam.
 * @author         Benjamin Horn
 * @package        MotionDetector
 * @version        -
 * 
 */

;(function(App) {
	
	"use strict";
	
	/*
	 * Creates a new web cam capture.
	 *
	 * @param <Element> videoElement The video element where we want to stream the footage.
	 *
	 * @return <Object> The initalized object.
	 *
	 */
	App.WebCamCapture = function(videoElement) {

		var webCamWindow = false;
		var width = 640;
		var height = 480;

		/*
		 * Initializes the object.
		 *
		 * @param <Element> videoElement The video element where we want to stream the footage.
		 *
		 * @return void.
		 *
		 */
		function initialize(videoElement) {
			if(typeof videoElement != 'object') {
				webCamWindow = document.getElementById(videoElement);
			} else {
				webCamWindow = videoElement;
			}

			if(hasSupport()) {
				if(webCamWindow) {
					webCamWindow.style.width = width + 'px';
					webCamWindow.style.height = height + 'px';
					startStream();
				}
				
			} else {
				alert('No support found');
			}
		}

		/*
		 * Starts the streaming from the webcamera to the video element.
		 *
		 * @return void.
		 *
		 */
		function startStream() {
			(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia).call(
				navigator, 
				{video: true}, 
				function(localMediaStream) {
					if(webCamWindow) {
						var vendorURL = window.URL || window.webkitURL;

						if (navigator.mozGetUserMedia) {
							webCamWindow.mozSrcObject = localMediaStream;
							webCamWindow.play();
						} else {
							try {
								webCamWindow.srcObject = localMediaStream;
							} catch (error) {
								webCamWindow.src = vendorURL.createObjectURL(localMediaStream);
							}
						}
					}
				}, 
				console.error
			);
		}

		/*
		 * Captures a still image from the video.
		 *
		 * @param <Element> append An optional element where we want to append the image. 
		 *
		 * @return <Element> A canvas element with the image.
		 *
		 */
		function captureImage(append) {
			var canvas = document.createElement('canvas');
			canvas.width = width;
			canvas.height = height;
			canvas.getContext('2d').drawImage(webCamWindow, 0, 0, width, height);

			var pngImage = canvas.toDataURL("image/png"); 
			
			if(append) {
				append.appendChild(canvas);	
			}

			return canvas;
		}

		/*
		 * Sets the size of the video
		 *
		 * @param <Int> w The width.
		 * @param <Int> h The height.
		 *
		 * @return void.
		 *
		 */
		function setSize(w, h) {
			width = w;
			height = h;
		}

		/*
		 * Checks if the browser supports webcam interfacing.
		 *
		 * @return <Boolean>.
		 *
		 */
		function hasSupport(){
			return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
				navigator.mozGetUserMedia || navigator.msGetUserMedia);
		}

		// Initialize on creation.
		initialize(videoElement);

		// Return public interface.
		return {
			setSize: setSize,
			hasSupport: hasSupport,
			captureImage: captureImage
		};

	}

})(MotionDetector);

		</script>
		<script>
			/**
 *
 * @project        Motion Detection in JS
 * @file           ImageCompare.js
 * @description    Compares two images on pixel level.
 * @author         Benjamin Horn
 * @package        MotionDetector
 * @version        -
 * 
 */

;(function(App) {

"use strict";

/*
 * Compares to images and shows the difference starting
 * from the top left to the bottom right.
 *
 * @return <Object> The initalized object.
 *
 */
App.ImageCompare = function() {
	var sensitivity, temp1Canvas, temp1Context, temp2Canvas, temp2Context, topLeft, bottomRight;

	/*
	 * Initializes the object.
	 * Also used as a reset between image comparements.
	 *
	 * @return void.
	 *
	 */
	function initialize() {
		sensitivity = 40;

		if(!temp1Canvas) {
			temp1Canvas = document.createElement('canvas');
			temp1Context = temp1Canvas.getContext("2d");
		}

		if(!temp2Canvas) {
			temp2Canvas = document.createElement('canvas');
			temp2Context = temp2Canvas.getContext("2d");
		}

		topLeft = [Infinity,Infinity];
		bottomRight = [0,0];
	}

	/*
	 * Compares to images.
	 *
	 * @param <Element> image1 The canvas of the first image.
	 * @param <Element> image2 The canvas of the second image.
	 * @param <Int>		width  The width to compare.
	 * @param <Int>		height The height to compare
	 *
	 * @return <Object> The top left, and the bottom right pixels.
	 *
	 */
	function compare(image1, image2, width, height) {
		initialize();

		if(!image1 || !image2) {
			return;
		}

		temp1Context.clearRect(0,0,100000,100000);
		temp1Context.clearRect(0,0,100000,100000);

		temp1Context.drawImage(image1, 0, 0, width, height);
		temp2Context.drawImage(image2, 0, 0, width, height);


		for(var y = 0; y < height; y++) {
			for(var x = 0; x <  width; x++) {
				var pixel1 = temp1Context.getImageData(x,y,1,1);
				var pixel1Data = pixel1.data;

				var pixel2 = temp2Context.getImageData(x,y,1,1);
				var pixel2Data = pixel2.data;

				if(comparePixel(pixel1Data, pixel2Data) == false) {
					setTopLeft(x,y);
					setBottomRight(x,y);
				}					
			}
		}

		return {
			'topLeft': topLeft,
			'bottomRight': bottomRight
		}
	}

	/*
	 * Compares an individual pixel (within a range based on sensitivity).
	 *
	 * @param <Array> p1 The first pixel [r,g,b,a].
	 * @param <Array> p2 The second pixel [r,g,b,a].
	 *
	 * @return <Boolean> If they are the same.
	 *
	 */
	function comparePixel(p1, p2) {
		var matches = true;

		for(var i = 0; i < p1.length; i++) {
			var t1 = Math.round(p1[i]/10)*10;
			var t2 = Math.round(p2[i]/10)*10;

			if(t1 != t2) {
				if((t1+sensitivity < t2 || t1-sensitivity > t2)) {
					matches = false;
				}
			}
		}

		return matches;
	}

	/*
	 * Sets the top left pixel.
	 *
	 * @param <int> x The x position.
	 * @param <int> y The y position.
	 *
	 * @return void.
	 *
	 */
	function setTopLeft(x,y) {
		if(x < topLeft[0] ) {
			topLeft[0] = x;
		}
		if(y < topLeft[1]) {
			topLeft[1] = [y];
		}
	}

	/*
	 * Sets the bottom right pixel.
	 *
	 * @param <int> x The x position.
	 * @param <int> y The y position.
	 *
	 * @return void.
	 *
	 */
	function setBottomRight(x,y) {
		if(x > bottomRight[0]) {
			bottomRight[0] = [x];
		}
		if(y > bottomRight[1]) {
			bottomRight[1] = [y];
		}
	}

	// Initialize on creation.
	initialize();

	// Return public interface.
	return {
		compare: compare
	}
};
})(MotionDetector);

		</script>
		<script>
			/**
 *
 * @project        Motion Detection in JS
 * @file           ImageCompare.js
 * @description    Core functionality.
 * @author         Benjamin Horn
 * @package        MotionDetector
 * @version        -
 * 
 */

;(function(App) {

"use strict";

/*
 * The core motion detector. Does all the work.
 *
 * @return <Object> The initalized object.
 *
 */
App.Core = function() {

	var rendering = false;

	var width = 64;
	var height = 48;

	var webCam = null;
	var imageCompare = null;

	var currentImage = null;
	var oldImage = null;

	var topLeft = [Infinity,Infinity];
	var bottomRight = [0,0];

	var raf = (function(){
		return  window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame ||
		function( callback ){
			window.setTimeout(callback, 1000/60);
		};
	})();

	/*
	 * Initializes the object.
	 *
	 * @return void.
	 *
	 */
	function initialize() {
		imageCompare = new App.ImageCompare();
		webCam = new App.WebCamCapture(document.getElementById('webCamWindow'));

		rendering = true;

		main();
	}

	/*
	 * Compares to images and updates the position
	 * of the motion div.
	 *
	 * @return void.
	 *
	 */
	function render() {
		oldImage = currentImage;
		currentImage = webCam.captureImage(false);

		if(!oldImage || !currentImage) {
			return;
		}

		var vals = imageCompare.compare(currentImage, oldImage, width, height);

		topLeft[0] = vals.topLeft[0] * 10;
		topLeft[1] = vals.topLeft[1] * 10;

		bottomRight[0] = vals.bottomRight[0] * 10;
		bottomRight[1] = vals.bottomRight[1] * 10;

		document.getElementById('movement').style.top = topLeft[1] + 'px';
		document.getElementById('movement').style.left = topLeft[0] + 'px';

		document.getElementById('movement').style.width = (bottomRight[0] - topLeft[0]) + 'px';
		document.getElementById('movement').style.height = (bottomRight[1] - topLeft[1]) + 'px';

		topLeft = [Infinity,Infinity];
		bottomRight = [0,0]

	}

	/*
	 * The main rendering loop.
	 *
	 * @return void.
	 *
	 */
	function main() {
		try{
			render();
		} catch(e) {
			console.log(e);
			return;
		}

		if(rendering == true) {
			raf(main.bind(this));
		}
	}

	initialize();
};
})(MotionDetector);
		</script>
		<script>
			var core = new MotionDetector.Core();
		</script>
	</body>
</html>

Leave a Reply