Changes for usability: less images, detection.box is deprecated, controls to show points and grid on all detections. Button to take screenshot.
20
dist/static/assets/images.json
vendored
|
@ -14,31 +14,11 @@
|
|||
"glasses1": "/assets/images/glasses1.png",
|
||||
"glasses2": "/assets/images/glasses2.png",
|
||||
"glasses3": "/assets/images/glasses3.png",
|
||||
"glasses4": "/assets/images/glasses4.png",
|
||||
"hat1": "/assets/images/hat1.png",
|
||||
"hat2": "/assets/images/hat2.png",
|
||||
"hat3": "/assets/images/hat3.png",
|
||||
"hat4": "/assets/images/hat4.png",
|
||||
"hat5": "/assets/images/hat5.png",
|
||||
"hat6": "/assets/images/hat6.png",
|
||||
"mustache1": "/assets/images/mustache1.png",
|
||||
"mustache10": "/assets/images/mustache10.png",
|
||||
"mustache11": "/assets/images/mustache11.png",
|
||||
"mustache12": "/assets/images/mustache12.png",
|
||||
"mustache13": "/assets/images/mustache13.png",
|
||||
"mustache14": "/assets/images/mustache14.png",
|
||||
"mustache15": "/assets/images/mustache15.png",
|
||||
"mustache16": "/assets/images/mustache16.png",
|
||||
"mustache17": "/assets/images/mustache17.png",
|
||||
"mustache18": "/assets/images/mustache18.png",
|
||||
"mustache19": "/assets/images/mustache19.png",
|
||||
"mustache2": "/assets/images/mustache2.png",
|
||||
"mustache20": "/assets/images/mustache20.png",
|
||||
"mustache3": "/assets/images/mustache3.png",
|
||||
"mustache4": "/assets/images/mustache4.png",
|
||||
"mustache5": "/assets/images/mustache5.png",
|
||||
"mustache6": "/assets/images/mustache6.png",
|
||||
"mustache7": "/assets/images/mustache7.png",
|
||||
"mustache8": "/assets/images/mustache8.png",
|
||||
"mustache9": "/assets/images/mustache9.png"
|
||||
}
|
BIN
dist/static/assets/images/glasses4.png
vendored
Before Width: | Height: | Size: 7.1 KiB |
BIN
dist/static/assets/images/hat1.png
vendored
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 13 KiB |
BIN
dist/static/assets/images/hat3.png
vendored
Before Width: | Height: | Size: 9.2 KiB |
BIN
dist/static/assets/images/hat4.png
vendored
Before Width: | Height: | Size: 7.2 KiB |
BIN
dist/static/assets/images/hat5.png
vendored
Before Width: | Height: | Size: 13 KiB |
BIN
dist/static/assets/images/hat6.png
vendored
Before Width: | Height: | Size: 13 KiB |
BIN
dist/static/assets/images/mustache1.png
vendored
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 4 KiB |
BIN
dist/static/assets/images/mustache10.png
vendored
Before Width: | Height: | Size: 5.9 KiB |
BIN
dist/static/assets/images/mustache11.png
vendored
Before Width: | Height: | Size: 7.1 KiB |
BIN
dist/static/assets/images/mustache12.png
vendored
Before Width: | Height: | Size: 4 KiB |
BIN
dist/static/assets/images/mustache13.png
vendored
Before Width: | Height: | Size: 1.8 KiB |
BIN
dist/static/assets/images/mustache14.png
vendored
Before Width: | Height: | Size: 2.8 KiB |
BIN
dist/static/assets/images/mustache15.png
vendored
Before Width: | Height: | Size: 2.8 KiB |
BIN
dist/static/assets/images/mustache16.png
vendored
Before Width: | Height: | Size: 3.1 KiB |
BIN
dist/static/assets/images/mustache17.png
vendored
Before Width: | Height: | Size: 6.1 KiB |
BIN
dist/static/assets/images/mustache18.png
vendored
Before Width: | Height: | Size: 3.4 KiB |
BIN
dist/static/assets/images/mustache19.png
vendored
Before Width: | Height: | Size: 5.6 KiB |
BIN
dist/static/assets/images/mustache20.png
vendored
Before Width: | Height: | Size: 4.5 KiB |
BIN
dist/static/assets/images/mustache5.png
vendored
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 3.2 KiB |
BIN
dist/static/assets/images/mustache6.png
vendored
Before Width: | Height: | Size: 6 KiB |
BIN
dist/static/assets/images/mustache7.png
vendored
Before Width: | Height: | Size: 8.6 KiB |
BIN
dist/static/assets/images/mustache8.png
vendored
Before Width: | Height: | Size: 3.2 KiB |
BIN
dist/static/assets/images/mustache9.png
vendored
Before Width: | Height: | Size: 4.5 KiB |
149
dist/static/assets/webcam.js
vendored
|
@ -18,6 +18,12 @@ var draw = function () {
|
|||
rotate(transformed.angle);
|
||||
|
||||
try {
|
||||
if( overlayGrid ) {
|
||||
drawGridOverlay(transformed)
|
||||
}
|
||||
if( overlayLandmarks ) {
|
||||
drawLandmarkOverlay(transformed);
|
||||
}
|
||||
drawMask(transformed);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
@ -27,6 +33,51 @@ var draw = function () {
|
|||
}
|
||||
};
|
||||
|
||||
function drawLandmarkOverlay(detection) {
|
||||
for(let nr in detection.points) {
|
||||
p = detection.points[nr]
|
||||
stroke('red')
|
||||
strokeWeight(5)
|
||||
point(p.x, p.y)
|
||||
|
||||
noStroke();
|
||||
textSize(12);
|
||||
fill('white');
|
||||
|
||||
text(nr, p.x, p.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function drawGridOverlay(detection) {
|
||||
textSize(20)
|
||||
stroke(100,100,100)
|
||||
|
||||
strokeWeight(1)
|
||||
for (let y = 0; y < detection.height; y+=10) {
|
||||
if(y%100 === 0) {
|
||||
strokeWeight(3)
|
||||
text(y, detection.x - 10, y);
|
||||
} else {
|
||||
strokeWeight(1)
|
||||
}
|
||||
line(detection.x, detection.y + y, detection.x+detection.width, detection.y + y);
|
||||
|
||||
}
|
||||
|
||||
for (let x = 0; x < detection.width; x+=10) {
|
||||
if(x != 0 && x%100 === 0) { // 0 already drawn for y
|
||||
strokeWeight(3)
|
||||
text(x, x, detection.y - 10);
|
||||
} else {
|
||||
strokeWeight(1)
|
||||
}
|
||||
|
||||
line(detection.x + x, detection.y, detection.x + x, detection.y + detection.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var drawMask = function(detection) {
|
||||
|
||||
};
|
||||
|
@ -140,6 +191,9 @@ function preload() {
|
|||
// console.log(images);
|
||||
}
|
||||
|
||||
var overlayLandmarks = false;
|
||||
var overlayGrid = false;
|
||||
|
||||
function setup() {
|
||||
// createCanvas(1280,720, WEBGL);
|
||||
createCanvas(540,420);
|
||||
|
@ -170,6 +224,46 @@ function setup() {
|
|||
textAlign(RIGHT);
|
||||
|
||||
setupAssets();
|
||||
|
||||
let controlEl = document.createElement('div');
|
||||
controlEl.classList.add('controls');
|
||||
let label1El = document.createElement('label');
|
||||
let check1El = document.createElement('input');
|
||||
check1El.type = 'checkbox';
|
||||
check1El.addEventListener('change', (e) => overlayLandmarks = e.target.checked);
|
||||
let text1Node = document.createTextNode("Show points")
|
||||
label1El.appendChild(check1El);
|
||||
label1El.appendChild(text1Node);
|
||||
controlEl.appendChild(label1El);
|
||||
|
||||
let label2El = document.createElement('label');
|
||||
let check2El = document.createElement('input');
|
||||
check2El.type = 'checkbox';
|
||||
check2El.addEventListener('change', (e) => overlayGrid = e.target.checked);
|
||||
let text2Node = document.createTextNode("Show coordinates")
|
||||
label2El.appendChild(check2El);
|
||||
label2El.appendChild(text2Node);
|
||||
controlEl.appendChild(label2El);
|
||||
|
||||
|
||||
let downloadBtn = document.createElement('button');
|
||||
downloadBtn.innerHTML = 'screenshot';
|
||||
downloadBtn.style.float = 'right';
|
||||
// Convert canvas to image
|
||||
downloadBtn.addEventListener("click", function(e) {
|
||||
const canvas = document.querySelector('canvas');
|
||||
const dataURL = canvas.toDataURL("image/png", 1.0);
|
||||
|
||||
let a = document.createElement('a');
|
||||
a.href = dataURL;
|
||||
a.download = 'screenshot.png';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
});
|
||||
|
||||
controlEl.appendChild(downloadBtn);
|
||||
|
||||
document.body.appendChild(controlEl);
|
||||
}
|
||||
|
||||
function modelReady() {
|
||||
|
@ -282,20 +376,20 @@ function faceDistance(face1, face2){
|
|||
// distance between faces, in pixels, not meters.. for now
|
||||
// we cheat a little: take centers, visualise circle with r = max(width, height)
|
||||
// and find distance between these circles
|
||||
box1 = (face1.box.x, face1.box.x + face1.box.width)
|
||||
box2 = (face2.box.x, face2.box.x + face2.box.width)
|
||||
box1 = (face1.x, face1.x + face1.width)
|
||||
box2 = (face2.x, face2.x + face2.width)
|
||||
|
||||
c1 = {
|
||||
x: face1.box.x + face1.box.width / 2,
|
||||
y: face1.box.y + face1.box.height / 2,
|
||||
x: face1.x + face1.width / 2,
|
||||
y: face1.y + face1.height / 2,
|
||||
}
|
||||
c2 = {
|
||||
x: face2.box.x + face2.box.width / 2,
|
||||
y: face2.box.y + face2.box.height / 2,
|
||||
x: face2.x + face2.width / 2,
|
||||
y: face2.y + face2.height / 2,
|
||||
}
|
||||
|
||||
r1 = Math.max(face1.box.width, face1.box.height) / 2;
|
||||
r2 = Math.max(face2.box.width, face2.box.height) / 2;
|
||||
r1 = Math.max(face1.width, face1.height) / 2;
|
||||
r2 = Math.max(face2.width, face2.height) / 2;
|
||||
|
||||
dx = c1.x - c2.x;
|
||||
dy = c1.y - c2.y;
|
||||
|
@ -346,19 +440,17 @@ function parseDetectionResults(results) {
|
|||
'points': landmarks,
|
||||
// TODO: rotation
|
||||
'parts': {},
|
||||
'box': {
|
||||
x: result.alignedRect._box._x * factor_x,
|
||||
y: result.alignedRect._box._y * factor_y,
|
||||
width: result.alignedRect._box._width * factor_x,
|
||||
height: result.alignedRect._box._height * factor_y,
|
||||
},
|
||||
x: result.alignedRect._box._x * factor_x,
|
||||
y: result.alignedRect._box._y * factor_y,
|
||||
width: result.alignedRect._box._width * factor_x,
|
||||
height: result.alignedRect._box._height * factor_y,
|
||||
}
|
||||
for(let idx in result.parts) {
|
||||
detection.parts[idx] = result.parts[idx].map((pos) => parseCoordinate(pos));
|
||||
}
|
||||
detection['center'] = {
|
||||
x: detection.box.x + detection.box.width / 2,
|
||||
y: detection.box.y + detection.box.height / 2,
|
||||
x: detection.x + detection.width / 2,
|
||||
y: detection.y + detection.height / 2,
|
||||
}
|
||||
detections.push(detection);
|
||||
}
|
||||
|
@ -382,12 +474,14 @@ function transformDetection(original) {
|
|||
|
||||
let b = original.points[36]; // outer point on left eye
|
||||
let a = original.points[45]; // outer point on right eye
|
||||
|
||||
let cx =a.x/2 + b.x/2
|
||||
let cy = a.y/2 + b.y/2
|
||||
|
||||
let angle = atan2(a.y - b.y, a.x - b.x);
|
||||
|
||||
// let cx =a.x/2 + b.x/2
|
||||
// let cy = a.y/2 + b.y/2
|
||||
|
||||
let cx = original.x
|
||||
let cy = original.y
|
||||
|
||||
let detection = {
|
||||
'points': original.points.map(p => transformPoint(p, cx, cy, angle)),
|
||||
'origin': {x:cx, y:cy},
|
||||
|
@ -399,12 +493,15 @@ function transformDetection(original) {
|
|||
padding_x = bbox.width * .1;
|
||||
padding_y = bbox.height * .1;
|
||||
|
||||
detection['box'] = {
|
||||
x: bbox.x - padding_x,
|
||||
y: bbox.y - padding_y,
|
||||
width: bbox.width * 1.2,
|
||||
height: bbox.height * 1.2
|
||||
}
|
||||
detection['x'] = bbox.x - padding_x,
|
||||
detection['y'] = bbox.y - padding_y,
|
||||
detection['width'] = bbox.width * 1.2,
|
||||
detection['height'] = bbox.height * 1.2
|
||||
|
||||
// detection['x'] = original.x - cx
|
||||
// detection['y'] = original.y - cy
|
||||
// detection['width'] = original.width
|
||||
// detection['height'] = original.height
|
||||
|
||||
return detection;
|
||||
}
|
||||
|
|
|
@ -10,45 +10,25 @@ classoption:
|
|||
|
||||
![](dlib_face_points.png)
|
||||
|
||||
|
||||
detection.points
|
||||
: Alle bovenstaande punten. Ieder punt bestaat uit `x` en `y`. Bijvoorbeeld `detection.points[33].x` is het x-coördinaat van het puntje van de neus.
|
||||
: Alle bovenstaande punten. Ieder punt bestaat uit een `x` en een `y` coördinaat. Bijvoorbeeld `detection.points[33].x` is het x-coördinaat van het puntje van de neus.
|
||||
: `x` is de afstand vanaf links. De horizontale positie.
|
||||
: `y` is de afstand vanaf boven. De verticale positie.
|
||||
|
||||
detection.parts.nose
|
||||
: punten 27--35
|
||||
detection.x
|
||||
: x coordinaat van de bounding box van het gezicht. Dit is het punt linkboven.
|
||||
|
||||
detection.parts.leftEye
|
||||
: punten 36--41
|
||||
detection.y
|
||||
: y coordinaat van de bounding box van het gezicht. Dit is het punt linkboven.
|
||||
|
||||
detection.parts.rightEye
|
||||
: punten 42--47
|
||||
detection.width
|
||||
: Breedte van de bounding box van het gezicht.
|
||||
|
||||
detection.parts.rightEyeBrow
|
||||
: punten 22--26
|
||||
detection.height
|
||||
: Hoogte van de bounding box van het gezicht.
|
||||
|
||||
detection.parts.leftEyeBrow
|
||||
: punten 17--21
|
||||
|
||||
detection.parts.jawOutline
|
||||
: punten 0--16
|
||||
|
||||
detection.box
|
||||
: de 'bounding box' van het gezicht.
|
||||
|
||||
detection.box.x
|
||||
: x coordinaat van de bounding box.
|
||||
|
||||
detection.box.y
|
||||
: y coordinaat van de bounding box.
|
||||
|
||||
detection.box.width
|
||||
: Breedte van de bounding box
|
||||
|
||||
detection.box.height
|
||||
: Hoogte van de bounding box
|
||||
|
||||
detection.center.x & detection.center.y
|
||||
: Het midden van de bounding box
|
||||
<!-- detection.center.x & detection.center.y
|
||||
: Het midden van de bounding box -->
|
||||
|
||||
|
||||
|
||||
|
@ -71,25 +51,26 @@ circle(cx, cy, radius)
|
|||
: Upload een afbeelding, waarna je hem kunt inladen met loadImage(...) -->
|
||||
|
||||
image(naam, x, y, breedte, hoogte)
|
||||
: Toon een ingeladen afbeelding. _x_ en _y_ bepalen de linker bovenhoek.
|
||||
: Toon een ingeladen afbeelding. _x_ en _y_ bepalen waar de linker bovenhoek wordt geplaatst.
|
||||
: Zie hieronder voor alle beschikbare afbeeldingen
|
||||
|
||||
getBoundingBox(punten)
|
||||
: Bepaald het rechthoek waarbinnen de punten vallen.
|
||||
|
||||
<!--
|
||||
mergePoints(punten, anderePunten)
|
||||
: Voeg meerdere sets van punten samen. Bijvoorbeeld `mergePoints( detection.parts.rightEyeBrow, detection.parts.leftEyeBrow )`
|
||||
: Voeg meerdere sets van punten samen. Bijvoorbeeld `mergePoints( detection.parts.rightEyeBrow, detection.parts.leftEyeBrow )` -->
|
||||
|
||||
## Opmaak
|
||||
|
||||
fill(kleur)
|
||||
: de kleur van de vulling
|
||||
: de kleur van de vulling van wat je gaat tekenen.
|
||||
|
||||
noFill()
|
||||
: geen vulling
|
||||
|
||||
stroke(kleur)
|
||||
: de omlijning
|
||||
: de kleur van de omlijning.
|
||||
|
||||
strokeWeight(dikte)
|
||||
: de dikte van de omlijning
|
||||
|
@ -116,8 +97,11 @@ https://genekogan.com/code/p5js-transformations/
|
|||
|
||||
|
||||
|
||||
## afbeeldingen
|
||||
## Afbeeldingen
|
||||
|
||||
Deze afbeeldingen kun je gebruiken met `image()`.
|
||||
|
||||
Bijvoorbeeld: `image(images.game1, 10, 10, 50, 50)` tekent het plaatje `images.game1`, waarbij de linker bovenhoek 10 pixels van links en 10 pixels vanaf rechts wordt geplaatst. En het plaatje 50 bij 50 pixels is.
|
||||
|
||||
images.game1
|
||||
![](../dist/static/assets/images/game1.png)
|
||||
|
@ -164,66 +148,15 @@ images.glasses2
|
|||
images.glasses3
|
||||
![](../dist/static/assets/images/glasses3.png)
|
||||
|
||||
images.glasses4
|
||||
![](../dist/static/assets/images/glasses4.png)
|
||||
|
||||
images.hat1
|
||||
![](../dist/static/assets/images/hat1.png)
|
||||
|
||||
images.hat2
|
||||
![](../dist/static/assets/images/hat2.png)
|
||||
|
||||
images.hat3
|
||||
![](../dist/static/assets/images/hat3.png)
|
||||
|
||||
images.hat4
|
||||
![](../dist/static/assets/images/hat4.png)
|
||||
|
||||
images.hat5
|
||||
![](../dist/static/assets/images/hat5.png)
|
||||
|
||||
images.hat6
|
||||
![](../dist/static/assets/images/hat6.png)
|
||||
|
||||
images.mustache1
|
||||
![](../dist/static/assets/images/mustache1.png)
|
||||
|
||||
images.mustache10
|
||||
![](../dist/static/assets/images/mustache10.png)
|
||||
|
||||
images.mustache11
|
||||
![](../dist/static/assets/images/mustache11.png)
|
||||
|
||||
images.mustache12
|
||||
![](../dist/static/assets/images/mustache12.png)
|
||||
|
||||
images.mustache13
|
||||
![](../dist/static/assets/images/mustache13.png)
|
||||
|
||||
images.mustache14
|
||||
![](../dist/static/assets/images/mustache14.png)
|
||||
|
||||
images.mustache15
|
||||
![](../dist/static/assets/images/mustache15.png)
|
||||
|
||||
images.mustache16
|
||||
![](../dist/static/assets/images/mustache16.png)
|
||||
|
||||
images.mustache17
|
||||
![](../dist/static/assets/images/mustache17.png)
|
||||
|
||||
images.mustache18
|
||||
![](../dist/static/assets/images/mustache18.png)
|
||||
|
||||
images.mustache19
|
||||
![](../dist/static/assets/images/mustache19.png)
|
||||
|
||||
images.mustache2
|
||||
![](../dist/static/assets/images/mustache2.png)
|
||||
|
||||
images.mustache20
|
||||
![](../dist/static/assets/images/mustache20.png)
|
||||
|
||||
images.mustache3
|
||||
![](../dist/static/assets/images/mustache3.png)
|
||||
|
||||
|
@ -232,16 +165,3 @@ images.mustache4
|
|||
|
||||
images.mustache5
|
||||
![](../dist/static/assets/images/mustache5.png)
|
||||
|
||||
images.mustache6
|
||||
![](../dist/static/assets/images/mustache6.png)
|
||||
|
||||
images.mustache7
|
||||
![](../dist/static/assets/images/mustache7.png)
|
||||
|
||||
images.mustache8
|
||||
![](../dist/static/assets/images/mustache8.png)
|
||||
|
||||
images.mustache9
|
||||
![](../dist/static/assets/images/mustache9.png)
|
||||
|
||||
|
|
BIN
doc/dlib_face_points.png
Normal file
After Width: | Height: | Size: 14 KiB |