Spaces:
Configuration error
Configuration error
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Intel Image Classifier</title> | |
| <style> | |
| body { font-family: Arial, sans-serif; background: #f4f7fb; color: #1f2937; margin: 0; padding: 0; } | |
| .container { max-width: 700px; margin: 3rem auto; padding: 2rem; background: white; border-radius: 16px; box-shadow: 0 20px 50px rgba(15,23,42,0.08); } | |
| h1 { margin-top: 0; font-size: 2rem; color: #111827; } | |
| p { line-height: 1.6; color: #374151; } | |
| .form-group { margin-bottom: 1.25rem; } | |
| label { display: block; margin-bottom: 0.5rem; font-weight: 600; } | |
| input[type="file"], select { width: 100%; padding: 0.8rem 1rem; border-radius: 0.75rem; border: 1px solid #d1d5db; background: #f9fafb; } | |
| button { border: none; background: #2563eb; color: white; padding: 0.9rem 1.4rem; border-radius: 0.9rem; font-weight: 700; cursor: pointer; transition: background 0.2s ease; } | |
| button:hover { background: #1d4ed8; } | |
| .result { margin-top: 1.5rem; padding: 1.2rem; border-radius: 1rem; background: #eff6ff; border: 1px solid #bfdbfe; } | |
| .result strong { display: inline-block; width: 170px; } | |
| .probabilities { margin-top: 1rem; width: 100%; border-collapse: collapse; } | |
| .probabilities th, .probabilities td { padding: 0.75rem 0.9rem; border-bottom: 1px solid #e5e7eb; text-align: left; } | |
| .spinner { display: none; margin-top: 1rem; color: #2563eb; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>Intel Image Classifier</h1> | |
| <p>Déposez une image et choisissez un modèle pour obtenir une prédiction en temps réel.</p> | |
| <form id="predict-form"> | |
| <div class="form-group"> | |
| <label for="image">Image</label> | |
| <input type="file" id="image" name="image" accept="image/*" required /> | |
| </div> | |
| <div class="form-group"> | |
| <label for="model-choice">Modèle</label> | |
| <select id="model-choice" name="model_choice"> | |
| <option value="pytorch">PyTorch</option> | |
| <option value="tensorflow">TensorFlow</option> | |
| </select> | |
| </div> | |
| <button type="submit">Classer l'image</button> | |
| <p class="spinner" id="spinner">Analyse en cours…</p> | |
| </form> | |
| <div class="result" id="result" style="display:none;"> | |
| <p><strong>Classe prédite :</strong> <span id="predicted-class"></span></p> | |
| <p><strong>Confiance :</strong> <span id="confidence"></span></p> | |
| <div id="probabilities-container"></div> | |
| </div> | |
| </div> | |
| <script> | |
| const form = document.getElementById('predict-form'); | |
| const spinner = document.getElementById('spinner'); | |
| const resultBox = document.getElementById('result'); | |
| const predictedClass = document.getElementById('predicted-class'); | |
| const confidence = document.getElementById('confidence'); | |
| const probabilitiesContainer = document.getElementById('probabilities-container'); | |
| form.addEventListener('submit', async (event) => { | |
| event.preventDefault(); | |
| const fileInput = document.getElementById('image'); | |
| const modelChoice = document.getElementById('model-choice').value; | |
| const file = fileInput.files[0]; | |
| if (!file) { | |
| alert('Veuillez sélectionner une image avant de soumettre.'); | |
| return; | |
| } | |
| const formData = new FormData(); | |
| formData.append('image', file); | |
| formData.append('model_choice', modelChoice); | |
| spinner.style.display = 'block'; | |
| resultBox.style.display = 'none'; | |
| probabilitiesContainer.innerHTML = ''; | |
| try { | |
| const response = await fetch('/predict', { | |
| method: 'POST', | |
| body: formData, | |
| }); | |
| if (!response.ok) { | |
| const errorText = await response.text(); | |
| throw new Error(errorText || 'Erreur serveur'); | |
| } | |
| const data = await response.json(); | |
| predictedClass.textContent = data.predicted_class; | |
| confidence.textContent = data.confidence; | |
| const table = document.createElement('table'); | |
| table.className = 'probabilities'; | |
| table.innerHTML = '<thead><tr><th>Classe</th><th>Probabilité</th></tr></thead>'; | |
| const tbody = document.createElement('tbody'); | |
| data.probabilities.forEach(item => { | |
| const row = document.createElement('tr'); | |
| row.innerHTML = `<td>${item[0]}</td><td>${(item[1] * 100).toFixed(2)}%</td>`; | |
| tbody.appendChild(row); | |
| }); | |
| table.appendChild(tbody); | |
| probabilitiesContainer.appendChild(table); | |
| resultBox.style.display = 'block'; | |
| } catch (error) { | |
| alert('Erreur lors de la requête : ' + error.message); | |
| } finally { | |
| spinner.style.display = 'none'; | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |