Changes for usability: less images, detection.box is deprecated, controls to show points and grid on all detections. Button to take screenshot.

This commit is contained in:
Ruben van de Ven 2020-10-25 12:18:13 +01:00
parent fa5e7cceb1
commit 14a4425dc2
27 changed files with 145 additions and 148 deletions

View file

@ -14,31 +14,11 @@
"glasses1": "/assets/images/glasses1.png", "glasses1": "/assets/images/glasses1.png",
"glasses2": "/assets/images/glasses2.png", "glasses2": "/assets/images/glasses2.png",
"glasses3": "/assets/images/glasses3.png", "glasses3": "/assets/images/glasses3.png",
"glasses4": "/assets/images/glasses4.png",
"hat1": "/assets/images/hat1.png", "hat1": "/assets/images/hat1.png",
"hat2": "/assets/images/hat2.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", "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", "mustache2": "/assets/images/mustache2.png",
"mustache20": "/assets/images/mustache20.png",
"mustache3": "/assets/images/mustache3.png", "mustache3": "/assets/images/mustache3.png",
"mustache4": "/assets/images/mustache4.png", "mustache4": "/assets/images/mustache4.png",
"mustache5": "/assets/images/mustache5.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"
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -18,6 +18,12 @@ var draw = function () {
rotate(transformed.angle); rotate(transformed.angle);
try { try {
if( overlayGrid ) {
drawGridOverlay(transformed)
}
if( overlayLandmarks ) {
drawLandmarkOverlay(transformed);
}
drawMask(transformed); drawMask(transformed);
} catch (error) { } catch (error) {
console.error(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) { var drawMask = function(detection) {
}; };
@ -140,6 +191,9 @@ function preload() {
// console.log(images); // console.log(images);
} }
var overlayLandmarks = false;
var overlayGrid = false;
function setup() { function setup() {
// createCanvas(1280,720, WEBGL); // createCanvas(1280,720, WEBGL);
createCanvas(540,420); createCanvas(540,420);
@ -170,6 +224,46 @@ function setup() {
textAlign(RIGHT); textAlign(RIGHT);
setupAssets(); 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() { function modelReady() {
@ -282,20 +376,20 @@ function faceDistance(face1, face2){
// distance between faces, in pixels, not meters.. for now // distance between faces, in pixels, not meters.. for now
// we cheat a little: take centers, visualise circle with r = max(width, height) // we cheat a little: take centers, visualise circle with r = max(width, height)
// and find distance between these circles // and find distance between these circles
box1 = (face1.box.x, face1.box.x + face1.box.width) box1 = (face1.x, face1.x + face1.width)
box2 = (face2.box.x, face2.box.x + face2.box.width) box2 = (face2.x, face2.x + face2.width)
c1 = { c1 = {
x: face1.box.x + face1.box.width / 2, x: face1.x + face1.width / 2,
y: face1.box.y + face1.box.height / 2, y: face1.y + face1.height / 2,
} }
c2 = { c2 = {
x: face2.box.x + face2.box.width / 2, x: face2.x + face2.width / 2,
y: face2.box.y + face2.box.height / 2, y: face2.y + face2.height / 2,
} }
r1 = Math.max(face1.box.width, face1.box.height) / 2; r1 = Math.max(face1.width, face1.height) / 2;
r2 = Math.max(face2.box.width, face2.box.height) / 2; r2 = Math.max(face2.width, face2.height) / 2;
dx = c1.x - c2.x; dx = c1.x - c2.x;
dy = c1.y - c2.y; dy = c1.y - c2.y;
@ -346,19 +440,17 @@ function parseDetectionResults(results) {
'points': landmarks, 'points': landmarks,
// TODO: rotation // TODO: rotation
'parts': {}, 'parts': {},
'box': { x: result.alignedRect._box._x * factor_x,
x: result.alignedRect._box._x * factor_x, y: result.alignedRect._box._y * factor_y,
y: result.alignedRect._box._y * factor_y, width: result.alignedRect._box._width * factor_x,
width: result.alignedRect._box._width * factor_x, height: result.alignedRect._box._height * factor_y,
height: result.alignedRect._box._height * factor_y,
},
} }
for(let idx in result.parts) { for(let idx in result.parts) {
detection.parts[idx] = result.parts[idx].map((pos) => parseCoordinate(pos)); detection.parts[idx] = result.parts[idx].map((pos) => parseCoordinate(pos));
} }
detection['center'] = { detection['center'] = {
x: detection.box.x + detection.box.width / 2, x: detection.x + detection.width / 2,
y: detection.box.y + detection.box.height / 2, y: detection.y + detection.height / 2,
} }
detections.push(detection); detections.push(detection);
} }
@ -382,12 +474,14 @@ function transformDetection(original) {
let b = original.points[36]; // outer point on left eye let b = original.points[36]; // outer point on left eye
let a = original.points[45]; // outer point on right 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 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 = { let detection = {
'points': original.points.map(p => transformPoint(p, cx, cy, angle)), 'points': original.points.map(p => transformPoint(p, cx, cy, angle)),
'origin': {x:cx, y:cy}, 'origin': {x:cx, y:cy},
@ -399,12 +493,15 @@ function transformDetection(original) {
padding_x = bbox.width * .1; padding_x = bbox.width * .1;
padding_y = bbox.height * .1; padding_y = bbox.height * .1;
detection['box'] = { detection['x'] = bbox.x - padding_x,
x: bbox.x - padding_x, detection['y'] = bbox.y - padding_y,
y: bbox.y - padding_y, detection['width'] = bbox.width * 1.2,
width: bbox.width * 1.2, detection['height'] = bbox.height * 1.2
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; return detection;
} }

View file

@ -10,45 +10,25 @@ classoption:
![](dlib_face_points.png) ![](dlib_face_points.png)
detection.points 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 detection.x
: punten 27--35 : x coordinaat van de bounding box van het gezicht. Dit is het punt linkboven.
detection.parts.leftEye detection.y
: punten 36--41 : y coordinaat van de bounding box van het gezicht. Dit is het punt linkboven.
detection.parts.rightEye detection.width
: punten 42--47 : Breedte van de bounding box van het gezicht.
detection.parts.rightEyeBrow detection.height
: punten 22--26 : Hoogte van de bounding box van het gezicht.
detection.parts.leftEyeBrow <!-- detection.center.x & detection.center.y
: punten 17--21 : Het midden van de bounding box -->
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
@ -71,25 +51,26 @@ circle(cx, cy, radius)
: Upload een afbeelding, waarna je hem kunt inladen met loadImage(...) --> : Upload een afbeelding, waarna je hem kunt inladen met loadImage(...) -->
image(naam, x, y, breedte, hoogte) 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 : Zie hieronder voor alle beschikbare afbeeldingen
getBoundingBox(punten) getBoundingBox(punten)
: Bepaald het rechthoek waarbinnen de punten vallen. : Bepaald het rechthoek waarbinnen de punten vallen.
<!--
mergePoints(punten, anderePunten) 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 ## Opmaak
fill(kleur) fill(kleur)
: de kleur van de vulling : de kleur van de vulling van wat je gaat tekenen.
noFill() noFill()
: geen vulling : geen vulling
stroke(kleur) stroke(kleur)
: de omlijning : de kleur van de omlijning.
strokeWeight(dikte) strokeWeight(dikte)
: de dikte van de omlijning : 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 images.game1
![](../dist/static/assets/images/game1.png) ![](../dist/static/assets/images/game1.png)
@ -164,66 +148,15 @@ images.glasses2
images.glasses3 images.glasses3
![](../dist/static/assets/images/glasses3.png) ![](../dist/static/assets/images/glasses3.png)
images.glasses4
![](../dist/static/assets/images/glasses4.png)
images.hat1 images.hat1
![](../dist/static/assets/images/hat1.png) ![](../dist/static/assets/images/hat1.png)
images.hat2 images.hat2
![](../dist/static/assets/images/hat2.png) ![](../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 images.mustache1
![](../dist/static/assets/images/mustache1.png) ![](../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 images.mustache3
![](../dist/static/assets/images/mustache3.png) ![](../dist/static/assets/images/mustache3.png)
@ -232,16 +165,3 @@ images.mustache4
images.mustache5 images.mustache5
![](../dist/static/assets/images/mustache5.png) ![](../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

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB