Boobs00's picture
Add 3 files
35c189d verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Describe Anything Model</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.gradient-bg {
background: linear-gradient(135deg, #6b73ff 0%, #000dff 100%);
}
.card-hover:hover {
transform: translateY(-5px);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.fade-in {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.textarea-auto {
min-height: 120px;
resize: none;
}
.loading-dots:after {
content: '.';
animation: dots 1.5s steps(5, end) infinite;
}
@keyframes dots {
0%, 20% { content: '.'; }
40% { content: '..'; }
60% { content: '...'; }
80%, 100% { content: ''; }
}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<!-- Header -->
<header class="gradient-bg text-white shadow-lg">
<div class="container mx-auto px-4 py-6">
<div class="flex justify-between items-center">
<div class="flex items-center space-x-3">
<i class="fas fa-robot text-3xl"></i>
<h1 class="text-2xl font-bold">Describe Anything Model</h1>
</div>
<div class="hidden md:flex space-x-4">
<a href="#embedding" class="hover:text-blue-200 transition">Embedding</a>
<a href="#description" class="hover:text-blue-200 transition">Description</a>
<a href="#about" class="hover:text-blue-200 transition">About</a>
</div>
<button class="md:hidden text-xl" id="menu-toggle">
<i class="fas fa-bars"></i>
</button>
</div>
</div>
</header>
<!-- Mobile Menu -->
<div class="hidden bg-white shadow-md" id="mobile-menu">
<div class="container mx-auto px-4 py-2 flex flex-col space-y-2">
<a href="#embedding" class="py-2 hover:text-blue-600 transition">Embedding</a>
<a href="#description" class="py-2 hover:text-blue-600 transition">Description</a>
<a href="#about" class="py-2 hover:text-blue-600 transition">About</a>
</div>
</div>
<!-- Hero Section -->
<section class="gradient-bg text-white py-12">
<div class="container mx-auto px-4 text-center">
<h2 class="text-4xl font-bold mb-4">AI-Powered Image Understanding</h2>
<p class="text-xl mb-8 max-w-2xl mx-auto">Generate detailed descriptions of any object in your images with our advanced computer vision model.</p>
<div class="flex justify-center space-x-4">
<a href="#embedding" class="bg-white text-blue-600 px-6 py-3 rounded-lg font-medium hover:bg-blue-50 transition">Try Embedding</a>
<a href="#description" class="border-2 border-white px-6 py-3 rounded-lg font-medium hover:bg-white hover:bg-opacity-10 transition">Try Description</a>
</div>
</div>
</section>
<!-- Main Content -->
<main class="container mx-auto px-4 py-12">
<!-- Embedding Section -->
<section id="embedding" class="mb-16 fade-in">
<div class="flex items-center mb-8">
<div class="h-1 bg-blue-500 w-12 mr-4"></div>
<h2 class="text-3xl font-bold">Image Embedding Generator</h2>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div class="bg-white rounded-xl shadow-md p-6 card-hover transition">
<h3 class="text-xl font-semibold mb-4">Upload Your Image</h3>
<div class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center mb-4" id="drop-area">
<i class="fas fa-cloud-upload-alt text-4xl text-blue-500 mb-3"></i>
<p class="mb-2">Drag & drop your image here</p>
<p class="text-sm text-gray-500 mb-4">or</p>
<input type="file" id="embedding-file" accept="image/*" class="hidden">
<label for="embedding-file" class="bg-blue-500 text-white px-4 py-2 rounded-lg cursor-pointer hover:bg-blue-600 transition">Select Image</label>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-500" id="embedding-file-name">No file selected</span>
<button id="clear-embedding" class="text-red-500 text-sm hover:text-red-700 hidden">Clear</button>
</div>
</div>
<div class="bg-white rounded-xl shadow-md p-6 card-hover transition">
<h3 class="text-xl font-semibold mb-4">Generated Embedding</h3>
<div class="relative">
<textarea id="embedding-result" class="w-full bg-gray-100 border border-gray-300 rounded-lg p-4 textarea-auto" placeholder="Your image embedding will appear here..." readonly></textarea>
<button id="copy-embedding" class="absolute top-2 right-2 bg-gray-200 hover:bg-gray-300 p-2 rounded-lg transition" title="Copy to clipboard">
<i class="fas fa-copy"></i>
</button>
</div>
<button id="generate-embedding" class="mt-4 w-full bg-blue-500 text-white py-3 rounded-lg font-medium hover:bg-blue-600 transition flex items-center justify-center">
<span id="embedding-button-text">Generate Embedding</span>
<span id="embedding-loading" class="hidden ml-2 loading-dots"></span>
</button>
</div>
</div>
</section>
<!-- Description Section -->
<section id="description" class="mb-16 fade-in">
<div class="flex items-center mb-8">
<div class="h-1 bg-blue-500 w-12 mr-4"></div>
<h2 class="text-3xl font-bold">Mask Description Generator</h2>
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<div class="bg-white rounded-xl shadow-md p-6 card-hover transition">
<h3 class="text-xl font-semibold mb-4">Upload Your Image</h3>
<div class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center mb-4" id="image-drop-area">
<i class="fas fa-image text-4xl text-blue-500 mb-3"></i>
<p class="mb-2">Drag & drop your image here</p>
<p class="text-sm text-gray-500 mb-4">or</p>
<input type="file" id="image-file" accept="image/*" class="hidden">
<label for="image-file" class="bg-blue-500 text-white px-4 py-2 rounded-lg cursor-pointer hover:bg-blue-600 transition">Select Image</label>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-500" id="image-file-name">No file selected</span>
<button id="clear-image" class="text-red-500 text-sm hover:text-red-700 hidden">Clear</button>
</div>
</div>
<div class="bg-white rounded-xl shadow-md p-6 card-hover transition">
<h3 class="text-xl font-semibold mb-4">Upload Your Mask</h3>
<div class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center mb-4" id="mask-drop-area">
<i class="fas fa-mask text-4xl text-blue-500 mb-3"></i>
<p class="mb-2">Drag & drop your mask here</p>
<p class="text-sm text-gray-500 mb-4">or</p>
<input type="file" id="mask-file" accept="image/*" class="hidden">
<label for="mask-file" class="bg-blue-500 text-white px-4 py-2 rounded-lg cursor-pointer hover:bg-blue-600 transition">Select Mask</label>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-500" id="mask-file-name">No file selected</span>
<button id="clear-mask" class="text-red-500 text-sm hover:text-red-700 hidden">Clear</button>
</div>
</div>
<div class="bg-white rounded-xl shadow-md p-6 card-hover transition">
<h3 class="text-xl font-semibold mb-4">Generate Description</h3>
<div class="mb-4">
<label for="description-prompt" class="block text-sm font-medium text-gray-700 mb-1">Prompt (Optional)</label>
<input type="text" id="description-prompt" class="w-full border border-gray-300 rounded-lg p-3" placeholder="What would you like to know about this object?">
</div>
<div class="relative mb-4">
<label for="description-result" class="block text-sm font-medium text-gray-700 mb-1">Description</label>
<textarea id="description-result" class="w-full bg-gray-100 border border-gray-300 rounded-lg p-4 textarea-auto" placeholder="Your description will appear here..." readonly></textarea>
<button id="copy-description" class="absolute top-7 right-2 bg-gray-200 hover:bg-gray-300 p-2 rounded-lg transition" title="Copy to clipboard">
<i class="fas fa-copy"></i>
</button>
</div>
<div class="flex space-x-3">
<button id="generate-description" class="flex-1 bg-blue-500 text-white py-3 rounded-lg font-medium hover:bg-blue-600 transition flex items-center justify-center">
<span id="description-button-text">Generate</span>
<span id="description-loading" class="hidden ml-2 loading-dots"></span>
</button>
<button id="generate-streaming" class="flex-1 bg-purple-500 text-white py-3 rounded-lg font-medium hover:bg-purple-600 transition flex items-center justify-center">
<span id="streaming-button-text">Stream</span>
<span id="streaming-loading" class="hidden ml-2 loading-dots"></span>
</button>
</div>
</div>
</div>
</section>
<!-- Preview Section -->
<section id="preview" class="mb-16 fade-in">
<div class="flex items-center mb-8">
<div class="h-1 bg-blue-500 w-12 mr-4"></div>
<h2 class="text-3xl font-bold">Image & Mask Preview</h2>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div class="bg-white rounded-xl shadow-md p-6">
<h3 class="text-xl font-semibold mb-4">Image Preview</h3>
<div class="border border-gray-200 rounded-lg overflow-hidden">
<img id="image-preview" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300' viewBox='0 0 400 300' fill='%23f3f4f6'%3E%3Crect width='400' height='300'/%3E%3Ctext x='50%' y='50%' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='16' fill='%239ca3af'%3ENo image selected%3C/text%3E%3C/svg%3E" alt="Image preview" class="w-full h-auto">
</div>
</div>
<div class="bg-white rounded-xl shadow-md p-6">
<h3 class="text-xl font-semibold mb-4">Mask Preview</h3>
<div class="border border-gray-200 rounded-lg overflow-hidden">
<img id="mask-preview" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300' viewBox='0 0 400 300' fill='%23f3f4f6'%3E%3Crect width='400' height='300'/%3E%3Ctext x='50%' y='50%' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='16' fill='%239ca3af'%3ENo mask selected%3C/text%3E%3C/svg%3E" alt="Mask preview" class="w-full h-auto">
</div>
</div>
</div>
</section>
<!-- About Section -->
<section id="about" class="fade-in">
<div class="flex items-center mb-8">
<div class="h-1 bg-blue-500 w-12 mr-4"></div>
<h2 class="text-3xl font-bold">About Describe Anything Model</h2>
</div>
<div class="bg-white rounded-xl shadow-md p-8">
<div class="prose max-w-none">
<h3 class="text-2xl font-semibold mb-4">Advanced Image Understanding</h3>
<p class="mb-4">The Describe Anything Model (DAM) is a cutting-edge AI system that combines computer vision with natural language processing to provide detailed descriptions of objects in images.</p>
<h4 class="text-xl font-semibold mt-6 mb-3">Key Features</h4>
<ul class="list-disc pl-6 mb-6 space-y-2">
<li>Generate rich semantic embeddings for any image</li>
<li>Describe specific objects using segmentation masks</li>
<li>Answer questions about objects in images</li>
<li>Streaming output for real-time results</li>
</ul>
<h4 class="text-xl font-semibold mt-6 mb-3">How It Works</h4>
<ol class="list-decimal pl-6 mb-6 space-y-2">
<li>Upload an image to generate its embedding</li>
<li>Optionally upload a mask to focus on specific objects</li>
<li>Provide a prompt to guide the description</li>
<li>Get detailed, AI-generated descriptions</li>
</ol>
<div class="bg-blue-50 border-l-4 border-blue-500 p-4 mt-6">
<p class="text-blue-700"><strong>Note:</strong> This is a demonstration interface. For production use, consider implementing proper API endpoints and error handling.</p>
</div>
</div>
</div>
</section>
</main>
<!-- Footer -->
<footer class="bg-gray-800 text-white py-8">
<div class="container mx-auto px-4">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="mb-4 md:mb-0">
<h3 class="text-xl font-bold mb-2">Describe Anything Model</h3>
<p class="text-gray-400">Advanced AI for image understanding</p>
</div>
<div class="flex space-x-6">
<a href="#" class="text-gray-400 hover:text-white transition"><i class="fab fa-github text-xl"></i></a>
<a href="#" class="text-gray-400 hover:text-white transition"><i class="fab fa-twitter text-xl"></i></a>
<a href="#" class="text-gray-400 hover:text-white transition"><i class="fab fa-linkedin text-xl"></i></a>
</div>
</div>
<div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400">
<p>&copy; 2023 Describe Anything Model. All rights reserved.</p>
</div>
</div>
</footer>
<script>
// Mobile menu toggle
document.getElementById('menu-toggle').addEventListener('click', function() {
const menu = document.getElementById('mobile-menu');
menu.classList.toggle('hidden');
});
// File handling for embedding
const embeddingFileInput = document.getElementById('embedding-file');
const embeddingDropArea = document.getElementById('drop-area');
const embeddingFileName = document.getElementById('embedding-file-name');
const clearEmbeddingBtn = document.getElementById('clear-embedding');
const generateEmbeddingBtn = document.getElementById('generate-embedding');
const embeddingResult = document.getElementById('embedding-result');
const copyEmbeddingBtn = document.getElementById('copy-embedding');
const embeddingButtonText = document.getElementById('embedding-button-text');
const embeddingLoading = document.getElementById('embedding-loading');
// File handling for description
const imageFileInput = document.getElementById('image-file');
const imageDropArea = document.getElementById('image-drop-area');
const imageFileName = document.getElementById('image-file-name');
const clearImageBtn = document.getElementById('clear-image');
const maskFileInput = document.getElementById('mask-file');
const maskDropArea = document.getElementById('mask-drop-area');
const maskFileName = document.getElementById('mask-file-name');
const clearMaskBtn = document.getElementById('clear-mask');
const generateDescriptionBtn = document.getElementById('generate-description');
const generateStreamingBtn = document.getElementById('generate-streaming');
const descriptionResult = document.getElementById('description-result');
const copyDescriptionBtn = document.getElementById('copy-description');
const descriptionPrompt = document.getElementById('description-prompt');
const descriptionButtonText = document.getElementById('description-button-text');
const descriptionLoading = document.getElementById('description-loading');
const streamingButtonText = document.getElementById('streaming-button-text');
const streamingLoading = document.getElementById('streaming-loading');
const imagePreview = document.getElementById('image-preview');
const maskPreview = document.getElementById('mask-preview');
// Prevent default drag behaviors
[embeddingDropArea, imageDropArea, maskDropArea].forEach(area => {
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
area.addEventListener(eventName, preventDefaults, false);
});
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
// Highlight drop area when item is dragged over it
[embeddingDropArea, imageDropArea, maskDropArea].forEach(area => {
['dragenter', 'dragover'].forEach(eventName => {
area.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
area.addEventListener(eventName, unhighlight, false);
});
});
function highlight() {
this.classList.add('border-blue-500', 'bg-blue-50');
}
function unhighlight() {
this.classList.remove('border-blue-500', 'bg-blue-50');
}
// Handle dropped files
embeddingDropArea.addEventListener('drop', handleEmbeddingDrop, false);
imageDropArea.addEventListener('drop', handleImageDrop, false);
maskDropArea.addEventListener('drop', handleMaskDrop, false);
function handleEmbeddingDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length) {
handleEmbeddingFile(files[0]);
}
}
function handleImageDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length) {
handleImageFile(files[0]);
}
}
function handleMaskDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length) {
handleMaskFile(files[0]);
}
}
// Handle selected files
embeddingFileInput.addEventListener('change', function() {
if (this.files.length) {
handleEmbeddingFile(this.files[0]);
}
});
imageFileInput.addEventListener('change', function() {
if (this.files.length) {
handleImageFile(this.files[0]);
}
});
maskFileInput.addEventListener('change', function() {
if (this.files.length) {
handleMaskFile(this.files[0]);
}
});
function handleEmbeddingFile(file) {
if (!file.type.match('image.*')) {
alert('Please select an image file.');
return;
}
embeddingFileName.textContent = file.name;
clearEmbeddingBtn.classList.remove('hidden');
// Preview would be similar to image preview, but we're not showing it here
}
function handleImageFile(file) {
if (!file.type.match('image.*')) {
alert('Please select an image file.');
return;
}
imageFileName.textContent = file.name;
clearImageBtn.classList.remove('hidden');
// Preview the image
const reader = new FileReader();
reader.onload = function(e) {
imagePreview.src = e.target.result;
};
reader.readAsDataURL(file);
}
function handleMaskFile(file) {
if (!file.type.match('image.*')) {
alert('Please select an image file.');
return;
}
maskFileName.textContent = file.name;
clearMaskBtn.classList.remove('hidden');
// Preview the mask
const reader = new FileReader();
reader.onload = function(e) {
maskPreview.src = e.target.result;
};
reader.readAsDataURL(file);
}
// Clear buttons
clearEmbeddingBtn.addEventListener('click', function() {
embeddingFileInput.value = '';
embeddingFileName.textContent = 'No file selected';
this.classList.add('hidden');
embeddingResult.value = '';
});
clearImageBtn.addEventListener('click', function() {
imageFileInput.value = '';
imageFileName.textContent = 'No file selected';
this.classList.add('hidden');
imagePreview.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300' viewBox='0 0 400 300' fill='%23f3f4f6'%3E%3Crect width='400' height='300'/%3E%3Ctext x='50%' y='50%' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='16' fill='%239ca3af'%3ENo image selected%3C/text%3E%3C/svg%3E";
});
clearMaskBtn.addEventListener('click', function() {
maskFileInput.value = '';
maskFileName.textContent = 'No file selected';
this.classList.add('hidden');
maskPreview.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300' viewBox='0 0 400 300' fill='%23f3f4f6'%3E%3Crect width='400' height='300'/%3E%3Ctext x='50%' y='50%' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='16' fill='%239ca3af'%3ENo mask selected%3C/text%3E%3C/svg%3E";
});
// Copy buttons
copyEmbeddingBtn.addEventListener('click', function() {
embeddingResult.select();
document.execCommand('copy');
// Show copied feedback
const originalText = this.innerHTML;
this.innerHTML = '<i class="fas fa-check"></i>';
setTimeout(() => {
this.innerHTML = originalText;
}, 2000);
});
copyDescriptionBtn.addEventListener('click', function() {
descriptionResult.select();
document.execCommand('copy');
// Show copied feedback
const originalText = this.innerHTML;
this.innerHTML = '<i class="fas fa-check"></i>';
setTimeout(() => {
this.innerHTML = originalText;
}, 2000);
});
// Generate buttons - these would call your actual API endpoints
generateEmbeddingBtn.addEventListener('click', function() {
if (!embeddingFileInput.files.length) {
alert('Please select an image file first.');
return;
}
// Simulate API call
embeddingButtonText.textContent = 'Processing';
embeddingLoading.classList.remove('hidden');
setTimeout(() => {
// This is where you would call your image_to_sam_embedding API
// For demo purposes, we're just showing a placeholder
embeddingResult.value = "This would be the base64 encoded embedding from the API response.";
embeddingButtonText.textContent = 'Generate Embedding';
embeddingLoading.classList.add('hidden');
}, 2000);
});
generateDescriptionBtn.addEventListener('click', function() {
if (!imageFileInput.files.length || !maskFileInput.files.length) {
alert('Please select both an image and a mask file first.');
return;
}
// Simulate API call
descriptionButtonText.textContent = 'Processing';
descriptionLoading.classList.remove('hidden');
descriptionResult.value = '';
setTimeout(() => {
// This is where you would call your describe_without_streaming API
// For demo purposes, we're just showing a placeholder
const prompt = descriptionPrompt.value || "Describe the object in the mask";
descriptionResult.value = `This is a detailed description of the object in the mask based on the prompt: "${prompt}".\n\nThe description would include specific details about the object's appearance, context, and any other relevant information the model can provide.`;
descriptionButtonText.textContent = 'Generate';
descriptionLoading.classList.add('hidden');
}, 3000);
});
generateStreamingBtn.addEventListener('click', function() {
if (!imageFileInput.files.length || !maskFileInput.files.length) {
alert('Please select both an image and a mask file first.');
return;
}
// Simulate streaming API call
streamingButtonText.textContent = 'Streaming';
streamingLoading.classList.remove('hidden');
descriptionResult.value = '';
const prompt = descriptionPrompt.value || "Describe the object in the mask";
const demoTexts = [
"This is the first part of the description... ",
"The object appears to be a person standing in a park. ",
"They are wearing a blue jacket and holding a bag. ",
"The background shows trees and a clear sky. ",
"The lighting suggests it's late afternoon. ",
"This completes the description of the object."
];
let i = 0;
const interval = setInterval(() => {
if (i < demoTexts.length) {
descriptionResult.value += demoTexts[i];
i++;
} else {
clearInterval(interval);
streamingButtonText.textContent = 'Stream';
streamingLoading.classList.add('hidden');
}
}, 500);
});
// Smooth scrolling for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href');
if (targetId === '#') return;
const targetElement = document.querySelector(targetId);
if (targetElement) {
targetElement.scrollIntoView({
behavior: 'smooth'
});
// Close mobile menu if open
const mobileMenu = document.getElementById('mobile-menu');
if (!mobileMenu.classList.contains('hidden')) {
mobileMenu.classList.add('hidden');
}
}
});
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Boobs00/ai-powered-image-understanding" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>