vancauwe commited on
Commit
b092e67
·
1 Parent(s): f64836c

feat: bounding boxes on bird body

Browse files
app/assets/images/bird.png ADDED
app/assets/images/bird_boxed.png ADDED
app/boxes_define.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import geopandas as gpd
2
+ from shapely.geometry import box
3
+
4
+ bounding_boxes = [
5
+ # 'Head incl. eyes',
6
+ box(250, 375, 350, 500),
7
+ # 'Beak and mouth region',
8
+ box(200, 450, 250, 500),
9
+ # 'Feathers/Wings',
10
+ box(10, 10, 50, 50),
11
+ # 'Legs',
12
+ box(325, 575, 450, 675),
13
+ # 'Body'
14
+ box(500, 500, 500, 500)
15
+ ]
16
+
17
+ # Create a GeoDataFrame from these boxes
18
+ gdf = gpd.GeoDataFrame({'geometry': bounding_boxes,
19
+ 'name': ['Head incl. eyes',
20
+ 'Beak and mouth region',
21
+ 'Feathers/Wings',
22
+ 'Legs',
23
+ 'Body']})
app/boxes_map.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from PIL import Image, ImageDraw, ImageFont
2
+
3
+ from boxes_define import gdf
4
+
5
+ # Function to draw the bounding boxes on the image
6
+ def draw_bounding_boxes(image_path, gdf):
7
+ image = Image.open(image_path+'bird.png').convert("RGB")
8
+ # Convert the image to an editable format
9
+ draw = ImageDraw.Draw(image)
10
+
11
+ # Optional: Load a font (requires a TTF file)
12
+ try:
13
+ font = ImageFont.truetype("arial.ttf", 15)
14
+ except IOError:
15
+ font = ImageFont.load_default()
16
+
17
+ # Draw each bounding box on the image
18
+ for _, row in gdf.iterrows():
19
+ xmin, ymin, xmax, ymax = row['geometry'].bounds
20
+ draw.rectangle([xmin, ymin, xmax, ymax], outline="red", width=2)
21
+ draw.text((xmin, ymin-10), row['name'], fill="red", font=font)
22
+
23
+ image.save(image_path+'bird_boxed.png', "PNG")
24
+
25
+ if __name__ == "__main__":
26
+ draw_bounding_boxes('assets/images/', gdf)
app/main.py CHANGED
@@ -38,6 +38,71 @@ with gr.Blocks(theme=theme, css=css) as demo:
38
  #to submit it
39
  submit_location = gr.Button("Get GPS Coordinates", visible=True, interactive=True, scale=3)
40
  submit_location.click(get_location, inputs=[location], outputs=[identified_location])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  # ---------------------------------------------------------
43
  # Dead and Wounded Buttons
 
38
  #to submit it
39
  submit_location = gr.Button("Get GPS Coordinates", visible=True, interactive=True, scale=3)
40
  submit_location.click(get_location, inputs=[location], outputs=[identified_location])
41
+
42
+ # ---------------------------------------------------------
43
+ # ---------------------------------------------------------
44
+ # ---------------------------------------------------------
45
+
46
+ import random
47
+ import numpy as np
48
+
49
+ section_labels = [
50
+ "apple",
51
+ "banana",
52
+ "carrot",
53
+ "donut",
54
+ "eggplant",
55
+ "fish",
56
+ "grapes",
57
+ "hamburger",
58
+ "ice cream",
59
+ "juice",
60
+ ]
61
+
62
+ with gr.Row():
63
+ num_boxes = gr.Slider(0, 5, 2, step=1, label="Number of boxes")
64
+ num_segments = gr.Slider(0, 5, 1, step=1, label="Number of segments")
65
+
66
+ with gr.Row():
67
+ img_input = gr.Image()
68
+ img_output = gr.AnnotatedImage(
69
+ color_map={"banana": "#a89a00", "carrot": "#ffae00"}
70
+ )
71
+
72
+ section_btn = gr.Button("Identify Sections")
73
+ selected_section = gr.Textbox(label="Selected Section")
74
+
75
+ def section(img, num_boxes, num_segments):
76
+ sections = []
77
+ for a in range(num_boxes):
78
+ x = random.randint(0, img.shape[1])
79
+ y = random.randint(0, img.shape[0])
80
+ w = random.randint(0, img.shape[1] - x)
81
+ h = random.randint(0, img.shape[0] - y)
82
+ sections.append(((x, y, x + w, y + h), section_labels[a]))
83
+ for b in range(num_segments):
84
+ x = random.randint(0, img.shape[1])
85
+ y = random.randint(0, img.shape[0])
86
+ r = random.randint(0, min(x, y, img.shape[1] - x, img.shape[0] - y))
87
+ mask = np.zeros(img.shape[:2])
88
+ for i in range(img.shape[0]):
89
+ for j in range(img.shape[1]):
90
+ dist_square = (i - y) ** 2 + (j - x) ** 2
91
+ if dist_square < r**2:
92
+ mask[i, j] = round((r**2 - dist_square) / r**2 * 4) / 4
93
+ sections.append((mask, section_labels[b + num_boxes]))
94
+ return (img, sections)
95
+
96
+ section_btn.click(section, [img_input, num_boxes, num_segments], img_output)
97
+
98
+ def select_section(evt: gr.SelectData):
99
+ return section_labels[evt.index]
100
+
101
+ img_output.select(select_section, None, selected_section)
102
+
103
+ # ---------------------------------------------------------
104
+ # ---------------------------------------------------------
105
+ # ---------------------------------------------------------
106
 
107
  # ---------------------------------------------------------
108
  # Dead and Wounded Buttons
app/select_bird.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ # from gradio_image_prompter import ImagePrompter
3
+ from typing import List
4
+ from shapely.geometry import Point
5
+
6
+ from boxes_define import gdf
7
+
8
+ # Function to find the matching bounding box for a given point and return the image with boxes
9
+ def find_bounding_box(evt: gr.SelectData, img):
10
+ x, y = evt.index[0], evt.index[1]
11
+ point = Point(x, y)
12
+ match = gdf[gdf.contains(point)]
13
+
14
+ if not match.empty:
15
+ matched_box = match.iloc[0]['name']
16
+ else:
17
+ matched_box = "No bounding box found"
18
+ return matched_box
19
+
20
+
21
+ # Gradio app
22
+ with gr.Blocks() as demo:
23
+ # Draw bounding boxes on the image
24
+
25
+ img_with_boxes = gr.Image(value='assets/images/bird_boxed.png', label=None)
26
+
27
+ bbox_label = gr.Label()
28
+
29
+ img_with_boxes.select(find_bounding_box,
30
+ inputs=[img_with_boxes],
31
+ outputs=[bbox_label])
32
+
33
+
34
+
35
+ demo.launch(server_name="0.0.0.0")
36
+
37
+
requirements.txt CHANGED
@@ -1,2 +1,4 @@
1
  gradio
2
- geopy
 
 
 
1
  gradio
2
+ geopy
3
+ geopandas
4
+ pillow