Skip to content

Commit 88b0a11

Browse files
committed
DisplaySolo
1 parent 9d536f6 commit 88b0a11

19 files changed

Lines changed: 6049 additions & 0 deletions
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html lang="de">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Face‑Capture mit ml5.js & p5.js</title>
6+
<link rel="stylesheet" href="styles.css">
7+
8+
<!-- p5.js -->
9+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.min.js"></script>
10+
<!-- ml5.js (enthält FaceAPI) -->
11+
<script src="https://cdnjs.cloudflare.com/ajax/libs/ml5/0.12.2/ml5.min.js"></script>
12+
</head>
13+
<body>
14+
<h1>Gesichtserkennung & -speicherung</h1>
15+
16+
<div id="canvas-container"></div>
17+
18+
<button id="saveBtn" disabled>Gesicht speichern (JPEG)</button>
19+
20+
<script src="script.js"></script>
21+
</body>
22+
</html>
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/* ------------- globale Variablen ------------- */
2+
let video; // p5 Video Capture
3+
let faceapi; // ml5 FaceAPI Instanz
4+
let detections = []; // Aktuelle Erkennungen
5+
let faceGraphics; // p5.Graphics für das ausgeschnittene Gesicht
6+
let saveBtn; // Button-Element
7+
8+
/* ------------- p5.js Setup ------------- */
9+
function setup() {
10+
// Canvas wird im HTML‑Container eingefügt
11+
const cnv = createCanvas(640, 480);
12+
cnv.parent('canvas-container');
13+
14+
// Kamera starten
15+
video = createCapture(VIDEO);
16+
video.size(width, height);
17+
video.hide(); // Wir zeichnen das Video selbst
18+
19+
// FaceAPI laden (nur "face" Modell)
20+
const faceOptions = { withLandmarks: false, withDescriptors: false };
21+
faceapi = ml5.faceApi(video, faceOptions, modelReady);
22+
23+
// Grafik‑Puffer für das Gesicht (initial leer)
24+
faceGraphics = createGraphics(width, height);
25+
26+
// Button einrichten
27+
saveBtn = select('#saveBtn');
28+
saveBtn.mousePressed(saveFace);
29+
}
30+
31+
/* ------------- Modell bereit ------------- */
32+
function modelReady() {
33+
console.log('FaceAPI‑Modell geladen');
34+
// Kontinuierlich nach Gesichtern suchen
35+
faceapi.detect(gotResults);
36+
}
37+
38+
/* ------------- Ergebnis‑Callback ------------- */
39+
function gotResults(err, result) {
40+
if (err) {
41+
console.error(err);
42+
return;
43+
}
44+
detections = result; // Array von Detektionen (kann leer sein)
45+
46+
// Nächste Erkennung starten
47+
faceapi.detect(gotResults);
48+
}
49+
50+
/* ------------- p5.js Draw ------------- */
51+
function draw() {
52+
// Videobild zeigen
53+
image(video, 0, 0, width, height);
54+
55+
// Falls ein Gesicht erkannt wurde, Bounding‑Box und Ausschnitt zeichnen
56+
if (detections && detections.length > 0) {
57+
const { alignedRect } = detections[0]; // erstes Gesicht
58+
const { _x, _y, _width, _height } = alignedRect._box;
59+
60+
// Rechteck um das Gesicht
61+
noFill();
62+
stroke(0, 255, 0);
63+
strokeWeight(2);
64+
rect(_x, _y, _width, _height);
65+
66+
// Gesicht in den Grafik‑Puffer kopieren
67+
faceGraphics.clear();
68+
faceGraphics.copy(
69+
video,
70+
_x, _y, _width, _height, // Quelle
71+
0, 0, _width, _height // Ziel (oben links im Puffer)
72+
);
73+
74+
// Button aktivieren
75+
saveBtn.removeAttribute('disabled');
76+
} else {
77+
// Kein Gesicht → Button deaktivieren
78+
saveBtn.attribute('disabled', '');
79+
}
80+
}
81+
82+
/* ------------- Bild speichern ------------- */
83+
function saveFace() {
84+
if (!detections || detections.length === 0) return;
85+
86+
// Das Gesicht befindet sich im faceGraphics‑Puffer.
87+
// Wir speichern nur den Teil, der das Gesicht enthält.
88+
const { alignedRect } = detections[0];
89+
const { _width, _height } = alignedRect._box;
90+
91+
// Erstelle ein temporäres Canvas mit exakt der Größe des Gesichts
92+
const tmp = createGraphics(_width, _height);
93+
tmp.image(faceGraphics, 0, 0, _width, _height, 0, 0, _width, _height);
94+
95+
// p5.saveCanvas speichert als PNG – wir konvertieren zu JPEG
96+
// (p5.js unterstützt nur PNG direkt, daher nutzen wir toDataURL)
97+
const dataURL = tmp.canvas.toDataURL('image/jpeg', 0.92);
98+
const link = document.createElement('a');
99+
link.href = dataURL;
100+
link.download = 'face_' + Date.now() + '.jpg';
101+
link.click();
102+
103+
// Aufräumen
104+
tmp.remove();
105+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* Grundlayout */
2+
body {
3+
font-family: Arial, Helvetica, sans-serif;
4+
background: #f0f0f0;
5+
text-align: center;
6+
margin: 0;
7+
padding: 20px;
8+
}
9+
10+
/* Überschrift */
11+
h1 {
12+
color: #333;
13+
}
14+
15+
/* Canvas‑Container – zentriert */
16+
#canvas-container {
17+
display: inline-block;
18+
position: relative;
19+
}
20+
21+
/* Button */
22+
#saveBtn {
23+
margin-top: 15px;
24+
padding: 10px 20px;
25+
font-size: 1rem;
26+
background: #4caf50;
27+
color: white;
28+
border: none;
29+
border-radius: 4px;
30+
cursor: pointer;
31+
}
32+
#saveBtn:disabled {
33+
background: #aaa;
34+
cursor: not-allowed;
35+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Quelle: The Coding Train: https://youtu.be/8HEgeAbYphA
2+
3+
Code-Beispiel: https://editor.p5js.org/codingtrain/sketches/zwGahux8a
4+
5+
6+
7+
8+
9+
10+
11+

0 commit comments

Comments
 (0)