Dev Nagaich commited on
Commit
fb6a0d1
Β·
1 Parent(s): bd0da6b

Fix-Error 403

Browse files
Files changed (2) hide show
  1. Dockerfile +32 -13
  2. app.py +135 -102
Dockerfile CHANGED
@@ -6,6 +6,7 @@ WORKDIR /app
6
  RUN apt-get update && apt-get install -y \
7
  git \
8
  wget \
 
9
  libgl1 \
10
  libglib2.0-0 \
11
  libsm6 \
@@ -16,34 +17,52 @@ RUN apt-get update && apt-get install -y \
16
  # Copy requirements first for better caching
17
  COPY requirements_deploy.txt .
18
 
19
- # Install Python dependencies
20
- RUN pip install --no-cache-dir -r requirements_deploy.txt
 
21
 
22
  # Clone SAM2 repository
23
  RUN git clone https://github.com/facebookresearch/segment-anything-2.git && \
24
  cd segment-anything-2 && \
25
- pip install --no-cache-dir -e .
 
26
 
27
- # Download SAM2 checkpoint
28
- RUN mkdir -p segment-anything-2/checkpoints && \
29
- cd segment-anything-2/checkpoints && \
30
- wget https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_small.pt
31
 
32
- # Download VREyeSAM fine-tuned weights
 
 
 
 
 
33
  RUN pip install --no-cache-dir huggingface-hub && \
34
- hf download devnagaich/VREyeSAM \
35
- VREyeSAM_uncertainity_best.torch \
36
- --local-dir segment-anything-2/checkpoints/
 
 
 
 
 
 
 
 
37
 
38
  # Copy application files
39
  COPY app.py .
40
 
 
41
  EXPOSE 7860
42
 
 
43
  ENV STREAMLIT_SERVER_PORT=7860
44
  ENV STREAMLIT_SERVER_ADDRESS=0.0.0.0
45
  ENV STREAMLIT_SERVER_HEADLESS=true
 
46
 
47
- CMD ["streamlit", "run", "app.py", "--server.port=7860", "--server.address=0.0.0.0"]
48
-
49
 
 
 
 
6
  RUN apt-get update && apt-get install -y \
7
  git \
8
  wget \
9
+ curl \
10
  libgl1 \
11
  libglib2.0-0 \
12
  libsm6 \
 
17
  # Copy requirements first for better caching
18
  COPY requirements_deploy.txt .
19
 
20
+ # Install Python dependencies with version constraints
21
+ RUN pip install --no-cache-dir --upgrade pip && \
22
+ pip install --no-cache-dir -r requirements_deploy.txt
23
 
24
  # Clone SAM2 repository
25
  RUN git clone https://github.com/facebookresearch/segment-anything-2.git && \
26
  cd segment-anything-2 && \
27
+ pip install --no-cache-dir -e . && \
28
+ cd ..
29
 
30
+ # Create checkpoints directory
31
+ RUN mkdir -p segment-anything-2/checkpoints
 
 
32
 
33
+ # Download SAM2 base checkpoint
34
+ RUN wget --no-check-certificate \
35
+ https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_small.pt \
36
+ -O segment-anything-2/checkpoints/sam2_hiera_small.pt
37
+
38
+ # Download VREyeSAM fine-tuned weights using Python
39
  RUN pip install --no-cache-dir huggingface-hub && \
40
+ python -c "from huggingface_hub import hf_hub_download; \
41
+ hf_hub_download(repo_id='devnagaich/VREyeSAM', \
42
+ filename='VREyeSAM_uncertainity_best.torch', \
43
+ local_dir='segment-anything-2/checkpoints', \
44
+ local_dir_use_symlinks=False)"
45
+
46
+ # Verify files were downloaded
47
+ RUN ls -lh segment-anything-2/checkpoints/ && \
48
+ test -f segment-anything-2/checkpoints/sam2_hiera_small.pt && \
49
+ test -f segment-anything-2/checkpoints/VREyeSAM_uncertainity_best.torch && \
50
+ echo "All checkpoints downloaded successfully!"
51
 
