hamada056 commited on
Commit
3a06621
·
verified ·
1 Parent(s): a1449bf

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -0
app.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import json
4
+ from io import BytesIO
5
+ from PIL import Image, ImageDraw, ImageFont, ImageColor
6
+ import google.generativeai as genai
7
+ from dotenv import load_dotenv
8
+
9
+ # =========================
10
+ # 1. SETUP API KEY
11
+ # =========================
12
+ load_dotenv()
13
+ api_key = os.getenv("Gemini_API_Key")
14
+ genai.configure(api_key=api_key)
15
+
16
+ # =========================
17
+ # 2. MODEL CONFIG
18
+ # =========================
19
+ bounding_box_system_instructions = """
20
+ Return bounding boxes as a JSON array with labels.
21
+ Never return masks or code fencing.
22
+ Limit to 25 objects.
23
+ If an object appears multiple times, use unique labels.
24
+ """
25
+
26
+ model = genai.GenerativeModel(
27
+ model_name="gemini-2.5-flash",
28
+ system_instruction=bounding_box_system_instructions
29
+ )
30
+
31
+ generation_config = genai.types.GenerationConfig(
32
+ temperature=0.5
33
+ )
34
+
35
+ # =========================
36
+ # 3. HELPERS
37
+ # =========================
38
+ def parse_json(json_output):
39
+ lines = json_output.splitlines()
40
+ for i, line in enumerate(lines):
41
+ if "```" in line:
42
+ json_output = "\n".join(lines[i + 1:])
43
+ json_output = json_output.split("```")[0]
44
+ break
45
+ return json_output
46
+
47
+
48
+ def plot_bounding_boxes(im, bounding_boxes):
49
+ im = im.copy()
50
+ width, height = im.size
51
+ draw = ImageDraw.Draw(im)
52
+
53
+ colors = list(ImageColor.colormap.keys())
54
+ font = ImageFont.load_default()
55
+
56
+ boxes = json.loads(bounding_boxes)
57
+
58
+ for i, box in enumerate(boxes):
59
+ color = colors[i % len(colors)]
60
+ y1, x1, y2, x2 = box["box_2d"]
61
+
62
+ # Convert from 0–1000 scale to image pixels
63
+ x1 = int(x1 / 1000 * width)
64
+ x2 = int(x2 / 1000 * width)
65
+ y1 = int(y1 / 1000 * height)
66
+ y2 = int(y2 / 1000 * height)
67
+
68
+ draw.rectangle([(x1, y1), (x2, y2)], outline=color, width=4)
69
+ draw.text((x1 + 6, y1 + 6), box["label"], fill=color, font=font)
70
+
71
+ return im
72
+
73
+
74
+ # =========================
75
+ # 4. MAIN FUNCTION (GRADIO)
76
+ # =========================
77
+ def detect_objects(user_prompt, image):
78
+ if image is None:
79
+ return None
80
+
81
+ prompt = user_prompt.strip()
82
+ if prompt == "":
83
+ prompt = "Identify and label the objects in the image."
84
+
85
+ response = model.generate_content(
86
+ [prompt, image],
87
+ generation_config=generation_config
88
+ )
89
+
90
+ bounding_boxes = parse_json(response.text)
91
+ image_with_boxes = plot_bounding_boxes(image, bounding_boxes)
92
+
93
+ return image_with_boxes
94
+
95
+
96
+ # =========================
97
+ # 5. GRADIO UI
98
+ # =========================
99
+ with gr.Blocks(title="Gemini Bounding Box Detector") as demo:
100
+ gr.Markdown("## Gemini Vision – Object Detection (Bounding Boxes Only)")
101
+
102
+ with gr.Row():
103
+ with gr.Column():
104
+ image_input = gr.Image(type="pil", label="Upload Image")
105
+ prompt_input = gr.Textbox(
106
+ label="Prompt",
107
+ placeholder="e.g. Detect cookies and plates"
108
+ )
109
+ submit_btn = gr.Button("Detect Objects ")
110
+
111
+ with gr.Column():
112
+ image_output = gr.Image(label="Image with Bounding Boxes")
113
+
114
+ submit_btn.click(
115
+ fn=detect_objects,
116
+ inputs=[prompt_input, image_input],
117
+ outputs=image_output
118
+ )
119
+
120
+ demo.launch()