Zeph27 commited on
Commit
0ca9ccb
·
1 Parent(s): 4ff6ab7

add bria for remove background model

Browse files
Files changed (3) hide show
  1. .gitignore +1 -0
  2. app.py +75 -43
  3. requirements.txt +8 -1
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ venv/
app.py CHANGED
@@ -6,8 +6,10 @@ import io
6
  from rembg import remove
7
  import gradio as gr
8
  from concurrent.futures import ThreadPoolExecutor
 
9
 
10
  def resize_and_crop_image(image_path, target_size=(1080, 1080), crop_mode='center'):
 
11
  with Image.open(image_path) as img:
12
  width, height = img.size
13
 
@@ -42,69 +44,81 @@ def resize_and_crop_image(image_path, target_size=(1080, 1080), crop_mode='cente
42
 
43
  return cropped_img
44
 
45
- def remove_background(input_path):
 
46
  with open(input_path, 'rb') as i:
47
  input_image = i.read()
48
  output_image = remove(input_image)
49
  img = Image.open(io.BytesIO(output_image)).convert("RGBA")
50
  return img
51
 
52
- def process_single_image(image_path, output_folder, crop_mode, remove_bg, output_format, bg_choice, watermark_path=None):
 
 
 
 
 
 
53
  filename = os.path.basename(image_path)
54
  try:
 
55
  if remove_bg == 'yes':
56
- # Remove background
57
- image_with_no_bg = remove_background(image_path)
 
 
 
 
 
58
  temp_image_path = os.path.join(output_folder, f"temp_{filename}")
59
  image_with_no_bg.save(temp_image_path, format='PNG')
 
60
  else:
61
  temp_image_path = image_path
62
 
63
  # Resize and crop the image with or without background removal
64
  new_image = resize_and_crop_image(temp_image_path, crop_mode=crop_mode)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
- # Apply watermark if provided
67
  if watermark_path:
68
  watermark = Image.open(watermark_path).convert("RGBA")
69
- new_image.paste(watermark, (0, 0), watermark)
70
-
71
- # Save the final image
72
- if remove_bg == 'yes' and output_format == 'PNG' and bg_choice == 'transparent':
73
- output_path = os.path.join(output_folder, f"{os.path.splitext(filename)[0]}.png")
74
- new_image.save(output_path, format='PNG')
75
- elif remove_bg == 'yes' and output_format == 'PNG' and bg_choice == 'white':
76
- # Create a white background
77
- background = Image.new("RGBA", new_image.size, (255, 255, 255, 255))
78
- # Paste the image with no background onto the white background
79
- background.paste(new_image, mask=new_image.split()[3]) # 3 is the alpha channel
80
- output_path = os.path.join(output_folder, f"{os.path.splitext(filename)[0]}.png")
81
- background.convert('RGB').save(output_path, format='PNG')
82
- elif remove_bg == 'yes' and output_format == 'JPG':
83
- # Create a white background
84
- background = Image.new("RGB", new_image.size, (255, 255, 255))
85
- # Paste the image with no background onto the white background
86
- background.paste(new_image, mask=new_image.split()[3]) # 3 is the alpha channel
87
- output_path = os.path.join(output_folder, f"{os.path.splitext(filename)[0]}.jpg")
88
- background.save(output_path, format='JPEG')
89
- else:
90
- output_ext = 'jpg' if output_format == 'JPG' else 'png'
91
- output_path = os.path.join(output_folder, f"{os.path.splitext(filename)[0]}.{output_ext}")
92
  if output_format == 'JPG':
93
- new_image.convert('RGB').save(output_path, format='JPEG')
94
  else:
95
- new_image.save(output_path, format='PNG')
 
 
96
 
97
  if remove_bg == 'yes':
98
  # Remove the temporary file
99
  os.remove(temp_image_path)
 
100
 
101
- return output_path
102
 
103
  except Exception as e:
104
  print(f"Error processing {filename}: {e}")
105
  return None
106
 
107
- def process_images(zip_file, crop_mode='center', remove_bg='yes', watermark_path=None, output_format='PNG', bg_choice='transparent', progress=gr.Progress()):
 
108
  # Create a temporary directory
109
  input_folder = "temp_input"
110
  output_folder = "temp_output"
@@ -116,42 +130,55 @@ def process_images(zip_file, crop_mode='center', remove_bg='yes', watermark_path
116
  os.makedirs(output_folder)
117
 
118
  # Extract the zip file
 
119
  with zipfile.ZipFile(zip_file, 'r') as zip_ref:
120
  zip_ref.extractall(input_folder)
121
 
122
  processed_images = []
123
  image_files = [os.path.join(input_folder, f) for f in os.listdir(input_folder) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))]
