| import sys |
| import os |
|
|
| os.environ.setdefault("HF_HUB_DISABLE_XET", "1") |
|
|
| try: |
| import gradio as gr |
| from PIL import Image |
| import re |
| import torch |
| from transformers import pipeline |
| except ModuleNotFoundError as exc: |
| package_map = { |
| "gradio": "gradio", |
| "transformers": "transformers", |
| "PIL": "Pillow", |
| "torch": "torch", |
| } |
| missing = exc.name or "unknown" |
| suggested = package_map.get(missing, missing) |
| print(f"[error] Required dependency '{missing}' is missing.") |
| print("[error] Install requirements first:") |
| print(" python3 -m pip install -r requirements.txt") |
| print(f" python3 -m pip install {suggested}") |
| print("Then rerun: python3 app.py") |
| sys.exit(1) |
|
|
| caption_model_name = "ydshieh/vit-gpt2-coco-en" |
| captioner = None |
| stop_words = { |
| "a", |
| "an", |
| "and", |
| "as", |
| "at", |
| "before", |
| "but", |
| "by", |
| "for", |
| "from", |
| "how", |
| "in", |
| "into", |
| "of", |
| "on", |
| "or", |
| "that", |
| "the", |
| "this", |
| "to", |
| "with", |
| "without", |
| "is", |
| "are", |
| "was", |
| "were", |
| "be", |
| "it", |
| "its", |
| "itself", |
| "they", |
| "their", |
| "there", |
| } |
|
|
| def get_captioner(): |
| global captioner |
|
|
| if captioner is None: |
| print("Loading caption model. This can take a moment...", flush=True) |
| captioner = pipeline( |
| "image-to-text", |
| model=caption_model_name, |
| dtype=torch.float32, |
| device=-1, |
| ) |
| print("Caption model loaded.", flush=True) |
|
|
| return captioner |
|
|
|
|
| def extract_labels_from_caption(caption, max_labels=6): |
| tokens = re.findall(r"[a-zA-Z][a-zA-Z']+", caption.lower()) |
| tokens = [token.strip("'") for token in tokens] |
| cleaned = [token for token in tokens if len(token) > 2 and token not in stop_words] |
| if not cleaned: |
| return {"other": 1.0} |
|
|
| ordered_unique = [] |
| seen = set() |
| for token in cleaned: |
| if token in seen: |
| continue |
| seen.add(token) |
| ordered_unique.append(token) |
|
|
| top_terms = ordered_unique[:max_labels] |
| raw_scores = [1.0 / (idx + 1) for idx in range(len(top_terms))] |
| total = sum(raw_scores) |
| return {term: score / total for term, score in zip(top_terms, raw_scores)} |
|
|
|
|
| def predict_from_image(image): |
| if image is None: |
| return "Please upload an image", {"Error": 1.0} |
|
|
| try: |
| caption = get_captioner()(image)[0]["generated_text"] |
| labels = extract_labels_from_caption(caption) |
| return caption, labels |
| except Exception as exc: |
| error_message = f"{exc.__class__.__name__}: {exc}" |
| print(f"[error] Prediction failed: {error_message}", flush=True) |
| return error_message, {"Error": 1.0} |
|
|
|
|
| |
|
|
| demo = gr.Interface( |
| fn=predict_from_image, |
| inputs=gr.Image(label="Upload Image", type="pil", sources=["upload"]), |
| outputs=[ |
| gr.Textbox(label="Caption", lines=2), |
| gr.Label(label="Generated Labels"), |
| ], |
| title="Image Classifier", |
| flagging_mode="never" |
| ) |
|
|
| |
| print("Starting Gradio app at http://127.0.0.1:7860", flush=True) |
| demo.launch(show_error=True) |
|
|