|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
|
|
const radioButtons = document.querySelectorAll('input[name="inputMethod"]'); |
|
|
radioButtons.forEach(radio => { |
|
|
radio.addEventListener('change', toggleInputMethod); |
|
|
}); |
|
|
|
|
|
|
|
|
generateLabelCheckboxes(); |
|
|
}); |
|
|
|
|
|
function toggleInputMethod() { |
|
|
const localInputGroup = document.getElementById('localInputGroup'); |
|
|
const urlInputGroup = document.getElementById('urlInputGroup'); |
|
|
const selectedMethod = document.querySelector('input[name="inputMethod"]:checked').value; |
|
|
|
|
|
if (selectedMethod === 'local') { |
|
|
localInputGroup.style.display = 'block'; |
|
|
urlInputGroup.style.display = 'none'; |
|
|
|
|
|
document.getElementById('urlInput').value = ''; |
|
|
} else { |
|
|
localInputGroup.style.display = 'none'; |
|
|
urlInputGroup.style.display = 'block'; |
|
|
|
|
|
document.getElementById('fileInput').value = ''; |
|
|
} |
|
|
|
|
|
|
|
|
clearPreviewAndResults(); |
|
|
} |
|
|
|
|
|
function clearPreviewAndResults() { |
|
|
const imagePreview = document.getElementById('imagePreview'); |
|
|
const resultsDiv = document.getElementById('results'); |
|
|
|
|
|
imagePreview.src = ''; |
|
|
resultsDiv.innerHTML = ''; |
|
|
} |
|
|
|
|
|
|
|
|
document.getElementById('fileInput').addEventListener('change', previewImage); |
|
|
document.getElementById('urlInput').addEventListener('input', debounce(previewImage, 500)); |
|
|
|
|
|
function debounce(func, wait) { |
|
|
let timeout; |
|
|
return function executedFunction(...args) { |
|
|
const later = () => { |
|
|
clearTimeout(timeout); |
|
|
func(...args); |
|
|
}; |
|
|
clearTimeout(timeout); |
|
|
timeout = setTimeout(later, wait); |
|
|
}; |
|
|
} |
|
|
|
|
|
function previewImage() { |
|
|
const fileInput = document.getElementById('fileInput'); |
|
|
const urlInput = document.getElementById('urlInput'); |
|
|
const imagePreview = document.getElementById('imagePreview'); |
|
|
|
|
|
if (fileInput.files && fileInput.files[0]) { |
|
|
const reader = new FileReader(); |
|
|
reader.onload = function(e) { |
|
|
imagePreview.src = e.target.result; |
|
|
}; |
|
|
reader.readAsDataURL(fileInput.files[0]); |
|
|
urlInput.value = ''; |
|
|
} else if (urlInput.value) { |
|
|
imagePreview.src = urlInput.value; |
|
|
fileInput.value = ''; |
|
|
} |
|
|
} |
|
|
|
|
|
async function getBase64FromUrl(url) { |
|
|
const response = await fetch(url); |
|
|
const blob = await response.blob(); |
|
|
return new Promise((resolve, reject) => { |
|
|
const reader = new FileReader(); |
|
|
reader.onload = () => { |
|
|
const base64String = reader.result.split(',')[1]; |
|
|
resolve(base64String); |
|
|
}; |
|
|
reader.onerror = reject; |
|
|
reader.readAsDataURL(blob); |
|
|
}); |
|
|
} |
|
|
|
|
|
async function analyzeImage() { |
|
|
|
|
|
document.getElementById('results').innerHTML = ''; |
|
|
|
|
|
const spinner = document.getElementById('spinner'); |
|
|
const analyzeBtn = document.getElementById('analyzeBtn'); |
|
|
const resultsDiv = document.getElementById('results'); |
|
|
|
|
|
spinner.style.display = 'block'; |
|
|
analyzeBtn.disabled = true; |
|
|
analyzeBtn.textContent = 'Analyzing...'; |
|
|
|
|
|
const fileInput = document.getElementById('fileInput'); |
|
|
const urlInput = document.getElementById('urlInput'); |
|
|
let base64Image; |
|
|
|
|
|
try { |
|
|
|
|
|
const selectedLabels = Array.from(document.querySelectorAll('.label-option input[type="checkbox"]:checked')) |
|
|
.map(checkbox => checkbox.value); |
|
|
|
|
|
if (selectedLabels.length === 0) { |
|
|
throw new Error('Please select at least one category'); |
|
|
} |
|
|
|
|
|
if (fileInput.files && fileInput.files[0]) { |
|
|
|
|
|
const reader = new FileReader(); |
|
|
base64Image = await new Promise((resolve) => { |
|
|
reader.onload = (e) => { |
|
|
resolve(e.target.result.split(',')[1]); |
|
|
}; |
|
|
reader.readAsDataURL(fileInput.files[0]); |
|
|
}); |
|
|
} else if (urlInput.value) { |
|
|
|
|
|
base64Image = await getBase64FromUrl(urlInput.value); |
|
|
} else { |
|
|
throw new Error('Please select a file or enter a URL.'); |
|
|
} |
|
|
|
|
|
const payload = { |
|
|
images: [base64Image], |
|
|
labels: selectedLabels, |
|
|
multilabel: false |
|
|
}; |
|
|
|
|
|
const response = await fetch('http://localhost:8000/predict', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json' |
|
|
}, |
|
|
body: JSON.stringify(payload) |
|
|
}); |
|
|
|
|
|
const data = await response.json(); |
|
|
displayResults(data.predictions); |
|
|
} catch (error) { |
|
|
console.error('Error:', error); |
|
|
resultsDiv.innerHTML = `<p class="error-message">Error: ${error.message}</p>`; |
|
|
} finally { |
|
|
spinner.style.display = 'none'; |
|
|
analyzeBtn.disabled = false; |
|
|
analyzeBtn.textContent = 'Analyze'; |
|
|
} |
|
|
} |
|
|
|
|
|
function displayResults(predictions) { |
|
|
const resultsDiv = document.getElementById('results'); |
|
|
resultsDiv.innerHTML = ''; |
|
|
|
|
|
if (!predictions || predictions.length === 0) { |
|
|
resultsDiv.innerHTML = '<p>No predictions available.</p>'; |
|
|
return; |
|
|
} |
|
|
|
|
|
predictions.forEach(prediction => { |
|
|
resultsDiv.innerHTML += '<h2>Results:</h2>'; |
|
|
for (const [label, probability] of Object.entries(prediction)) { |
|
|
resultsDiv.innerHTML += ` |
|
|
<div class="prediction-result"> |
|
|
<strong>${label}:</strong> |
|
|
<div class="progress-bar"> |
|
|
<div class="progress" style="width: ${probability * 100}%"></div> |
|
|
</div> |
|
|
<span>${(probability * 100).toFixed(2)}%</span> |
|
|
</div>`; |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
const medicalLabels = [ |
|
|
'Tumor', |
|
|
'Normal', |
|
|
'Pneumonia', |
|
|
'Fracture', |
|
|
'Edema', |
|
|
'Effusion', |
|
|
'Urtikaria', |
|
|
'Akne', |
|
|
'Eczema', |
|
|
'Psoriasis' |
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
function generateLabelCheckboxes() { |
|
|
const labelGrid = document.getElementById('labelGrid'); |
|
|
labelGrid.innerHTML = ''; |
|
|
|
|
|
medicalLabels.forEach(label => { |
|
|
const labelElement = document.createElement('label'); |
|
|
labelElement.className = 'label-option'; |
|
|
|
|
|
labelElement.innerHTML = ` |
|
|
<input type="checkbox" value="${label}"> |
|
|
<span>${label}</span> |
|
|
`; |
|
|
|
|
|
labelGrid.appendChild(labelElement); |
|
|
}); |
|
|
} |