124
  total_images = len(image_files)
 
125
 
126
  # Process images using ThreadPoolExecutor
127
  with ThreadPoolExecutor(max_workers=2) as executor:
128
- future_to_image = {executor.submit(process_single_image, image_path, output_folder, crop_mode, remove_bg, output_format, bg_choice, watermark_path): image_path for image_path in image_files}
129
  for idx, future in enumerate(future_to_image):
130
  result = future.result()
131
  if result:
132
- processed_images.append(result)
133
  # Update progress
134
  progress((idx + 1) / total_images, f"{idx + 1}/{total_images} images processed")
135
-
 
136
  # Create a zip file of the processed images
137
  output_zip_path = "processed_images.zip"
138
  with zipfile.ZipFile(output_zip_path, 'w') as zipf:
139
  for file in processed_images:
140
- zipf.write(file, os.path.basename(file))
141
-
 
 
 
 
142
  # Return the images and the zip file path
143
  return processed_images, output_zip_path
144
 
145
- def gradio_interface(zip_file, crop_mode, remove_bg, watermark, output_format, bg_choice):
 
146
  progress = gr.Progress() # Initialize progress
147
  watermark_path = watermark.name if watermark else None
148
- return process_images(zip_file.name, crop_mode, remove_bg, watermark_path, output_format, bg_choice, progress)
149
 
150
  def show_bg_choice(remove_bg, output_format):
151
  if remove_bg == 'yes' and output_format == 'PNG':
152
  return gr.update(visible=True)
153
  return gr.update(visible=False)
154
 
 
 
 
 
 
155
  # Create the Gradio interface
156
  with gr.Blocks() as iface:
157
  gr.Markdown("# Image Background Removal and Resizing with Optional Watermark")
@@ -164,21 +191,26 @@ with gr.Blocks() as iface:
164
  with gr.Row():
165
  crop_mode = gr.Radio(choices=["center", "top", "bottom", "left", "right"], label="Crop Mode", value="center")
166
  remove_bg = gr.Radio(choices=["yes", "no"], label="Remove Background", value="yes")
167
- output_format = gr.Radio(choices=["PNG", "JPG"], label="Output Format", value="PNG")
 
 
 
 
168
  bg_choice = gr.Radio(choices=["transparent", "white"], label="Background Choice", value="transparent", visible=True)
169
 
170
  remove_bg.change(show_bg_choice, inputs=[remove_bg, output_format], outputs=bg_choice)
 
171
  output_format.change(show_bg_choice, inputs=[remove_bg, output_format], outputs=bg_choice)
172
 
173
  gallery = gr.Gallery(label="Processed Images")
174
  output_zip = gr.File(label="Download Processed Images as ZIP")
175
 
176
- def process(zip_file, crop_mode, remove_bg, watermark, output_format, bg_choice):
177
- processed_images, zip_path = gradio_interface(zip_file, crop_mode, remove_bg, watermark, output_format, bg_choice)
178
  return processed_images, zip_path
179
 
180
  process_button = gr.Button("Process Images")
181
- process_button.click(process, inputs=[zip_file, crop_mode, remove_bg, watermark, output_format, bg_choice], outputs=[gallery, output_zip])
182
 
183
  # Launch the interface
184
  iface.launch()
 
6
  from rembg import remove
7
  import gradio as gr
8
  from concurrent.futures import ThreadPoolExecutor
9
+ from transformers import pipeline
10
 
11
  def resize_and_crop_image(image_path, target_size=(1080, 1080), crop_mode='center'):
12
+ print(f"Resizing and cropping image: {image_path}")
13
  with Image.open(image_path) as img:
14
  width, height = img.size
15
 
 
44
 
45
  return cropped_img
46
 
47
+ def remove_background_rembg(input_path):
48
+ print(f"Removing background using rembg: {input_path}")
49
  with open(input_path, 'rb') as i:
50
  input_image = i.read()
51
  output_image = remove(input_image)
52
  img = Image.open(io.BytesIO(output_image)).convert("RGBA")
