use green backgrounds + fix button naming
Browse files- app.py +17 -12
- db.py +2 -0
- utils/add_green_background.py +38 -0
- utils/upload-to-dataset.py +69 -61
app.py
CHANGED
@@ -21,7 +21,7 @@ from huggingface_hub import CommitScheduler
|
|
21 |
token = os.getenv("HUGGINGFACE_HUB_TOKEN")
|
22 |
|
23 |
# Load datasets
|
24 |
-
dataset = load_dataset("bgsys/background-removal-arena-
|
25 |
|
26 |
# Configure logging
|
27 |
logging.basicConfig(level=logging.INFO)
|
@@ -131,13 +131,20 @@ def get_notice_markdown():
|
|
131 |
"""
|
132 |
|
133 |
def compute_mask_difference(segmented_a, segmented_b):
|
134 |
-
"""Compute the absolute difference between two image masks."""
|
135 |
mask_a = np.asarray(segmented_a)
|
136 |
mask_b = np.asarray(segmented_b)
|
137 |
|
138 |
-
#
|
139 |
-
|
140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
|
142 |
# Compute the absolute difference between the masks
|
143 |
return np.abs(mask_a_1d - mask_b_1d)
|
@@ -146,6 +153,7 @@ def gradio_interface():
|
|
146 |
"""Create and return the Gradio interface."""
|
147 |
with gr.Blocks() as demo:
|
148 |
gr.Markdown("# Background Removal Arena")
|
|
|
149 |
|
150 |
with gr.Tabs() as tabs:
|
151 |
with gr.Tab("⚔️ Arena (battle)", id=0):
|
@@ -168,7 +176,7 @@ def gradio_interface():
|
|
168 |
height=500
|
169 |
)
|
170 |
input_image_display = gr.AnnotatedImage(
|
171 |
-
value=(input_image, [(mask_difference > 0,
|
172 |
label="Input Image",
|
173 |
width=500,
|
174 |
height=500
|
@@ -218,11 +226,8 @@ def gradio_interface():
|
|
218 |
|
219 |
try:
|
220 |
logging.debug("Adding vote data to the database: %s", vote_data)
|
221 |
-
|
222 |
-
|
223 |
-
if is_running_in_space():
|
224 |
-
result = add_vote(vote_data)
|
225 |
-
logging.info("Vote successfully recorded in the database with ID: %s", result["id"])
|
226 |
except Exception as e:
|
227 |
logging.error("Error recording vote: %s", str(e))
|
228 |
|
@@ -236,7 +241,7 @@ def gradio_interface():
|
|
236 |
# Update the notice markdown with the new vote count
|
237 |
new_notice_markdown = get_notice_markdown()
|
238 |
|
239 |
-
return (fpath_input.value, (new_input_image, [(mask_difference,
|
240 |
new_segmented_b, model_a_name.value, model_b_name.value, new_notice_markdown)
|
241 |
|
242 |
with gr.Tab("🏆 Leaderboard", id=1) as leaderboard_tab:
|
|
|
21 |
token = os.getenv("HUGGINGFACE_HUB_TOKEN")
|
22 |
|
23 |
# Load datasets
|
24 |
+
dataset = load_dataset("bgsys/background-removal-arena-green", split='train')
|
25 |
|
26 |
# Configure logging
|
27 |
logging.basicConfig(level=logging.INFO)
|
|
|
131 |
"""
|
132 |
|
133 |
def compute_mask_difference(segmented_a, segmented_b):
|
134 |
+
"""Compute the absolute difference between two image masks, ignoring green background."""
|
135 |
mask_a = np.asarray(segmented_a)
|
136 |
mask_b = np.asarray(segmented_b)
|
137 |
|
138 |
+
# Define the green background color
|
139 |
+
green_background = (0, 255, 0, 255)
|
140 |
+
|
141 |
+
# Create a binary mask where non-green and non-transparent pixels are marked as 1
|
142 |
+
mask_a_1d = np.where(
|
143 |
+
(mask_a[..., :3] != green_background[:3]).any(axis=-1) & (mask_a[..., 3] != 0), 1, 0
|
144 |
+
)
|
145 |
+
mask_b_1d = np.where(
|
146 |
+
(mask_b[..., :3] != green_background[:3]).any(axis=-1) & (mask_b[..., 3] != 0), 1, 0
|
147 |
+
)
|
148 |
|
149 |
# Compute the absolute difference between the masks
|
150 |
return np.abs(mask_a_1d - mask_b_1d)
|
|
|
153 |
"""Create and return the Gradio interface."""
|
154 |
with gr.Blocks() as demo:
|
155 |
gr.Markdown("# Background Removal Arena")
|
156 |
+
button_name = "Difference between masks"
|
157 |
|
158 |
with gr.Tabs() as tabs:
|
159 |
with gr.Tab("⚔️ Arena (battle)", id=0):
|
|
|
176 |
height=500
|
177 |
)
|
178 |
input_image_display = gr.AnnotatedImage(
|
179 |
+
value=(input_image, [(mask_difference > 0, button_name)]),
|
180 |
label="Input Image",
|
181 |
width=500,
|
182 |
height=500
|
|
|
226 |
|
227 |
try:
|
228 |
logging.debug("Adding vote data to the database: %s", vote_data)
|
229 |
+
result = add_vote(vote_data)
|
230 |
+
logging.info("Vote successfully recorded in the database with ID: %s", result["id"])
|
|
|
|
|
|
|
231 |
except Exception as e:
|
232 |
logging.error("Error recording vote: %s", str(e))
|
233 |
|
|
|
241 |
# Update the notice markdown with the new vote count
|
242 |
new_notice_markdown = get_notice_markdown()
|
243 |
|
244 |
+
return (fpath_input.value, (new_input_image, [(mask_difference, button_name)]), new_segmented_a,
|
245 |
new_segmented_b, model_a_name.value, model_b_name.value, new_notice_markdown)
|
246 |
|
247 |
with gr.Tab("🏆 Leaderboard", id=1) as leaderboard_tab:
|
db.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import os
|
|
|
2 |
from sqlalchemy import create_engine, Column, Integer, String, DateTime
|
3 |
from sqlalchemy.ext.declarative import declarative_base
|
4 |
from sqlalchemy.orm import sessionmaker, Session
|
@@ -48,6 +49,7 @@ def add_vote(vote_data):
|
|
48 |
db.add(db_vote)
|
49 |
db.commit()
|
50 |
db.refresh(db_vote)
|
|
|
51 |
return {"id": db_vote.id, "user_id": db_vote.user_id, "timestamp": db_vote.timestamp}
|
52 |
|
53 |
# Function to get all votes
|
|
|
1 |
import os
|
2 |
+
import logging
|
3 |
from sqlalchemy import create_engine, Column, Integer, String, DateTime
|
4 |
from sqlalchemy.ext.declarative import declarative_base
|
5 |
from sqlalchemy.orm import sessionmaker, Session
|
|
|
49 |
db.add(db_vote)
|
50 |
db.commit()
|
51 |
db.refresh(db_vote)
|
52 |
+
logging.info("Vote registered with ID: %s, using database: %s", db_vote.id, DATABASE_URL)
|
53 |
return {"id": db_vote.id, "user_id": db_vote.user_id, "timestamp": db_vote.timestamp}
|
54 |
|
55 |
# Function to get all votes
|
utils/add_green_background.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from PIL import Image
|
3 |
+
|
4 |
+
def add_green_background_to_image(image_path, output_path, background_color=(0, 255, 0)):
|
5 |
+
"""Add a green background to an image and save it as PNG."""
|
6 |
+
with Image.open(image_path) as img:
|
7 |
+
img = img.convert("RGBA")
|
8 |
+
background = Image.new("RGBA", img.size, background_color + (255,))
|
9 |
+
combined = Image.alpha_composite(background, img)
|
10 |
+
combined.save(output_path, "PNG")
|
11 |
+
|
12 |
+
def process_directory(input_dir, output_dir, background_color=(0, 255, 0)):
|
13 |
+
"""Recursively process a directory to add a green background to all images and convert them to PNG."""
|
14 |
+
if not os.path.exists(output_dir):
|
15 |
+
os.makedirs(output_dir)
|
16 |
+
|
17 |
+
for root, _, files in os.walk(input_dir):
|
18 |
+
for file in files:
|
19 |
+
if file.lower().endswith(('.png', '.jpg', '.jpeg')):
|
20 |
+
input_path = os.path.join(root, file)
|
21 |
+
relative_path = os.path.relpath(input_path, input_dir)
|
22 |
+
output_path = os.path.join(output_dir, os.path.splitext(relative_path)[0] + '.png')
|
23 |
+
|
24 |
+
# Ensure the output directory exists
|
25 |
+
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
26 |
+
|
27 |
+
# Check if the output file already exists
|
28 |
+
if not os.path.exists(output_path):
|
29 |
+
# Add green background to the image and convert to PNG
|
30 |
+
add_green_background_to_image(input_path, output_path, background_color)
|
31 |
+
print(f"Processed: {input_path} -> {output_path}")
|
32 |
+
else:
|
33 |
+
print(f"Skipped: {output_path} already exists")
|
34 |
+
|
35 |
+
# Example usage
|
36 |
+
input_directory = "../../background-removal-arena-v0/train/data/resized"
|
37 |
+
output_directory = "../data/resized-green/"
|
38 |
+
process_directory(input_directory, output_directory)
|
utils/upload-to-dataset.py
CHANGED
@@ -3,74 +3,82 @@ from huggingface_hub import HfApi
|
|
3 |
import os
|
4 |
from collections import defaultdict
|
5 |
import pandas as pd
|
|
|
6 |
|
7 |
-
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
-
#
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
"original_filename": Value("string") # Original filename
|
18 |
-
})
|
19 |
|
20 |
-
#
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
|
|
27 |
|
28 |
-
#
|
29 |
-
|
30 |
-
for
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
break # Stop checking other extensions if a file is found
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
}
|
57 |
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
dataset_dict["clipdrop_image"].append(entry["clipdrop_image"])
|
62 |
-
dataset_dict["bria_image"].append(entry["bria_image"])
|
63 |
-
dataset_dict["photoroom_image"].append(entry["photoroom_image"])
|
64 |
-
dataset_dict["removebg_image"].append(entry["removebg_image"])
|
65 |
-
dataset_dict["original_filename"].append(filename)
|
66 |
|
67 |
-
#
|
68 |
-
|
69 |
-
df.to_csv("image_data.csv", index=False)
|
70 |
|
71 |
-
#
|
72 |
-
|
|
|
73 |
|
74 |
-
|
75 |
-
|
76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
3 |
import os
|
4 |
from collections import defaultdict
|
5 |
import pandas as pd
|
6 |
+
import argparse
|
7 |
|
8 |
+
def upload_to_dataset(image_dir, dataset_name):
|
9 |
+
# Define the dataset features with dedicated columns for each model
|
10 |
+
features = Features({
|
11 |
+
"original_image": Image(), # Original image feature
|
12 |
+
"clipdrop_image": Image(), # Clipdrop segmented image
|
13 |
+
"bria_image": Image(), # Bria segmented image
|
14 |
+
"photoroom_image": Image(), # Photoroom segmented image
|
15 |
+
"removebg_image": Image(), # RemoveBG segmented image
|
16 |
+
"original_filename": Value("string") # Original filename
|
17 |
+
})
|
18 |
|
19 |
+
# Load image paths and metadata
|
20 |
+
data = defaultdict(lambda: {
|
21 |
+
"clipdrop_image": None,
|
22 |
+
"bria_image": None,
|
23 |
+
"photoroom_image": None,
|
24 |
+
"removebg_image": None
|
25 |
+
})
|
|
|
|
|
26 |
|
27 |
+
# Walk into the web-original-images folder
|
28 |
+
web_original_images_dir = os.path.join(image_dir, "web-original-images")
|
29 |
+
for root, _, files in os.walk(web_original_images_dir):
|
30 |
+
for f in files:
|
31 |
+
if f.endswith(('.png', '.jpg', '.jpeg')):
|
32 |
+
original_image_path = os.path.join(root, f)
|
33 |
+
data[f]["original_image"] = original_image_path
|
34 |
+
data[f]["original_filename"] = f
|
35 |
|
36 |
+
# Check for corresponding images in other directories
|
37 |
+
for source in ["clipdrop", "bria", "photoroom", "removebg"]:
|
38 |
+
# Check for processed images ending in .png or .jpg
|
39 |
+
for ext in ['.png', '.jpg']:
|
40 |
+
processed_image_filename = os.path.splitext(f)[0] + ext
|
41 |
+
source_image_path = os.path.join(image_dir, source, processed_image_filename)
|
42 |
+
|
43 |
+
if os.path.exists(source_image_path):
|
44 |
+
data[f][f"{source}_image"] = source_image_path
|
45 |
+
break # Stop checking other extensions if a file is found
|
46 |
|
47 |
+
# Convert the data to a dictionary of lists
|
48 |
+
dataset_dict = {
|
49 |
+
"original_image": [],
|
50 |
+
"clipdrop_image": [],
|
51 |
+
"bria_image": [],
|
52 |
+
"photoroom_image": [],
|
53 |
+
"removebg_image": [],
|
54 |
+
"original_filename": []
|
55 |
+
}
|
|
|
56 |
|
57 |
+
for filename, entry in data.items():
|
58 |
+
if "original_image" in entry:
|
59 |
+
dataset_dict["original_image"].append(entry["original_image"])
|
60 |
+
dataset_dict["clipdrop_image"].append(entry["clipdrop_image"])
|
61 |
+
dataset_dict["bria_image"].append(entry["bria_image"])
|
62 |
+
dataset_dict["photoroom_image"].append(entry["photoroom_image"])
|
63 |
+
dataset_dict["removebg_image"].append(entry["removebg_image"])
|
64 |
+
dataset_dict["original_filename"].append(filename)
|
|
|
65 |
|
66 |
+
# Save the data dictionary to a CSV file for inspection
|
67 |
+
df = pd.DataFrame.from_dict(dataset_dict)
|
68 |
+
df.to_csv("image_data.csv", index=False)
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
+
# Create a Dataset
|
71 |
+
dataset = Dataset.from_dict(dataset_dict, features=features)
|
|
|
72 |
|
73 |
+
# Push the dataset to Hugging Face Hub
|
74 |
+
api = HfApi()
|
75 |
+
dataset.push_to_hub(dataset_name, token=api.token)
|
76 |
|
77 |
+
if __name__ == "__main__":
|
78 |
+
parser = argparse.ArgumentParser(description="Upload images to a Hugging Face dataset.")
|
79 |
+
parser.add_argument("image_dir", type=str, help="Directory containing the images.")
|
80 |
+
parser.add_argument("dataset_name", type=str, help="Name of the dataset to upload to Hugging Face Hub.")
|
81 |
+
|
82 |
+
args = parser.parse_args()
|
83 |
+
|
84 |
+
upload_to_dataset(args.image_dir, args.dataset_name)
|