Asrar990 commited on
Commit
c045ba0
Β·
verified Β·
1 Parent(s): df2f7ab

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -51
app.py CHANGED
@@ -1,79 +1,93 @@
1
  import streamlit as st
 
2
  import open3d as o3d
3
  import numpy as np
4
  import tempfile
5
  import os
6
- from PIL import Image
7
 
8
  # Title of the App
9
- st.title("3D Reconstruction Tool from Images πŸ“· β†’ πŸ› οΈ β†’ 🧊")
10
 
11
  # Sidebar: Information
12
  st.sidebar.write("""
13
  ## About the App
14
- Upload multiple images of an object taken from different angles.
15
- The app will reconstruct a 3D point cloud, generate a surface mesh, and allow you to visualize and download the 3D model.
16
  """)
17
 
18
- # Step 1: Upload Images
19
- uploaded_images = st.file_uploader(
20
- "Upload Multiple Images (PNG, JPG, JPEG)",
21
- type=["png", "jpg", "jpeg"],
22
- accept_multiple_files=True
23
- )
24
-
25
- # Check if images are uploaded
26
- if uploaded_images:
27
- st.write(f"βœ… {len(uploaded_images)} images uploaded successfully!")
28
-
29
- # Step 2: Process Uploaded Images
30
- st.write("πŸ”„ Generating 3D Point Cloud from the images...")
31
-
32
- # Save uploaded images temporarily
33
- images_dir = tempfile.mkdtemp()
34
- image_paths = []
35
- for idx, uploaded_file in enumerate(uploaded_images):
36
- image_path = os.path.join(images_dir, f"image_{idx:04d}.png")
37
- image = Image.open(uploaded_file)
38
- image.save(image_path)
39
- image_paths.append(image_path)
40
-
41
- # Step 3: Generate Point Cloud (Simplified Approach)
42
- # Combine grayscale data into a pseudo-3D point cloud
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  pcd = o3d.geometry.PointCloud()
44
-
45
- for image_path in image_paths:
46
- # Load image and convert to grayscale
47
- img = np.array(Image.open(image_path).convert("L"))
48
- height, width = img.shape
49
-
50
- # Generate x, y, z coordinates (z = intensity as pseudo-depth)
51
  x, y = np.meshgrid(np.arange(width), np.arange(height))
52
- z = img / 255.0 # Normalize grayscale intensity to pseudo-depth
53
  points = np.stack((x.flatten(), y.flatten(), z.flatten()), axis=1)
54
-
55
- # Add points to the point cloud
56
  pcd.points.extend(o3d.utility.Vector3dVector(points))
57
 
58
- # Step 4: Surface Reconstruction using Poisson Reconstruction
59
- st.write("πŸ› οΈ Generating mesh using Poisson Surface Reconstruction...")
60
-
61
- # Estimate normals for the point cloud
62
  pcd.estimate_normals()
63
  mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=8)
64
 
65
  # Step 5: Visualization
66
  st.write("βœ… Reconstruction Complete! Visualizing the 3D model:")
 
67
 
68
- # Save the mesh temporarily for visualization
69
- output_mesh_path = "reconstructed_mesh.stl"
70
- o3d.io.write_triangle_mesh(output_mesh_path, mesh)
71
-
72
- # Use Plotly to visualize the 3D mesh
73
  import plotly.graph_objects as go
74
  vertices = np.asarray(mesh.vertices)
75
  triangles = np.asarray(mesh.triangles)
