faceapi / js /emocoes.js
faustinopsy's picture
Upload 52 files
cc65f2f verified
const form = document.querySelector("#detectar-emocoes-form");
let resultsContainer = document.querySelector("#detectar-emocoes-results");
let resultsidade = document.querySelector("#detectar-emocoes-idade");
let pontos = document.querySelector("#pontos");
const sourceSwitch = document.getElementById("detectar-emocoes-source-switch");
let stream;
let startCameraButton = document.getElementById("start-camera-button");
let detectEmotionsButton = document.getElementById("detect-emotions-button");
let detectLandmarksButton = document.getElementById("detect-landmarks-button");
let detectAgeButton = document.getElementById("detect-age-button");
let extractPointsButton = document.getElementById("extract-points-button");
let displaySize;
let detections;
let resizedDetections;
let canvas = document.createElement("canvas");
resultsContainer.appendChild(canvas);
let startCameraInterval;
detectEmotionsButton.disabled = true;
detectLandmarksButton.disabled = true;
detectAgeButton.disabled = true;
extractPointsButton.disabled = true;
startCameraButton.addEventListener("change", async (event) => {
if (event.target.checked) {
detectEmotionsButton.disabled = false;
detectLandmarksButton.disabled = false;
detectAgeButton.disabled = false;
extractPointsButton.disabled = false;
detectEmotionsButton.addEventListener("change", detectEmotionsButton);
detectLandmarksButton.addEventListener("change", detectLandmarksButton);
detectAgeButton.addEventListener("change", detectAgeButton);
extractPointsButton.addEventListener("change", extractPointsButton);
resultsContainer.innerHTML = "";
video = document.createElement("video");
video.width = 200;
video.height = 150;
video.autoplay = true;
stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: true,
});
canvas.width = video.width;
canvas.height = video.height;
canvas.id = "landmarkCanvas";
video.srcObject = stream;
resultsContainer.appendChild(video);
resultsContainer.appendChild(canvas);
} else {
detectEmotionsButton.checked = false;
detectEmotionsButton.disabled = true;
detectLandmarksButton.checked = false;
detectLandmarksButton.disabled = true;
detectAgeButton.checked = false;
detectAgeButton.disabled = true;
extractPointsButton.checked = false;
extractPointsButton.disabled = true;
detectEmotionsButton.removeEventListener("change", detectEmotionsButton);
detectLandmarksButton.removeEventListener("change", detectLandmarksButton);
detectAgeButton.removeEventListener("change", detectAgeButton);
extractPointsButton.removeEventListener("change", extractPointsButton);
clearInterval(detectLandmarksInterval);
clearInterval(detectEmotionsInterval);
clearInterval(detectAgeInterval);
clearInterval(extractPointsInterval);
resultsContainer.innerHTML = "";
video.srcObject = null;
if (stream != null) {
stream.getTracks().forEach((track) => track.stop());
}
}
});
let detectEmotionsInterval;
detectEmotionsButton.addEventListener("change", async (event) => {
if (event.target.checked) {
detectEmotionsInterval = setInterval(async () => {
canvas = document.getElementById("landmarkCanvas");
displaySize = { width: video.width, height: video.height};
faceapi.matchDimensions(canvas,displaySize);
detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions();
resizedDetections = faceapi.resizeResults(detections, displaySize);
resultsContainer.innerHTML = "";
resultsContainer.appendChild(video);
resultsContainer.appendChild(canvas);
detections.forEach((result) => {
if (result.expressions) {
const happy = result.expressions.Feliz || 0;
const sad = result.expressions.Triste || 0;
const angry = result.expressions.Raiva || 0;
const disgusted = result.expressions.Nojo || 0;
const fear = result.expressions.Medo || 0;
const surprise = result.expressions.Surpreso || 0;
const neutr = result.expressions.Neutro || 0;
const card = document.createElement("div");
card.innerHTML = `<h3>Emoções detectadas:</h3> <ul>
<li>Neutro: ${neutr.toFixed(2)}</li>
<li>Felicidade: ${happy.toFixed(2)}</li>
<li>Tristeza: ${sad.toFixed(2)}</li>
<li>Raiva: ${angry.toFixed(2)}</li>
<li>Desprezo: ${disgusted.toFixed(2)}</li>
<li>Medo: ${fear.toFixed(2)}</li>
<li>Surpresa: ${surprise.toFixed(2)}</li>
</ul>`;
resultsContainer.appendChild(card);
} else {
console.error("Nenhuma emoção detectada.");
}
});
}, 500)
} else {
clearInterval(detectEmotionsInterval);
}
});
let detectLandmarksInterval;
function unite(leftEyebrow, rightEyebrow) {
const united = [];
for (const point of leftEyebrow) { united.push(point); }
for (const point of rightEyebrow) {united.push(point); }
return united;
}
detectLandmarksButton.addEventListener("change", async (event) => {
if (event.target.checked) {
detectLandmarksInterval = setInterval(async () => {
canvas = document.getElementById("landmarkCanvas");
displaySize = { width: video.width, height: video.height};
faceapi.matchDimensions(canvas,displaySize);
detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks();
resizedDetections = faceapi.resizeResults(detections, displaySize);
canvas.getContext('2d').clearRect(0,0,canvas.width, canvas.height);
for (const detection of resizedDetections) {
const landmarks = detection.landmarks;
const leftEyebrow = landmarks.getLeftEyeBrow();
const rightEyebrow = landmarks.getRightEyeBrow();
faceapi.draw.drawFaceLandmarks(canvas, detection, {
drawLines: true,
color: 'red',
landmarkIndices: leftEyebrow.concat(rightEyebrow)
});
faceapi.draw.drawFaceLandmarks(canvas, detection, {
drawLines: true,
color: 'yellow',
landmarkIndices: leftEyebrow.concat(rightEyebrow)
});
}
resultsContainer.innerHTML = "";
resultsContainer.appendChild(video);
resultsContainer.appendChild(canvas);
}, 500)
} else {
clearInterval(detectLandmarksInterval);
}
});
let detectAgeInterval;
detectAgeButton.addEventListener("change", async (event) => {
if (event.target.checked) {
detectAgeInterval = setInterval(async () => {
canvas = document.getElementById("landmarkCanvas");
displaySize = { width: video.width, height: video.height};
faceapi.matchDimensions(canvas,displaySize);
detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()).withAgeAndGender();
resizedDetections = faceapi.resizeResults(detections, displaySize);
resultsidade.innerHTML = "";
resultsidade.appendChild(video);
resultsidade.appendChild(canvas);
detections.forEach((result) => {
if (result.age) {
const card = document.createElement("div");
card.innerHTML = `<h3>Idade detectada:</h3> <p>${result.age.toFixed(0)} anos</p>`;
resultsidade.appendChild(card);
} else {
console.error("Nenhuma idade detectada.");
}
});
}, 500)
} else {
clearInterval(detectAgeInterval);
}
});
let extractPointsInterval;
extractPointsButton.addEventListener("change", async (event) => {
if (event.target.checked) {
extractPointsInterval = setInterval(async () => {
canvas = document.getElementById("landmarkCanvas");
displaySize = { width: video.width, height: video.height};
faceapi.matchDimensions(canvas,displaySize);
detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks();
resizedDetections = faceapi.resizeResults(detections, displaySize);
resultsContainer.appendChild(video);
resultsContainer.appendChild(canvas);
function getBoxFromPoints(points) {
const box = { bottom: -Infinity, left: Infinity, right: -Infinity, top: Infinity,
get center() {return { x: this.left + this.width / 2, y: this.top + this.height / 2, };
},
get height() { return this.bottom - this.top; },
get width() { return this.right - this.left; },
};
for (const point of points) {
box.left = Math.min(box.left, point.x);
box.right = Math.max(box.right, point.x);
box.bottom = Math.max(box.bottom, point.y);
box.top = Math.min(box.top, point.y);
}
return box;
}
let tempoDeSelecao = 2000;
let tempoInicial;
let botaoSelecionado = null;
function calcularPontoDeOlhar(face) {
const olhoEsquerdo = face.landmarks.positions.slice(36, 42);
const olhoDireito = face.landmarks.positions.slice(42, 48);
// Calculando os pontos centrais para cada olho
const centroEsquerdo = calcularCentro(olhoEsquerdo);
const centroDireito = calcularCentro(olhoDireito);
// Calculando um ponto médio entre os centros dos dois olhos
const pontoFocal = {
x: (centroEsquerdo.x + centroDireito.x) / 2,
y: (centroEsquerdo.y + centroDireito.y) / 2
};
return pontoFocal;
}
function calcularCentro(pontos) {
const totalPontos = pontos.length;
const centro = pontos.reduce((soma, ponto) => {
soma.x += ponto._x;
soma.y += ponto._y;
return soma;
}, {x: 0, y: 0});
centro.x /= totalPontos;
centro.y /= totalPontos;
return centro;
}
function verificarBotaoSobOlhar(pontoFocal) {
const botoes = document.querySelectorAll('.eye-button');
for(const botao of botoes) {
const rect = botao.getBoundingClientRect();
console.log(rect.left)
console.log(pontoFocal.x)
if (
pontoFocal.x >= rect.left && pontoFocal.x <= rect.right &&
pontoFocal.y >= rect.top && pontoFocal.y <= rect.bottom
) {
console.log(pontoFocal)
return botao; // Retornará o botão que está sob o olhar
}
}
return null; // Retornará null se nenhum botão estiver sob o olhar
}
function olhoEstaSobreBotao(pontoFocal, botao) {
return pontoFocal._x > botao.x && pontoFocal._x < botao.x + botao.width && pontoFocal._y > botao.y && pontoFocal._y < botao.y + botao.height;
}
document.querySelectorAll('.eye-button').forEach(botao => {
botao.addEventListener('mouseenter', () => {
tempoInicial = new Date().getTime();
});
botao.addEventListener('mouseleave', () => {
tempoInicial = null;
});
});
setInterval(() => {
if(tempoInicial && new Date().getTime() - tempoInicial > tempoDeSelecao) {
console.log('Botão selecionado!');
tempoInicial = null;
// Adicione a lógica para lidar com a seleção do botão aqui
}
}, 100);
for (const face of resizedDetections) {
//const pontoFocal = calcularPontoDeOlhar(face);
const features = {
mandibula: face.landmarks.positions.slice(0, 17),
sobrancelhaesquerda: face.landmarks.positions.slice(17, 22),
sobrancelhaDireita: face.landmarks.positions.slice(22, 27),
Pontenasal: face.landmarks.positions.slice(27, 31),
nariz: face.landmarks.positions.slice(31, 36),
olhoEsquerdo: face.landmarks.positions.slice(36, 42),
olhoDireito: face.landmarks.positions.slice(42, 48),
labioExterno: face.landmarks.positions.slice(48, 60),
labiointerno: face.landmarks.positions.slice(60),
};
const pre = document.createElement("pre");
pre.innerText = JSON.stringify(features, null, 2);
pontos.innerHTML = "";
pontos.appendChild(pre);
for (const eye of [features.olhoEsquerdo, features.olhoDireito]) {
const eyeBox = getBoxFromPoints(eye);
const fontSize = 20;
const context = canvas.getContext("2d");
context.lineWidth = 2;
context.fillStyle = "#FF0000";
context.beginPath();
context.fillStyle = "rgba(20,30,22,0.5)";
context.strokeRect(eyeBox.center.x-10, eyeBox.center.y-10, 30, 20, 30 );
context.arc(eyeBox.center.x, eyeBox.center.y, 4, 0, 2 * Math.PI);
context.fillStyle = "rgba(255, 255, 255, 0)";
context.fill();
context.closePath();
let pontoFocal = {
x: (eyeBox.center.x ) / 2,
y: (eyeBox.center.y ) / 2
};
const botaoSobOlhar = verificarBotaoSobOlhar(pontoFocal);
console.log(botaoSobOlhar)
if (botaoSobOlhar) {
if (botaoSelecionado !== botaoSobOlhar) {
botaoSelecionado = botaoSobOlhar;
tempoInicial = new Date().getTime();
} else if (new Date().getTime() - tempoInicial > tempoDeSelecao) {
console.log('Botão selecionado:', botaoSelecionado.id);
// Adicione a lógica para lidar com a seleção do botão aqui...
}
} else {
botaoSelecionado = null;
tempoInicial = null;
}
}
}
}, 500)
} else {
clearInterval(extractPointsInterval);
}
});