xxxxxxxxxx
209
let mobilenet;
let video;
let detections = [];
let eyes = [];
let lastPersonCount = 0;
let eyeMinDisplayTime = 10000;
let smoothFactor = 0.2;
let movementThreshold = 2;
// Initialisierung der Augen mit unterschiedlichen Bewegungseigenschaften
let eyeProperties = [
{ movementFactor: 0.015, delay: 0 },
{ movementFactor: 0.01, delay: 50 },
{ movementFactor: 0.019, delay: 100 },
{ movementFactor: 0.025, delay: 150 },
{ movementFactor: 0.029, delay: 200 }
];
function modelReady() {
console.log('Model is ready!!!');
mobilenet.detect(gotResults);
}
function gotResults(error, results) {
if (error) {
console.error(error);
} else {
detections = results;
mobilenet.detect(gotResults);
}
}
function setup() {
createCanvas(800, 600);
video = createCapture(VIDEO);
video.size(800, 600);
video.hide();
mobilenet = ml5.objectDetector('cocossd', video, modelReady);
}
function draw() {
background(0);
let currentPersonCount = 0;
let newEyes = [];
if (detections) {
for (let i = 0; i < detections.length; i++) {
let object = detections[i];
if (object.label === 'person') {
let x = object.x + object.width / 2;
let y = object.y + object.height / 2;
let diameter = min(object.width, object.height);
newEyes.push({ x: x, y: y, diameter: diameter });
noFill();
stroke(255, 0, 0);
strokeWeight(2);
rect(object.x, object.y, object.width, object.height);
currentPersonCount++;
}
}
fill(255);
textSize(20);
text('Anzahl der Personen: ' + currentPersonCount, 10, 30);
} else {
fill(255);
textSize(32);
textAlign(CENTER, CENTER);
text('Lade...', width / 2, height / 2);
}
if (currentPersonCount !== lastPersonCount) {
eyes = updateEyes(currentPersonCount, newEyes, eyes);
lastPersonCount = currentPersonCount;
}
eyes = smoothEyes(newEyes, eyes, smoothFactor, movementThreshold);
drawEyes(eyes);
}
function updateEyes(personCount, newEyes, existingEyes) {
let updatedEyes = [];
for (let i = 0; i < personCount; i++) {
let eye = newEyes[i];
let found = false;
for (let j = 0; j < existingEyes.length; j++) {
let existingEye = existingEyes[j];
if (dist(existingEye.x, existingEye.y, eye.x, eye.y) < eye.diameter / 2) {
updatedEyes.push(existingEye);
found = true;
break;
}
}
if (!found) {
let newCircle;
let safeToAdd;
let tries = 0;
let maxTries = 100;
do {
newCircle = {
x: random(eye.diameter / 2, width - eye.diameter / 2),
y: random(eye.diameter / 2, height - eye.diameter / 2),
diameter: eye.diameter,
creationTime: millis(),
movementFactor: eyeProperties[i % eyeProperties.length].movementFactor,
targetX: random(width),
targetY: random(height),
delay: eyeProperties[i % eyeProperties.length].delay
};
safeToAdd = true;
for (let j = 0; j < updatedEyes.length; j++) {
let otherCircle = updatedEyes[j];
let distance = dist(newCircle.x, newCircle.y, otherCircle.x, otherCircle.y);
if (distance < (newCircle.diameter / 2 + otherCircle.diameter / 2)) {
safeToAdd = false;
break;
}
}
tries++;
} while (!safeToAdd && tries < maxTries);
if (safeToAdd) {
updatedEyes.push(newCircle);
}
}
}
updatedEyes = updatedEyes.filter(eye => millis() - eye.creationTime < eyeMinDisplayTime);
return updatedEyes;
}
function smoothEyes(newEyes, existingEyes, factor, threshold) {
return newEyes.map((newEye, index) => {
let existingEye = existingEyes[index] || newEye;
let dx = abs(existingEye.x - newEye.x);
let dy = abs(existingEye.y - newEye.y);
if (dx < threshold && dy < threshold) {
existingEye.x = lerp(existingEye.x, newEye.x, factor);
existingEye.y = lerp(existingEye.y, newEye.y, factor);
} else {
let direction = createVector(newEye.x - existingEye.x, newEye.y - existingEye.y).normalize();
existingEye.x += direction.x * existingEye.movementFactor;
existingEye.y += direction.y * existingEye.movementFactor;
}
existingEye.diameter = newEye.diameter;
existingEye.creationTime = newEye.creationTime;
return existingEye;
});
}
function drawEyes(eyes) {
for (let i = 0; i < eyes.length; i++) {
let eye = eyes[i];
fill(0);
noStroke();
ellipse(eye.x, eye.y, eye.diameter, eye.diameter);
let innerDiameter = eye.diameter / 2;
let maxOffset = (eye.diameter - innerDiameter) / 2;
let whiteX = eye.x;
let whiteY = eye.y - eye.diameter / 2;
let distanceToEdge = dist(whiteX, whiteY, eye.x, eye.y);
if (distanceToEdge > maxOffset) {
let factor = maxOffset / distanceToEdge;
whiteX = eye.x + (whiteX - eye.x) * factor;
whiteY = eye.y + (whiteY - eye.y) * factor;
}
fill(255);
ellipse(whiteX, whiteY, innerDiameter, innerDiameter);
let largerWhiteDiameter = innerDiameter * 1.3;
fill(0, 0, 255, 150);
ellipse(whiteX, whiteY, largerWhiteDiameter, largerWhiteDiameter);
let blueDiameter = innerDiameter * 0.7;
let blueMaxOffset = (innerDiameter - blueDiameter) / 2;
let blueOffsetX = constrain(whiteX - eye.x, -blueMaxOffset, blueMaxOffset);
let blueOffsetY = constrain(whiteY - eye.y, -blueMaxOffset, blueMaxOffset);
fill(200, 0, 300);
ellipse(whiteX + blueOffsetX, whiteY + blueOffsetY, blueDiameter, blueDiameter);
let largerBlueDiameter1 = blueDiameter * 0.3;
let largerBlueDiameter2 = blueDiameter * 0.5;
let speedFactor = map(blueDiameter, innerDiameter * 0.7, innerDiameter * 1.6, 1.5, 0.5);
fill(0, 0, 0);
ellipse(whiteX + blueOffsetX * speedFactor, whiteY + blueOffsetY * speedFactor, largerBlueDiameter1, largerBlueDiameter1);
ellipse(whiteX + blueOffsetX * (speedFactor * 0.5), whiteY + blueOffsetY * (speedFactor * 0.5), largerBlueDiameter2, largerBlueDiameter2);
}
}