samcoding5854 commited on
Commit
3b6c254
β€’
1 Parent(s): fd45eb4

Completed creating visuals

Browse files
.gitignore CHANGED
@@ -1 +1,3 @@
1
- .streamlit
 
 
 
1
+ .streamlit
2
+ **/__pycache__
3
+ /weights
App/__pycache__/AboutMe.cpython-310.pyc DELETED
Binary file (3.4 kB)
 
App/__pycache__/bgImages.cpython-310.pyc DELETED
Binary file (1.98 kB)
 
App/__pycache__/createVisual.cpython-310.pyc DELETED
Binary file (396 Bytes)
 
App/createVisual.py DELETED
@@ -1,12 +0,0 @@
1
- import streamlit as st
2
-
3
- # Main function
4
- def CREATEVISUALS():
5
- st.title("Detective Game")
6
- st.write("Hey how are you")
7
-
8
-
9
- if __name__ == "__main__":
10
- CREATEVISUALS()
11
-
12
-
 
 
 
 
 
 
 
 
 
 
 
 
 
{App β†’ Pages}/AboutMe.py RENAMED
File without changes
{App β†’ Pages}/bgImages.py RENAMED
File without changes
Pages/createVideo.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from PIL import Image
2
+ import streamlit as st
3
+ import os
4
+
5
+ # Main function
6
+ def CREATEGIF():
7
+ st.title("Create photoshoot visual")
8
+
9
+ # Set the directory where the uploaded images will be saved
10
+ UPLOAD_DIR = 'uploaded_images'
11
+
12
+ # Create the directory if it doesn't exist
13
+ if not os.path.exists(UPLOAD_DIR):
14
+ os.makedirs(UPLOAD_DIR)
15
+
16
+ # Streamlit app title
17
+ st.title("Image Upload and Save App")
18
+
19
+ # File uploader allows user to upload an image
20
+ uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
21
+
22
+ if uploaded_file is not None:
23
+ # Open the uploaded image
24
+ image = Image.open(uploaded_file)
25
+
26
+ # Display the uploaded image
27
+ st.image(image, caption='Uploaded Image.', use_column_width=True)
28
+
29
+ # Save the uploaded image to the specified directory
30
+ image_path = os.path.join(UPLOAD_DIR, uploaded_file.name)
31
+ image.save(image_path)
32
+
33
+ st.write(f"Image saved at: {image_path}")
34
+
35
+ else:
36
+ st.write("No image uploaded yet.")
37
+
38
+ image_files = [f for f in os.listdir("bgImages") if os.path.isfile(os.path.join("bgImages", f))]
39
+
40
+ # Create a dropdown with the list of image files
41
+ selected_image = st.selectbox("Select an image file", image_files)
42
+
43
+ if selected_image:
44
+ # Display the selected image
45
+ image_path = os.path.join("bgImages", selected_image)
46
+ image = Image.open(image_path)
47
+ st.image(image, caption=f"Selected image: {selected_image}")
48
+
49
+
50
+ if __name__ == "__main__":
51
+ CREATEGIF()
52
+
53
+
Pages/createVisual.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from PIL import Image
2
+ import streamlit as st
3
+ import os
4
+ from Pages.imageBB import run
5
+
6
+ # Main function
7
+ def CREATEVISUALS():
8
+ st.title("Create photoshoot visual")
9
+
10
+ # Set the directory where the uploaded images will be saved
11
+ UPLOAD_DIR = 'uploaded_images'
12
+
13
+ # Create the directory if it doesn't exist
14
+ if not os.path.exists(UPLOAD_DIR):
15
+ os.makedirs(UPLOAD_DIR)
16
+
17
+ # Streamlit app title
18
+ st.header("Image Upload and Save App")
19
+
20
+ # File uploader allows user to upload an image
21
+ uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
22
+
23
+ if uploaded_file is not None:
24
+ # Open the uploaded image
25
+ image = Image.open(uploaded_file)
26
+
27
+ # Save the uploaded image to the specified directory
28
+ image_path = os.path.join(UPLOAD_DIR, uploaded_file.name)
29
+ image.save(image_path)
30
+
31
+ st.write(f"Image Saved")
32
+ run(image_path)
33
+
34
+
35
+ else:
36
+ st.write("No image uploaded yet.")
37
+
38
+ if __name__ == "__main__":
39
+ CREATEVISUALS()
40
+
41
+
Pages/imageBB.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from segment_anything import sam_model_registry, SamAutomaticMaskGenerator, SamPredictor
2
+ import torch
3
+ import streamlit as st
4
+ from Pages.streamlit_img_label import st_img_label
5
+ from Pages.streamlit_img_label.manage import ImageManager
6
+ import os
7
+ from PIL import Image
8
+ import cv2
9
+ import numpy as np
10
+
11
+ @st.cache_data
12
+ def get_masks(rect,img_path):
13
+
14
+ CHECKPOINT_PATH = os.path.join("weights", "sam_vit_h_4b8939.pth")
15
+ DEVICE = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
16
+ MODEL_TYPE = "vit_h"
17
+ sam = sam_model_registry[MODEL_TYPE](checkpoint=CHECKPOINT_PATH).to(device=DEVICE)
18
+ mask_predictor = SamPredictor(sam)
19
+
20
+ rect = np.array([
21
+ rect['left'],
22
+ rect['top'],
23
+ rect['left'] + rect['width'],
24
+ rect['top'] + rect['height']
25
+ ])
26
+ image_bgr = cv2.imread(img_path)
27
+ image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
28
+
29
+ mask_predictor.set_image(image_rgb)
30
+
31
+ masks, scores, logits = mask_predictor.predict(
32
+ box=rect,
33
+ multimask_output=False
34
+ )
35
+ return masks
36
+
37
+
38
+
39
+ def run(img_path):
40
+ st.set_option("deprecation.showfileUploaderEncoding", False)
41
+
42
+ im = ImageManager(img_path)
43
+ resized_img = im.resizing_img()
44
+ resized_rects = im.get_resized_rects()
45
+
46
+ if "rects" not in st.session_state:
47
+ st.session_state.rects = resized_rects
48
+
49
+ # Only display st_img_label if Save button hasn't been clicked
50
+ if not st.session_state.get("saved"):
51
+ rects = st_img_label(resized_img, box_color="red", rects=st.session_state.rects)
52
+ st.session_state.rects = rects
53
+ else:
54
+ st.image(resized_img, caption="Annotated Image",width=300, use_column_width=True)
55
+
56
+ for rect in st.session_state.rects:
57
+ # st.write(f"Rectangle: {rect}")
58
+
59
+ with st.spinner('Please wait while the product image is being extracted...'):
60
+
61
+ masks = get_masks(rect,img_path)
62
+
63
+ save_dir = "saved_masks"
64
+ if not os.path.exists(save_dir):
65
+ os.makedirs(save_dir)
66
+
67
+ for i, mask in enumerate(masks):
68
+ inverted_mask = 255 - (mask * 255).astype(np.uint8)
69
+ file_path = os.path.join(save_dir, f"inverted_mask_{i}.png")
70
+ cv2.imwrite(file_path, inverted_mask)
71
+
72
+ print(f"Inverted masks saved to directory: {save_dir}")
73
+
74
+ image_files = [f for f in os.listdir("bgImages") if os.path.isfile(os.path.join("bgImages", f))]
75
+
76
+ st.header("Template Selection")
77
+ # Create a dropdown with the list of image files
78
+ selected_image = st.selectbox("Select an image file", image_files)
79
+
80
+ if selected_image:
81
+ # Display the selected image
82
+ image_pathBG = os.path.join("bgImages", selected_image)
83
+ image = Image.open(image_pathBG)
84
+ st.image(image, width=300, caption=f"Selected image: {selected_image}")
85
+
86
+ if st.button("Create Image"):
87
+ # Read the base image and background image
88
+ image_bgr = cv2.imread(img_path)
89
+ background_bgr = cv2.imread(image_pathBG)
90
+
91
+ # Resize the background image to match the size of image_bgr
92
+ background_bgr = cv2.resize(background_bgr, (image_bgr.shape[1], image_bgr.shape[0]))
93
+
94
+ # Convert the base image to RGB format for mask prediction if it's not already in RGB
95
+ if image_bgr.shape[2] == 3: # No alpha channel, standard BGR image
96
+ image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
97
+ else:
98
+ image_rgb = image_bgr[:, :, :3] # Drop alpha channel if it exists
99
+
100
+ # Assuming masks is a binary mask, convert it to uint8 format
101
+ mask = (masks[0] > 0).astype(np.uint8) * 255
102
+
103
+ # Apply a Gaussian blur to the mask to smooth the edges
104
+ mask = cv2.GaussianBlur(mask, (3,3), 0)
105
+
106
+ # Ensure the image has an alpha channel
107
+ if image_bgr.shape[2] == 3: # If no alpha channel, add one
108
+ b, g, r = cv2.split(image_bgr)
109
+ alpha_channel = mask # Use the blurred mask as the alpha channel
110
+ image_bgra = cv2.merge((b, g, r, alpha_channel))
111
+ else:
112
+ image_bgra = image_bgr
113
+
114
+ # Get the dimensions of the images
115
+ masked_height, masked_width = image_bgra.shape[:2]
116
+ background_height, background_width = background_bgr.shape[:2]
117
+
118
+ # Calculate the coordinates to place the masked image in the center of the background image
119
+ x_offset = (background_width - masked_width) // 2
120
+ y_offset = (background_height - masked_height) // 2
121
+
122
+ # Resize the masked image if it is larger than the background area
123
+ if masked_width > background_width or masked_height > background_height:
124
+ scaling_factor = min(background_width / masked_width, background_height / masked_height)
125
+ new_size = (int(masked_width * scaling_factor), int(masked_height * scaling_factor))
126
+ image_bgra = cv2.resize(image_bgra, new_size, interpolation=cv2.INTER_AREA)
127
+ masked_height, masked_width = image_bgra.shape[:2]
128
+ x_offset = (background_width - masked_width) // 2
129
+ y_offset = (background_height - masked_height) // 2
130
+
131
+ # Create a copy of the background image and convert it to BGRA
132
+ background_bgra = cv2.cvtColor(background_bgr, cv2.COLOR_BGR2BGRA)
133
+
134
+ # Overlay the masked image onto the center of the background image
135
+ overlay_image = background_bgra.copy()
136
+
137
+ # Only update the region where the segmented image will be placed
138
+ overlay = np.zeros_like(background_bgra)
139
+ overlay[y_offset:y_offset+masked_height, x_offset:x_offset+masked_width] = image_bgra
140
+
141
+ # Create the alpha mask for blending
142
+ alpha_mask = overlay[:, :, 3] / 255.0
143
+ alpha_inv = 1.0 - alpha_mask
144
+
145
+ # Modify alpha channel for smoother blending
146
+ alpha_mask = alpha_mask ** 0.5 # Applying square root for smoother blending
147
+
148
+ # Blend the images
149
+ for c in range(0, 3):
150
+ overlay_image[:, :, c] = (alpha_mask * overlay[:, :, c] + alpha_inv * overlay_image[:, :, c])
151
+
152
+ # Set the alpha channel
153
+ overlay_image[:, :, 3] = np.clip(overlay[:, :, 3] + background_bgra[:, :, 3], 0, 255)
154
+
155
+ # Save the result
156
+ output_path = 'output/overlay_image.png'
157
+ cv2.imwrite(output_path, overlay_image)
158
+
159
+ # Display the overlay image
160
+ st.image(output_path, caption="Overlay Image", use_column_width=True, width=300)
161
+
162
+
163
+ def annotate():
164
+ st.session_state.saved = True
165
+
166
+ if st.session_state.rects:
167
+ st.button(label="Save", on_click=annotate)
168
+
Pages/streamlit_img_label/__init__.py ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit.components.v1 as components
3
+ import numpy as np
4
+ from .manage import ImageManager, ImageDirManager
5
+
6
+ _RELEASE = True
7
+
8
+ if not _RELEASE:
9
+ _component_func = components.declare_component(
10
+ "st_img_label",
11
+ url="http://localhost:3001",
12
+ )
13
+ else:
14
+ parent_dir = os.path.dirname(os.path.abspath(__file__))
15
+ build_dir = os.path.join(parent_dir, "frontend/build")
16
+ _component_func = components.declare_component("st_img_label", path=build_dir)
17
+
18
+
19
+ def st_img_label(resized_img, box_color="blue", rects=[], key=None):
20
+ """Create a new instance of "st_img_label".
21
+
22
+ Parameters
23
+ ----------
24
+ img_file: PIL.Image
25
+ The image to be croppepd
26
+ box_color: string
27
+ The color of the cropper's bounding box. Defaults to blue.
28
+ rects: list
29
+ list of bounding boxes that already exists.
30
+ key: str or None
31
+ An optional key that uniquely identifies this component. If this is
32
+ None, and the component's arguments are changed, the component will
33
+ be re-mounted in the Streamlit frontend and lose its current state.
34
+
35
+ Returns
36
+ -------
37
+ rects: list
38
+ list of bounding boxes.
39
+ """
40
+ # Get arguments to send to frontend
41
+ canvasWidth = resized_img.width
42
+ canvasHeight = resized_img.height
43
+
44
+ # Translates image to a list for passing to Javascript
45
+ imageData = np.array(resized_img.convert("RGBA")).flatten().tolist()
46
+
47
+ # Call through to our private component function. Arguments we pass here
48
+ # will be sent to the frontend, where they'll be available in an "args"
49
+ # dictionary.
50
+ #
51
+ # Defaults to a box whose vertices are at 20% and 80% of height and width.
52
+ # The _recommended_box function could be replaced with some kind of image
53
+ # detection algorith if it suits your needs.
54
+ component_value = _component_func(
55
+ canvasWidth=canvasWidth,
56
+ canvasHeight=canvasHeight,
57
+ rects=rects,
58
+ boxColor=box_color,
59
+ imageData=imageData,
60
+ key=key,
61
+ )
62
+ # Return a cropped image using the box from the frontend
63
+ if component_value:
64
+ return component_value["rects"]
65
+ else:
66
+ return rects
67
+
68
+
69
+ # Add some test code to play with the component while it's in development.
70
+ # During development, we can run this just as we would any other Streamlit
71
+ # app: `$ streamlit run my_component/__init__.py`
72
+ if not _RELEASE:
73
+ import streamlit as st
74
+
75
+ st.set_option("deprecation.showfileUploaderEncoding", False)
76
+ custom_labels = ["", "dog", "cat"]
77
+
78
+ img_dir = "img_dir"
79
+
80
+ idm = ImageDirManager(img_dir)
81
+
82
+ if "files" not in st.session_state:
83
+ st.session_state["files"] = idm.get_all_files()
84
+ st.session_state["annotation_files"] = idm.get_exist_annotation_files()
85
+ st.session_state["image_index"] = 0
86
+ else:
87
+ idm.set_all_files(st.session_state["files"])
88
+ idm.set_annotation_files(st.session_state["annotation_files"])
89
+
90
+ def refresh():
91
+ st.session_state["files"] = idm.get_all_files()
92
+ st.session_state["annotation_files"] = idm.get_exist_annotation_files()
93
+ st.session_state["image_index"] = 0
94
+
95
+ def next_image():
96
+ image_index = st.session_state["image_index"]
97
+ if image_index < len(st.session_state["files"]) - 1:
98
+ st.session_state["image_index"] += 1
99
+ else:
100
+ st.warning("This is the last image.")
101
+
102
+ def previous_image():
103
+ image_index = st.session_state["image_index"]
104
+ if image_index > 0:
105
+ st.session_state["image_index"] -= 1
106
+ else:
107
+ st.warning("This is the first image.")
108
+
109
+ def next_annotate_file():
110
+ image_index = st.session_state["image_index"]
111
+ next_image_index = idm.get_next_annotation_image(image_index)
112
+ if next_image_index:
113
+ st.session_state["image_index"] = idm.get_next_annotation_image(image_index)
114
+ else:
115
+ st.warning("All images are annotated.")
116
+ next_image()
117
+
118
+ def go_to_image():
119
+ file_index = st.session_state["files"].index(st.session_state["file"])
120
+ st.session_state["image_index"] = file_index
121
+
122
+ # Sidebar: show status
123
+ n_files = len(st.session_state["files"])
124
+ n_annotate_files = len(st.session_state["annotation_files"])
125
+ st.sidebar.write("Total files:", n_files)
126
+ st.sidebar.write("Total annotate files:", n_annotate_files)
127
+ st.sidebar.write("Remaining files:", n_files - n_annotate_files)
128
+
129
+ st.sidebar.selectbox(
130
+ "Files",
131
+ st.session_state["files"],
132
+ index=st.session_state["image_index"],
133
+ on_change=go_to_image,
134
+ key="file",
135
+ )
136
+ col1, col2 = st.sidebar.columns(2)
137
+ with col1:
138
+ st.button(label="Previous image", on_click=previous_image)
139
+ with col2:
140
+ st.button(label="Next image", on_click=next_image)
141
+ st.sidebar.button(label="Next need annotate", on_click=next_annotate_file)
142
+ st.sidebar.button(label="Refresh", on_click=refresh)
143
+
144
+ # Main content: annotate images
145
+ img_file_name = idm.get_image(st.session_state["image_index"])
146
+ img_path = os.path.join(img_dir, img_file_name)
147
+ im = ImageManager(img_path)
148
+ img = im.get_img()
149
+ resized_img = im.resizing_img()
150
+ resized_rects = im.get_resized_rects()
151
+ rects = st_img_label(resized_img, box_color="red", rects=resized_rects)
152
+
153
+ def annotate():
154
+ im.save_annotation()
155
+ image_annotate_file_name = img_file_name.split(".")[0] + ".xml"
156
+ if image_annotate_file_name not in st.session_state["annotation_files"]:
157
+ st.session_state["annotation_files"].append(image_annotate_file_name)
158
+ next_annotate_file()
159
+
160
+ if rects:
161
+ st.button(label="Save", on_click=annotate)
162
+ preview_imgs = im.init_annotation(rects)
163
+
164
+ for i, prev_img in enumerate(preview_imgs):
165
+ prev_img[0].thumbnail((200, 200))
166
+ col1, col2 = st.columns(2)
167
+ with col1:
168
+ col1.image(prev_img[0])
169
+ with col2:
170
+ default_index = 0
171
+ if prev_img[1]:
172
+ default_index = custom_labels.index(prev_img[1])
173
+
174
+ select_label = col2.selectbox(
175
+ "Label", custom_labels, key=f"label_{i}", index=default_index
176
+ )
177
+ im.set_annotation(i, select_label)
Pages/streamlit_img_label/annotation.py ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from pascal_voc_writer import Writer
3
+ from xml.etree import ElementTree as ET
4
+
5
+ """
6
+ .. module:: streamlit_img_label
7
+ :synopsis: annotation.
8
+ .. moduleauthor:: Tianning Li <ltianningli@gmail.com>
9
+ """
10
+
11
+
12
+ def read_xml(img_file):
13
+ """read_xml
14
+ Read the xml annotation file and extract the bounding boxes if exists.
15
+
16
+ Args:
17
+ img_file(str): the image file.
18
+ Returns:
19
+ rects(list): the bounding boxes of the image.
20
+ """
21
+ file_name = img_file.split(".")[0]
22
+ if not os.path.isfile(f"{file_name}.xml"):
23
+ return []
24
+ tree = ET.parse(f"{file_name}.xml")
25
+ root = tree.getroot()
26
+
27
+ rects = []
28
+
29
+ for boxes in root.iter("object"):
30
+ label = boxes.find("name").text
31
+ ymin = int(boxes.find("bndbox/ymin").text)
32
+ xmin = int(boxes.find("bndbox/xmin").text)
33
+ ymax = int(boxes.find("bndbox/ymax").text)
34
+ xmax = int(boxes.find("bndbox/xmax").text)
35
+ rects.append(
36
+ {
37
+ "left": xmin,
38
+ "top": ymin,
39
+ "width": xmax - xmin,
40
+ "height": ymax - ymin,
41
+ "label": label,
42
+ }
43
+ )
44
+ return rects
45
+
46
+
47
+ def output_xml(img_file, img, rects):
48
+ """output_xml
49
+ Output the xml image annotation file
50
+
51
+ Args:
52
+ img_file(str): the image file.
53
+ img(PIL.Image): the image object.
54
+ rects(list): the bounding boxes of the image.
55
+ """
56
+ file_name = img_file.split(".")[0]
57
+ writer = Writer(img_file, img.width, img.height)
58
+ for box in rects:
59
+ xmin = box["left"]
60
+ ymin = box["top"]
61
+ xmax = box["left"] + box["width"]
62
+ ymax = box["top"] + box["height"]
63
+
64
+ writer.addObject(box["label"], xmin, ymin, xmax, ymax)
65
+ writer.save(f"{file_name}.xml")
Pages/streamlit_img_label/frontend/.gitignore ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.js
7
+ yarn.lock
8
+
9
+ # testing
10
+ /coverage
11
+
12
+ # production
13
+ /build
14
+
15
+ # misc
16
+ .DS_Store
17
+ .env.local
18
+ .env.development.local
19
+ .env.test.local
20
+ .env.production.local
21
+
22
+ npm-debug.log*
23
+ yarn-debug.log*
24
+ yarn-error.log*
Pages/streamlit_img_label/frontend/.prettierrc ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "endOfLine": "lf",
3
+ "semi": false,
4
+ "trailingComma": "es5",
5
+ "tabWidth": 4
6
+ }
Pages/streamlit_img_label/frontend/package.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "streamlit_img_label",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "dependencies": {
6
+ "@testing-library/jest-dom": "^4.2.4",
7
+ "@testing-library/react": "^9.3.2",
8
+ "@testing-library/user-event": "^7.1.2",
9
+ "@types/fabric": "^3.6.8",
10
+ "@types/hoist-non-react-statics": "^3.3.1",
11
+ "@types/jest": "^24.0.0",
12
+ "@types/node": "^12.0.0",
13
+ "@types/react": "^16.9.0",
14
+ "@types/react-dom": "^16.9.0",
15
+ "apache-arrow": "^0.17.0",
16
+ "hoist-non-react-statics": "^3.3.2",
17
+ "fabric": "^3.6.3",
18
+ "react": "^16.13.1",
19
+ "react-dom": "^16.13.1",
20
+ "react-scripts": "3.4.1",
21
+ "streamlit-component-lib": "^1.1.3",
22
+ "typescript": "~3.7.2"
23
+ },
24
+ "scripts": {
25
+ "start": "react-scripts start",
26
+ "build": "react-scripts build",
27
+ "test": "react-scripts test",
28
+ "eject": "react-scripts eject"
29
+ },
30
+ "eslintConfig": {
31
+ "extends": "react-app"
32
+ },
33
+ "browserslist": {
34
+ "production": [
35
+ ">0.2%",
36
+ "not dead",
37
+ "not op_mini all"
38
+ ],
39
+ "development": [
40
+ "last 1 chrome version",
41
+ "last 1 firefox version",
42
+ "last 1 safari version"
43
+ ]
44
+ },
45
+ "homepage": "."
46
+ }
Pages/streamlit_img_label/frontend/public/bootstrap.min.css ADDED
The diff for this file is too large to render. See raw diff
 