53
  return img
54
 
55
+ def remove_background_bria(input_path):
56
+ print(f"Removing background using bria: {input_path}")
57
+ pipe = pipeline("image-segmentation", model="briaai/RMBG-1.4", trust_remote_code=True)
58
+ pillow_image = pipe(input_path) # applies mask on input and returns a pillow image
59
+ return pillow_image
60
+
61
+ def process_single_image(image_path, output_folder, crop_mode, remove_bg, bg_method, output_format, bg_choice, watermark_path=None):
62
  filename = os.path.basename(image_path)
63
  try:
64
+ print(f"Processing image: {filename}")
65
  if remove_bg == 'yes':
66
+ if bg_method == 'rembg':
67
+ # Remove background using rembg
68
+ image_with_no_bg = remove_background_rembg(image_path)
69
+ elif bg_method == 'bria':
70
+ # Remove background using bria
71
+ image_with_no_bg = remove_background_bria(image_path)
72
+
73
  temp_image_path = os.path.join(output_folder, f"temp_{filename}")
74
  image_with_no_bg.save(temp_image_path, format='PNG')
75
+ print(f"Background removed and saved temporary image: {temp_image_path}")
76
  else:
77
  temp_image_path = image_path
78
 
79
  # Resize and crop the image with or without background removal
80
  new_image = resize_and_crop_image(temp_image_path, crop_mode=crop_mode)
81
+ print(f"Resized and cropped image: {temp_image_path}")
82
+
83
+ # Save both versions of the image (with and without watermark)
84
+ images_paths = []
85
+
86
+ # Save without watermark
87
+ output_ext = 'jpg' if output_format == 'JPG' else 'png'
88
+ output_path_without_watermark = os.path.join(output_folder, f"without_watermark_{os.path.splitext(filename)[0]}.{output_ext}")
89
+ if output_format == 'JPG':
90
+ new_image.convert('RGB').save(output_path_without_watermark, format='JPEG')
91
+ else:
92
+ new_image.save(output_path_without_watermark, format='PNG')
93
+ images_paths.append(output_path_without_watermark)
94
+ print(f"Saved final image without watermark: {output_path_without_watermark}")
95
 
96
+ # Apply watermark if provided and save the version with watermark
97
  if watermark_path:
98
  watermark = Image.open(watermark_path).convert("RGBA")
99
+ new_image_with_watermark = new_image.copy()
100
+ new_image_with_watermark.paste(watermark, (0, 0), watermark)
101
+ output_path_with_watermark = os.path.join(output_folder, f"with_watermark_{os.path.splitext(filename)[0]}.{output_ext}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  if output_format == 'JPG':
103
+ new_image_with_watermark.convert('RGB').save(output_path_with_watermark, format='JPEG')
104
  else:
105
+ new_image_with_watermark.save(output_path_with_watermark, format='PNG')
106
+ images_paths.append(output_path_with_watermark)
107
+ print(f"Saved final image with watermark: {output_path_with_watermark}")
108
 
109
  if remove_bg == 'yes':
110
  # Remove the temporary file
111
  os.remove(temp_image_path)
112
+ print(f"Removed temporary file: {temp_image_path}")
113
 
114
+ return images_paths
115
 
116
  except Exception as e:
117
  print(f"Error processing {filename}: {e}")
118
  return None
119
 
120
+ def process_images(zip_file, crop_mode='center', remove_bg='yes', bg_method='rembg', watermark_path=None, output_format='PNG', bg_choice='transparent', progress=gr.Progress()):
121
+ print("Starting to process images...")
122
  # Create a temporary directory
123
  input_folder = "temp_input"
124
  output_folder = "temp_output"
 
130
  os.makedirs(output_folder)
131
 
132
  # Extract the zip file
133
+ print(f"Extracting zip file: {zip_file}")
134
  with zipfile.ZipFile(zip_file, 'r') as zip_ref:
135
  zip_ref.extractall(input_folder)
136
 
137
  processed_images = []
138
  image_files = [os.path.join(input_folder, f) for f in os.listdir(input_folder) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))]
139
  total_images = len(image_files)
140
+ print(f"Found {total_images} images to process.")
141
 
142
  # Process images using ThreadPoolExecutor
143
  with ThreadPoolExecutor(max_workers=2) as executor:
