Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import base64 | |
| import numpy as np | |
| from flask import Flask, request, jsonify, render_template | |
| from langchain_experimental.open_clip.open_clip import OpenCLIPEmbeddings | |
| from sklearn.metrics.pairwise import cosine_similarity | |
| from io import BytesIO | |
| from PIL import Image | |
| # from matplotlib.offsetbox import OffsetImage, AnnotationBbox | |
| from io import BytesIO | |
| from pathlib import Path | |
| # ============================== # | |
| # INITIALIZE APP # | |
| # ============================== # | |
| app = Flask(__name__) | |
| clip_embd = OpenCLIPEmbeddings() | |
| BASE_DIR = Path("/app") | |
| BLOCKS_DIR = BASE_DIR / "blocks" | |
| # STATIC_DIR = BASE_DIR / "static" | |
| # GEN_PROJECT_DIR = BASE_DIR / "generated_projects" | |
| BACKDROP_DIR = BLOCKS_DIR / "Backdrops" | |
| SPRITE_DIR = BLOCKS_DIR / "sprites" | |
| CODE_BLOCKS_DIR = BLOCKS_DIR / "code_blocks" | |
| # === new: outputs rooted under BASE_DIR === | |
| OUTPUT_DIR = BASE_DIR / "outputs" | |
| # ============================== # | |
| # LOAD PRE-COMPUTED EMBEDS # | |
| # ============================== # | |
| with open(f"{BLOCKS_DIR}/embeddings.json", "r") as f: | |
| embedding_json = json.load(f) | |
| image_paths = [item["file-path"] for item in embedding_json] | |
| image_embeds = np.array([item["embeddings"] for item in embedding_json]) | |
| # ============================== # | |
| # HELPER: Decode Base64 Image # | |
| # ============================== # | |
| def decode_base64_image(b64_string): | |
| img_data = base64.b64decode(b64_string) | |
| img = Image.open(BytesIO(img_data)).convert("RGB") | |
| return img | |
| # ============================== # | |
| # API ROUTE # | |
| # ============================== # | |
| def match_image(): | |
| data = request.get_json() | |
| if "images" not in data: | |
| return jsonify({"error": "No images provided"}), 400 | |
| results = [] | |
| for b64_img in data["images"]: | |
| try: | |
| # Convert Base64 → BytesIO | |
| b_io = BytesIO(base64.b64decode(b64_img)) | |
| # Embed the query image | |
| query_embed = np.array(clip_embd.embed_image([b_io])) | |
| # Cosine similarity with stored embeddings | |
| sims = cosine_similarity(query_embed, image_embeds)[0] | |
| best_idx = np.argmax(sims) | |
| results.append({ | |
| "input": b64_img[:50] + "...", | |
| "best_match": { | |
| "name": os.path.basename(image_paths[best_idx]), | |
| "path": image_paths[best_idx], | |
| "similarity": float(sims[best_idx]) | |
| } | |
| }) | |
| except Exception as e: | |
| results.append({"error": str(e)}) | |
| return jsonify(results) | |
| # ============================== # | |
| # SIMPLE HTML UI # | |
| # ============================== # | |
| def index(): | |
| return render_template("index.html") | |
| # ============================== # | |
| # MAIN ENTRY # | |
| # ============================== # | |
| if __name__ == "__main__": | |
| app.run(debug=True, port=7860) |