Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from transformers import AutoImageProcessor, AutoModel | |
| import torch | |
| from PIL import Image | |
| import os | |
| import json | |
| import uuid | |
| import numpy as np | |
| # Загрузка модели DINOv2 | |
| processor = AutoImageProcessor.from_pretrained("facebook/dino-vits16") | |
| model = AutoModel.from_pretrained("facebook/dino-vits16") | |
| # Функция для извлечения эмбеддинга | |
| def extract_features(img): | |
| inputs = processor(images=img, return_tensors="pt") | |
| with torch.no_grad(): | |
| outputs = model(**inputs) | |
| return outputs.last_hidden_state[:, 0].squeeze().numpy() | |
| # Косинусное расстояние между двумя эмбеддингами | |
| def cosine_similarity(vec1, vec2): | |
| a = np.array(vec1) | |
| b = np.array(vec2) | |
| return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) | |
| # Путь к базе | |
| db_path = "embeddings2.json" | |
| # Сохранение фото в базу | |
| def save_embedding(image, building_name): | |
| if not building_name: | |
| return "Ошибка: нужно указать название здания." | |
| embedding = extract_features(image).tolist() | |
| entry = { | |
| "id": str(uuid.uuid4()), | |
| "building_name": building_name, | |
| "embedding": embedding | |
| } | |
| if os.path.exists(db_path): | |
| with open(db_path, "r") as f: | |
| data = json.load(f) | |
| else: | |
| data = [] | |
| data.append(entry) | |
| with open(db_path, "w") as f: | |
| json.dump(data, f, indent=2) | |
| return f"Фото сохранено для здания: {building_name}" | |
| # Поиск похожего здания | |
| def identify_building(image): | |
| if not os.path.exists(db_path): | |
| return "База данных пуста. Добавьте здания." | |
| with open(db_path, "r") as f: | |
| data = json.load(f) | |
| if not data: | |
| return "База данных пуста." | |
| embedding = extract_features(image).tolist() | |
| similarities = [] | |
| for item in data: | |
| score = cosine_similarity(item["embedding"], embedding) | |
| similarities.append({ | |
| "building_name": item["building_name"], | |
| "score": score | |
| }) | |
| similarities.sort(key=lambda x: x["score"], reverse=True) | |
| best = similarities[0] | |
| return f"Похоже на: {best['building_name']}\nСовпадение: {best['score']:.4f}" | |
| # Интерфейс | |
| with gr.Blocks() as demo: | |
| gr.Markdown("## 🏛 Распознавание зданий и пополнение базы") | |
| with gr.Tab("🔍 Найти здание"): | |
| with gr.Row(): | |
| img_input = gr.Image(type="pil") | |
| recognize_button = gr.Button("Распознать здание") | |
| result_text = gr.Textbox() | |
| recognize_button.click(fn=identify_building, inputs=img_input, outputs=result_text) | |
| with gr.Tab("➕ Добавить новое здание"): | |
| with gr.Row(): | |
| img_save = gr.Image(type="pil") | |
| building_name = gr.Textbox(label="Название здания") | |
| save_button = gr.Button("Сохранить в базу") | |
| save_result = gr.Textbox() | |
| save_button.click(fn=save_embedding, inputs=[img_save, building_name], outputs=save_result) | |
| demo.launch() |