asimfayaz commited on
Commit
de0b133
·
1 Parent(s): c9cfa1e

Fixed OpenMP Fork Errors and OpenCV Resize Error

Browse files
gradio_app.py CHANGED
@@ -4,6 +4,12 @@ os.environ["OMP_NUM_THREADS"] = "1" # Limit OpenMP to single thread
4
  os.environ["PYTHONFAULTHANDLER"] = "1" # Better error reporting
5
  os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # Avoid Intel MKL errors
6
  os.environ["OMP_THREAD_LIMIT"] = "1" # Limit total number of OpenMP threads
 
 
 
 
 
 
7
 
8
  # Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
9
  # except for the third-party components listed below.
 
4
  os.environ["PYTHONFAULTHANDLER"] = "1" # Better error reporting
5
  os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # Avoid Intel MKL errors
6
  os.environ["OMP_THREAD_LIMIT"] = "1" # Limit total number of OpenMP threads
7
+ os.environ["MKL_NUM_THREADS"] = "1" # Intel MKL threading
8
+ os.environ["NUMEXPR_NUM_THREADS"] = "1" # NumExpr threading
9
+ os.environ["OPENBLAS_NUM_THREADS"] = "1" # OpenBLAS threading
10
+ os.environ["VECLIB_MAXIMUM_THREADS"] = "1" # Apple vecLib threading
11
+ os.environ["OMP_DISPLAY_ENV"] = "FALSE" # Suppress OpenMP environment display
12
+ os.environ["KMP_WARNINGS"] = "FALSE" # Suppress KMP warnings
13
 
14
  # Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
15
  # except for the third-party components listed below.
hy3dshape/hy3dshape/preprocessors.py CHANGED
@@ -88,17 +88,54 @@ class ImageProcessorV2:
88
  return result, mask
89
 
90
  def load_image(self, image, border_ratio=0.15, to_tensor=True):
 
91
  if isinstance(image, str):
 
92
  image = cv2.imread(image, cv2.IMREAD_UNCHANGED)
 
 
93
  image, mask = self.recenter(image, border_ratio=border_ratio)
94
  image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
95
  elif isinstance(image, Image.Image):
 
96
  image = image.convert("RGBA")
97
  image = np.asarray(image)
98
  image, mask = self.recenter(image, border_ratio=border_ratio)
99
-
100
- image = cv2.resize(image, (self.size, self.size), interpolation=cv2.INTER_CUBIC)
101
- mask = cv2.resize(mask, (self.size, self.size), interpolation=cv2.INTER_NEAREST)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  mask = mask[..., np.newaxis]
103
 
104
  if to_tensor:
 
88
  return result, mask
89
 
90
  def load_image(self, image, border_ratio=0.15, to_tensor=True):
91
+ # Handle different input types
92
  if isinstance(image, str):
93
+ # Load from file path
94
  image = cv2.imread(image, cv2.IMREAD_UNCHANGED)
95
+ if image is None:
96
+ raise ValueError(f"Could not load image from path: {image}")
97
  image, mask = self.recenter(image, border_ratio=border_ratio)
98
  image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
99
  elif isinstance(image, Image.Image):
100
+ # Convert PIL Image to numpy array
101
  image = image.convert("RGBA")
102
  image = np.asarray(image)
103
  image, mask = self.recenter(image, border_ratio=border_ratio)
104
+ elif isinstance(image, np.ndarray):
105
+ # Handle numpy array input
106
+ if image.size == 0:
107
+ raise ValueError("Input image array is empty")
108
+ image, mask = self.recenter(image, border_ratio=border_ratio)
109
+ else:
110
+ # Handle any other type by trying to convert to numpy array
111
+ try:
112
+ if hasattr(image, 'convert'):
113
+ # Assume it's a PIL-like image
114
+ image = image.convert("RGBA")
115
+ image = np.asarray(image)
116
+ else:
117
+ # Try direct conversion to numpy array
118
+ image = np.asarray(image)
119
+
120
+ if image.size == 0:
121
+ raise ValueError("Converted image array is empty")
122
+ image, mask = self.recenter(image, border_ratio=border_ratio)
123
+ except Exception as e:
124
+ raise ValueError(f"Could not process image input of type {type(image)}: {e}")
125
+
126
+ # Validate that we have valid arrays before resizing
127
+ if not isinstance(image, np.ndarray) or image.size == 0:
128
+ raise ValueError("Image processing failed - invalid image array")
129
+ if not isinstance(mask, np.ndarray) or mask.size == 0:
130
+ raise ValueError("Image processing failed - invalid mask array")
131
+
132
+ # Resize with error handling
133
+ try:
134
+ image = cv2.resize(image, (self.size, self.size), interpolation=cv2.INTER_CUBIC)
135
+ mask = cv2.resize(mask, (self.size, self.size), interpolation=cv2.INTER_NEAREST)
136
+ except cv2.error as e:
137
+ raise ValueError(f"OpenCV resize failed: {e}. Image shape: {image.shape if hasattr(image, 'shape') else 'unknown'}, Mask shape: {mask.shape if hasattr(mask, 'shape') else 'unknown'}")
138
+
139
  mask = mask[..., np.newaxis]
140
 
141
  if to_tensor:
