whuang06 commited on
Commit
6fa6fdb
·
verified ·
1 Parent(s): e332546

Upload 7 files

Browse files
Files changed (7) hide show
  1. LICENSE +21 -0
  2. README.md +4 -12
  3. app.py +111 -0
  4. data/0497c5.png +0 -0
  5. data/857e7d.png +0 -0
  6. img/map.png +0 -0
  7. requirements.txt +7 -0
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Weichen Huang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md CHANGED
@@ -1,13 +1,5 @@
1
- ---
2
- title: GeoIA
3
- emoji: 📈
4
- colorFrom: green
5
- colorTo: green
6
- sdk: streamlit
7
- sdk_version: 1.30.0
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
+ # Streamlit - Drawable Canvas - Demo
 
 
 
 
 
 
 
 
 
 
2
 
3
+ Streamlit Drawable Canvas demo on Streamlit Sharing
4
+
5
+ [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://share.streamlit.io/andfanilo/streamlit-drawable-canvas-demo/master/app.py)
app.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from streamlit_drawable_canvas import st_canvas
3
+ from PIL import Image
4
+ import numpy as np
5
+ import cv2
6
+ import hashlib
7
+ import time
8
+ import os
9
+
10
+ # Function to convert the canvas drawing to a binary mask
11
+ def canvas_to_mask(canvas_result, img_shape):
12
+ if canvas_result is not None and canvas_result.image_data is not None:
13
+ canvas_image_data = np.array(canvas_result.image_data)
14
+ mask = cv2.cvtColor(canvas_image_data, cv2.COLOR_RGBA2GRAY)
15
+ mask = cv2.threshold(mask, 1, 255, cv2.THRESH_BINARY)[1]
16
+ mask = cv2.resize(mask, (img_shape[1], img_shape[0]))
17
+ return mask
18
+ else:
19
+ return None
20
+
21
+ # Function to fill enclosed areas in the binary mask
22
+ def fill_enclosed_areas(mask):
23
+ filled_mask = mask.copy()
24
+ h, w = filled_mask.shape[:2]
25
+ flood_fill_mask = np.zeros((h + 2, w + 2), np.uint8)
26
+ cv2.floodFill(filled_mask, flood_fill_mask, (0, 0), 255)
27
+ filled_mask_inv = cv2.bitwise_not(filled_mask)
28
+ filled_foreground = mask | filled_mask_inv
29
+ return filled_foreground
30
+
31
+ def generate_short_hash():
32
+ current_time = str(time.time())
33
+ sha256_hash = hashlib.sha256(current_time.encode()).hexdigest()
34
+ short_hash = sha256_hash[:6]
35
+
36
+ return short_hash
37
+
38
+ # Function to calculate the mean mask from all masks in the data folder
39
+ def calculate_mean_mask(mask_folder):
40
+ mask_list = []
41
+ for filename in os.listdir(mask_folder):
42
+ if filename.endswith('.png'):
43
+ mask_path = os.path.join(mask_folder, filename)
44
+ mask_image = Image.open(mask_path).convert('L') # convert to grayscale
45
+ mask_array = np.array(mask_image)
46
+ mask_list.append(mask_array)
47
+ if mask_list:
48
+ # Stack mask arrays and calculate the mean along the stack
49
+ mean_mask = np.mean(np.stack(mask_list), axis=0).astype(np.uint8)
50
+ return mean_mask
51
+ else:
52
+ return None
53
+
54
+ # Function to overlay the mean mask onto the base image
55
+ def overlay_mask(base_image_path, mean_mask):
56
+ base_image = Image.open(base_image_path).convert('RGBA')
57
+ mean_mask_image = Image.fromarray(mean_mask)
58
+ mean_mask_image = mean_mask_image.resize(base_image.size, resample=Image.BILINEAR)
59
+ mask_rgba = Image.merge('RGBA', (mean_mask_image, mean_mask_image, mean_mask_image, mean_mask_image))
60
+ final_image = Image.composite(mask_rgba, base_image, mean_mask_image)
61
+ return final_image
62
+
63
+ st.title("IB Geo IA Survey")
64
+
65
+ # Upload an image
66
+
67
+
68
+ image = Image.open("img/map.png").convert("RGB")
69
+ img_array = np.array(image)
70
+ width = st.slider('Stroke width', 0, 20, 5)
71
+
72
+ # Create a canvas for drawing
73
+ st.subheader("Highlight the central business district area:")
74
+ canvas_result = st_canvas(
75
+ fill_color="rgba(255, 165, 0, 0.7)", # Use an orange, semi-transparent fill
76
+ stroke_width=width,
77
+ stroke_color="rgba(255, 165, 0, 0.7)",
78
+ background_image=Image.open("img/map.png"),
79
+ update_streamlit=True,
80
+ height=img_array.shape[0],
81
+ width=img_array.shape[1],
82
+ drawing_mode="freedraw",
83
+ key="canvas",
84
+ )
85
+
86
+ if st.button("Save"):
87
+
88
+ mask = canvas_to_mask(canvas_result, img_array.shape)
89
+ if mask is not None:
90
+ mask = fill_enclosed_areas(mask)
91
+ cv2.imwrite(f"data/{generate_short_hash()}.png", mask)
92
+ else:
93
+ st.warning("Please draw on the image.")
94
+
95
+ if st.button("Aggregate data"):
96
+
97
+ mean_mask = calculate_mean_mask("data")
98
+
99
+ if mean_mask is not None:
100
+ final_image = overlay_mask("img/map.png", mean_mask)
101
+
102
+ st.image(final_image, caption='Where most people think the CBD is', use_column_width=True)
103
+
104
+ st.download_button(
105
+ label="Download Image",
106
+ data=final_image.tobytes(),
107
+ file_name="final_overlay.png",
108
+ mime="image/png"
109
+ )
110
+ else:
111
+ st.warning("No saved data found in the data folder.")
data/0497c5.png ADDED
data/857e7d.png ADDED
img/map.png ADDED
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ streamlit>=0.88
2
+ streamlit-drawable-canvas>=0.8
3
+ svgpathtools
4
+ svgwrite
5
+ numpy
6
+ pillow
7
+ opencv-python