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() |