area metric calculation error corrected
Browse files
app.py
CHANGED
|
@@ -181,7 +181,44 @@ dpt_processor = None
|
|
| 181 |
# ============================================================================
|
| 182 |
|
| 183 |
def process_image(image, model_choice="GLPN (Recommended)", visualization_type="mesh"):
|
| 184 |
-
"""Main processing pipeline"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
|
| 186 |
if image is None:
|
| 187 |
return None, None, None, "Please upload an image first.", None
|
|
@@ -347,16 +384,31 @@ def process_image(image, model_choice="GLPN (Recommended)", visualization_type="
|
|
| 347 |
'is_edge_manifold': mesh.is_edge_manifold(),
|
| 348 |
'is_vertex_manifold': mesh.is_vertex_manifold(),
|
| 349 |
'is_watertight': mesh.is_watertight(),
|
| 350 |
-
'surface_area': float(mesh.get_surface_area()),
|
| 351 |
}
|
| 352 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 353 |
try:
|
| 354 |
if mesh.is_watertight():
|
| 355 |
-
|
| 356 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
metrics['volume'] = None
|
| 358 |
|
| 359 |
print("Metrics computed!")
|
|
|
|
|
|
|
|
|
|
| 360 |
|
| 361 |
# STEP 9: Create 3D visualization
|
| 362 |
print("Step 9: Creating 3D visualization...")
|
|
@@ -473,17 +525,20 @@ def process_image(image, model_choice="GLPN (Recommended)", visualization_type="
|
|
| 473 |
|
| 474 |
### Point Cloud Statistics
|
| 475 |
- **Initial Points**: {metrics['initial_points']:,}
|
| 476 |
-
- **Outliers Removed**: {metrics['outliers_removed']:,}
|
| 477 |
- **Final Points**: {metrics['final_points']:,}
|
| 478 |
|
| 479 |
### Mesh Quality
|
| 480 |
- **Vertices**: {metrics['vertices']:,}
|
| 481 |
- **Triangles**: {metrics['triangles']:,}
|
| 482 |
-
- **Edge Manifold**: {'β' if metrics['is_edge_manifold'] else 'β'}
|
| 483 |
-
- **Vertex Manifold**: {'β' if metrics['is_vertex_manifold'] else 'β'}
|
| 484 |
-
- **Watertight**: {'β' if metrics['is_watertight'] else 'β'}
|
| 485 |
-
- **Surface Area**: {metrics['surface_area']:.2f}
|
| 486 |
-
- **Volume**: {metrics.get('volume'
|
|
|
|
|
|
|
|
|
|
| 487 |
|
| 488 |
### Files Exported
|
| 489 |
- Point Cloud: PLY format
|
|
@@ -506,11 +561,12 @@ def process_image(image, model_choice="GLPN (Recommended)", visualization_type="
|
|
| 506 |
# GRADIO INTERFACE
|
| 507 |
# ============================================================================
|
| 508 |
|
| 509 |
-
with gr.Blocks(title="3D Reconstruction", theme=gr.themes.Soft()) as demo:
|
| 510 |
|
| 511 |
gr.Markdown("""
|
| 512 |
-
# ποΈ
|
| 513 |
|
|
|
|
| 514 |
|
| 515 |
Upload an image to generate:
|
| 516 |
- High-quality depth maps
|
|
@@ -523,7 +579,7 @@ with gr.Blocks(title="3D Reconstruction", theme=gr.themes.Soft()) as demo:
|
|
| 523 |
with gr.Tabs():
|
| 524 |
|
| 525 |
# ========== RECONSTRUCTION TAB ==========
|
| 526 |
-
with gr.Tab("Reconstruction"):
|
| 527 |
with gr.Row():
|
| 528 |
with gr.Column(scale=1):
|
| 529 |
input_image = gr.Image(type="pil", label="Upload Image")
|
|
@@ -541,7 +597,7 @@ with gr.Blocks(title="3D Reconstruction", theme=gr.themes.Soft()) as demo:
|
|
| 541 |
label="3D Visualization Type"
|
| 542 |
)
|
| 543 |
|
| 544 |
-
reconstruct_btn = gr.Button("Start Reconstruction", variant="primary", size="lg")
|
| 545 |
|
| 546 |
with gr.Column(scale=2):
|
| 547 |
depth_output = gr.Image(label="Depth Map Comparison")
|
|
@@ -659,7 +715,10 @@ with gr.Blocks(title="3D Reconstruction", theme=gr.themes.Soft()) as demo:
|
|
| 659 |
|
| 660 |
**Depth Map Comparison:**
|
| 661 |
- Left: Your original image
|
| 662 |
-
- Right: Estimated depth map
|
|
|
|
|
|
|
|
|
|
| 663 |
|
| 664 |
**Interactive 3D Viewer:**
|
| 665 |
- **Rotate**: Click and drag
|
|
@@ -853,13 +912,18 @@ with gr.Blocks(title="3D Reconstruction", theme=gr.themes.Soft()) as demo:
|
|
| 853 |
|
| 854 |
# ========== FOOTER ==========
|
| 855 |
gr.Markdown("""
|
| 856 |
-
---
|
|
|
|
|
|
|
|
|
|
| 857 |
This application demonstrates comprehensive understanding of:
|
| 858 |
- Computer vision and deep learning
|
| 859 |
- 3D geometry and reconstruction
|
| 860 |
- Software engineering best practices
|
| 861 |
- Research methodology and evaluation
|
| 862 |
|
|
|
|
|
|
|
| 863 |
*Version 1.0*
|
| 864 |
""")
|
| 865 |
|
|
|
|
| 181 |
# ============================================================================
|
| 182 |
|
| 183 |
def process_image(image, model_choice="GLPN (Recommended)", visualization_type="mesh"):
|
| 184 |
+
"""Main processing pipeline - simplified from first version"""
|
| 185 |
+
|
| 186 |
+
def _generate_quality_assessment(metrics):
|
| 187 |
+
"""Generate quality assessment based on metrics"""
|
| 188 |
+
assessment = []
|
| 189 |
+
|
| 190 |
+
# Check outlier removal
|
| 191 |
+
outlier_pct = (metrics['outliers_removed'] / metrics['initial_points']) * 100
|
| 192 |
+
if outlier_pct < 5:
|
| 193 |
+
assessment.append("β
Very clean depth estimation (low noise)")
|
| 194 |
+
elif outlier_pct < 15:
|
| 195 |
+
assessment.append("β
Good depth quality (normal noise level)")
|
| 196 |
+
else:
|
| 197 |
+
assessment.append("β οΈ High noise in depth estimation")
|
| 198 |
+
|
| 199 |
+
# Check manifold properties
|
| 200 |
+
if metrics['is_edge_manifold'] and metrics['is_vertex_manifold']:
|
| 201 |
+
assessment.append("β
Excellent topology - mesh is well-formed")
|
| 202 |
+
elif metrics['is_vertex_manifold']:
|
| 203 |
+
assessment.append("β οΈ Good local topology but has some edge issues")
|
| 204 |
+
else:
|
| 205 |
+
assessment.append("β οΈ Topology issues present - may need cleanup")
|
| 206 |
+
|
| 207 |
+
# Check watertight
|
| 208 |
+
if metrics['is_watertight']:
|
| 209 |
+
assessment.append("β
Watertight mesh - ready for 3D printing!")
|
| 210 |
+
else:
|
| 211 |
+
assessment.append("βΉοΈ Not watertight - use MeshLab's 'Close Holes' for 3D printing")
|
| 212 |
+
|
| 213 |
+
# Check complexity
|
| 214 |
+
if metrics['triangles'] > 1000000:
|
| 215 |
+
assessment.append("βΉοΈ Very detailed mesh - may be slow in some software")
|
| 216 |
+
elif metrics['triangles'] > 500000:
|
| 217 |
+
assessment.append("β
High detail mesh - good quality")
|
| 218 |
+
else:
|
| 219 |
+
assessment.append("β
Moderate detail - good balance of quality and performance")
|
| 220 |
+
|
| 221 |
+
return "\n".join(f"- {item}" for item in assessment)
|
| 222 |
|
| 223 |
if image is None:
|
| 224 |
return None, None, None, "Please upload an image first.", None
|
|
|
|
| 384 |
'is_edge_manifold': mesh.is_edge_manifold(),
|
| 385 |
'is_vertex_manifold': mesh.is_vertex_manifold(),
|
| 386 |
'is_watertight': mesh.is_watertight(),
|
|
|
|
| 387 |
}
|
| 388 |
|
| 389 |
+
# Compute surface area safely
|
| 390 |
+
try:
|
| 391 |
+
surface_area = mesh.get_surface_area()
|
| 392 |
+
metrics['surface_area'] = float(surface_area) if surface_area > 0 else "Unable to compute"
|
| 393 |
+
except Exception as e:
|
| 394 |
+
print(f"Could not compute surface area: {e}")
|
| 395 |
+
metrics['surface_area'] = "Unable to compute"
|
| 396 |
+
|
| 397 |
+
# Compute volume only if watertight
|
| 398 |
try:
|
| 399 |
if mesh.is_watertight():
|
| 400 |
+
volume = mesh.get_volume()
|
| 401 |
+
metrics['volume'] = float(volume)
|
| 402 |
+
else:
|
| 403 |
+
metrics['volume'] = None
|
| 404 |
+
except Exception as e:
|
| 405 |
+
print(f"Could not compute volume: {e}")
|
| 406 |
metrics['volume'] = None
|
| 407 |
|
| 408 |
print("Metrics computed!")
|
| 409 |
+
print(f"Surface area: {metrics['surface_area']}")
|
| 410 |
+
print(f"Edge manifold: {metrics['is_edge_manifold']}")
|
| 411 |
+
print(f"Watertight: {metrics['is_watertight']}")
|
| 412 |
|
| 413 |
# STEP 9: Create 3D visualization
|
| 414 |
print("Step 9: Creating 3D visualization...")
|
|
|
|
| 525 |
|
| 526 |
### Point Cloud Statistics
|
| 527 |
- **Initial Points**: {metrics['initial_points']:,}
|
| 528 |
+
- **Outliers Removed**: {metrics['outliers_removed']:,} ({(metrics['outliers_removed']/metrics['initial_points']*100):.1f}%)
|
| 529 |
- **Final Points**: {metrics['final_points']:,}
|
| 530 |
|
| 531 |
### Mesh Quality
|
| 532 |
- **Vertices**: {metrics['vertices']:,}
|
| 533 |
- **Triangles**: {metrics['triangles']:,}
|
| 534 |
+
- **Edge Manifold**: {'β Good topology' if metrics['is_edge_manifold'] else 'β Has non-manifold edges'}
|
| 535 |
+
- **Vertex Manifold**: {'β Clean vertices' if metrics['is_vertex_manifold'] else 'β Has non-manifold vertices'}
|
| 536 |
+
- **Watertight**: {'β Closed surface (3D printable)' if metrics['is_watertight'] else 'β Has boundaries (needs repair for 3D printing)'}
|
| 537 |
+
- **Surface Area**: {metrics['surface_area'] if isinstance(metrics['surface_area'], str) else f"{metrics['surface_area']:.2f}"}
|
| 538 |
+
- **Volume**: {f"{metrics['volume']:.2f}" if metrics.get('volume') else 'N/A (not watertight)'}
|
| 539 |
+
|
| 540 |
+
### Quality Assessment
|
| 541 |
+
{self._generate_quality_assessment(metrics)}
|
| 542 |
|
| 543 |
### Files Exported
|
| 544 |
- Point Cloud: PLY format
|
|
|
|
| 561 |
# GRADIO INTERFACE
|
| 562 |
# ============================================================================
|
| 563 |
|
| 564 |
+
with gr.Blocks(title="Advanced 3D Reconstruction", theme=gr.themes.Soft()) as demo:
|
| 565 |
|
| 566 |
gr.Markdown("""
|
| 567 |
+
# ποΈ Advanced 3D Reconstruction from Single Images
|
| 568 |
|
| 569 |
+
**Academic-grade pipeline for monocular depth estimation and 3D surface reconstruction**
|
| 570 |
|
| 571 |
Upload an image to generate:
|
| 572 |
- High-quality depth maps
|
|
|
|
| 579 |
with gr.Tabs():
|
| 580 |
|
| 581 |
# ========== RECONSTRUCTION TAB ==========
|
| 582 |
+
with gr.Tab("π― Reconstruction"):
|
| 583 |
with gr.Row():
|
| 584 |
with gr.Column(scale=1):
|
| 585 |
input_image = gr.Image(type="pil", label="Upload Image")
|
|
|
|
| 597 |
label="3D Visualization Type"
|
| 598 |
)
|
| 599 |
|
| 600 |
+
reconstruct_btn = gr.Button("π Start Reconstruction", variant="primary", size="lg")
|
| 601 |
|
| 602 |
with gr.Column(scale=2):
|
| 603 |
depth_output = gr.Image(label="Depth Map Comparison")
|
|
|
|
| 715 |
|
| 716 |
**Depth Map Comparison:**
|
| 717 |
- Left: Your original image
|
| 718 |
+
- Right: Estimated depth map
|
| 719 |
+
- **Yellow/Red colors = CLOSER** objects
|
| 720 |
+
- **Purple/Blue colors = FARTHER** objects
|
| 721 |
+
- Color scale shows relative depth (not absolute distance)
|
| 722 |
|
| 723 |
**Interactive 3D Viewer:**
|
| 724 |
- **Rotate**: Click and drag
|
|
|
|
| 912 |
|
| 913 |
# ========== FOOTER ==========
|
| 914 |
gr.Markdown("""
|
| 915 |
+
---
|
| 916 |
+
|
| 917 |
+
### π PhD Application Demo
|
| 918 |
+
|
| 919 |
This application demonstrates comprehensive understanding of:
|
| 920 |
- Computer vision and deep learning
|
| 921 |
- 3D geometry and reconstruction
|
| 922 |
- Software engineering best practices
|
| 923 |
- Research methodology and evaluation
|
| 924 |
|
| 925 |
+
**Developed for academic research purposes**
|
| 926 |
+
|
| 927 |
*Version 1.0*
|
| 928 |
""")
|
| 929 |
|