suryaprakash01 commited on
Commit
2c63a77
·
verified ·
1 Parent(s): bce406b

Upload folder using huggingface_hub

Browse files
.vs/detectron_model/FileContentIndex/41db3a26-7ff6-483d-a361-f297ad6da18e.vsidx ADDED
Binary file (29 kB). View file
 
.vs/detectron_model/FileContentIndex/85bb5c5c-11eb-434c-8427-b75d39bcd171.vsidx ADDED
Binary file (20.6 kB). View file
 
.vs/detectron_model/FileContentIndex/b78701b3-342c-48c5-b440-4495ec02309d.vsidx ADDED
Binary file (107 Bytes). View file
 
.vs/detectron_model/v17/.suo ADDED
Binary file (27.1 kB). View file
 
.vs/detectron_model/v17/DocumentLayout.backup.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "Version": 1,
3
+ "WorkspaceRootPath": "C:\\Users\\pc\\TLproj\\detectron_model\\",
4
+ "Documents": [
5
+ {
6
+ "AbsoluteMoniker": "D:0:0:{547F1ED0-B3CB-4F4C-B952-A38644838CF5}|detectron_model.pyproj|C:\\Users\\pc\\TLproj\\detectron_model\\detectron_model.py||{8B382828-6202-11D1-8870-0000F87579D2}",
7
+ "RelativeMoniker": "D:0:0:{547F1ED0-B3CB-4F4C-B952-A38644838CF5}|detectron_model.pyproj|solutionrelative:detectron_model.py||{8B382828-6202-11D1-8870-0000F87579D2}"
8
+ }
9
+ ],
10
+ "DocumentGroupContainers": [
11
+ {
12
+ "Orientation": 0,
13
+ "VerticalTabListWidth": 256,
14
+ "DocumentGroups": [
15
+ {
16
+ "DockedWidth": 200,
17
+ "SelectedChildIndex": 0,
18
+ "Children": [
19
+ {
20
+ "$type": "Document",
21
+ "DocumentIndex": 0,
22
+ "Title": "detectron_model.py",
23
+ "DocumentMoniker": "C:\\Users\\pc\\TLproj\\detectron_model\\detectron_model.py",
24
+ "RelativeDocumentMoniker": "detectron_model.py",
25
+ "ToolTip": "C:\\Users\\pc\\TLproj\\detectron_model\\detectron_model.py",
26
+ "RelativeToolTip": "detectron_model.py",
27
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
28
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
29
+ "WhenOpened": "2025-05-10T12:10:14.159Z",
30
+ "EditorCaption": ""
31
+ }
32
+ ]
33
+ }
34
+ ]
35
+ }
36
+ ]
37
+ }
.vs/detectron_model/v17/DocumentLayout.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "Version": 1,
3
+ "WorkspaceRootPath": "C:\\Users\\pc\\TLproj\\detectron_model\\",
4
+ "Documents": [
5
+ {
6
+ "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\pc\\TLproj\\detectron_model\\detectron_model.py||{8B382828-6202-11D1-8870-0000F87579D2}",
7
+ "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:detectron_model.py||{8B382828-6202-11D1-8870-0000F87579D2}"
8
+ }
9
+ ],
10
+ "DocumentGroupContainers": [
11
+ {
12
+ "Orientation": 0,
13
+ "VerticalTabListWidth": 256,
14
+ "DocumentGroups": [
15
+ {
16
+ "DockedWidth": 200,
17
+ "SelectedChildIndex": 0,
18
+ "Children": [
19
+ {
20
+ "$type": "Document",
21
+ "DocumentIndex": 0,
22
+ "Title": "detectron_model.py",
23
+ "DocumentMoniker": "C:\\Users\\pc\\TLproj\\detectron_model\\detectron_model.py",
24
+ "RelativeDocumentMoniker": "detectron_model.py",
25
+ "ToolTip": "C:\\Users\\pc\\TLproj\\detectron_model\\detectron_model.py",
26
+ "RelativeToolTip": "detectron_model.py",
27
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|",
28
+ "WhenOpened": "2025-05-10T12:10:14.159Z"
29
+ }
30
+ ]
31
+ }
32
+ ]
33
+ }
34
+ ]
35
+ }
README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ # detectron_model
app.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from det_model import predict_dimensions # function you'll define
3
+ from detectron_model import load_detectron_model # function you'll define
4
+ from PIL import Image
5
+ import torch
6
+
7
+ st.title("Object Dimension Estimator using Detectron2")
8
+
9
+ uploaded_file = st.file_uploader("Upload an image", type=["jpg", "png", "jpeg"])
10
+
11
+ if uploaded_file:
12
+ image = Image.open(uploaded_file).convert("RGB")
13
+ st.image(image, caption="Uploaded Image", use_column_width=True)
14
+
15
+ st.write("Running detection and dimension estimation...")
16
+ detectron = load_detectron_model()
17
+ dimensions = predict_dimensions(image, detectron)
18
+
19
+ st.success(f"Estimated Dimensions (LxWxH): {dimensions}")
det_model.py ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import torch
3
+ import torchvision.transforms as T
4
+ import numpy as np
5
+ import cv2
6
+ from PIL import Image, UnidentifiedImageError
7
+ import os
8
+ import subprocess # For Detectron2 installation check
9
+ import sys # For Detectron2 installation check
10
+
11
+ # --- Detectron2 Imports (handle potential import errors) ---
12
+ d2_imported_successfully = False
13
+ try:
14
+ import detectron2
15
+ from detectron2.engine import DefaultPredictor
16
+ from detectron2.config import get_cfg
17
+ from detectron2 import model_zoo
18
+ from detectron2.utils.visualizer import Visualizer, ColorMode
19
+ from detectron2.data import MetadataCatalog
20
+ from detectron2.structures import Boxes # For Bounding Boxes
21
+ d2_imported_successfully = True
22
+ print("Detectron2 utilities imported successfully.")
23
+ except ImportError:
24
+ st.error("Detectron2 not found or not installed correctly. Please ensure it's installed in your environment.")
25
+ print("❌ Failed to import Detectron2 utilities.")
26
+ except Exception as e:
27
+ st.error(f"An error occurred during Detectron2 imports: {e}")
28
+ print(f"❌ An error occurred during Detectron2 imports: {e}")
29
+
30
+
31
+ # --- PyTorch Model Imports ---
32
+ from torchvision import models as torchvision_models
33
+ import torch.nn as nn
34
+
35
+ # ------------------------------
36
+ # Configuration
37
+ # ------------------------------
38
+ DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
39
+ CNN_INPUT_SIZE = 224
40
+ IMAGENET_MEAN = [0.485, 0.456, 0.406]
41
+ IMAGENET_STD = [0.229, 0.224, 0.225]
42
+ # Ensure this path is correct for your environment
43
+ MODEL_PATH = r"pix3d_dimension_estimator_mask_crop.pth"
44
+ OUTPUT_DIR = 'streamlit_d2_output'
45
+ os.makedirs(OUTPUT_DIR, exist_ok=True)
46
+
47
+
48
+ # ------------------------------
49
+ # Dimension Estimation CNN
50
+ # ------------------------------
51
+ def create_dimension_estimator_cnn_for_inference(num_outputs=4):
52
+ model = torchvision_models.resnet50(weights=None) # Load architecture only
53
+ num_ftrs = model.fc.in_features
54
+ model.fc = nn.Sequential(
55
+ nn.Linear(num_ftrs, 512),
56
+ nn.ReLU(),
57
+ nn.Dropout(0.5),
58
+ nn.Linear(512, num_outputs) # Outputs L, W, H, V
59
+ )
60
+ return model
61
+
62
+ @st.cache_resource
63
+ def load_dimension_model():
64
+ model = None
65
+ if not os.path.exists(MODEL_PATH):
66
+ st.error(f"Dimension estimation model not found at {MODEL_PATH}. Please check the path.")
67
+ return None
68
+ try:
69
+ model = create_dimension_estimator_cnn_for_inference()
70
+ model.load_state_dict(torch.load(MODEL_PATH, map_location=DEVICE))
71
+ model.to(DEVICE)
72
+ model.eval()
73
+ print(f"Dimension estimation model loaded from {MODEL_PATH}")
74
+ except Exception as e:
75
+ st.error(f"Error loading dimension estimation model: {e}")
76
+ return None
77
+ return model
78
+
79
+ # ------------------------------
80
+ # Detectron2 Model
81
+ # ------------------------------
82
+ @st.cache_resource
83
+ def load_detectron2_model():
84
+ if not d2_imported_successfully:
85
+ return None, None
86
+ try:
87
+ cfg = get_cfg()
88
+ # Example: Mask R-CNN for instance segmentation
89
+ cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
90
+ cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # Set threshold for detection
91
+ cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
92
+ if not torch.cuda.is_available():
93
+ cfg.MODEL.DEVICE = "cpu"
94
+ else:
95
+ cfg.MODEL.DEVICE = "cuda" # Explicitly set
96
+ predictor = DefaultPredictor(cfg)
97
+ print("Detectron2 predictor created.")
98
+ return predictor, cfg
99
+ except Exception as e:
100
+ st.error(f"Error loading Detectron2 model: {e}")
101
+ return None, None
102
+
103
+ # ------------------------------
104
+ # Helper Functions
105
+ # ------------------------------
106
+ def get_largest_instance_index(instances):
107
+ """Returns the index of the largest instance based on mask area or box area."""
108
+ if not len(instances):
109
+ return -1 # No instances
110
+
111
+ if instances.has("pred_masks"):
112
+ areas = instances.pred_masks.sum(dim=(1,2)) # Sum of True pixels in boolean mask
113
+ if len(areas) > 0:
114
+ return areas.argmax().item()
115
+ elif instances.has("pred_boxes"):
116
+ boxes_tensor = instances.pred_boxes.tensor
117
+ areas = (boxes_tensor[:, 2] - boxes_tensor[:, 0]) * (boxes_tensor[:, 3] - boxes_tensor[:, 1])
118
+ if len(areas) > 0:
119
+ return areas.argmax().item()
120
+ return 0 # Default to first instance if area calculation fails or no masks/boxes
121
+
122
+ def crop_from_mask(image_np_rgb, mask_tensor):
123
+ """Crops an object from an image using a boolean mask tensor."""
124
+ mask_np = mask_tensor.cpu().numpy().astype(np.uint8) # Ensure mask is on CPU and uint8
125
+ if mask_np.sum() == 0: return None # Empty mask
126
+
127
+ rows = np.any(mask_np, axis=1)
128
+ cols = np.any(mask_np, axis=0)
129
+ if not np.any(rows) or not np.any(cols): return None
130
+
131
+ ymin, ymax = np.where(rows)[0][[0, -1]]
132
+ xmin, xmax = np.where(cols)[0][[0, -1]]
133
+
134
+ # Add padding to the bounding box from mask
135
+ padding = 5
136
+ ymin = max(0, ymin - padding)
137
+ xmin = max(0, xmin - padding)
138
+ ymax = min(image_np_rgb.shape[0] - 1, ymax + padding)
139
+ xmax = min(image_np_rgb.shape[1] - 1, xmax + padding)
140
+
141
+
142
+ if ymin >= ymax or xmin >= xmax : return None
143
+ cropped_image = image_np_rgb[ymin:ymax+1, xmin:xmax+1, :]
144
+ return cropped_image
145
+
146
+ def predict_dimensions_cnn(image_patch_np_rgb, model):
147
+ """Predicts dimensions using the custom CNN."""
148
+ if model is None:
149
+ return {"L": "N/A", "W": "N/A", "H": "N/A", "V": "N/A", "Note": "DimCNN not loaded"}
150
+ try:
151
+ if image_patch_np_rgb.dtype != np.uint8:
152
+ image_patch_np_rgb = image_patch_np_rgb.astype(np.uint8)
153
+
154
+ transform = T.Compose([
155
+ T.ToPILImage(),
156
+ T.Resize((CNN_INPUT_SIZE, CNN_INPUT_SIZE)),
157
+ T.ToTensor(),
158
+ T.Normalize(mean=IMAGENET_MEAN, std=IMAGENET_STD)
159
+ ])
160
+ input_tensor = transform(image_patch_np_rgb).unsqueeze(0).to(DEVICE)
161
+ with torch.no_grad():
162
+ pred = model(input_tensor)
163
+ dims = pred.squeeze().cpu().tolist()
164
+
165
+ if not isinstance(dims, list): dims = [dims]
166
+ while len(dims) < 4: dims.append(0.0) # Pad if model outputs fewer
167
+
168
+ # Assuming model was trained to output in meters, convert to cm for display
169
+ L_cm = dims[0] * 100
170
+ W_cm = dims[1] * 100
171
+ H_cm = dims[2] * 100
172
+ V_cm3 = dims[3] * 1_000_000 # Convert m^3 to cm^3
173
+
174
+ return {
175
+ "Length (cm)": f"{L_cm:.1f}",
176
+ "Width (cm)": f"{W_cm:.1f}",
177
+ "Height (cm)": f"{H_cm:.1f}",
178
+ "Volume (cm³)": f"{V_cm3:.1f}",
179
+ "Note": "CustomCNN (Pix3D Scale)"
180
+ }
181
+ except Exception as e:
182
+ print(f"Error in predict_dimensions_cnn: {e}")
183
+ return {"L": "N/A", "W": "N/A", "H": "N/A", "V": "N/A", "Note": "CNN Predict Error"}
184
+
185
+ # ------------------------------
186
+ # Streamlit UI
187
+ # ------------------------------
188
+ st.set_page_config(layout="wide", page_title="Object Dimension Estimator")
189
+ st.title("📦 Object Dimension & Volume Estimation")
190
+ st.write("Upload an image. The system will detect objects using Detectron2, draw bounding boxes and masks, and estimate dimensions for the largest detected object using a custom-trained CNN.")
191
+
192
+ # Load models
193
+ dim_model = load_dimension_model()
194
+ if d2_imported_successfully:
195
+ d2_predictor, d2_cfg = load_detectron2_model()
196
+ if d2_cfg is not None:
197
+ # Attempt to get metadata, handle potential KeyErrors
198
+ try:
199
+ d2_metadata = MetadataCatalog.get(d2_cfg.DATASETS.TRAIN[0] if d2_cfg.DATASETS.TRAIN else "coco_2017_val")
200
+ except KeyError:
201
+ st.warning("Default COCO metadata not found. Trying 'coco_2017_train'. Class names might be generic if this also fails.")
202
+ try:
203
+ d2_metadata = MetadataCatalog.get("coco_2017_train")
204
+ except KeyError:
205
+ st.warning("Could not load standard COCO metadata. Using dummy metadata.")
206
+ dummy_name = "streamlit_dummy_coco_dataset_main"
207
+ if dummy_name not in MetadataCatalog.list():
208
+ MetadataCatalog.get(dummy_name).thing_classes = [f"class_{i}" for i in range(80)] # COCO has 80 classes
209
+ d2_metadata = MetadataCatalog.get(dummy_name)
210
+ else:
211
+ d2_metadata = None # Set to None if cfg is None
212
+ else:
213
+ d2_predictor = None
214
+ d2_cfg = None
215
+ d2_metadata = None
216
+
217
+
218
+ uploaded_file = st.file_uploader("Upload a single image (JPG/PNG)", accept_multiple_files=False, type=['jpg', 'jpeg', 'png'])
219
+
220
+ if uploaded_file:
221
+ st.subheader(f"🖼️ Processing: {uploaded_file.name}")
222
+ try:
223
+ image_pil = Image.open(uploaded_file).convert("RGB")
224
+ image_np_rgb = np.array(image_pil) # Convert PIL to NumPy RGB
225
+ image_bgr = cv2.cvtColor(image_np_rgb, cv2.COLOR_RGB2BGR) # OpenCV BGR for Detectron2
226
+ except UnidentifiedImageError:
227
+ st.error("Cannot identify image file. Please upload a valid image.")
228
+ image_bgr = None
229
+ except Exception as e:
230
+ st.error(f"Error loading image: {e}")
231
+ image_bgr = None
232
+
233
+ if image_bgr is not None:
234
+ st.image(image_pil, caption="Uploaded Image", use_container_width=True)
235
+
236
+ if d2_predictor is None or dim_model is None:
237
+ st.error("One or more models (Detectron2, Dimension CNN) failed to load. Cannot process.")
238
+ else:
239
+ with st.spinner("Detecting objects and estimating dimensions..."):
240
+ # --- Detectron2 Inference ---
241
+ outputs = d2_predictor(image_bgr) # Detectron2 expects BGR
242
+ instances = outputs["instances"].to("cpu")
243
+
244
+ if len(instances) == 0:
245
+ st.warning("No objects detected by Detectron2.")
246
+ else:
247
+ # --- Visualization with Bounding Boxes and Masks ---
248
+ # Create a copy for drawing Detectron2's full visualization
249
+ viz_image_bgr = image_bgr.copy()
250
+ v = Visualizer(viz_image_bgr[:, :, ::-1], metadata=d2_metadata, scale=0.8, instance_mode=ColorMode.IMAGE_BW)
251
+ out_vis = v.draw_instance_predictions(instances)
252
+ annotated_img_d2_rgb = out_vis.get_image()[:, :, ::-1] # Visualizer gives RGB
253
+
254
+ st.image(annotated_img_d2_rgb, caption="Detectron2 Detections (Masks & Boxes)", use_container_width=True)
255
+
256
+ # --- Process the largest detected instance for dimension estimation ---
257
+ largest_idx = get_largest_instance_index(instances)
258
+ if largest_idx != -1:
259
+ instance = instances[largest_idx]
260
+
261
+ class_name = "Unknown"
262
+ if instance.has("pred_classes") and d2_metadata and hasattr(d2_metadata, 'thing_classes'):
263
+ class_id = instance.pred_classes.item()
264
+ if class_id < len(d2_metadata.thing_classes):
265
+ class_name = d2_metadata.thing_classes[class_id]
266
+ score = instance.scores.item() if instance.has("scores") else 0.0
267
+ st.write(f"**Processing largest detected object:** {class_name} (Confidence: {score:.2f})")
268
+
269
+ # --- Crop from Mask for Custom CNN ---
270
+ if instance.has("pred_masks"):
271
+ mask_tensor = instance.pred_masks[0] # Get the mask for the largest instance
272
+ # Crop from the RGB numpy array
273
+ object_crop_rgb = crop_from_mask(image_np_rgb, mask_tensor)
274
+
275
+ if object_crop_rgb is not None and object_crop_rgb.shape[0] > 0 and object_crop_rgb.shape[1] > 0:
276
+ st.image(object_crop_rgb, caption="Cropped Object Patch for Dimension CNN", width=250) # Smaller display
277
+
278
+ # --- Predict Dimensions with Custom CNN ---
279
+ dims = predict_dimensions_cnn(object_crop_rgb, dim_model)
280
+ st.write("📏 **Predicted Dimensions (from Custom CNN):**")
281
+ st.json(dims)
282
+ else:
283
+ st.error("Could not crop a valid object patch from the mask.")
284
+ else:
285
+ st.warning("No segmentation mask found for the largest instance. Cannot estimate dimensions with custom CNN.")
286
+ else:
287
+ st.info("Could not determine the largest object to process for dimensions.")
288
+ else:
289
+ if uploaded_file: # If a file was uploaded but image_bgr is None
290
+ st.error("Image could not be loaded for processing.")
291
+
292
+
293
+ # --- Status Footer ---
294
+ st.sidebar.markdown("---")
295
+ st.sidebar.subheader("ℹ️ System Status")
296
+ st.sidebar.markdown(f"**Processing Device:** `{DEVICE}`")
297
+ st.sidebar.markdown(f"**Detectron2 Predictor:** `{'Loaded' if d2_predictor else 'Not Loaded'}`")
298
+ st.sidebar.markdown(f"**Dimension CNN:** `{'Loaded' if dim_model else 'Not Loaded'}`")
299
+ if not os.path.exists(MODEL_PATH):
300
+ st.sidebar.warning(f"Dimension CNN weights file not found at the specified path.")
301
+
hf.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import HfApi
2
+ import os
3
+
4
+ api = HfApi(token=os.getenv("HF_TOKEN"))
5
+ api.upload_folder(
6
+ folder_path=r"C:\Users\pc\TLproj\detectron_model",
7
+ repo_id="suryaprakash01/dimension_Detect",
8
+ repo_type="model",
9
+ )
pix3d_dimension_estimator_mask_crop.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9ab2ec97426df1b3d74e7c9c22760edb774ae3f0015afe1f69ad5ba087356950
3
+ size 98564182
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ torch
3
+ torchvision
4
+ Pillow
5
+ numpy
6
+ opencv-python-headless
7
+ detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu118/torch2.1/index.html