Spaces:
Runtime error
Runtime error
File size: 5,273 Bytes
22ef1d5 746bf5b 0c4adc5 22ef1d5 746bf5b 7fae8fb 0c4adc5 22ef1d5 0c4adc5 22ef1d5 7fae8fb 22ef1d5 0c4adc5 22ef1d5 0c4adc5 22ef1d5 7fae8fb 22ef1d5 7fae8fb 22ef1d5 746bf5b 22ef1d5 0d5f8a4 22ef1d5 7fae8fb 22ef1d5 7fae8fb 22ef1d5 0c4adc5 22ef1d5 a1501eb 22ef1d5 a06f639 22ef1d5 a06f639 0c4adc5 a06f639 0c4adc5 a06f639 22ef1d5 a06f639 22ef1d5 746bf5b 7fae8fb 22ef1d5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
import gradio as gr
import uuid
import os
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct
from sentence_transformers import SentenceTransformer
from PIL import Image
import numpy as np
# Create uploads folder
UPLOAD_DIR = "uploads"
os.makedirs(UPLOAD_DIR, exist_ok=True)
# Connect to Qdrant
COLLECTION = "lost_and_found"
qclient = QdrantClient(":memory:") # for demo, replace with your Qdrant server for persistence
# Load CLIP model
model = SentenceTransformer("sentence-transformers/clip-ViT-B-32-multilingual-v1")
# Ensure collection exists
qclient.recreate_collection(
collection_name=COLLECTION,
vectors_config={"size": 512, "distance": "Cosine"}
)
# Encode helper
def encode_data(text=None, image=None):
if image is not None:
img = Image.open(image).convert("RGB")
emb = model.encode(img, convert_to_numpy=True, normalize_embeddings=True)
elif text:
emb = model.encode(text, convert_to_numpy=True, normalize_embeddings=True)
else:
raise ValueError("Need text or image")
return emb.astype(np.float32)
# Add item
def add_item(mode, text, image, name, phone):
try:
vector = encode_data(text=text if text else None, image=image if image else None)
payload = {
"mode": mode,
"text": text,
"has_image": image is not None,
}
# Save image file if uploaded
if image is not None:
img = Image.open(image).convert("RGB")
fname = f"{uuid.uuid4().hex}.png"
fpath = os.path.join(UPLOAD_DIR, fname)
img.save(fpath)
payload["image_path"] = fpath
if mode == "found":
payload["finder_name"] = name
payload["finder_phone"] = phone
qclient.upsert(
collection_name=COLLECTION,
points=[PointStruct(id=str(uuid.uuid4()), vector=vector.tolist(), payload=payload)]
)
return "β
Item added successfully!"
except Exception as e:
return f"β Error: {e}"
# Search items
def search_items(query_image, query_text, limit, min_score):
try:
query_vector = encode_data(
text=query_text if query_text else None,
image=query_image if query_image else None
)
results = qclient.search(
collection_name=COLLECTION,
query_vector=query_vector.tolist(),
limit=limit,
)
out_texts, out_imgs = [], []
for r in results:
if r.score < min_score:
continue
pl = r.payload
info = f"id:{r.id} | score:{r.score:.4f} | mode:{pl.get('mode','')}"
if pl.get("text"):
info += f" | text:{pl['text']}"
if pl.get("mode") == "found":
info += f" | found by: {pl.get('finder_name','?')} ({pl.get('finder_phone','?')})"
out_texts.append(info)
if pl.get("image_path"):
out_imgs.append(pl["image_path"])
return "\n".join(out_texts) if out_texts else "No matches.", out_imgs
except Exception as e:
return f"β Error: {e}", []
# Clear all images
def clear_all_images():
try:
# Clear uploads folder
for f in os.listdir(UPLOAD_DIR):
os.remove(os.path.join(UPLOAD_DIR, f))
# Clear Qdrant
qclient.delete(
collection_name=COLLECTION,
points_selector={"filter": {"must": [{"key": "has_image", "match": {"value": True}}]}}
)
return "ποΈ All image items cleared!"
except Exception as e:
return f"β Error clearing images: {e}"
# Gradio UI
with gr.Blocks() as demo:
gr.Markdown("# π Lost & Found System")
with gr.Tab("β Add Item"):
mode = gr.Radio(["lost", "found"], label="Mode")
text = gr.Textbox(label="Describe the item (optional)")
img = gr.Image(type="filepath", label="Upload image (optional)")
name = gr.Textbox(label="Finder's Name (only if found)", placeholder="John Doe")
phone = gr.Textbox(label="Finder's Phone (only if found)", placeholder="+1234567890")
add_btn = gr.Button("Add Item")
add_out = gr.Textbox(label="Add result")
add_btn.click(add_item, inputs=[mode, text, img, name, phone], outputs=add_out)
with gr.Tab("π Search"):
query_text = gr.Textbox(label="Search by text (optional)")
query_img = gr.Image(type="filepath", label="Search by image (optional)")
max_results = gr.Slider(1, 10, value=5, step=1, label="Max results")
score_slider = gr.Slider(0.5, 1.0, value=0.9, step=0.01, label="Min similarity threshold")
search_btn = gr.Button("Search")
search_out = gr.Textbox(label="Search results (text)")
gallery = gr.Gallery(label="Search Results", show_label=True, elem_id="gallery", columns=2, height="auto")
search_btn.click(search_items, inputs=[query_img, query_text, max_results, score_slider], outputs=[search_out, gallery])
with gr.Tab("ποΈ Admin"):
clear_btn = gr.Button("Clear All Images")
clear_out = gr.Textbox(label="Clear Result")
clear_btn.click(clear_all_images, outputs=clear_out)
demo.launch()
|