Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Image Classifier</title> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| font-size: 20px; | |
| line-height: 1.6; | |
| text-align: center; | |
| } | |
| /* Styling for loading overlay */ | |
| .overlay { | |
| position: fixed; | |
| width: 100%; | |
| height: 100%; | |
| top: 0; | |
| left: 0; | |
| background-color: rgba(0, 0, 0, 0.5); /* semi-transparent black */ | |
| display: none; | |
| justify-content: center; | |
| align-items: center; | |
| z-index: 999; /* ensure it's above other content */ | |
| } | |
| .spinner { | |
| border: 8px solid rgba(255, 255, 255, 0.3); /* light border */ | |
| border-top: 8px solid #ffffff; /* white border on top */ | |
| border-radius: 50%; | |
| width: 50px; | |
| height: 50px; | |
| animation: spin 1s linear infinite; /* spinning animation */ | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| /* Styling for specific elements */ | |
| #dropArea { | |
| border: 2px dashed #007bff; /* Blue dashed border */ | |
| border-radius: 8px; | |
| padding: 20px; | |
| margin: 20px auto; | |
| width: 80%; | |
| max-width: 400px; | |
| cursor: pointer; | |
| } | |
| #dropArea:hover { | |
| background-color: #f0faff; /* Light blue background on hover */ | |
| } | |
| img { | |
| width: 300px; | |
| display: block; | |
| margin: 0 auto; /* Center image horizontally */ | |
| } | |
| button { | |
| display: inline-block; | |
| padding: 12px 24px; | |
| font-weight: bold; | |
| font-size: 18px; | |
| color: white; | |
| background-color: #007bff; /* Blue background */ | |
| border-radius: 8px; | |
| cursor: pointer; | |
| margin-top: 20px; | |
| } | |
| p#result { | |
| margin-top: 20px; | |
| font-weight: bold; | |
| font-size: 24px; | |
| } | |
| #recommendationContainer { | |
| margin-top: 20px; | |
| font-weight: bold; | |
| font-size: 24px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="overlay" id="loadingOverlay"> | |
| <div class="spinner"></div> | |
| </div> | |
| <div id="dropArea" onclick="uploadImage(event)" ondrop="handleDrop(event)" ondragover="handleDragOver(event)"> | |
| <p>Drag and drop an OCT image file here, or click to select file</p> | |
| </div> | |
| <img id="img1" src="" style="display: none;" /> | |
| <button class="predict-btn" onclick="predict()">Predict</button> | |
| <p id="result"></p> | |
| <button class="suggest-recommend-btn" style="display: none;" onclick="suggestRecommendation()">Suggest Recommendation</button> | |
| <div id="recommendationContainer"></div> | |
| <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script> | |
| <script> | |
| function handleDragOver(event) { | |
| event.preventDefault(); | |
| } | |
| function handleDrop(event) { | |
| event.preventDefault(); | |
| const file = event.dataTransfer.files[0]; | |
| if (file) { | |
| showImage(file); | |
| } | |
| } | |
| function uploadImage(event) { | |
| const input = document.createElement('input'); | |
| input.type = 'file'; | |
| input.accept = 'image/*'; | |
| input.style.display = 'none'; | |
| input.onchange = function(event) { | |
| const file = event.target.files[0]; | |
| if (file) { | |
| showImage(file); | |
| } | |
| }; | |
| document.body.appendChild(input); // Append input to the document | |
| input.click(); // Trigger the file input dialog | |
| document.body.removeChild(input); // Clean up the input element | |
| } | |
| function showImage(file) { | |
| const reader = new FileReader(); | |
| reader.onload = function(event) { | |
| const image = document.getElementById('img1'); | |
| image.src = event.target.result; | |
| image.style.display = 'block'; | |
| clearRecommendations(); | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| async function predict() { | |
| document.getElementById('loadingOverlay').style.display = 'flex'; // Show loading overlay | |
| document.getElementById('result').innerText = ''; // Clear previous result | |
| clearRecommendations(); // Clear previous recommendations | |
| const model = await tf.loadGraphModel('./model.json'); | |
| let example = tf.browser.fromPixels(document.getElementById('img1')).cast('float32'); | |
| example = example.expandDims(0); | |
| let prediction = model.predict(example); | |
| let class_scores = prediction.dataSync(); | |
| let max_score_id = class_scores.indexOf(Math.max(...class_scores)); | |
| const classes = [ | |
| "Non-neovascular AMD", | |
| "Non-neovascular AMD", | |
| "Non-neovascular AMD with Geographic atrophy", | |
| "Normal", | |
| "Active Neovascular AMD", | |
| "Non-neovascular AMD" | |
| ]; | |
| const result = classes[max_score_id]; | |
| document.getElementById('result').innerText = result; | |
| document.getElementById('loadingOverlay').style.display = 'none'; // Hide loading overlay | |
| if (result !== "Normal") { | |
| document.querySelector('.suggest-recommend-btn').style.display = 'inline-block'; // Show suggest recommendation button | |
| } else { | |
| document.querySelector('.suggest-recommend-btn').style.display = 'none'; // Hide suggest recommendation button | |
| } | |
| } | |
| function suggestRecommendation() { | |
| const className = document.getElementById('result').innerText; | |
| showRecommendations(className); | |
| document.querySelector('.suggest-recommend-btn').style.display = 'none'; // Hide suggest recommendation button | |
| } | |
| function showRecommendations(className) { | |
| const recommendationContainer = document.getElementById('recommendationContainer'); | |
| const recommendations = { | |
| "Non-neovascular AMD": "Non-smokers should use AREDS oral supplements, while smokers should use AREDS 2 and quit smoking. Supplements are recommended if the other eye has intermediate or advanced AMD and at least one eye has 20/100 vision or better. Self-monitor using the Amsler test and see an ophthalmologist every 3 months.", | |
| "Active Neovascular AMD": "Intravitreal injection of VEGF blockade agents every four weeks for three consecutive injections, followed by OCT to assess response to treatment.", | |
| "Non-neovascular AMD with Geographic atrophy": "Non-smokers should take AREDS oral supplements, while smokers should take AREDS 2 and stop smoking. Geographic atrophy can be slowed by injecting anti-complement intravitreal injections. Self-monitor using the Amsler grid and see an ophthalmologist every 3 months." | |
| }; | |
| const recommendationText = recommendations[className] || "No recommendation available for this condition."; | |
| recommendationContainer.innerHTML = `<p><b>${recommendationText}</b></p>`; | |
| const buildCaseButton = document.createElement('button'); | |
| buildCaseButton.innerHTML = "Build your case with AI"; | |
| buildCaseButton.classList.add('predict-btn'); | |
| buildCaseButton.onclick = function() { | |
| window.top.location.href = "https://ameenmarashi-mretinaaisas.static.hf.space/AI%20case%20generator.html"; | |
| }; | |
| recommendationContainer.appendChild(buildCaseButton); | |
| } | |
| function clearRecommendations() { | |
| document.getElementById('recommendationContainer').innerHTML = ''; | |
| } | |
| </script> | |
| </body> | |
| </html> | |