hy3dshape/hy3dshape/rembg.py CHANGED
@@ -73,40 +73,78 @@ class BackgroundRemover():
73
  def __init__(self):
74
  # Set multiprocessing start method to 'spawn' to avoid OpenMP fork issues
75
  # Only set if not already set
76
- if multiprocessing.get_start_method(allow_none=True) != 'spawn':
 
77
  try:
78
  multiprocessing.set_start_method('spawn', force=True)
79
- except RuntimeError:
 
80
  # If already set and not 'spawn', we'll have to work with what we have
81
- print("Warning: Could not set multiprocessing start method to 'spawn'")
 
82
 
83
  # We don't initialize the session here anymore as it will be created in the subprocess
84
  self.session = None
 
85
 
86
  def __call__(self, image: Image.Image):
 
 
 
 
 
 
 
 
 
 
 
 
87
  try:
 
 
 
 
88
  # Convert image to bytes for passing to subprocess
89
  img_bytes = io.BytesIO()
90
  image.save(img_bytes, format='PNG')
91
  img_bytes = img_bytes.getvalue()
92
 
93
  # Create a process context
94
- ctx = multiprocessing.get_context('spawn')
 
 
 
 
95
 
96
  # Try with alpha matting first (high quality)
97
- with ctx.Pool(processes=1) as pool:
98
- result = pool.apply(_remove_bg_in_process, args=(img_bytes, True))
99
-
100
- if result is not None:
101
- return Image.open(io.BytesIO(result))
 
 
 
 
 
 
 
102
 
103
  # If alpha matting fails, try without it
104
  print("Alpha matting failed, falling back to standard background removal")
105
- with ctx.Pool(processes=1) as pool:
106
- result = pool.apply(_remove_bg_in_process, args=(img_bytes, False))
107
-
108
- if result is not None:
109
- return Image.open(io.BytesIO(result))
 
 
 
 
 
 
 
110
 
111
  # If all else fails, return the original image
112
  print("Background removal completely failed, returning original image")
 
73
  def __init__(self):
74
  # Set multiprocessing start method to 'spawn' to avoid OpenMP fork issues
75
  # Only set if not already set
76
+ current_method = multiprocessing.get_start_method(allow_none=True)
77
+ if current_method != 'spawn':
78
  try:
79
  multiprocessing.set_start_method('spawn', force=True)
80
+ print(f"Set multiprocessing start method to 'spawn' (was: {current_method})")
81
+ except RuntimeError as e:
82
  # If already set and not 'spawn', we'll have to work with what we have
83
+ print(f"Warning: Could not set multiprocessing start method to 'spawn': {e}")
84
+ print(f"Current method: {multiprocessing.get_start_method()}")
85
 
86
  # We don't initialize the session here anymore as it will be created in the subprocess
87
  self.session = None
88
+ self.max_retries = 2 # Maximum number of retries for background removal
89
 
90
  def __call__(self, image: Image.Image):
91
+ if not isinstance(image, Image.Image):
92
+ print(f"Warning: Expected PIL Image, got {type(image)}. Attempting conversion...")
93
+ try:
94
+ if hasattr(image, 'convert'):
95
+ image = image.convert('RGBA')
96
+ else:
97
+ # Try to create PIL Image from input
98
+ image = Image.fromarray(np.asarray(image))
99
+ except Exception as e:
100
+ print(f"Could not convert input to PIL Image: {e}")
101
+ return image
102
+
103
  try:
104
+ # Ensure image is in RGBA mode
105
+ if image.mode != 'RGBA':
106
+ image = image.convert('RGBA')
107
+
108
  # Convert image to bytes for passing to subprocess
109
  img_bytes = io.BytesIO()
110
  image.save(img_bytes, format='PNG')
111
  img_bytes = img_bytes.getvalue()
112
 
113
  # Create a process context
114
+ try:
115
+ ctx = multiprocessing.get_context('spawn')
116
+ except RuntimeError:
117
+ # Fallback to default context if spawn is not available
118
+ ctx = multiprocessing
119
 
120
  # Try with alpha matting first (high quality)
121
+ for attempt in range(self.max_retries):
122
+ try:
123
+ with ctx.Pool(processes=1) as pool:
124
+ result = pool.apply(_remove_bg_in_process, args=(img_bytes, True))
125
+
126
+ if result is not None:
127
+ return Image.open(io.BytesIO(result))
128
+ break # Exit retry loop if we got a result (even if None)
129
+ except Exception as e:
130
+ print(f"Alpha matting attempt {attempt + 1} failed: {e}")
131
+ if attempt == self.max_retries - 1:
132
+ break
133
 
134
  # If alpha matting fails, try without it
135
  print("Alpha matting failed, falling back to standard background removal")
136
+ for attempt in range(self.max_retries):
137
+ try:
138
+ with ctx.Pool(processes=1) as pool:
139
+ result = pool.apply(_remove_bg_in_process, args=(img_bytes, False))
140
+
141
+ if result is not None:
142
+ return Image.open(io.BytesIO(result))
143
+ break # Exit retry loop if we got a result (even if None)
144
+ except Exception as e:
145
+ print(f"Standard background removal attempt {attempt + 1} failed: {e}")
146
+ if attempt == self.max_retries - 1:
147
+ break
148
 
149
  # If all else fails, return the original image
150
  print("Background removal completely failed, returning original image")