7 Commits

Autor SHA1 Mensagem Data
Bernhard Weißhuhn 641f1b12d2 Update public/js/nodecopter-stream.js
reword comment again
(I'm really just playing around with github online editing)
2012-12-12 12:26:17 +01:00
Bernhard Weißhuhn 117cbe745e Update public/js/nodecopter-stream.js
fix typo in comment
2012-12-12 12:22:10 +01:00
Bernhard K. Weisshuhn 58725f5341 add nodecopter-track.
This should be refactored to use @karlwestin refactored version and
made a separate module. Just checking in for @felixge.
2012-12-11 10:49:40 +01:00
Bernhard K. Weisshuhn dc720a20c2 add sniper image 2012-12-11 10:45:21 +01:00
Bernhard K. Weisshuhn eb2994355d add jsfeat 2012-12-11 10:44:39 +01:00
Bernhard K. Weisshuhn 7bfe53f958 preserveDrawingBuffer of webgl canvas to get contents 2012-12-11 10:43:31 +01:00
Bernhard K. Weisshuhn 247b8582fc add methods to get canvas and canvas contents 2012-12-11 10:42:42 +01:00
6 arquivos alterados com 189 adições e 6 exclusões
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 5.5 KiB

+25 -4
Ver Arquivo
@@ -5,7 +5,9 @@
var NS,
socket,
avc,
webGLCanvas;
webGLCanvas,
width,
height;
function setupAvc() {
avc = new Avc();
@@ -32,9 +34,10 @@
}
function setupCanvas(div) {
var width = div.attributes.width ? div.attributes.width.value : 640,
height = div.attributes.height ? div.attributes.height.value : 360,
canvas = document.createElement('canvas');
var canvas = document.createElement('canvas');
width = div.attributes.width ? div.attributes.width.value : 640;
height = div.attributes.height ? div.attributes.height.value : 360;
canvas.width = width;
canvas.height = height;
@@ -58,6 +61,24 @@
socket.onmessage = handleNalUnits;
};
NS.prototype.getImageData = function (rgbaData) {
var gl = webGLCanvas.gl;
gl.readPixels(
0, 0, width, height,
gl.RGBA, gl.UNSIGNED_BYTE,
rgbaData
);
// WebGL returns pixels upside down.
// Instead of wasting time by vertically flipping it now,
// we just leave it like it is and invert the coordinates later:
return;
};
NS.prototype.getCanvas = function () {
return webGLCanvas.canvas;
};
window.NodecopterStream = NS;
}(window, document, undefined));
+156
Ver Arquivo
@@ -0,0 +1,156 @@
/*jshint browser:true */
/*global jsfeat:true console:true */
(function (window, document, undefined) {
'use strict';
var NodecopterTrack,
lastTime;
function schedule (callback, element) {
var requestAnimationFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element) {
var currTime = new Date().getTime(),
timeToCall = Math.max(0, 16 - (currTime - lastTime)),
id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
return requestAnimationFrame.call(window, callback, element);
}
var relMouseCoords = function (event) {
var totalOffsetX = 0,
totalOffsetY = 0,
canvasX = 0,
canvasY = 0,
currentElement = this;
do {
totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
} while (currentElement = currentElement.offsetParent);
canvasX = event.pageX - totalOffsetX;
canvasY = event.pageY - totalOffsetY;
return {x:canvasX, y:canvasY};
};
NodecopterTrack = function (copterStream, imgId) {
var tracker = this;
this.curr_img_pyr = new jsfeat.pyramid_t(3);
this.prev_img_pyr = new jsfeat.pyramid_t(3);
this.point_count = 0;
this.point_status = new Uint8Array(1);
this.prev_xy = new Float32Array(2);
this.curr_xy = new Float32Array(2);
this.copterStream = copterStream;
this.canvas = copterStream.getCanvas();
this.rgbaData = new Uint8Array(
this.canvas.width * this.canvas.height * 4
); // RGBA
this.crosshairs = document.querySelector(imgId);
this.curr_img_pyr.allocate(
this.canvas.width, this.canvas.height, jsfeat.U8_t | jsfeat.C1_t
);
this.prev_img_pyr.allocate(
this.canvas.width, this.canvas.height, jsfeat.U8_t | jsfeat.C1_t
);
this.canvas.addEventListener('click', function(event) {
tracker.canvasClickHandler(event);
}, false);
HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords;
// this.canvas.prototype.relMouseCoords = relMouseCoords;
this.update();
};
NodecopterTrack.prototype.update = function () {
var _pt_xy, _pyr,
tracker = this;
schedule(function () {
tracker.update();
});
if (! this.point_count) {
this.crosshairs.style.display = 'none';
return;
}
_pt_xy = this.prev_xy;
_pyr = this.prev_img_pyr;
this.prev_xy = this.curr_xy;
this.curr_xy = _pt_xy;
this.prev_img_pyr = this.curr_img_pyr;
this.curr_img_pyr = _pyr; // reuse old pyramid data structure
this.copterStream.getImageData(this.rgbaData);
jsfeat.imgproc.grayscale(
this.rgbaData,
this.curr_img_pyr.data[0].data
);
// optional: enhance contrast:
jsfeat.imgproc.equalize_histogram(
this.curr_img_pyr.data[0].data,
this.curr_img_pyr.data[0].data
);
this.curr_img_pyr.build(this.curr_img_pyr.data[0], true);
jsfeat.optical_flow_lk.track(
this.prev_img_pyr,
this.curr_img_pyr,
this.prev_xy,
this.curr_xy,
1,
50, // win_size
30, // max_iterations
this.point_status,
0.01, // epsilon,
0.001 // min_eigen
);
if (this.point_status[0] == 1) {
this.crosshairs.style.left = (this.curr_xy[0] - 83) + 'px';
this.crosshairs.style.top = (
this.canvas.height - 83 - this.curr_xy[1]
) + 'px';
this.crosshairs.style.display = 'block';
} else {
this.point_count = 0;
console.log('lost target');
}
};
NodecopterTrack.prototype.canvasClickHandler = function (e) {
var coords = this.canvas.relMouseCoords(e);
if (
(coords.x > 0) &&
(coords.y > 0) &&
(coords.x < this.canvas.width) &&
(coords.y < this.canvas.height)
) {
this.curr_xy[0] = coords.x;
this.curr_xy[1] = this.canvas.height - coords.y;
this.point_count = 1;
}
console.log('Click:', coords);
};
window.NodecopterTrack = NodecopterTrack;
}(window, document, undefined));
+1 -1
Ver Arquivo
@@ -337,7 +337,7 @@ var WebGLCanvas = (function () {
},
onInitWebGL: function () {
try {
this.gl = this.canvas.getContext("experimental-webgl");
this.gl = this.canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true});
} catch(e) {}
if (!this.gl) {
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+6 -1
Ver Arquivo
@@ -7,11 +7,16 @@ block append head
script(type='text/javascript', src='/js/vendor/broadway/avc-codec.js')
script(type='text/javascript', src='/js/vendor/broadway/avc.js')
script(type='text/javascript', src='/js/vendor/broadway/canvas.js')
script(type='text/javascript', src='/js/vendor/jsfeat/jsfeat-min.js')
script(type='text/javascript', src='/js/nodecopter-stream.js')
script(type='text/javascript', src='/js/nodecopter-track.js')
block append bodyscripts
script
'use strict';
var copterStream = new NodecopterStream(document.querySelector('#dronestream'));
var tracker = new NodecopterTrack(copterStream, '#sniper');
block content
div#dronestream(width=640, height=360)
div#dronestream(width=640, height=360, style="position:relative")
img#sniper(src="images/sniper.png", style="position:absolute; opacity:0.6")