52
  # Copy application files
53
  COPY app.py .
54
 
55
+ # Expose Streamlit port
56
  EXPOSE 7860
57
 
58
+ # Set environment variables
59
  ENV STREAMLIT_SERVER_PORT=7860
60
  ENV STREAMLIT_SERVER_ADDRESS=0.0.0.0
61
  ENV STREAMLIT_SERVER_HEADLESS=true
62
+ ENV STREAMLIT_BROWSER_GATHER_USAGE_STATS=false
63
 
64
+ # Health check
65
+ HEALTHCHECK CMD curl --fail http://localhost:7860/_stcore/health || exit 1
66
 
67
+ # Run the application
68
+ CMD ["streamlit", "run", "app.py", "--server.port=7860", "--server.address=0.0.0.0"]
app.py CHANGED
@@ -6,6 +6,7 @@ from PIL import Image
6
  import io
7
  import sys
8
  import os
 
9
 
10
  # Add segment-anything-2 to path
11
  sys.path.insert(0, os.path.join(os.path.dirname(__file__), "segment-anything-2"))
@@ -46,17 +47,41 @@ st.markdown("""
46
  def load_model():
47
  """Load the VREyeSAM model"""
48
  try:
49
- model_cfg = "configs/sam2/sam2_hiera_s.yaml"
 
50
  sam2_checkpoint = "segment-anything-2/checkpoints/sam2_hiera_small.pt"
51
  fine_tuned_weights = "segment-anything-2/checkpoints/VREyeSAM_uncertainity_best.torch"
52
 
53
- sam2_model = build_sam2(model_cfg, sam2_checkpoint, device="cuda" if torch.cuda.is_available() else "cpu")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  predictor = SAM2ImagePredictor(sam2_model)
55
- predictor.model.load_state_dict(torch.load(fine_tuned_weights, map_location="cuda" if torch.cuda.is_available() else "cpu"))
56
 
57
  return predictor
58
  except Exception as e:
59
- st.error(f"Error loading model: {str(e)}")
 
 
60
  return None
61
 
62
  def read_and_resize_image(image):
@@ -132,7 +157,7 @@ def extract_iris_strip(image, binary_mask):
132
 
133
  # Create a rectangular strip (normalize height)
134
  strip_height = 150
135
- aspect_ratio = w / h
136
  strip_width = int(strip_height * aspect_ratio)
137
 
138
  iris_strip = cv2.resize(iris_region, (strip_width, strip_height))
@@ -168,15 +193,16 @@ def main():
168
  - Inconsistent lighting conditions
169
 
170
  **Model Performance:**
 
171
  - Recall: 0.870
172
  - F1-Score: 0.806
173
-
174
-
175
  """)
176
 
177
  st.header("Settings")
178
  show_overlay = st.checkbox("Show Mask Overlay", value=True)
179
  show_probabilistic = st.checkbox("Show Probabilistic Mask", value=False)
 
180
 
181
  # Load model
182
  with st.spinner("Loading VREyeSAM model..."):
@@ -208,113 +234,120 @@ def main():
208
  # Process button
209
  if st.button("πŸ” Segment Iris", type="primary"):
210
  with st.spinner("Segmenting iris..."):
