mac9087 commited on
Commit
8f1ba82
·
verified ·
1 Parent(s): 60b2de7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -37
app.py CHANGED
@@ -14,17 +14,7 @@ from huggingface_hub import snapshot_download
14
  from flask_cors import CORS
15
  import numpy as np
16
  import trimesh
17
- import sys
18
-
19
- # Add SF3D code to sys.path
20
- sys.path.append('/app/stable-fast-3d')
21
-
22
- # Import SF3D components (adjust based on actual module structure)
23
- try:
24
- from sf3d.system import SF3D
25
- except ImportError as e:
26
- print(f"Failed to import SF3D: {e}")
27
- raise
28
 
29
  # Force CPU usage
30
  os.environ["CUDA_VISIBLE_DEVICES"] = ""
@@ -59,13 +49,13 @@ app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
59
  processing_jobs = {}
60
 
61
  # Global model variables
62
- sf3d_model = None
63
  model_loaded = False
64
  model_loading = False
65
 
66
  # Configuration for processing
67
- TIMEOUT_SECONDS = 240 # 4 minutes max for SF3D on CPU
68
- MAX_DIMENSION = 512 # SF3D expects 512x512
69
 
70
  # TimeoutError for handling timeouts
71
  class TimeoutError(Exception):
@@ -104,30 +94,30 @@ def process_with_timeout(function, args, timeout):
104
  def allowed_file(filename):
105
  return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
106
 
107
- # Image preprocessing for SF3D (512x512, no background removal)
108
  def preprocess_image(image_path):
109
  with Image.open(image_path) as img:
110
  img = img.convert("RGB")
111
- # SF3D requires 512x512
112
  img = img.resize((512, 512), Image.LANCZOS)
113
  return img
114
 
115
  def load_model():
116
- global sf3d_model, model_loaded, model_loading
117
 
118
  if model_loaded:
119
- return sf3d_model
120
 
121
  if model_loading:
122
  while model_loading and not model_loaded:
123
  time.sleep(0.5)
124
- return sf3d_model
125
 
126
  try:
127
  model_loading = True
128
  print("Starting model loading...")
129
 
130
- model_name = "stabilityai/stable-fast-3d"
131
 
132
  # Download model with retry mechanism
133
  max_retries = 3
@@ -148,8 +138,8 @@ def load_model():
148
  else:
149
  raise
150
 