144
+ future_to_image = {executor.submit(process_single_image, image_path, output_folder, crop_mode, remove_bg, bg_method, output_format, bg_choice, watermark_path): image_path for image_path in image_files}
145
  for idx, future in enumerate(future_to_image):
146
  result = future.result()
147
  if result:
148
+ processed_images.extend(result)
149
  # Update progress
150
  progress((idx + 1) / total_images, f"{idx + 1}/{total_images} images processed")
151
+ print(f"Processed {idx + 1}/{total_images} images")
152
+
153
  # Create a zip file of the processed images
154
  output_zip_path = "processed_images.zip"
155
  with zipfile.ZipFile(output_zip_path, 'w') as zipf:
156
  for file in processed_images:
157
+ if "with_watermark" in file:
158
+ zipf.write(file, os.path.join("with_watermark", os.path.basename(file)))
159
+ else:
160
+ zipf.write(file, os.path.join("without_watermark", os.path.basename(file)))
161
+
162
+ print(f"Created zip file of processed images: {output_zip_path}")
163
  # Return the images and the zip file path
164
  return processed_images, output_zip_path
165
 
166
+ def gradio_interface(zip_file, crop_mode, remove_bg, bg_method, watermark, output_format, bg_choice):
167
+ print("Initializing Gradio interface processing...")
168
  progress = gr.Progress() # Initialize progress
169
  watermark_path = watermark.name if watermark else None
170
+ return process_images(zip_file.name, crop_mode, remove_bg, bg_method, watermark_path, output_format, bg_choice, progress)
171
 
172
  def show_bg_choice(remove_bg, output_format):
173
  if remove_bg == 'yes' and output_format == 'PNG':
174
  return gr.update(visible=True)
175
  return gr.update(visible=False)
176
 
177
+ def show_bg_method(remove_bg):
178
+ if remove_bg == 'yes':
179
+ return gr.update(visible=True)
180
+ return gr.update(visible=False)
181
+
182
  # Create the Gradio interface
183
  with gr.Blocks() as iface:
184
  gr.Markdown("# Image Background Removal and Resizing with Optional Watermark")
 
191
  with gr.Row():
192
  crop_mode = gr.Radio(choices=["center", "top", "bottom", "left", "right"], label="Crop Mode", value="center")
193
  remove_bg = gr.Radio(choices=["yes", "no"], label="Remove Background", value="yes")
194
+
195
+ output_format = gr.Radio(choices=["PNG", "JPG"], label="Output Format", value="PNG")
196
+
197
+ with gr.Row():
198
+ bg_method = gr.Radio(choices=["bria", "rembg"], label="Background Removal Method", value="bria", visible=True)
199
  bg_choice = gr.Radio(choices=["transparent", "white"], label="Background Choice", value="transparent", visible=True)
200
 
201
  remove_bg.change(show_bg_choice, inputs=[remove_bg, output_format], outputs=bg_choice)
202
+ remove_bg.change(show_bg_method, inputs=remove_bg, outputs=bg_method)
203
  output_format.change(show_bg_choice, inputs=[remove_bg, output_format], outputs=bg_choice)
204
 
205
  gallery = gr.Gallery(label="Processed Images")
206
  output_zip = gr.File(label="Download Processed Images as ZIP")
207
 
208
+ def process(zip_file, crop_mode, remove_bg, bg_method, watermark, output_format, bg_choice):
209
+ processed_images, zip_path = gradio_interface(zip_file, crop_mode, remove_bg, bg_method, watermark, output_format, bg_choice)
210
  return processed_images, zip_path
211
 
212
  process_button = gr.Button("Process Images")
213
+ process_button.click(process, inputs=[zip_file, crop_mode, remove_bg, bg_method, watermark, output_format, bg_choice], outputs=[gallery, output_zip])
214
 
215
  # Launch the interface
216
  iface.launch()
requirements.txt CHANGED
@@ -1,3 +1,10 @@
1
  gradio==4.37.2
2
- Pillow==10.4.0
3
  rembg==2.0.57
 
 
 
 
 
 
 
 
 
1
  gradio==4.37.2
 
2
  rembg==2.0.57
3
+ torch==2.3.1
4
+ torchvision==0.18.1
5
+ pillow==10.4.0
6
+ numpy==1.26.4
7
+ typing==3.7.4.3
8
+ scikit-image==0.24.0
9
+ huggingface_hub==0.23.4
10
+ transformers==4.42.4