lakshmi082024 commited on
Commit
281c6dd
·
verified ·
1 Parent(s): 2350f8f

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +129 -1
src/streamlit_app.py CHANGED
@@ -37,4 +37,132 @@ st.altair_chart(alt.Chart(df, height=700, width=700)
37
  y=alt.Y("y", axis=None),
38
  color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
  size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  y=alt.Y("y", axis=None),
38
  color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
  size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
+ ))
41
+
42
+
43
+ import streamlit as st
44
+ import cv2
45
+ import numpy as np
46
+ import pandas as pd
47
+ from PIL import Image
48
+ import torch
49
+ from torchvision.transforms import Compose, Resize, ToTensor, Normalize
50
+ from segment_anything import SamPredictor, sam_model_registry
51
+
52
+ # Set Streamlit configuration
53
+ st.set_page_config(page_title="Volume Estimator", layout="wide")
54
+ st.title("📦 Volume Estimation using SAM Segmentation + MiDaS Depth")
55
+
56
+ # Load SAM and MiDaS models
57
+ @st.cache_resource
58
+ def load_models():
59
+ sam_checkpoint = "C:/Users/Administrator/Desktop/streamlit_tl/models/sam_vit_h_4b8939.pth"
60
+ sam = sam_model_registry["vit_h"](checkpoint=sam_checkpoint).to("cuda" if torch.cuda.is_available() else "cpu")
61
+ predictor = SamPredictor(sam)
62
+
63
+ midas = torch.hub.load("intel-isl/MiDaS", "DPT_Large")
64
+ midas.eval()
65
+ midas_transform = Compose([
66
+ Resize(384),
67
+ ToTensor(),
68
+ Normalize(mean=[0.5]*3, std=[0.5]*3)
69
+ ])
70
+ return predictor, midas, midas_transform
71
+
72
+ predictor, midas_model, midas_transform = load_models()
73
+
74
+ # Input source selection
75
+ source_option = st.radio("Select input source", ("Upload Image", "Use Webcam"))
76
+
77
+ uploaded_file = None
78
+ image_pil = None
79
+
80
+ if source_option == "Upload Image":
81
+ uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
82
+ if uploaded_file:
83
+ image_pil = Image.open(uploaded_file).convert("RGB")
84
+
85
+ elif source_option == "Use Webcam":
86
+ run_camera = st.checkbox("Start Camera")
87
+
88
+ if run_camera:
89
+ cap = cv2.VideoCapture(0)
90
+ stframe = st.empty()
91
+ capture = False
92
+
93
+ while run_camera and cap.isOpened():
94
+ ret, frame = cap.read()
95
+ if not ret:
96
+ break
97
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
98
+ stframe.image(frame_rgb, caption="Live Camera Feed", channels="RGB")
99
+
100
+ if st.button("📸 Capture Frame"):
101
+ image_pil = Image.fromarray(frame_rgb)
102
+ run_camera = False
103
+ cap.release()
104
+ break
105
+
106
+ # Continue processing if we have an image
107
+ if image_pil:
108
+ image_np = np.array(image_pil)
109
+ img_h, img_w = image_np.shape[:2]
110
+ st.image(image_pil, caption="Selected Image", use_container_width=True)
111
+
112
+ # Real-world reference dimensions
113
+ real_image_width_cm = 100
114
+ real_image_height_cm = 75
115
+ assumed_max_depth_cm = 100
116
+
117
+ pixel_to_cm_x = real_image_width_cm / img_w
118
+ pixel_to_cm_y = real_image_height_cm / img_h
119
+
120
+ # SAM Segmentation
121
+ predictor.set_image(image_np)
122
+ masks, _, _ = predictor.predict(multimask_output=False)
123
+
124
+ # MiDaS Depth Estimation
125
+ input_tensor = midas_transform(image_pil).unsqueeze(0)
126
+ with torch.no_grad():
127
+ depth_prediction = midas_model(input_tensor).squeeze().cpu().numpy()
128
+ depth_resized = cv2.resize(depth_prediction, (img_w, img_h))
129
+
130
+ # Object volume computation
131
+ volume_data = []
132
+ for i, mask in enumerate(masks):
133
+ mask_np = mask
134
+ x, y, w, h = cv2.boundingRect(mask_np.astype(np.uint8))
135
+ width_px = w
136
+ height_px = h
137
+
138
+ width_cm = width_px * pixel_to_cm_x
139
+ height_cm = height_px * pixel_to_cm_y
140
+
141
+ depth_masked = depth_resized[mask_np > 0.5]
142
+
143
+ if depth_masked.size == 0:
144
+ continue
145
+
146
+ normalized_depth = (depth_masked - np.min(depth_resized)) / (np.max(depth_resized) - np.min(depth_resized) + 1e-6)
147
+ depth_cm = np.mean(normalized_depth) * assumed_max_depth_cm
148
+
149
+ volume_cm3 = round(depth_cm * width_cm * height_cm, 2)
150
+
151
+ volume_data.append({
152
+ "Object": f"Object #{i+1}",
153
+ "Length (Depth)": f"{round(depth_cm, 2)} cm",
154
+ "Breadth (Width)": f"{round(width_cm, 2)} cm",
155
+ "Height": f"{round(height_cm, 2)} cm",
156
+ "Volume": f"{volume_cm3} cm³"
157
+ })
158
+
159
+ # Display volume table
160
+ if volume_data:
161
+ df = pd.DataFrame(volume_data)
162
+ st.markdown("### 📊 Object Dimensions and Volume")
163
+ st.dataframe(df)
164
+
165
+ csv = df.to_csv(index=False).encode('utf-8')
166
+ st.download_button("📂 Download Volume Table as CSV", csv, "object_volumes_with_units.csv", "text/csv")
167
+ else:
168
+ st.warning("🚫 No objects were segmented.")