211
- # Prepare image
212
- img_array = read_and_resize_image(image)
213
-
214
- # Perform segmentation
215
- binary_mask, prob_mask = segment_iris(predictor, img_array)
216
-
217
- # Extract iris strip
218
- ## iris_strip = extract_iris_strip(img_array, binary_mask)
219
-
220
- with col2:
221
- st.subheader("🎯 Binary Mask")
222
- binary_mask_img = (binary_mask * 255).astype(np.uint8)
223
- st.image(binary_mask_img, use_container_width=True)
224
-
225
- # Additional results
226
- st.markdown("---")
227
- st.subheader("πŸ“Š Segmentation Results")
228
-
229
- result_cols = st.columns(3)
230
-
231
- with result_cols[0]:
232
- if show_overlay:
233
- st.markdown("**Overlay View**")
234
- overlay = overlay_mask_on_image(img_array, binary_mask)
235
- st.image(overlay, use_container_width=True)
236
-
237
- with result_cols[1]:
238
- if show_probabilistic:
239
- st.markdown("**Probabilistic Mask**")
240
- prob_mask_img = (prob_mask * 255).astype(np.uint8)
241
- st.image(prob_mask_img, use_container_width=True)
242
-
243
- # with result_cols[2]:
244
- # if iris_strip is not None:
245
- # st.markdown("**Extracted Iris Strip**")
246
- # st.image(iris_strip, use_container_width=True)
247
- # else:
248
- # st.warning("No iris region detected")
249
-
250
- # Download options
251
- st.markdown("---")
252
- st.subheader("πŸ’Ύ Download Results")
253
-
254
- download_cols = st.columns(3)
255
-
256
- with download_cols[0]:
257
- # Binary mask download
258
- binary_pil = Image.fromarray(binary_mask_img)
259
- buf = io.BytesIO()
260
- binary_pil.save(buf, format="PNG")
261
- st.download_button(
262
- label="Download Binary Mask",
263
- data=buf.getvalue(),
264
- file_name="binary_mask.png",
265
- mime="image/png"
266
- )
267
-
268
- with download_cols[1]:
269
- if show_overlay:
270
- # Overlay download
271
- overlay_pil = Image.fromarray(cv2.cvtColor(overlay, cv2.COLOR_BGR2RGB))
272
  buf = io.BytesIO()
