Spaces:
Running
Running
File size: 11,004 Bytes
acc4685 f03defd acc4685 f03defd acc4685 f03defd acc4685 f03defd acc4685 f03defd acc4685 f03defd acc4685 f03defd acc4685 f03defd acc4685 f03defd acc4685 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Emotion Detector - Positive Vibes</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/face-api.js@0.22.2/dist/face-api.min.js"></script>
<style>
#video {
transform: scaleX(-1);
}
.emoji {
font-size: 2rem;
margin-bottom: 0.5rem;
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.fade-in {
animation: fadeIn 1s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.falling-smiley {
position: fixed;
font-size: 2rem;
animation: fall linear forwards;
z-index: 10;
pointer-events: none;
opacity: 0.8;
}
@keyframes fall {
to {
transform: translateY(100vh);
opacity: 0;
}
}
</style>
</head>
<body class="bg-gradient-to-br from-indigo-100 to-purple-100 min-h-screen">
<div class="container mx-auto px-4 py-8">
<header class="text-center mb-8">
<h1 class="text-4xl font-bold text-indigo-800 mb-2">Emotion Detector</h1>
<p class="text-lg text-purple-700">Smile for the camera and get some positive vibes!</p>
</header>
<div class="flex flex-col lg:flex-row gap-8 items-center justify-center">
<!-- Camera Section -->
<div class="bg-white rounded-xl shadow-xl p-4 w-full max-w-md">
<div class="relative aspect-video bg-gray-200 rounded-lg overflow-hidden mb-4">
<video id="video" width="100%" height="100%" autoplay muted class="object-cover"></video>
<canvas id="canvas" class="absolute top-0 left-0 w-full h-full pointer-events-none"></canvas>
</div>
</div>
<!-- Results Section -->
<div id="resultsSection" class="bg-white rounded-xl shadow-xl p-6 w-full max-w-md">
<div class="text-center mb-6">
<div id="emojiDisplay" class="emoji text-5xl mb-4"></div>
<h2 id="emotionText" class="text-2xl font-bold text-indigo-800 mb-2"></h2>
<p id="confidenceText" class="text-gray-600"></p>
</div>
<div class="bg-indigo-50 rounded-lg p-4 mb-4">
<h3 class="font-semibold text-indigo-700 mb-2">Positive Suggestion:</h3>
<p id="suggestionText" class="text-indigo-900"></p>
</div>
<div class="bg-purple-50 rounded-lg p-4">
<h3 class="font-semibold text-purple-700 mb-2">Did you know?</h3>
<p id="factText" class="text-purple-900"></p>
</div>
</div>
</div>
</div>
<script>
// DOM Elements
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const resultsSection = document.getElementById('resultsSection');
const emojiDisplay = document.getElementById('emojiDisplay');
const emotionText = document.getElementById('emotionText');
const confidenceText = document.getElementById('confidenceText');
const suggestionText = document.getElementById('suggestionText');
const factText = document.getElementById('factText');
// Emotion to emoji mapping
const emotionEmojis = {
'happy': 'π',
'sad': 'π’',
'angry': 'π ',
'fearful': 'π¨',
'disgusted': 'π€’',
'surprised': 'π²',
'neutral': 'π'
};
// Positive suggestions for each emotion
const positiveSuggestions = {
'happy': "Your smile is contagious! Why not spread that joy by complimenting someone today?",
'sad': "It's okay to feel down sometimes. Try listening to your favorite music or calling a friend - you're not alone.",
'angry': "Take a deep breath. Try counting to 10 slowly. Remember, this feeling will pass.",
'fearful': "You're stronger than you think. Focus on what you can control right now.",
'disgusted': "Sometimes things bother us. Try shifting your focus to something beautiful around you.",
'surprised': "Life is full of surprises! Embrace the unexpected - it might lead to something wonderful.",
'neutral': "A calm moment is a gift. Enjoy this peaceful state or try something creative!"
};
// Fun facts about emotions
const emotionFacts = {
'happy': "Smiling (even when you don't feel like it) can actually trick your brain into feeling happier!",
'sad': "Tears contain stress hormones - crying literally helps your body release stress.",
'angry': "Anger typically lasts just 90 seconds if you don't feed it with more negative thoughts.",
'fearful': "Facing your fears in small doses can actually rewire your brain to be less afraid over time.",
'disgusted': "Disgust evolved to protect us from potential contaminants - your brain is looking out for you!",
'surprised': "Surprise helps us reset our attention and focus on new information more effectively.",
'neutral': "Neutral expressions are actually perceived as slightly positive by most people."
};
// Initialize camera
async function initCamera() {
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
// Load required face-api.js models
await faceapi.nets.tinyFaceDetector.loadFromUri('https://justadudewhohacks.github.io/face-api.js/models');
await faceapi.nets.faceExpressionNet.loadFromUri('https://justadudewhohacks.github.io/face-api.js/models');
// Start face detection
detectFaces();
} catch (err) {
console.error("Error accessing camera:", err);
alert("Could not access the camera. Please make sure you've granted camera permissions.");
}
}
// Detect faces and emotions in real-time
function detectFaces() {
const displaySize = { width: video.width, height: video.height };
faceapi.matchDimensions(canvas, displaySize);
setInterval(async () => {
const detections = await faceapi.detectAllFaces(video,
new faceapi.TinyFaceDetectorOptions()).withFaceExpressions();
// Clear canvas
canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
if (detections.length > 0) {
// Get the dominant emotion
const expressions = detections[0].expressions;
let dominantEmotion = 'neutral';
let maxConfidence = 0;
for (const [emotion, confidence] of Object.entries(expressions)) {
if (confidence > maxConfidence) {
maxConfidence = confidence;
dominantEmotion = emotion;
}
}
// Update UI with results
emojiDisplay.textContent = emotionEmojis[dominantEmotion];
emojiDisplay.classList.add('pulse');
createFallingSmileys(dominantEmotion);
emotionText.textContent = `${dominantEmotion.charAt(0).toUpperCase() + dominantEmotion.slice(1)}`;
confidenceText.textContent = `Confidence: ${Math.round(maxConfidence * 100)}%`;
suggestionText.textContent = positiveSuggestions[dominantEmotion];
factText.textContent = emotionFacts[dominantEmotion];
}
}, 2000); // Update every 4 seconds
}
// Set video dimensions when metadata is loaded
video.addEventListener('loadedmetadata', () => {
video.width = video.videoWidth;
video.height = video.videoHeight;
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
});
// Create falling smileys
function createFallingSmileys(emotion) {
const emoji = emotionEmojis[emotion];
const duration = 8; // Slower falling
// Create multiple smileys
for (let i = 0; i < 15; i++) {
const smiley = document.createElement('div');
smiley.className = 'falling-smiley';
smiley.textContent = emoji;
// Random position across the whole screen width
const left = Math.random() * window.innerWidth;
smiley.style.left = `${left}px`;
smiley.style.top = '-50px'; // Start above the viewport
smiley.style.animationDuration = `${duration + Math.random() * 4}s`; // Varying speeds
// Random size variation
const size = 1 + Math.random();
smiley.style.fontSize = `${size}rem`;
document.body.appendChild(smiley);
// Remove smiley after animation completes
setTimeout(() => {
smiley.remove();
}, duration * 1000);
}
}
// Initialize app when page loads
window.addEventListener('DOMContentLoaded', initCamera);
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 𧬠<a href="https://enzostvs-deepsite.hf.space?remix=manmohanai/emotiondetector" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html> |