Pages/streamlit_img_label/frontend/public/index.html ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Streamlit Component</title>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <meta name="theme-color" content="#000000" />
8
+ <meta name="description" content="Streamlit Component" />
9
+ <link rel="stylesheet" href="bootstrap.min.css" />
10
+ </head>
11
+ <body>
12
+ <noscript>You need to enable JavaScript to run this app.</noscript>
13
+ <div id="root"></div>
14
+ <!--
15
+ This HTML file is a template.
16
+ If you open it directly in the browser, you will see an empty page.
17
+
18
+ You can add webfonts, meta tags, or analytics to this file.
19
+ The build step will place the bundled scripts into the <body> tag.
20
+
21
+ To begin the development, run `npm start` or `yarn start`.
22
+ To create a production bundle, use `npm run build` or `yarn build`.
23
+ -->
24
+ </body>
25
+ </html>
Pages/streamlit_img_label/frontend/src/StreamlitImgLabel.module.css ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .dark{
2
+ background-color:rgb(14, 17, 23);
3
+ }
4
+
5
+ button{
6
+ padding: 0.25rem 0.75rem;
7
+ border-radius: 0.25rem;
8
+ line-height: 1.3;
9
+ border: 1px solid;
10
+ margin-right: 5px;
11
+ margin-top: 5px;
12
+
13
+ }
14
+ button.dark{
15
+ color: white;
16
+ border-color: rgba(250, 250, 250, 0.2);
17
+ }
Pages/streamlit_img_label/frontend/src/StreamlitImgLabel.tsx ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useEffect, useState } from "react"
2
+ import {
3
+ ComponentProps,
4
+ Streamlit,
5
+ withStreamlitConnection,
6
+ } from "streamlit-component-lib"
7
+ import { fabric } from "fabric"
8
+ import styles from "./StreamlitImgLabel.module.css"
9
+
10
+ interface RectProps {
11
+ top: number
12
+ left: number
13
+ width: number
14
+ height: number
15
+ label: string
16
+ }
17
+
18
+ interface PythonArgs {
19
+ canvasWidth: number
20
+ canvasHeight: number
21
+ rects: RectProps[]
22
+ boxColor: string
23
+ imageData: Uint8ClampedArray
24
+ }
25
+
26
+ const StreamlitImgLabel = (props: ComponentProps) => {
27
+ const [mode, setMode] = useState<string>("light")
28
+ const [labels, setLabels] = useState<string[]>([])
29
+ const [canvas, setCanvas] = useState(new fabric.Canvas(""))
30
+ const { canvasWidth, canvasHeight, imageData }: PythonArgs = props.args
31
+ const [newBBoxIndex, setNewBBoxIndex] = useState<number>(0)
32
+
33
+ /*
34
+ * Translate Python image data to a JavaScript Image
35
+ */
36
+ var invisCanvas = document.createElement("canvas")
37
+ var ctx = invisCanvas.getContext("2d")
38
+
39
+ invisCanvas.width = canvasWidth
40
+ invisCanvas.height = canvasHeight
41
+
42
+ // create imageData object
43
+ let dataUri: any
44
+ if (ctx) {
45
+ var idata = ctx.createImageData(canvasWidth, canvasHeight)
46
+
47
+ // set our buffer as source
48
+ idata.data.set(imageData)
49
+
50
+ // update canvas with new data
51
+ ctx.putImageData(idata, 0, 0)
52
+ dataUri = invisCanvas.toDataURL()
53
+ } else {
54
+ dataUri = ""
55
+ }
56
+
57
+ // Initialize canvas on mount and add a rectangle
58
+ useEffect(() => {
59
+ const { rects, boxColor }: PythonArgs = props.args
60
+ const canvasTmp = new fabric.Canvas("c", {
61
+ enableRetinaScaling: false,
62
+ backgroundImage: dataUri,
63
+ uniScaleTransform: true,
64
+ })
65
+
66
+ rects.forEach((rect) => {
67
+ const { top, left, width, height } = rect
68
+ canvasTmp.add(
69
+ new fabric.Rect({
70
+ left,
71
+ top,
72
+ fill: "",
73
+ width,
74
+ height,
75
+ objectCaching: true,
76
+ stroke: boxColor,
77
+ strokeWidth: 1,
78
+ strokeUniform: true,
79
+ hasRotatingPoint: false,
80
+ })
81
+ )
82
+ })
83
+ setLabels(rects.map((rect) => rect.label))
84
+
85
+ setCanvas(canvasTmp)
86
+ Streamlit.setFrameHeight()
87
+ // eslint-disable-next-line
88
+ }, [canvasHeight, canvasWidth, dataUri])
89
+
90
+ // Create defualt bounding box
91
+ const defaultBox = () => ({
92
+ left: canvasWidth * 0.15 + newBBoxIndex * 3,
93
+ top: canvasHeight * 0.15 + newBBoxIndex * 3,
94
+ width: canvasWidth * 0.2,
95
+ height: canvasHeight * 0.2,
96
+ })
97
+
98
+ // Add new bounding box to be image
99
+ const addBoxHandler = () => {
100
+ const box = defaultBox()
101
+ setNewBBoxIndex(newBBoxIndex + 1)
102
+ canvas.add(
103
+ new fabric.Rect({
104
+ ...box,
105
+ fill: "",
106
+ objectCaching: true,
107
+ stroke: props.args.boxColor,
108
+ strokeWidth: 1,
109
+ strokeUniform: true,
110
+ hasRotatingPoint: false,
111
+ })
112
+ )
113
+ sendCoordinates([...labels, ""])
114
+ }
115
+
116
+ // Remove the selected bounding box
117
+ const removeBoxHandler = () => {
118
+ const selectObject = canvas.getActiveObject()
119
+ const selectIndex = canvas.getObjects().indexOf(selectObject)
120
+ canvas.remove(selectObject)
121
+ sendCoordinates(labels.filter((label, i) => i !== selectIndex))
122
+ }
123
+
124
+ // Reset the bounding boxes
125
+ const resetHandler = () => {
126
+ clearHandler()
127
+ const { rects, boxColor }: PythonArgs = props.args
128
+ rects.forEach((rect) => {
129
+ const { top, left, width, height } = rect
130
+ canvas.add(
131
+ new fabric.Rect({
132
+ left,
133
+ top,
134
+ fill: "",
135
+ width,
136
+ height,
137
+ objectCaching: true,
138
+ stroke: boxColor,
139
+ strokeWidth: 1,
140
+ strokeUniform: true,
141
+ hasRotatingPoint: false,
142
+ })
143
+ )
144
+ })
145
+ sendCoordinates(labels)
146
+ }
147
+
148
+ // Remove all the bounding boxes
149
+ const clearHandler = () => {
150
+ setNewBBoxIndex(0)
151
+ canvas.getObjects().forEach((rect) => canvas.remove(rect))
152
+ sendCoordinates([])
153
+ }
154
+
155
+ // Send the coordinates of the rectangle back to streamlit.
156
+ const sendCoordinates = (returnLabels: string[]) => {
157
+ setLabels(returnLabels)
158
+ const rects = canvas.getObjects().map((rect, i) => ({
159
+ ...rect.getBoundingRect(),
160
+ label: returnLabels[i],
161
+ }))
162
+ Streamlit.setComponentValue({ rects })
163
+ }
164
+
165
+ // Update the bounding boxes when modified
166
+ useEffect(() => {
167
+ if (!canvas) {
168
+ return
169
+ }
170
+ const handleEvent = () => {
171
+ canvas.renderAll()
172
+ sendCoordinates(labels)
173
+ }
174
+
175
+ canvas.on("object:modified", handleEvent)
176
+ return () => {
177
+ canvas.off("object:modified")
178
+ }
179
+ })
180
+
181
+ // Adjust the theme according to the system
182
+ const onSelectMode = (mode: string) => {
183
+ setMode(mode)
184
+ if (mode === "dark") document.body.classList.add("dark-mode")
185
+ else document.body.classList.remove("dark-mode")
186
+ }
187
+
188
+ useEffect(() => {
189
+ // Add listener to update styles
190
+ window
191
+ .matchMedia("(prefers-color-scheme: dark)")
192
+ .addEventListener("change", (e) =>
193
+ onSelectMode(e.matches ? "dark" : "light")
194
+ )
195
+
196
+ // Setup dark/light mode for the first time
197
+ onSelectMode(
198
+ window.matchMedia("(prefers-color-scheme: dark)").matches
199
+ ? "dark"
200
+ : "light"
201
+ )
202
+
203
+ // Remove listener
204
+ return () => {
205
+ window
206
+ .matchMedia("(prefers-color-scheme: dark)")
207
+ .removeEventListener("change", () => {})
208
+ }
209
+ }, [])
210
+
211
+ return (
212
+ <>
213
+ <canvas
214
+ id="c"
215
+ className={mode === "dark" ? styles.dark : ""}
216
+ width={canvasWidth}
217
+ height={canvasHeight}
218
+ />
219
+ <div className={mode === "dark" ? styles.dark : ""}>
220
+ <button
221
+ className={mode === "dark" ? styles.dark : ""}
222
+ onClick={addBoxHandler}
223
+ >
224
+ Add bounding box
225
+ </button>
226
+ <button
227
+ className={mode === "dark" ? styles.dark : ""}
228
+ onClick={removeBoxHandler}
229
+ >
230
+ Remove select
231
+ </button>
232
+ <button
233
+ className={mode === "dark" ? styles.dark : ""}
234
+ onClick={resetHandler}
235
+ >
236
+ Reset
237
+ </button>
238
+ <button
239
+ className={mode === "dark" ? styles.dark : ""}
240
+ onClick={clearHandler}
241
+ >
242
+ Clear all
243
+ </button>
244
+ </div>
245
+ </>
246
+ )
247
+ }
248
+
249
+ export default withStreamlitConnection(StreamlitImgLabel)
Pages/streamlit_img_label/frontend/src/index.tsx ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react"
2
+ import ReactDOM from "react-dom"
3
+ import StreamlitImgLabel from "./StreamlitImgLabel"
4
+
5
+ ReactDOM.render(
6
+ <React.StrictMode>
7
+ <StreamlitImgLabel />
8
+ </React.StrictMode>,
9
+ document.getElementById("root")
10
+ )
Pages/streamlit_img_label/frontend/src/react-app-env.d.ts ADDED
@@ -0,0 +1 @@
 
 
1
+ /// <reference types="react-scripts" />
Pages/streamlit_img_label/frontend/tsconfig.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "esModuleInterop": true,
8
+ "allowSyntheticDefaultImports": true,
9
+ "strict": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "module": "esnext",
12
+ "moduleResolution": "node",
13
+ "resolveJsonModule": true,
14
+ "isolatedModules": true,
15
+ "noEmit": true,
16
+ "jsx": "react"
17
+ },
18
+ "include": ["src"]
19
+ }
Pages/streamlit_img_label/manage.py ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import numpy as np
4
+ from PIL import Image
5
+ from .annotation import output_xml, read_xml
6
+
7
+ """
8
+ .. module:: streamlit_img_label
9
+ :synopsis: manage.
10
+ .. moduleauthor:: Tianning Li <ltianningli@gmail.com>
11
+ """
12
+
13
+
14
+ class ImageManager:
15
+ """ImageManager
16
+ Manage the image object.
17
+
18
+ Args:
19
+ filename(str): the image file.
20
+ """
21
+
22
+ def __init__(self, filename):
23
+ """initiate module"""
24
+ self._filename = filename
25
+ self._img = Image.open(filename)
26
+ self._rects = []
27
+ self._load_rects()
28
+ self._resized_ratio_w = 1
29
+ self._resized_ratio_h = 1
30
+
31
+ def _load_rects(self):
32
+ rects_xml = read_xml(self._filename)
33
+ if rects_xml:
34
+ self._rects = rects_xml
35
+
36
+ def get_img(self):
37
+ """get the image object
38
+
39
+ Returns:
40
+ img(PIL.Image): the image object.
41
+ """
42
+ return self._img
43
+
44
+ def get_rects(self):
45
+ """get the rects
46
+
47
+ Returns:
48
+ rects(list): the bounding boxes of the image.
49
+ """
50
+ return self._rects
51
+
52
+ def resizing_img(self, max_height=700, max_width=700):
53
+ """resizing the image by max_height and max_width.
54
+
55
+ Args:
56
+ max_height(int): the max_height of the frame.
57
+ max_width(int): the max_width of the frame.
58
+ Returns:
59
+ resized_img(PIL.Image): the resized image.
60
+ """
61
+ resized_img = self._img.copy()
62
+ if resized_img.height > max_height:
63
+ ratio = max_height / resized_img.height
64
+ resized_img = resized_img.resize(
65
+ (int(resized_img.width * ratio), int(resized_img.height * ratio))
66
+ )
67
+ if resized_img.width > max_width:
68
+ ratio = max_width / resized_img.width
69
+ resized_img = resized_img.resize(
70
+ (int(resized_img.width * ratio), int(resized_img.height * ratio))
71
+ )
72
+
73
+ self._resized_ratio_w = self._img.width / resized_img.width
74
+ self._resized_ratio_h = self._img.height / resized_img.height
75
+ return resized_img
76
+
77
+ def _resize_rect(self, rect):
78
+ resized_rect = {}
79
+ resized_rect["left"] = rect["left"] / self._resized_ratio_w
80
+ resized_rect["width"] = rect["width"] / self._resized_ratio_w
81
+ resized_rect["top"] = rect["top"] / self._resized_ratio_h
82
+ resized_rect["height"] = rect["height"] / self._resized_ratio_h
83
+ if "label" in rect:
84
+ resized_rect["label"] = rect["label"]
85
+ return resized_rect
86
+
87
+ def get_resized_rects(self):
88
+ """get resized the rects according to the resized image.
89
+
90
+ Returns:
91
+ resized_rects(list): the resized bounding boxes of the image.
92
+ """
93
+ return [self._resize_rect(rect) for rect in self._rects]
94
+
95
+ def _chop_box_img(self, rect):
96
+ rect["left"] = int(rect["left"] * self._resized_ratio_w)
97
+ rect["width"] = int(rect["width"] * self._resized_ratio_w)
98
+ rect["top"] = int(rect["top"] * self._resized_ratio_h)
99
+ rect["height"] = int(rect["height"] * self._resized_ratio_h)
100
+ left, top, width, height = (
101
+ rect["left"],
102
+ rect["top"],
103
+ rect["width"],
104
+ rect["height"],
105
+ )
106
+
107
+ raw_image = np.asarray(self._img).astype("uint8")
108
+ prev_img = np.zeros(raw_image.shape, dtype="uint8")
109
+ prev_img[top : top + height, left : left + width] = raw_image[
110
+ top : top + height, left : left + width
111
+ ]
112
+ prev_img = prev_img[top : top + height, left : left + width]
113
+ label = ""
114
+ if "label" in rect:
115
+ label = rect["label"]
116
+ return (Image.fromarray(prev_img), label)
117
+
118
+ def init_annotation(self, rects):
119
+ """init annotation for current rects.
120
+
121
+ Args:
122
+ rects(list): the bounding boxes of the image.
123
+ Returns:
124
+ prev_img(list): list of preview images with default label.
125
+ """
126
+ self._current_rects = rects
127
+ return [self._chop_box_img(rect) for rect in self._current_rects]
128
+
129
+ def set_annotation(self, index, label):
130
+ """set the label of the image.
131
+
132
+ Args:
133
+ index(int): the index of the list of bounding boxes of the image.
134
+ label(str): the label of the bounding box
135
+ """
136
+ self._current_rects[index]["label"] = label
137
+
138
+ def save_annotation(self):
139
+ """output the xml annotation file."""
140
+ output_xml(self._filename, self._img, self._current_rects)
141
+
142
+
143
+ class ImageDirManager:
144
+ def __init__(self, dir_name):
145
+ self._dir_name = dir_name
146
+ self._files = []
147
+ self._annotations_files = []
148
+
149
+ def get_all_files(self, allow_types=["png", "jpg", "jpeg"]):
150
+ allow_types += [i.upper() for i in allow_types]
151
+ mask = ".*\.[" + "|".join(allow_types) + "]"
152
+ self._files = [
153
+ file for file in os.listdir(self._dir_name) if re.match(mask, file)
154
+ ]
155
+ return self._files
156
+
157
+ def get_exist_annotation_files(self):
158
+ self._annotations_files = [
159
+ file for file in os.listdir(self._dir_name) if re.match(".*.xml", file)
160
+ ]
161
+ return self._annotations_files
162
+
163
+ def set_all_files(self, files):
164
+ self._files = files
165
+
166
+ def set_annotation_files(self, files):
167
+ self._annotations_files = files
168
+
169
+ def get_image(self, index):
170
+ return self._files[index]
171
+
172
+ def _get_next_image_helper(self, index):
173
+ while index < len(self._files) - 1:
174
+ index += 1
175
+ image_file = self._files[index]
176
+ image_file_name = image_file.split(".")[0]
177
+ if f"{image_file_name}.xml" not in self._annotations_files:
178
+ return index
179
+ return None
180
+
181
+ def get_next_annotation_image(self, index):
182
+ image_index = self._get_next_image_helper(index)
183
+ if image_index:
184
+ return image_index
185
+ if not image_index and len(self._files) != len(self._annotations_files):
186
+ return self._get_next_image_helper(0)
{App β†’ Pages}/utils.py RENAMED
File without changes
app.py CHANGED
@@ -1,7 +1,8 @@
1
  import streamlit as st
