Diff of /templates/index.html [000000] .. [d71357]

Switch to side-by-side view

--- a
+++ b/templates/index.html
@@ -0,0 +1,333 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Medical X-Ray Classifier</title>
+  <style>
+    /* General Styles */
+    body {
+      font-family: 'Arial', sans-serif;
+      background: linear-gradient(to right, #e3f2fd, #ffffff);
+      margin: 0;
+      padding: 0;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      min-height: 100vh;
+    }
+
+    .container {
+      width: 90%;
+      max-width: 1200px;
+      background: #fff;
+      border-radius: 12px;
+      box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
+      display: flex;
+      overflow: hidden;
+      animation: fadeIn 1s ease-in-out;
+    }
+
+    @keyframes fadeIn {
+      from {
+        opacity: 0;
+        transform: translateY(20px);
+      }
+      to {
+        opacity: 1;
+        transform: translateY(0);
+      }
+    }
+
+    .left-column {
+      width: 35%;
+      background: #f8f9fa;
+      padding: 20px;
+      border-right: 1px solid #ddd;
+    }
+
+    .right-column {
+      width: 65%;
+      padding: 20px;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
+
+    h1 {
+      text-align: center;
+      font-size: 1.8rem;
+      margin-bottom: 20px;
+      color: #333;
+    }
+
+    input[type="file"] {
+      margin: 15px 0;
+      padding: 10px;
+      border: 1px solid #ddd;
+      border-radius: 6px;
+      cursor: pointer;
+      width: 100%;
+    }
+
+    button {
+      padding: 12px 30px;
+      background: #007bff;
+      color: #fff;
+      border: none;
+      border-radius: 6px;
+      font-size: 14px;
+      cursor: pointer;
+      transition: background 0.3s ease;
+      margin: 10px 0;
+    }
+
+    button:hover {
+      background: #0056b3;
+    }
+
+    .progress-bar {
+      width: 100%;
+      height: 10px;
+      background: #e9ecef;
+      border-radius: 5px;
+      margin: 15px 0;
+      overflow: hidden;
+      position: relative;
+    }
+
+    .progress-bar .progress {
+      height: 100%;
+      background: #28a745;
+      width: 0;
+      transition: width 0.5s;
+    }
+
+    .fixed-box {
+      margin-top: 20px;
+      text-align: center;
+      border: 1px solid #ddd;
+      border-radius: 10px;
+      padding: 10px;
+      background: #fff;
+      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+    }
+
+    .fixed-box img {
+      max-width: 100%;
+      border-radius: 8px;
+    }
+
+    .results {
+      font-size: 1rem;
+      margin-bottom: 20px;
+      text-align: center;
+      display: none;
+    }
+
+    .results.visible {
+      display: block;
+    }
+
+    .note {
+      font-size: 1rem;
+      color: #d9534f;
+      text-align: center;
+      margin-top: 20px;
+    }
+
+    .visualization-group {
+      margin-top: 20px;
+      width: 100%;
+      display: none;
+    }
+
+    .visualization-group.visible {
+      display: block;
+    }
+
+    .visualization-group h3 {
+      font-size: 1.2rem;
+      margin-bottom: 10px;
+      text-align: center;
+    }
+
+    .visualization {
+      display: grid;
+      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+      gap: 15px;
+      justify-items: center;
+    }
+
+    .visualization img {
+      max-width: 100%;
+      border-radius: 8px;
+      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+      transition: transform 0.2s ease;
+    }
+
+    .visualization img:hover {
+      transform: scale(1.05);
+    }
+
+    .image-name {
+      text-align: center;
+      font-size: 0.9rem;
+      margin-top: 5px;
+      color: #555;
+    }
+
+    /* Prediction Result Box */
+    .prediction-box {
+      padding: 20px;
+      background-color: #f8f9fa;
+      border-radius: 8px;
+      border: 1px solid #ddd;
+      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+      margin-top: 20px;
+      text-align: center;
+    }
+
+    .prediction-box p {
+      font-size: 1.2rem;
+      margin: 5px 0;
+    }
+
+    .prediction-box .class {
+      font-weight: bold;
+      font-size: 1.5rem;
+      color: #007bff;
+    }
+
+    .prediction-box .confidence {
+      font-size: 1.1rem;
+      color: #28a745;
+    }
+  </style>
+</head>
+<body>
+  <div class="container">
+    <!-- Left Column -->
+    <div class="left-column">
+      <h1>Upload X-Ray</h1>
+      <form id="upload-form">
+        <input type="file" id="file-input" name="file" accept="image/*" required>
+        <button type="submit">Predict</button>
+        <button id="refresh-button">Refresh</button>
+        <div class="progress-bar">
+          <div class="progress" id="progress-bar"></div>
+        </div>
+      </form>
+      <div class="fixed-box">
+        <h3>Uploaded Image</h3>
+        <img id="original" src="https://via.placeholder.com/150?text=Upload+Image" alt="Uploaded Image">
+        <div class="image-name" id="image-name">Image Name</div>
+      </div>
+    </div>
+
+    <!-- Right Column -->
+    <div class="right-column">
+      <div class="prediction-box" id="result-box">
+        <p><strong>Predicted Class:</strong> <span id="predicted-class">N/A</span></p>
+        <p><strong>Confidence Score:</strong> <span id="confidence-score">N/A</span></p>
+      </div>
+      <div id="note" class="note" style="display: none;">
+        Sorry, you uploaded a non chest X-ray image. Please upload a chest X-ray image. Thank you!
+      </div>
+      <div class="visualization-group" id="visualization-group">
+        <h3>Image Visualizations</h3>
+        <div class="visualization">
+          <div>
+            <img id="grayscale" src="https://via.placeholder.com/150?text=Grayscale" alt="Grayscale Image">
+            <div class="image-name">Grayscale</div>
+          </div>
+          <div>
+            <img id="equalized" src="https://via.placeholder.com/150?text=Equalized" alt="Equalized Image">
+            <div class="image-name">Equalized</div>
+          </div>
+          <div>
+            <img id="edges" src="https://via.placeholder.com/150?text=Edges" alt="Edge Detection">
+            <div class="image-name">Edges</div>
+          </div>
+          <div>
+            <img id="segmented" src="https://via.placeholder.com/150?text=Segmented" alt="Segmented Image">
+            <div class="image-name">Segmented</div>
+          </div>
+        </div>
+        <h3>Advanced Visualizations</h3>
+        <div class="visualization">
+          <div>
+            <img id="grad_cam" src="https://via.placeholder.com/150?text=Grad-CAM" alt="Grad-CAM Visualization">
+            <div class="image-name">Grad-CAM</div>
+          </div>
+          <div>
+            <img id="roi" src="https://via.placeholder.com/150?text=ROI" alt="Region of Interest">
+            <div class="image-name">ROI</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <script>
+    const form = document.getElementById('upload-form');
+    const progressBar = document.getElementById('progress-bar');
+    const resultBox = document.getElementById('result-box');
+    const refreshButton = document.getElementById('refresh-button');
+    const note = document.getElementById('note');
+    const visualizationGroup = document.getElementById('visualization-group');
+    const imageName = document.getElementById('image-name');
+
+    form.addEventListener('submit', async (event) => {
+      event.preventDefault();
+
+      progressBar.style.width = '0';
+      resultBox.style.display = 'none';
+      note.style.display = 'none';
+      visualizationGroup.style.display = 'none';
+      const formData = new FormData(form);
+
+      // Simulate progress
+      let progress = 0;
+      const interval = setInterval(() => {
+        if (progress < 100) {
+          progress += 10;
+          progressBar.style.width = `${progress}%`;
+        } else {
+          clearInterval(interval);
+        }
+      }, 100);
+
+      const response = await fetch('/predict', { method: 'POST', body: formData });
+      const data = await response.json();
+
+      document.getElementById('original').src = URL.createObjectURL(formData.get('file'));
+      imageName.textContent = formData.get('file').name;
+
+      if (data.error) {
+        resultBox.style.display = 'block';
+        document.getElementById('predicted-class').textContent = 'N/A';
+        document.getElementById('confidence-score').textContent = 'N/A';
+        note.style.display = 'block';
+        return;
+      }
+
+      resultBox.style.display = 'block';
+      document.getElementById('predicted-class').textContent = data.predicted_class;
+      document.getElementById('confidence-score').textContent = `${data.confidence_score}%`;
+      visualizationGroup.style.display = 'block';
+
+      document.getElementById('grayscale').src = data.visualizations.grayscale;
+      document.getElementById('equalized').src = data.visualizations.equalized;
+      document.getElementById('edges').src = data.visualizations.edges;
+      document.getElementById('segmented').src = data.visualizations.segmented;
+      document.getElementById('grad_cam').src = data.visualizations.grad_cam;
+      document.getElementById('roi').src = data.visualizations.roi;
+    });
+
+    refreshButton.addEventListener('click', () => {
+      window.location.reload();
+    });
+  </script>
+</body>
+</html>