File "motion.js"
Full Path: /home/analogde/www/php/js/motion.js
File size: 6.1 KB
MIME-type: text/plain
Charset: utf-8
// config start
var OUTLINES = false;
// config end
window.hotSpots = [];
var content = $('#dmotion');
var canvases = $('canvas');
var lastImageData;
var canvasSource = $("#canvas-source")[0];
var canvasBlended = $("#canvas-blended")[0];
var contextSource = canvasSource.getContext('2d');
var contextBlended = canvasBlended.getContext('2d');
var video;
//var sensitivity = 3;
function startMotion() {
console.log("Motion detection started.");
//change this to remote
video = $('#remote')[0];
var resize = function () {
var ratio = video.width / video.height;
var w = $(this).width();
var h = $(this).height() - 110;
if (content.width() > w) {
content.width(w);
content.height(w / ratio);
} else {
content.height(h);
content.width(h * ratio);
}
canvases.width(content.width());
canvases.height(content.height());
}
$(window).resize(resize);
$(window).ready(function () {
resize();
});
// mirror video
contextSource.translate(canvasSource.width, 0);
contextSource.scale(-1, 1);
var c = 5;
start();
} //end function
function start() {
//$('.loading').fadeOut();
$('#hotSpots').fadeIn();
// $('body').addClass('black-background');
// $(".instructions").delay(600).fadeIn();
$(canvasSource).delay(600).fadeIn();
$(canvasBlended).delay(600).fadeIn();
$('#canvas-highlights').delay(600).fadeIn();
$(window).trigger('start');
update();
}
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function update() {
drawVideo();
blend();
checkAreas();
requestAnimFrame(update);
}
function drawVideo() {
contextSource.drawImage(video, 0, 0, video.width, video.height);
}
function blend() {
var width = canvasSource.width;
var height = canvasSource.height;
// get webcam image data
var sourceData = contextSource.getImageData(0, 0, width, height);
// create an image if the previous image doesn’t exist
if (!lastImageData) lastImageData = contextSource.getImageData(0, 0, width, height);
// create a ImageData instance to receive the blended result
var blendedData = contextSource.createImageData(width, height);
// blend the 2 images
differenceAccuracy(blendedData.data, sourceData.data, lastImageData.data);
// draw the result in a canvas
contextBlended.putImageData(blendedData, 0, 0);
// store the current webcam image
lastImageData = sourceData;
}
function fastAbs(value) {
// funky bitwise, equal Math.abs
return (value ^ (value >> 31)) - (value >> 31);
}
function threshold(value) {
return (value > 0x15) ? 0xFF : 0;
}
function difference(target, data1, data2) {
// blend mode difference
if (data1.length != data2.length) return null;
var i = 0;
while (i < (data1.length * 0.25)) {
target[4 * i] = data1[4 * i] == 0 ? 0 : fastAbs(data1[4 * i] - data2[4 * i]);
target[4 * i + 1] = data1[4 * i + 1] == 0 ? 0 : fastAbs(data1[4 * i + 1] - data2[4 * i + 1]);
target[4 * i + 2] = data1[4 * i + 2] == 0 ? 0 : fastAbs(data1[4 * i + 2] - data2[4 * i + 2]);
target[4 * i + 3] = 0xFF;
++i;
}
}
function differenceAccuracy(target, data1, data2) {
if (data1.length != data2.length) return null;
var i = 0;
while (i < (data1.length * 0.25)) {
var average1 = (data1[4 * i] + data1[4 * i + 1] + data1[4 * i + 2]) / 3;
var average2 = (data2[4 * i] + data2[4 * i + 1] + data2[4 * i + 2]) / 3;
var diff = threshold(fastAbs(average1 - average2));
target[4 * i] = diff;
target[4 * i + 1] = diff;
target[4 * i + 2] = diff;
target[4 * i + 3] = 0xFF;
++i;
}
}
//This is still setup for looking at individual hotspots. Could be simplified to con
function checkAreas() {
var data;
for (var h = 0; h < hotSpots.length; h++) {
var blendedData = contextBlended.getImageData(hotSpots[h].x, hotSpots[h].y, hotSpots[h].width, hotSpots[h].height);
var i = 0;
var average = 0;
while (i < (blendedData.data.length * 0.25)) {
// make an average between the color channel
average += (blendedData.data[i * 4] + blendedData.data[i * 4 + 1] + blendedData.data[i * 4 + 2]) / 3;
++i;
}
// calculate an average between the color values of the spot area
average = Math.round(average / (blendedData.data.length * 0.25));
//CHAD: Value below was originaly 10 - made very sensisitve
if (average > 1) {
// over a small limit, consider that a movement is detected
data = { confidence: average, spot: hotSpots[h] };
$(data.spot.el).trigger('motion', data);
}
} }
function getCoords() {
$('#hotSpots').children().each(function (i, el) {
var ratio = $("#canvas-highlights").width() / $('video').width();
hotSpots[i] = {
x: this.offsetLeft / ratio,
y: this.offsetTop / ratio,
width: this.scrollWidth / ratio,
height: this.scrollHeight / ratio,
el: el
};
});
if (OUTLINES) highlightHotSpots();
}
$(window).on('start resize', getCoords);