Spaces:
Runtime error
Runtime error
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Highly Accurate Dichotomous Image Segmentation</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
max-width: 1000px; | |
margin: 0 auto; | |
padding: 20px; | |
line-height: 1.6; | |
} | |
h1 { | |
color: #333; | |
text-align: center; | |
} | |
.container { | |
display: flex; | |
flex-direction: column; | |
gap: 20px; | |
} | |
.upload-section { | |
border: 2px dashed #ccc; | |
padding: 30px; | |
text-align: center; | |
border-radius: 8px; | |
background: #f9f9f9; | |
} | |
.results { | |
display: grid; | |
grid-template-columns: repeat(3, 1fr); | |
gap: 20px; | |
margin-top: 30px; | |
} | |
.result-box { | |
border: 1px solid #ddd; | |
padding: 15px; | |
border-radius: 5px; | |
text-align: center; | |
} | |
.result-box h3 { | |
margin-top: 0; | |
} | |
.result-img { | |
max-width: 100%; | |
height: auto; | |
max-height: 300px; | |
margin-bottom: 10px; | |
} | |
button { | |
background-color: #4CAF50; | |
color: white; | |
padding: 12px 20px; | |
border: none; | |
border-radius: 4px; | |
cursor: pointer; | |
font-size: 16px; | |
transition: background-color 0.3s; | |
} | |
button:hover { | |
background-color: #45a049; | |
} | |
#loading { | |
display: none; | |
text-align: center; | |
margin: 20px 0; | |
font-size: 18px; | |
} | |
.error { | |
color: #d32f2f; | |
margin: 10px 0; | |
text-align: center; | |
} | |
.download-btn { | |
display: inline-block; | |
background: #2196F3; | |
color: white; | |
padding: 8px 15px; | |
text-decoration: none; | |
border-radius: 4px; | |
margin-top: 5px; | |
} | |
.download-btn:hover { | |
background: #0b7dda; | |
} | |
.info { | |
background-color: #f8f9fa; | |
padding: 20px; | |
border-radius: 8px; | |
margin-top: 30px; | |
} | |
.example-images { | |
display: flex; | |
gap: 15px; | |
margin: 20px 0; | |
justify-content: center; | |
} | |
.example-img { | |
width: 150px; | |
height: 150px; | |
object-fit: cover; | |
cursor: pointer; | |
border: 2px solid transparent; | |
border-radius: 4px; | |
} | |
.example-img:hover { | |
border-color: #4CAF50; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Highly Accurate Dichotomous Image Segmentation</h1> | |
<div class="upload-section"> | |
<h2>Upload Image</h2> | |
<input type="file" id="imageInput" accept="image/*" style="display: none;"> | |
<button onclick="document.getElementById('imageInput').click()">Select Image</button> | |
<p id="fileName" style="margin: 10px 0;"></p> | |
<button onclick="processImage()">Remove Background</button> | |
<div id="loading">Processing your image... Please wait...</div> | |
<div id="error" class="error"></div> | |
<div class="example-images"> | |
<img src="/examples/robot.png" class="example-img" onclick="loadExample('robot.png')" alt="Robot Example"> | |
<img src="/examples/ship.png" class="example-img" onclick="loadExample('ship.png')" alt="Ship Example"> | |
</div> | |
</div> | |
<div id="resultsContainer" style="display: none;"> | |
<h2 style="text-align: center;">Results</h2> | |
<div class="results" id="results"> | |
<!-- Results will be inserted here --> | |
</div> | |
</div> | |
<div class="info"> | |
<h3>About this service</h3> | |
<p>This is an implementation of DIS, a model that can remove the background from a given image with high accuracy.</p> | |
<p>GitHub: <a href="https://github.com/xuebinqin/DIS" target="_blank">https://github.com/xuebinqin/DIS</a></p> | |
<p>Telegram bot: <a href="https://t.me/restoration_photo_bot" target="_blank">https://t.me/restoration_photo_bot</a></p> | |
<div style="text-align: center; margin-top: 15px;"> | |
<img src="https://visitor-badge.glitch.me/badge?page_id=dis_image_segmentation" alt="visitor badge"> | |
</div> | |
</div> | |
</div> | |
<script> | |
// Update file name display | |
document.getElementById('imageInput').addEventListener('change', function(e) { | |
const fileName = e.target.files[0] ? e.target.files[0].name : 'No file selected'; | |
document.getElementById('fileName').textContent = `Selected: ${fileName}`; | |
document.getElementById('error').textContent = ''; | |
document.getElementById('resultsContainer').style.display = 'none'; | |
}); | |
// Process image | |
function processImage() { | |
const fileInput = document.getElementById('imageInput'); | |
const file = fileInput.files[0]; | |
const errorDiv = document.getElementById('error'); | |
errorDiv.textContent = ''; | |
if (!file) { | |
errorDiv.textContent = 'Please select an image first'; | |
return; | |
} | |
const loading = document.getElementById('loading'); | |
const resultsContainer = document.getElementById('resultsContainer'); | |
loading.style.display = 'block'; | |
resultsContainer.style.display = 'none'; | |
const formData = new FormData(); | |
formData.append('image', file); | |
fetch('/api/process', { | |
method: 'POST', | |
body: formData | |
}) | |
.then(response => { | |
if (!response.ok) { | |
return response.json().then(err => { throw err; }); | |
} | |
return response.json(); | |
}) | |
.then(data => { | |
loading.style.display = 'none'; | |
if (data.error) { | |
errorDiv.textContent = 'Error: ' + data.error; | |
return; | |
} | |
const resultsDiv = document.getElementById('results'); | |
resultsDiv.innerHTML = ` | |
<div class="result-box"> | |
<h3>Original Image</h3> | |
<img src="${data.original}" class="result-img" alt="Original Image"> | |
<a href="${data.original}" class="download-btn" download="${data.filename}">Download</a> | |
</div> | |
<div class="result-box"> | |
<h3>Background Removed</h3> | |
<img src="${data.rgba}" class="result-img" alt="Background Removed"> | |
<a href="${data.rgba}" class="download-btn" download="no_bg_${data.filename}">Download</a> | |
</div> | |
<div class="result-box"> | |
<h3>Segmentation Mask</h3> | |
<img src="${data.mask}" class="result-img" alt="Segmentation Mask"> | |
<a href="${data.mask}" class="download-btn" download="mask_${data.filename}">Download</a> | |
</div> | |
`; | |
resultsContainer.style.display = 'block'; | |
}) | |
.catch(error => { | |
loading.style.display = 'none'; | |
console.error('Error:', error); | |
errorDiv.textContent = error.error || 'An error occurred while processing the image'; | |
}); | |
} | |
// Load example image | |
function loadExample(filename) { | |
fetch(`/examples/${filename}`) | |
.then(response => response.blob()) | |
.then(blob => { | |
const file = new File([blob], filename, { type: blob.type }); | |
const dataTransfer = new DataTransfer(); | |
dataTransfer.items.add(file); | |
document.getElementById('imageInput').files = dataTransfer.files; | |
// Trigger file name display | |
const event = new Event('change'); | |
document.getElementById('imageInput').dispatchEvent(event); | |
// Process the example immediately | |
processImage(); | |
}) | |
.catch(error => { | |
console.error('Error loading example:', error); | |
document.getElementById('error').textContent = 'Failed to load example image'; | |
}); | |
} | |
</script> | |
</body> | |
</html> |