151
- # Load SF3D model
152
- sf3d_model = SF3D.from_pretrained(
153
  model_name,
154
  cache_dir=CACHE_DIR,
155
  torch_dtype=torch.float16,
@@ -158,7 +148,7 @@ def load_model():
158
 
159
  model_loaded = True
160
  print("Model loaded successfully on CPU")
161
- return sf3d_model
162
 
163
  except Exception as e:
164
  print(f"Error loading model: {str(e)}")
@@ -171,7 +161,7 @@ def load_model():
171
  def health_check():
172
  return jsonify({
173
  "status": "healthy",
174
- "model": "Stable Fast 3D (SF3D)",
175
  "device": "cpu"
176
  }), 200
177
 
@@ -259,7 +249,7 @@ def convert_image_to_3d():
259
  processing_jobs[job_id]['progress'] = 10
260
 
261
  try:
262
- model = load_model()
263
  processing_jobs[job_id]['progress'] = 30
264
  except Exception as e:
265
  processing_jobs[job_id]['status'] = 'error'
@@ -269,19 +259,22 @@ def convert_image_to_3d():
269
  try:
270
  def generate_3d():
271
  # Adjust settings based on detail level
272
- texture_sizes = {'low': 512, 'medium': 1024, 'high': 2048}
273
- remesh_options = {'low': 0.5, 'medium': 1.0, 'high': 2.0}
274
 
275
- # Convert image to numpy (no background removal)
276
- img_array = np.array(image)
 
277
 
278
- # Generate mesh
279
- mesh = model(
280
- image=img_array,
281
- texture_size=texture_sizes[detail_level],
282
- remesh_option=remesh_options[detail_level],
283
  seed=12345
284
  )
 
 
 
285
  return mesh
286
 
287
  mesh, error = process_with_timeout(generate_3d, [], TIMEOUT_SECONDS)
@@ -420,7 +413,7 @@ def model_info(job_id):
420
  @app.route('/', methods=['GET'])
421
  def index():
422
  return jsonify({
423
- "message": "Image to 3D API (Stable Fast 3D)",
424
  "endpoints": [
425
  "/convert",
426
  "/progress/<job_id>",
@@ -430,9 +423,9 @@ def index():
430
  ],
431
  "parameters": {
432
  "output_format": "glb",
433
- "detail_level": "low, medium, or high - controls texture and mesh detail"
434
  },
435
- "description": "This API creates full 3D models from 2D images using Stable Fast 3D. Images should have transparent backgrounds."
436
  }), 200
437
 
438
  if __name__ == '__main__':
 
14
  from flask_cors import CORS
15
  import numpy as np
16
  import trimesh
17
+ from diffusers import DiffusionPipeline
 
 
 
 
 
 
 
 
 
 
18
 
19
  # Force CPU usage
20
  os.environ["CUDA_VISIBLE_DEVICES"] = ""
 
49
  processing_jobs = {}
50
 
51
  # Global model variables
52
+ zero123plus_pipeline = None
53
  model_loaded = False
54
  model_loading = False
55
 
56
  # Configuration for processing
57
+ TIMEOUT_SECONDS = 240 # 4 minutes max for Zero123++ on CPU
58
+ MAX_DIMENSION = 512 # Zero123++ expects 512x512
59
 
60
  # TimeoutError for handling timeouts
61
  class TimeoutError(Exception):
 
94
  def allowed_file(filename):
95
  return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
96
 
97
+ # Image preprocessing for Zero123++ (512x512, no background removal)
98
  def preprocess_image(image_path):
99
  with Image.open(image_path) as img:
100
  img = img.convert("RGB")
101
+ # Zero123++ requires 512x512
102
  img = img.resize((512, 512), Image.LANCZOS)
103
  return img
104
 
105
  def load_model():
106
+ global zero123plus_pipeline, model_loaded, model_loading
107
 
108
  if model_loaded:
109
+ return zero123plus_pipeline
110
 
111
  if model_loading:
112
  while model_loading and not model_loaded:
113
  time.sleep(0.5)
114
+ return zero123plus_pipeline
115
 
116
  try:
117
  model_loading = True
118
  print("Starting model loading...")
119
 
120
+ model_name = "sudo-ai/zero123plus-v1.2"
121
 
122
  # Download model with retry mechanism
123
  max_retries = 3
 
138
  else:
139
  raise
140
 
141
+ # Load Zero123++ pipeline
142
+ zero123plus_pipeline = DiffusionPipeline.from_pretrained(
143
  model_name,
144
  cache_dir=CACHE_DIR,
145
  torch_dtype=torch.float16,
 
148
 
149
  model_loaded = True
150
  print("Model loaded successfully on CPU")
151
+ return zero123plus_pipeline
152
 
153
  except Exception as e:
154
  print(f"Error loading model: {str(e)}")
 
161
  def health_check():
162
  return jsonify({
163
  "status": "healthy",
164
+ "model": "Zero123++",
165
  "device": "cpu"
166
  }), 200
167
 
 
249
  processing_jobs[job_id]['progress'] = 10
250
 
251
  try:
252
+ pipeline = load_model()
253
  processing_jobs[job_id]['progress'] = 30
254
  except Exception as e:
255
  processing_jobs[job_id]['status'] = 'error'
 
259
  try:
260
  def generate_3d():
261
  # Adjust settings based on detail level
262
+ num_steps = {'low': 20, 'medium': 50, 'high': 75}
 
263
 
264
+ # Convert image to tensor
265
+ img_array = np.array(image) / 255.0
266
+ img_tensor = torch.from_numpy(img_array).permute(2, 0, 1).float()
267
 
268
+ # Generate multi-view images and reconstruct mesh
269
+ pipeline_output = pipeline(
270
+ img_tensor.unsqueeze(0),
271
+ num_inference_steps=num_steps[detail_level],
272
+ guidance_scale=7.5,
273
  seed=12345
274
  )
275
+
276
+ # Extract mesh (Zero123++ outputs mesh directly)
277
+ mesh = pipeline_output.meshes[0]
278
  return mesh
279
 
280
  mesh, error = process_with_timeout(generate_3d, [], TIMEOUT_SECONDS)
 
413
  @app.route('/', methods=['GET'])
414
  def index():
415
  return jsonify({
416
+ "message": "Image to 3D API (Zero123++)",
417
  "endpoints": [
418
  "/convert",
419
  "/progress/<job_id>",
 
423
  ],
424
  "parameters": {
425
  "output_format": "glb",
426
+ "detail_level": "low, medium, or high - controls inference steps"
427
  },
428
+ "description": "This API creates full 3D models from 2D images using Zero123++. Images should have transparent backgrounds."
429
  }), 200
430
 
431
  if __name__ == '__main__':