File size: 8,860 Bytes
4983aaa |
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 |
document.addEventListener("DOMContentLoaded", () => {
document
.getElementById("detectBtn")
.addEventListener("click", onDetectEmotionClick);
document.getElementById("settingsBtn").addEventListener("click", onDetectEmotionClick);
initWebcam();
const technicalSection = document.getElementById("technical-section");
technicalSection.style.display = "none";
});
// Send the image to the Flask backend
async function sendImageToBackend(imageData) {
try {
// Get base64 string and remove the prefix
const base64String = imageData.src.split(',')[1];
const response = await fetch("/upload", { // Changed to relative path
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
image: base64String
})
});
if (!response.ok) {
throw new Error(`Server responded with status: ${response.status}`);
}
const result = await response.json();
console.log("Emotion detection result:", result);
return result;
} catch (error) {
console.error("Error during API call:", error);
throw error;
}
}
// Handle the Detect Emotion button click
async function onDetectEmotionClick() {
const initialContent = document.getElementById("initial-content");
const calculatingContent = document.getElementById("calculating-content");
const detectBtn = document.getElementById("detectBtn");
const technicalSection = document.getElementById("technical-section");
const loadingSpinner = document.querySelector(".loading-spinner");
try {
// Hide initial content and show loading
initialContent.style.display = "none";
calculatingContent.style.display = "flex";
detectBtn.style.opacity = "0";
loadingSpinner.style.display = "block";
// Hide technical section while processing
technicalSection.style.display = "none";
// Capture and process image
const capturedImage = captureImage();
const result = await sendImageToBackend(capturedImage);
if (result.error) {
throw new Error(result.error);
}
// Hide loading spinner after getting results
loadingSpinner.style.display = "none";
// Show and update technical section
technicalSection.style.display = "block";
void technicalSection.offsetWidth;
technicalSection.classList.add('visible');
// Update technical section with processing steps
updateTechnicalSection(result);
// Update emotion display with personalized message
document.querySelector(".result-emoji").textContent = result.emoji;
document.querySelector(".result-comment").textContent = getEmotionMessage(result.emotion);
// Update button
detectBtn.innerHTML = '<i class="fas fa-code mr-2"></i>Show Details';
detectBtn.style.opacity = "1";
// Remove old click handler and add new one
detectBtn.removeEventListener('click', onDetectEmotionClick);
detectBtn.addEventListener('click', handleShowDetails);
} catch (error) {
console.error("Error:", error);
loadingSpinner.style.display = "none";
document.querySelector(".result-emoji").textContent = "β";
document.querySelector(".result-comment").textContent = "Failed to detect emotion. Please try again.";
detectBtn.style.opacity = "1";
technicalSection.style.display = "none";
}
}
// Initialize when document is loaded
document.addEventListener("DOMContentLoaded", () => {
const detectBtn = document.getElementById("detectBtn");
const settingsBtn = document.getElementById("settingsBtn");
const technicalSection = document.getElementById("technical-section");
// Hide technical section initially
technicalSection.style.display = "none";
// Add click handlers
detectBtn.addEventListener("click", onDetectEmotionClick);
settingsBtn.addEventListener("click", onDetectEmotionClick);
initWebcam();
});
function updateTechnicalSection(result) {
console.log("Full result:", result);
console.log("Processing steps:", result.processing_steps);
console.log("Detailed steps:", result.processing_steps.detailed_steps);
// Update preprocessed image with processing info
document.getElementById("preprocessed-image").innerHTML = `
<img src="${result.grayscale_image}" alt="Preprocessed Image" class="preprocessed-image">
<div class="processing-info">
<p>Image Size: ${result.processing_steps.original_size[0]}x${result.processing_steps.original_size[1]}</p>
<p>Color Mode: ${result.processing_steps.color_mode}</p>
</div>
`;
// Update processing pipeline steps
const processSteps = result.processing_steps.detailed_steps;
if (!processSteps) {
console.error("No processing steps found in result");
return;
}
let stepsHtml = '<div class="process-flow">';
// Add each processing stage with error handling
try {
for (const [stage, steps] of Object.entries(processSteps)) {
console.log("Processing stage:", stage, steps);
const stageName = stage.split('_').map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join(' ');
stepsHtml += `
<div class="process-stage">
<h4>${stageName}</h4>
<ul class="step-list">
${Array.isArray(steps) ? steps.map(step => `<li>${step}</li>`).join('') : ''}
</ul>
</div>
`;
}
stepsHtml += '</div>';
// Add model information
stepsHtml += `
<div class="model-info">
<h4>MODEL SPECIFICATIONS</h4>
<ul class="step-list">
<li>Type: ${result.processing_steps.model_type}</li>
<li>Input Shape: ${result.processing_steps.input_shape}</li>
<li>Output: ${result.processing_steps.output_classes}</li>
</ul>
</div>
`;
console.log("Generated HTML:", stepsHtml);
document.getElementById("processing-steps").innerHTML = stepsHtml;
} catch (error) {
console.error("Error generating steps HTML:", error);
}
// Update emotion probabilities
const probContainer = document.getElementById("emotion-probabilities");
probContainer.innerHTML = "";
Object.entries(result.model_probabilities).forEach(([emotion, probability]) => {
const percentage = (probability * 100).toFixed(1);
const barElement = document.createElement('div');
barElement.className = 'probability-bar probability-bar-custom probability-bar-width';
barElement.style.setProperty('--percentage', `${percentage}%`);
probContainer.innerHTML += `
<div class="probability-label">
<span>${emotion}</span>
<span>${percentage}%</span>
</div>
`;
probContainer.appendChild(barElement);
});
// Update remaining elements
document.getElementById("detected-emoji").textContent = result.emoji;
document.getElementById("detected-emotion").textContent = result.emotion;
document.getElementById("confidence-score").querySelector("h4").textContent =
`${(result.model_probabilities[result.emotion] * 100).toFixed(1)}%`;
}
function getEmotionMessage(emotion) {
const messages = {
happy: "You're radiating happiness! Your smile lights up the room! π",
sad: "I see some sadness there. Remember, every cloud has a silver lining! π",
angry: "Whoa, looking pretty fired up! Take a deep breath and count to ten. π§",
disgust: "That's quite the expression! Something leave a bad taste? π",
fear: "I sense some anxiety there. Remember, you're stronger than you think! πͺ",
surprise: "Well, that caught you off guard! What an unexpected moment! π²",
neutral: "Keeping it cool and collected with that poker face! π"
};
return messages[emotion] || "Interesting expression you've got there! π€";
}
// Add this new function for handling the "Show Details" click
function handleShowDetails() {
const technicalSection = document.getElementById("technical-section");
// First ensure the section is visible
technicalSection.style.display = "block";
// Then scroll to it
setTimeout(() => {
technicalSection.scrollIntoView({
behavior: "smooth",
block: "start"
});
}, 100);
}
|