273
- overlay_pil.save(buf, format="PNG")
274
  st.download_button(
275
- label="Download Overlay",
276
  data=buf.getvalue(),
277
- file_name="overlay.png",
278
  mime="image/png"
279
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
281
- # with download_cols[2]:
282
- # if iris_strip is not None:
283
- # # Iris strip download
284
- # strip_pil = Image.fromarray(cv2.cvtColor(iris_strip, cv2.COLOR_BGR2RGB))
285
- # buf = io.BytesIO()
286
- # strip_pil.save(buf, format="PNG")
287
- # st.download_button(
288
- # label="Download Iris Strip",
289
- # data=buf.getvalue(),
290
- # file_name="iris_strip.png",
291
- # mime="image/png"
292
- # )
293
-
294
- # Statistics
295
- st.markdown("---")
296
- st.subheader("πŸ“ˆ Segmentation Statistics")
297
- stats_cols = st.columns(4)
298
-
299
- mask_area = np.sum(binary_mask > 0)
300
- total_area = binary_mask.shape[0] * binary_mask.shape[1]
301
- coverage = (mask_area / total_area) * 100
302
-
303
- with stats_cols[0]:
304
- st.metric("Mask Coverage", f"{coverage:.2f}%")
305
- with stats_cols[1]:
306
- st.metric("Image Size", f"{img_array.shape[1]}x{img_array.shape[0]}")
307
- with stats_cols[2]:
308
- st.metric("Mask Area (pixels)", f"{mask_area:,}")
309
- # with stats_cols[3]:
310
- # if iris_strip is not None:
311
- # st.metric("Strip Size", f"{iris_strip.shape[1]}x{iris_strip.shape[0]}")
312
 
313
  # Footer
314
  st.markdown("---")
315
  st.markdown("""
316
  <div style='text-align: center'>
317
  <p><strong>VREyeSAM</strong> - Virtual Reality Non-Frontal Iris Segmentation</p>
 
318
  <p>πŸ”— <a href='https://github.com/GeetanjaliGTZ/VREyeSAM'>GitHub</a> |
319
  πŸ“§ <a href='mailto:geetanjalisharma546@gmail.com'>Contact</a></p>
320
  </div>
 
6
  import io
7
  import sys
8
  import os
9
+ import traceback
10
 
11
  # Add segment-anything-2 to path
12
  sys.path.insert(0, os.path.join(os.path.dirname(__file__), "segment-anything-2"))
 
47
  def load_model():
48
  """Load the VREyeSAM model"""
49
  try:
50
+ # Path handling for both local and Docker environments
51
+ model_cfg = "segment-anything-2/configs/sam2/sam2_hiera_s.yaml"
52
  sam2_checkpoint = "segment-anything-2/checkpoints/sam2_hiera_small.pt"
53
  fine_tuned_weights = "segment-anything-2/checkpoints/VREyeSAM_uncertainity_best.torch"
54
 
55
+ # Verify files exist
56
+ if not os.path.exists(sam2_checkpoint):
57
+ st.error(f"❌ SAM2 checkpoint not found at: {sam2_checkpoint}")
58
+ st.info("Current directory: " + os.getcwd())
59
+ st.info("Directory contents: " + str(os.listdir(".")))
60
+ return None
61
+
62
+ if not os.path.exists(fine_tuned_weights):
63
+ st.error(f"❌ VREyeSAM weights not found at: {fine_tuned_weights}")
64
+ return None
65
+
66
+ # Check file sizes
67
+ sam2_size = os.path.getsize(sam2_checkpoint) / (1024 * 1024)
68
+ vresam_size = os.path.getsize(fine_tuned_weights) / (1024 * 1024)
69
+ st.info(f"πŸ“¦ SAM2 checkpoint: {sam2_size:.1f} MB")
70
+ st.info(f"πŸ“¦ VREyeSAM weights: {vresam_size:.1f} MB")
71
+
72
+ # Load model
73
+ device = "cuda" if torch.cuda.is_available() else "cpu"
74
+ st.info(f"πŸ–₯️ Loading model on: {device.upper()}")
75
+
76
+ sam2_model = build_sam2(model_cfg, sam2_checkpoint, device=device)
77
  predictor = SAM2ImagePredictor(sam2_model)
78
+ predictor.model.load_state_dict(torch.load(fine_tuned_weights, map_location=device))
79
 
80
  return predictor
81
  except Exception as e:
82
+ st.error(f"❌ Error loading model: {str(e)}")
83
+ st.error("Full traceback:")
84
+ st.code(traceback.format_exc())
85
  return None
86
 
87
  def read_and_resize_image(image):
 
157
 
158
  # Create a rectangular strip (normalize height)
159
  strip_height = 150
160
+ aspect_ratio = w / h if h > 0 else 1
161
  strip_width = int(strip_height * aspect_ratio)
162
 
163
  iris_strip = cv2.resize(iris_region, (strip_width, strip_height))
 
193
  - Inconsistent lighting conditions
194
 
195
  **Model Performance:**
196
+ - Precision: 0.751
197
  - Recall: 0.870
198
  - F1-Score: 0.806
199
+ - Mean IoU: 0.647
 
200
  """)
201
 
202
  st.header("Settings")
203
  show_overlay = st.checkbox("Show Mask Overlay", value=True)
204
  show_probabilistic = st.checkbox("Show Probabilistic Mask", value=False)
205
+ show_iris_strip = st.checkbox("Show Iris Strip", value=True)
206
 
207
  # Load model
208
  with st.spinner("Loading VREyeSAM model..."):
 
234
  # Process button
235
  if st.button("πŸ” Segment Iris", type="primary"):
236
  with st.spinner("Segmenting iris..."):
237
+ try:
238
+ # Prepare image
239
+ img_array = read_and_resize_image(image)
240
+
241
+ # Perform segmentation
242
+ binary_mask, prob_mask = segment_iris(predictor, img_array)
243
+
244
+ # Extract iris strip
245
+ iris_strip = extract_iris_strip(img_array, binary_mask) if show_iris_strip else None
246
+
247
+ with col2:
248
+ st.subheader("🎯 Binary Mask")
249
+ binary_mask_img = (binary_mask * 255).astype(np.uint8)
250
+ st.image(binary_mask_img, use_container_width=True)
251
+
252
+ # Additional results
253
+ st.markdown("---")
254
+ st.subheader("πŸ“Š Segmentation Results")
255
+
256
+ result_cols = st.columns(3)
257
+
258
+ with result_cols[0]:
259
+ if show_overlay:
260
+ st.markdown("**Overlay View**")
261
+ overlay = overlay_mask_on_image(img_array, binary_mask)
262
+ st.image(overlay, use_container_width=True)
263
+
264
+ with result_cols[1]:
265
+ if show_probabilistic:
266
+ st.markdown("**Probabilistic Mask**")
267
+ prob_mask_img = (prob_mask * 255).astype(np.uint8)
268
+ st.image(prob_mask_img, use_container_width=True)
269
+
270
+ with result_cols[2]:
271
+ if show_iris_strip and iris_strip is not None:
272
+ st.markdown("**Extracted Iris Strip**")
273
+ st.image(iris_strip, use_container_width=True)
274
+ elif show_iris_strip:
275
+ st.warning("No iris region detected")
276
+
277
+ # Download options
278
+ st.markdown("---")
279
+ st.subheader("πŸ’Ύ Download Results")
280
+
281
+ download_cols = st.columns(3)
282
+
283
+ with download_cols[0]:
284
+ # Binary mask download
285
+ binary_pil = Image.fromarray(binary_mask_img)
 
 
 
 
 
 
 
 
 
 
 
 
286
  buf = io.BytesIO()
287
+ binary_pil.save(buf, format="PNG")
288
  st.download_button(
289
+ label="Download Binary Mask",
290
  data=buf.getvalue(),
291
+ file_name="binary_mask.png",
292
  mime="image/png"
293
  )
294
+
295
+ with download_cols[1]:
296
+ if show_overlay:
297
+ # Overlay download
298
+ overlay_pil = Image.fromarray(cv2.cvtColor(overlay, cv2.COLOR_BGR2RGB))
299
+ buf = io.BytesIO()
300
+ overlay_pil.save(buf, format="PNG")
301
+ st.download_button(
302
+ label="Download Overlay",
303
+ data=buf.getvalue(),
304
+ file_name="overlay.png",
305
+ mime="image/png"
306
+ )
307
+
308
+ with download_cols[2]:
309
+ if iris_strip is not None:
310
+ # Iris strip download
311
+ strip_pil = Image.fromarray(cv2.cvtColor(iris_strip, cv2.COLOR_BGR2RGB))
312
+ buf = io.BytesIO()
313
+ strip_pil.save(buf, format="PNG")
314
+ st.download_button(
315
+ label="Download Iris Strip",
316
+ data=buf.getvalue(),
317
+ file_name="iris_strip.png",
318
+ mime="image/png"
319
+ )
320
+
321
+ # Statistics
322
+ st.markdown("---")
323
+ st.subheader("πŸ“ˆ Segmentation Statistics")
324
+ stats_cols = st.columns(4)
325
+
326
+ mask_area = np.sum(binary_mask > 0)
327
+ total_area = binary_mask.shape[0] * binary_mask.shape[1]
328
+ coverage = (mask_area / total_area) * 100
329
+
330
+ with stats_cols[0]:
331
+ st.metric("Mask Coverage", f"{coverage:.2f}%")
332
+ with stats_cols[1]:
333
+ st.metric("Image Size", f"{img_array.shape[1]}x{img_array.shape[0]}")
334
+ with stats_cols[2]:
335
+ st.metric("Mask Area (pixels)", f"{mask_area:,}")
336
+ with stats_cols[3]:
337
+ if iris_strip is not None:
338
+ st.metric("Strip Size", f"{iris_strip.shape[1]}x{iris_strip.shape[0]}")
339
 
340
+ except Exception as e:
341
+ st.error(f"❌ Error during segmentation: {str(e)}")
342
+ st.error("Full traceback:")
343
+ st.code(traceback.format_exc())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
 
345
  # Footer
346
  st.markdown("---")
347
  st.markdown("""
348
  <div style='text-align: center'>
349
  <p><strong>VREyeSAM</strong> - Virtual Reality Non-Frontal Iris Segmentation</p>
350
+ <p>Sharma et al., IJCB 2025</p>
351
  <p>πŸ”— <a href='https://github.com/GeetanjaliGTZ/VREyeSAM'>GitHub</a> |
352
  πŸ“§ <a href='mailto:geetanjalisharma546@gmail.com'>Contact</a></p>
353
  </div>