76
-
77
  fig = go.Figure(data=[go.Mesh3d(
78
  x=vertices[:, 0],
79
  y=vertices[:, 1],
@@ -88,5 +102,5 @@ if uploaded_images:
88
 
89
  # Step 6: Download the Optimized Mesh
90
  st.write("πŸ“₯ Download the reconstructed 3D model:")
91
- with open(output_mesh_path, "rb") as f:
92
- st.download_button("Download 3D Mesh (STL)", f, file_name="3D_Model.stl")
 
1
  import streamlit as st
2
+ import cv2
3
  import open3d as o3d
4
  import numpy as np
5
  import tempfile
6
  import os
 
7
 
8
  # Title of the App
9
+ st.title("3D Reconstruction Tool from Video πŸ“Ή β†’ πŸ› οΈ β†’ 🧊")
10
 
11
  # Sidebar: Information
12
  st.sidebar.write("""
13
  ## About the App
14
+ Upload a video file, extract frames, reconstruct a 3D point cloud using Structure from Motion (SfM), and visualize or download the 3D mesh.
 
15
  """)
16
 
17
+ # Step 1: Upload Video File
18
+ uploaded_file = st.file_uploader("Upload a Video File (MP4, AVI)", type=["mp4", "avi"])
19
+
20
+ # Function to extract frames from video
21
+ def extract_frames(video_path, frame_rate=10):
22
+ cap = cv2.VideoCapture(video_path)
23
+ frames = []
24
+ count = 0
25
+ while cap.isOpened():
26
+ ret, frame = cap.read()
27
+ if not ret:
28
+ break
29
+ if count % frame_rate == 0:
30
+ frames.append(frame)
31
+ count += 1
32
+ cap.release()
33
+ return frames
34
+
35
+ # Function to save frames as images
36
+ def save_frames_as_images(frames, output_dir):
37
+ os.makedirs(output_dir, exist_ok=True)
38
+ for i, frame in enumerate(frames):
39
+ filename = os.path.join(output_dir, f"frame_{i:04d}.png")
40
+ cv2.imwrite(filename, frame)
41
+
42
+ # Step 2: Process Uploaded Video
43
+ if uploaded_file:
44
+ st.video(uploaded_file)
45
+ st.write("Extracting frames...")
46
+
47
+ # Save the uploaded video temporarily
48
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_video:
49
+ tmp_video.write(uploaded_file.read())
50
+ video_path = tmp_video.name
51
+
52
+ # Extract frames
53
+ frames = extract_frames(video_path, frame_rate=10)
54
+ st.write(f"βœ… Extracted {len(frames)} frames from the video.")
55
+
56
+ # Save extracted frames
57
+ frames_dir = tempfile.mkdtemp()
58
+ save_frames_as_images(frames, frames_dir)
59
+ st.write(f"Frames saved temporarily at `{frames_dir}`.")
60
+
61
+ # Step 3: Structure from Motion (3D Reconstruction)
62
+ st.write("πŸ”„ Reconstructing 3D point cloud using Structure from Motion...")
63
+
64
+ # Create Open3D Point Cloud
65
  pcd = o3d.geometry.PointCloud()
66
+ for image_file in sorted(os.listdir(frames_dir)):
67
+ img_path = os.path.join(frames_dir, image_file)
68
+ frame = cv2.imread(img_path)
69
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
70
+
71
+ # Dummy point cloud generation for simplicity
72
+ height, width = gray.shape
73
  x, y = np.meshgrid(np.arange(width), np.arange(height))
74
+ z = gray / 255.0 # Use gray intensity as a pseudo depth
75
  points = np.stack((x.flatten(), y.flatten(), z.flatten()), axis=1)
 
 
76
  pcd.points.extend(o3d.utility.Vector3dVector(points))
77
 
78
+ # Step 4: Surface Reconstruction
79
+ st.write("πŸ› οΈ Generating mesh using Poisson Reconstruction...")
 
 
80
  pcd.estimate_normals()
81
  mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=8)
82
 
83
  # Step 5: Visualization
84
  st.write("βœ… Reconstruction Complete! Visualizing the 3D model:")
85
+ o3d.io.write_triangle_mesh("reconstructed_mesh.stl", mesh)
86
 
87
+ # Use Plotly for visualization
 
 
 
 
88
  import plotly.graph_objects as go
89
  vertices = np.asarray(mesh.vertices)
90
  triangles = np.asarray(mesh.triangles)
 
91
  fig = go.Figure(data=[go.Mesh3d(
92
  x=vertices[:, 0],
93
  y=vertices[:, 1],
 
102
 
103
  # Step 6: Download the Optimized Mesh
104
  st.write("πŸ“₯ Download the reconstructed 3D model:")
105
+ with open("reconstructed_mesh.stl", "rb") as f:
106
+ st.download_button("Download 3D Mesh (STL)", f, file_name="reconstructed_3D_Model.stl")