Skip to content
This repository was archived by the owner on Sep 15, 2022. It is now read-only.

Commit

Permalink
Edge app PoC with bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
GearsAD committed Aug 9, 2020
1 parent efc431b commit 2908c34
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 51 deletions.
81 changes: 55 additions & 26 deletions capture.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@

var video = null;
var canvas = null;
var photo = null;
var startbutton = null;

var detector = AprilTags();

var timer = null;

function startup() {
video = document.getElementById('video');
canvas = document.getElementById('canvas');
photo = document.getElementById('photo');
startbutton = document.getElementById('startbutton');
stopbutton = document.getElementById('stopbutton');

navigator.mediaDevices.getUserMedia({video: true, audio: false})
.then(function(stream) {
Expand All @@ -37,14 +40,14 @@
video.addEventListener('canplay', function(ev){
if (!streaming) {
height = video.videoHeight / (video.videoWidth/width);

// Firefox currently has a bug where the height can't be read from
// the video, so we will make assumptions if this happens.

if (isNaN(height)) {
height = width / (4/3);
}

video.setAttribute('width', width);
video.setAttribute('height', height);
canvas.setAttribute('width', width);
Expand All @@ -54,42 +57,68 @@
}, false);

startbutton.addEventListener('click', function(ev){
takepicture();
startDetections();
ev.preventDefault();
}, false);
stopbutton.addEventListener('click', function(ev){
stopDetections();
ev.preventDefault();
}, false);

clearphoto();
}

// Fill the photo with an indication that none has been
// captured.
// Draw the detections.

function clearphoto() {
function drawDetections(detections) {
var context = canvas.getContext('2d');
context.fillStyle = "#AAA";
context.fillRect(0, 0, canvas.width, canvas.height);
// Set the stroke style
var gradient = context.createLinearGradient(0, 0, 170, 0);
gradient.addColorStop("0", "green");
gradient.addColorStop("0.5" ,"red");
gradient.addColorStop("1.0", "yellow");
context.strokeStyle = gradient;
context.lineWidth = 3;
context.font = "14px Arial";

context.fillStyle = "#FF0000";
for (index in detections) {
d = detections[index];
console.log(d);
context.beginPath();
context.moveTo(d['x1'], d['y1']);
context.lineTo(d['x2'], d['y2']);
context.lineTo(d['x3'], d['y3']);
context.lineTo(d['x4'], d['y4']);
context.closePath();
context.stroke();

var data = canvas.toDataURL('image/png');
photo.setAttribute('src', data);
context.fillText("Tag " + d['id'].toString(), d['x3'], d['y3']);
}
}

// Capture a photo by fetching the current contents of the video
// and drawing it into a canvas, then converting that to a PNG
// format data URL. By drawing it on an offscreen canvas and then
// drawing that to the screen, we can change its size and/or apply
// other changes before drawing it.

var detections = [];

function takepicture() {
var context = canvas.getContext('2d');
if (width && height) {
canvas.width = width;
canvas.height = height;
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(video, 0, 0, width, height);

var data = canvas.toDataURL('image/png');
photo.setAttribute('src', data);
} else {
clearphoto();

// Do AprilTags detections
detections = detector(canvas);
// console.log(detections);
drawDetections(detections);
}
}

function startDetections() {
timer = window.setInterval(takepicture, 500);
}

function stopDetections() {
if (timer != null) {
clearInterval(timer);
}
}

Expand Down
43 changes: 43 additions & 0 deletions detector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
function AprilTags() {
var detections = [];

var detect = Module.cwrap('detect', 'number', [
'number', 'number', 'number', 'number'
]);

var detected = Runtime.addFunction(function(
id,
x1,y1,x2,y2,x3,y3,x4,y4,
m00,m01,m02,m10,m11,m12,m20,m21,m22
) {
detections.push({
id: id,
x1: x1, y1: y1,
x2: x2, y2: y2,
x3: x3, y3: y3,
x4: x4, y4: y4,
m: [m00,m01,m02,m10,m11,m12,m20,m21,m22],
})
})

var buf = null;

return function(canvas) {
var context = canvas.getContext("2d");

var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
if (buf == null) {
console.log("Initializing buffer");
buf = Module._malloc(imageData.data.length * imageData.data.BYTES_PER_ELEMENT);
}
Module.HEAPU8.set(imageData.data, buf);

detections = [];
detect(detected, canvas.width, canvas.height, buf);

//TODO: Clean this up afterwards...
// Module._free(buf);

return detections;
}
}
71 changes: 46 additions & 25 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,60 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>PoC Javascript Device</title>
<script src="capture.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<script src='apriltag.js'></script>
<script src="detector.js"></script>
<script src="capture.js"></script>
</head>
<body>
<script>
//TODO: Refactor to use Generic Sensor API...
window.addEventListener('deviceorientation', function(event) {
document.getElementById("accel").innerText = "Accel: [" + event.alpha + ', ' + event.beta + ', ' + event.gamma + "]"
});

<div id='accel'>Static stuff</div>
<div id="magneto">Static stuff</div>
<script>
window.addEventListener('deviceorientation', function(event) {
document.getElementById("accel").innerText = event.alpha + ' : ' + event.beta + ' : ' + event.gamma
});

let sensor = new Accelerometer();
sensor.start();
let sensor = new Accelerometer();
sensor.start();

sensor.onreading = () => {
document.getElementById("magneto").innerText = "x: " + sensor.x + " y: " + sensor.y + " z: " + sensor.z
}
sensor.onerror = event => console.log(event.error.name, event.error.message);
</script>
sensor.onreading = () => {
document.getElementById("magneto").innerText = "Mag: [" + sensor.x + ", " + sensor.y + ", " + sensor.z + "]"
}
sensor.onerror = event => console.log(event.error.name, event.error.message);
</script>

<div class="camera">
<video id="video">Video stream not available.</video>
<button id="startbutton">Take photo</button>
<div class="container">
<div class="row">
<div class="col-sm">
<div id='accel' class="alert alert-info" role="alert">Accel: [0, 0, 0]</div>
</div>
<div class="col-sm">
<div id="magneto" class="alert alert-info" role="alert">Mag: [0, 0, 0]</div>
</div>
</div>
<div class="row">
<div class="col-sm">
<video id="video">Video stream not available.</video>
</div>
<div class="col-sm">
<canvas id="canvas">
</div>
</canvas>
</div>
<div class="row">
<div class="col-sm">
<button id="startbutton" class="btn btn-primary btn-block">Start Detections</button>
</div>
<div class="col-sm">
<button id="stopbutton" class="btn btn-danger btn-block">Stop Detections</button>
</div>
</div>
</div>
<canvas id="canvas">
</canvas>
<div class="output">
<img id="photo" alt="The screen capture will appear in this box.">
</div>


<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
</body>
</html>
Empty file removed logic.js
Empty file.

0 comments on commit 2908c34

Please sign in to comment.