2
- from App.createVisual import CREATEVISUALS
3
- from App.AboutMe import ABOUTUS
4
- from App.bgImages import BGIMAGES
 
5
 
6
 
7
  st.set_page_config(
@@ -14,13 +15,15 @@ st.set_page_config(
14
 
15
  def MAIN():
16
  st.sidebar.title('LumiereIQ')
17
- app = st.sidebar.selectbox('', ['Create Visuals','Background Images', 'About Me'])
18
  if app == "Create Visuals":
19
  CREATEVISUALS()
20
  elif app == "About Me":
21
  ABOUTUS()
22
  elif app == "Background Images":
23
  BGIMAGES()
 
 
24
 
25
 
26
  MAIN()
 
1
  import streamlit as st
2
+ from Pages.createVisual import CREATEVISUALS
3
+ from Pages.AboutMe import ABOUTUS
4
+ from Pages.bgImages import BGIMAGES
5
+ from Pages.createVideo import CREATEGIF
6
 
7
 
8
  st.set_page_config(
 
15
 
16
  def MAIN():
17
  st.sidebar.title('LumiereIQ')
18
+ app = st.sidebar.selectbox('', ['Create Visuals','Background Images','Create Video', 'About Me'])
19
  if app == "Create Visuals":
20
  CREATEVISUALS()
21
  elif app == "About Me":
22
  ABOUTUS()
23
  elif app == "Background Images":
24
  BGIMAGES()
25
+ elif app == "Create Video":
26
+ CREATEGIF()
27
 
28
 
29
  MAIN()
output/overlay_image.png ADDED
requirements.txt CHANGED
@@ -1,3 +1,9 @@
1
  streamlit
2
  diffusers
3
- torch
 
 
 
 
 
 
 
1
  streamlit
2
  diffusers
3
+ torch
4
+ transformers
5
+ git+https://github.com/facebookresearch/segment-anything.git
6
+ pascal_voc_writer
7
+ roboflow
8
+ dataclasses-json
9
+ supervision
saved_masks/inverted_mask_0.png ADDED
setup.sh ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Create the directory for weights if it doesn't exist
4
+ mkdir -p weights
5
+
6
+ # Download the file
7
+ wget -q https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth -P weights
8
+
9
+
uploaded_images/download.png ADDED