asimfayaz commited on
Commit
5ec9af2
·
1 Parent(s): 39d16fa

Simplify background removal: remove multiprocessing entirely

Browse files

- Alpha matting works perfectly without multiprocessing
- OpenMP conflicts are already handled by environment variables
- Eliminates daemon process compatibility issues completely
- Much simpler, cleaner, and more reliable code
- Direct alpha matting with proper fallback to standard removal

Files changed (1) hide show
  1. hy3dshape/hy3dshape/rembg.py +41 -48
hy3dshape/hy3dshape/rembg.py CHANGED
@@ -14,23 +14,16 @@
14
 
15
  import os
16
  import io
17
- import multiprocessing
18
  import traceback
19
  import numpy as np
20
 
21
- # Set OpenMP environment variables to prevent fork() errors
 
22
  os.environ["OMP_NUM_THREADS"] = "1" # Limit OpenMP to single thread
23
  os.environ["PYTHONFAULTHANDLER"] = "1" # Better error reporting
24
  os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # Avoid Intel MKL errors
25
  os.environ["OMP_THREAD_LIMIT"] = "1" # Limit total number of OpenMP threads
26
 
27
- # Fix daemon process multiprocessing by using spawn instead of fork
28
- try:
29
- multiprocessing.set_start_method('spawn', force=True)
30
- print("Set multiprocessing start method to 'spawn' for daemon compatibility")
31
- except RuntimeError as e:
32
- print(f"Could not set multiprocessing start method: {e}")
33
-
34
  from PIL import Image
35
  from rembg import remove, new_session
36
 
@@ -78,11 +71,10 @@ def _remove_bg_in_process(image_bytes, use_alpha_matting=True):
78
 
79
  class BackgroundRemover():
80
  def __init__(self):
81
- # Initialize background remover with multiprocessing using spawn method
82
- # OpenMP conflicts are handled by environment variables and process isolation
83
- print("Initializing BackgroundRemover with multiprocessing (spawn method)")
84
- self.session = None # Session will be created in subprocess
85
- self.max_retries = 2
86
 
87
  def __call__(self, image: Image.Image):
88
  if not isinstance(image, Image.Image):
@@ -102,44 +94,45 @@ class BackgroundRemover():
102
  if image.mode != 'RGBA':
103
  image = image.convert('RGBA')
104
 
105
- print("Starting background removal with multiprocessing (spawn method)...")
106
-
107
- # Convert image to bytes for passing to subprocess
108
- img_bytes = io.BytesIO()
109
- image.save(img_bytes, format='PNG')
110
- img_bytes = img_bytes.getvalue()
111
 
112
- # Try with alpha matting first (high quality)
113
  print("Attempting alpha matting background removal...")
114
- for attempt in range(self.max_retries):
115
- try:
116
- with multiprocessing.Pool(processes=1) as pool:
117
- result = pool.apply(_remove_bg_in_process, args=(img_bytes, True))
118
-
119
- if result is not None:
120
- print("Alpha matting successful")
121
- return Image.open(io.BytesIO(result))
122
- break # Exit retry loop if we got a result (even if None)
123
- except Exception as e:
124
- print(f"Alpha matting attempt {attempt + 1} failed: {e}")
125
- if attempt == self.max_retries - 1:
126
- break
 
 
 
 
 
127
 
128
- # If alpha matting fails, try without it
129
  print("Alpha matting failed, falling back to standard background removal")
130
- for attempt in range(self.max_retries):
131
- try:
132
- with multiprocessing.Pool(processes=1) as pool:
133
- result = pool.apply(_remove_bg_in_process, args=(img_bytes, False))
134
-
135
- if result is not None:
136
- print("Standard background removal successful")
137
- return Image.open(io.BytesIO(result))
138
- break # Exit retry loop if we got a result (even if None)
139
- except Exception as e:
140
- print(f"Standard background removal attempt {attempt + 1} failed: {e}")
141
- if attempt == self.max_retries - 1:
142
- break
 
143
 
144
  # If all else fails, return the original image
145
  print("Background removal completely failed, returning original image")
 
14
 
15
  import os
16
  import io
 
17
  import traceback
18
  import numpy as np
19
 
20
+ # Set OpenMP environment variables to prevent threading conflicts
21
+ # This allows rembg to run safely in the main thread without multiprocessing
22
  os.environ["OMP_NUM_THREADS"] = "1" # Limit OpenMP to single thread
23
  os.environ["PYTHONFAULTHANDLER"] = "1" # Better error reporting
24
  os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # Avoid Intel MKL errors
25
  os.environ["OMP_THREAD_LIMIT"] = "1" # Limit total number of OpenMP threads
26
 
 
 
 
 
 
 
 
27
  from PIL import Image
28
  from rembg import remove, new_session
29
 
 
71
 
72
  class BackgroundRemover():
73
  def __init__(self):
74
+ # Initialize background remover with direct processing
75
+ # OpenMP conflicts are prevented by environment variables set at module level
76
+ print("Initializing BackgroundRemover with direct processing (no multiprocessing needed)")
77
+ self.session = None # Session will be created per request
 
78
 
79
  def __call__(self, image: Image.Image):
80
  if not isinstance(image, Image.Image):
 
94
  if image.mode != 'RGBA':
95
  image = image.convert('RGBA')
96
 
97
+ print("Starting direct background removal (OpenMP conflicts handled by environment variables)...")
 
 
 
 
 
98
 
99
+ # Try alpha matting first (high quality)
100
  print("Attempting alpha matting background removal...")
101
+ try:
102
+ session = new_session()
103
+ output = remove(
104
+ image,
105
+ session=session,
106
+ bgcolor=[255, 255, 255, 0],
107
+ alpha_matting=True,
108
+ alpha_matting_foreground_threshold=220,
109
+ alpha_matting_background_threshold=5,
110
+ alpha_matting_erode_structure_size=5,
111
+ alpha_matting_base_size=512,
112
+ )
113
+ print("Alpha matting successful!")
114
+ return output
115
+ except Exception as e:
116
+ print(f"Alpha matting failed: {e}")
117
+ import traceback
118
+ traceback.print_exc()
119
 
120
+ # If alpha matting fails, try standard background removal
121
  print("Alpha matting failed, falling back to standard background removal")
122
+ try:
123
+ session = new_session()
124
+ output = remove(
125
+ image,
126
+ session=session,
127
+ bgcolor=[255, 255, 255, 0],
128
+ alpha_matting=False,
129
+ )
130
+ print("Standard background removal successful!")
131
+ return output
132
+ except Exception as e:
133
+ print(f"Standard background removal failed: {e}")
134
+ import traceback
135
+ traceback.print_exc()
136
 
137
  # If all else fails, return the original image
138
  print("Background removal completely failed, returning original image")