mac9087 commited on
Commit
de67259
·
verified ·
1 Parent(s): 6c9e0d6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -13
app.py CHANGED
@@ -17,6 +17,8 @@ import trimesh
17
  from transformers import pipeline
18
  from scipy.ndimage import gaussian_filter
19
  import open3d as o3d
 
 
20
 
21
  # Force CPU usage
22
  os.environ["CUDA_VISIBLE_DEVICES"] = ""
@@ -96,13 +98,28 @@ def process_with_timeout(function, args, timeout):
96
  def allowed_file(filename):
97
  return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
98
 
99
- # Image preprocessing for Depth-Anything (512x512, no background removal)
100
  def preprocess_image(image_path):
101
- with Image.open(image_path) as img:
102
- img = img.convert("RGB")
103
- # Depth-Anything requires 512x512
104
- img = img.resize((512, 512), Image.LANCZOS)
105
- return img
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
  def load_model():
108
  global depth_pipeline, model_loaded, model_loading
@@ -182,20 +199,20 @@ def depth_to_point_cloud(depth_map, image, detail_level):
182
  h, w = depth_array.shape
183
  x, y = np.meshgrid(np.arange(w), np.arange(h))
184
 
185
- # Simple camera intrinsics (assumed focal length)
186
  fx = fy = w * 0.5
187
  cx, cy = w / 2, h / 2
188
 
189
- # Convert to 3D coordinates
190
  z = depth_array
191
  x = (x - cx) * z / fx
192
- y = (y - cy) * z / fy
193
 
194
  points = np.stack([x, y, z], axis=-1).reshape(-1, 3)
195
  colors = img_array.reshape(-1, 3) / 255.0
196
 
197
- # Filter out invalid points (e.g., background)
198
- mask = (z.reshape(-1) > 0.1) & (z.reshape(-1) < 0.9)
199
  points = points[mask]
200
  colors = colors[mask]
201
 
@@ -223,6 +240,9 @@ def depth_to_point_cloud(depth_map, image, detail_level):
223
  vertex_colors=vertex_colors
224
  )
225
 
 
 
 
226
  return trimesh_mesh
227
 
228
  @app.route('/health', methods=['GET'])
@@ -297,7 +317,8 @@ def convert_image_to_3d():
297
  filepath = os.path.join(app.config['UPLOAD_FOLDER'], f"{job_id}_{filename}")
298
  file.save(filepath)
299
 
300
- processing_jobs[job_id] = {
 
301
  'status': 'processing',
302
  'progress': 0,
303
  'result_url': None,
@@ -484,7 +505,7 @@ def index():
484
  "output_format": "glb",
485
  "detail_level": "low, medium, or high - controls point cloud density"
486
  },
487
- "description": "This API creates 3D models from 2D images using Depth-Anything depth estimation. Images should have transparent backgrounds."
488
  }), 200
489
 
490
  if __name__ == '__main__':
 
17
  from transformers import pipeline
18
  from scipy.ndimage import gaussian_filter
19
  import open3d as o3d
20
+ from rembg import remove
21
+ import cv2
22
 
23
  # Force CPU usage
24
  os.environ["CUDA_VISIBLE_DEVICES"] = ""
 
98
  def allowed_file(filename):
99
  return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
100
 
101
+ # Image preprocessing: Remove background and resize
102
  def preprocess_image(image_path):
103
+ try:
104
+ # Load image
105
+ with Image.open(image_path) as img:
106
+ # Remove background using rembg
107
+ img_no_bg = remove(img)
108
+ # Convert to RGB if it has an alpha channel
109
+ if img_no_bg.mode == 'RGBA':
110
+ img_no_bg = img_no_bg.convert('RGB')
111
+ # Resize to 512x512
112
+ img_no_bg = img_no_bg.resize((512, 512), Image.LANCZOS)
113
+
114
+ # Optional: Use cv2 for additional segmentation (e.g., refine mask)
115
+ img_array = np.array(img_no_bg)
116
+ gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
117
+ _, mask = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
118
+ img_array = cv2.bitwise_and(img_array, img_array, mask=mask)
119
+
120
+ return Image.fromarray(img_array)
121
+ except Exception as e:
122
+ raise Exception(f"Error preprocessing image: {str(e)}")
123
 
124
  def load_model():
125
  global depth_pipeline, model_loaded, model_loading
 
199
  h, w = depth_array.shape
200
  x, y = np.meshgrid(np.arange(w), np.arange(h))
201
 
202
+ # Camera intrinsics (assumed focal length)
203
  fx = fy = w * 0.5
204
  cx, cy = w / 2, h / 2
205
 
206
+ # Convert to 3D coordinates (Z-up for Unity)
207
  z = depth_array
208
  x = (x - cx) * z / fx
209
+ y = -(y - cy) * z / fy # Flip y-axis to correct orientation
210
 
211
  points = np.stack([x, y, z], axis=-1).reshape(-1, 3)
212
  colors = img_array.reshape(-1, 3) / 255.0
213
 
214
+ # Filter out invalid points (tighter range for foreground)
215
+ mask = (z.reshape(-1) > 0.2) & (z.reshape(-1) < 0.8)
216
  points = points[mask]
217
  colors = colors[mask]
218
 
 
240
  vertex_colors=vertex_colors
241
  )
242
 
243
+ # Rotate mesh to correct orientation (180 degrees around X-axis)
244
+ trimesh_mesh.apply_transform(trimesh.transformations.rotation_matrix(np.pi, [1, 0, 0]))
245
+
246
  return trimesh_mesh
247
 
248
  @app.route('/health', methods=['GET'])
 
317
  filepath = os.path.join(app.config['UPLOAD_FOLDER'], f"{job_id}_{filename}")
318
  file.save(filepath)
319
 
320
+ processing_jobs[job_id] =*.
321
+ {
322
  'status': 'processing',
323
  'progress': 0,
324
  'result_url': None,
 
505
  "output_format": "glb",
506
  "detail_level": "low, medium, or high - controls point cloud density"
507
  },
508
+ "description": "This API creates 3D models from 2D images using Depth-Anything depth estimation. Images should have transparent backgrounds for best results."
509
  }), 200
510
 
511
  if __name__ == '__main__':