lakshmi082024 commited on
Commit
7500064
·
verified ·
1 Parent(s): 581a214

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -77
app.py CHANGED
@@ -1,26 +1,25 @@
1
- import streamlit as st
2
- import cv2
3
  import numpy as np
4
- import pandas as pd
5
  from PIL import Image
6
- import torch
7
  from torchvision.transforms import Compose, Resize, ToTensor, Normalize
8
- #from segment_anything import SamPredictor, sam_model_registry
9
- from segment_anything import sam_model_registry, SamPredictor
10
-
11
- # Set Streamlit configuration
12
- st.set_page_config(page_title="Volume Estimator", layout="wide")
13
- st.title("📦 Volume Estimation using SAM Segmentation + MiDaS Depth")
14
 
15
  # Load SAM and MiDaS models
16
- @st.cache_resource
17
  def load_models():
18
- sam_checkpoint = "C:/Users/Administrator/Desktop/streamlit_tl/models/sam_vit_h_4b8939.pth"
19
- sam = sam_model_registry["vit_h"](checkpoint=sam_checkpoint).to("cuda" if torch.cuda.is_available() else "cpu")
 
 
 
 
20
  predictor = SamPredictor(sam)
21
 
22
  midas = torch.hub.load("intel-isl/MiDaS", "DPT_Large")
23
- midas.eval()
24
  midas_transform = Compose([
25
  Resize(384),
26
  ToTensor(),
@@ -30,45 +29,12 @@ def load_models():
30
 
31
  predictor, midas_model, midas_transform = load_models()
32
 
33
- # Input source selection
34
- source_option = st.radio("Select input source", ("Upload Image", "Use Webcam"))
35
-
36
- uploaded_file = None
37
- image_pil = None
38
-
39
- if source_option == "Upload Image":
40
- uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
41
- if uploaded_file:
42
- image_pil = Image.open(uploaded_file).convert("RGB")
43
-
44
- elif source_option == "Use Webcam":
45
- run_camera = st.checkbox("Start Camera")
46
-
47
- if run_camera:
48
- cap = cv2.VideoCapture(0)
49
- stframe = st.empty()
50
- capture = False
51
-
52
- while run_camera and cap.isOpened():
53
- ret, frame = cap.read()
54
- if not ret:
55
- break
56
- frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
57
- stframe.image(frame_rgb, caption="Live Camera Feed", channels="RGB")
58
-
59
- if st.button("📸 Capture Frame"):
60
- image_pil = Image.fromarray(frame_rgb)
61
- run_camera = False
62
- cap.release()
63
- break
64
-
65
- # Continue processing if we have an image
66
- if image_pil:
67
  image_np = np.array(image_pil)
68
  img_h, img_w = image_np.shape[:2]
69
- st.image(image_pil, caption="Selected Image", use_container_width=True)
70
 
71
- # Real-world reference dimensions
72
  real_image_width_cm = 100
73
  real_image_height_cm = 75
74
  assumed_max_depth_cm = 100
@@ -76,12 +42,12 @@ if image_pil:
76
  pixel_to_cm_x = real_image_width_cm / img_w
77
  pixel_to_cm_y = real_image_height_cm / img_h
78
 
79
- # SAM Segmentation
80
  predictor.set_image(image_np)
81
  masks, _, _ = predictor.predict(multimask_output=False)
82
 
83
- # MiDaS Depth Estimation
84
- input_tensor = midas_transform(image_pil).unsqueeze(0)
85
  with torch.no_grad():
86
  depth_prediction = midas_model(input_tensor).squeeze().cpu().numpy()
87
  depth_resized = cv2.resize(depth_prediction, (img_w, img_h))
@@ -89,39 +55,43 @@ if image_pil:
89
  # Object volume computation
90
  volume_data = []
91
  for i, mask in enumerate(masks):
92
- mask_np = mask
93
- x, y, w, h = cv2.boundingRect(mask_np.astype(np.uint8))
94
  width_px = w
95
  height_px = h
96
-
97
  width_cm = width_px * pixel_to_cm_x
98
  height_cm = height_px * pixel_to_cm_y
99
 
100
- depth_masked = depth_resized[mask_np > 0.5]
101
-
102
  if depth_masked.size == 0:
103
  continue
104
 
105
  normalized_depth = (depth_masked - np.min(depth_resized)) / (np.max(depth_resized) - np.min(depth_resized) + 1e-6)
106
  depth_cm = np.mean(normalized_depth) * assumed_max_depth_cm
107
-
108
  volume_cm3 = round(depth_cm * width_cm * height_cm, 2)
109
 
110
- volume_data.append({
111
- "Object": f"Object #{i+1}",
112
- "Length (Depth)": f"{round(depth_cm, 2)} cm",
113
- "Breadth (Width)": f"{round(width_cm, 2)} cm",
114
- "Height": f"{round(height_cm, 2)} cm",
115
- "Volume": f"{volume_cm3} cm³"
116
- })
117
-
118
- # Display volume table
119
- if volume_data:
120
- df = pd.DataFrame(volume_data)
121
- st.markdown("### 📊 Object Dimensions and Volume")
122
- st.dataframe(df)
123
-
124
- csv = df.to_csv(index=False).encode('utf-8')
125
- st.download_button("📂 Download Volume Table as CSV", csv, "object_volumes_with_units.csv", "text/csv")
126
- else:
127
- st.warning("🚫 No objects were segmented.")
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
  import numpy as np
4
+ import cv2
5
  from PIL import Image
6
+ import pandas as pd
7
  from torchvision.transforms import Compose, Resize, ToTensor, Normalize
8
+ from segment_anything import SamPredictor, sam_model_registry
9
+ import os
 
 
 
 
10
 
11
  # Load SAM and MiDaS models
 
12
  def load_models():
13
+ sam_checkpoint = "sam_vit_h_4b8939.pth"
14
+ if not os.path.exists(sam_checkpoint):
15
+ raise FileNotFoundError("Please upload the SAM checkpoint file to the working directory.")
16
+
17
+ device = "cuda" if torch.cuda.is_available() else "cpu"
18
+ sam = sam_model_registry["vit_h"](checkpoint=sam_checkpoint).to(device)
19
  predictor = SamPredictor(sam)
20
 
21
  midas = torch.hub.load("intel-isl/MiDaS", "DPT_Large")
22
+ midas.eval().to(device)
23
  midas_transform = Compose([
24
  Resize(384),
25
  ToTensor(),
 
29
 
30
  predictor, midas_model, midas_transform = load_models()
31
 
32
+ # Processing function
33
+ def process_image(image_pil):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  image_np = np.array(image_pil)
35
  img_h, img_w = image_np.shape[:2]
 
36
 
37
+ # Real-world reference dimensions (adjust as needed)
38
  real_image_width_cm = 100
39
  real_image_height_cm = 75
40
  assumed_max_depth_cm = 100
 
42
  pixel_to_cm_x = real_image_width_cm / img_w
43
  pixel_to_cm_y = real_image_height_cm / img_h
44
 
45
+ # SAM segmentation
46
  predictor.set_image(image_np)
47
  masks, _, _ = predictor.predict(multimask_output=False)
48
 
49
+ # MiDaS depth estimation
50
+ input_tensor = midas_transform(image_pil).unsqueeze(0).to(next(midas_model.parameters()).device)
51
  with torch.no_grad():
52
  depth_prediction = midas_model(input_tensor).squeeze().cpu().numpy()
53
  depth_resized = cv2.resize(depth_prediction, (img_w, img_h))
 
55
  # Object volume computation
56
  volume_data = []
57
  for i, mask in enumerate(masks):
58
+ x, y, w, h = cv2.boundingRect(mask.astype(np.uint8))
 
59
  width_px = w
60
  height_px = h
 
61
  width_cm = width_px * pixel_to_cm_x
62
  height_cm = height_px * pixel_to_cm_y
63
 
64
+ depth_masked = depth_resized[mask > 0.5]
 
65
  if depth_masked.size == 0:
66
  continue
67
 
68
  normalized_depth = (depth_masked - np.min(depth_resized)) / (np.max(depth_resized) - np.min(depth_resized) + 1e-6)
69
  depth_cm = np.mean(normalized_depth) * assumed_max_depth_cm
 
70
  volume_cm3 = round(depth_cm * width_cm * height_cm, 2)
71
 
72
+ volume_data.append([
73
+ f"Object #{i+1}",
74
+ round(depth_cm, 2),
75
+ round(width_cm, 2),
76
+ round(height_cm, 2),
77
+ volume_cm3
78
+ ])
79
+
80
+ if not volume_data:
81
+ return image_pil, "No objects segmented."
82
+
83
+ df = pd.DataFrame(volume_data, columns=["Object", "Length (Depth) cm", "Breadth (Width) cm", "Height cm", "Volume cm³"])
84
+ return image_pil, df
85
+
86
+ # Gradio Interface
87
+ with gr.Blocks() as demo:
88
+ gr.Markdown("# 📦 Volume Estimation using SAM + MiDaS")
89
+ with gr.Row():
90
+ image_input = gr.Image(type="pil", label="Upload Image")
91
+ run_btn = gr.Button("Estimate Volume")
92
+ with gr.Row():
93
+ output_image = gr.Image(label="Original Image")
94
+ volume_table = gr.Dataframe(headers=["Object", "Length (Depth) cm", "Breadth (Width) cm", "Height cm", "Volume cm³"])
95
+ run_btn.click(fn=process_image, inputs=image_input, outputs=[output_image, volume_table])
96
+
97
+ demo.launch()