Spaces:
Sleeping
Sleeping
Dev Nagaich commited on
Commit Β·
7e95037
1
Parent(s): 8794644
Path error resolved
Browse files- .streamlit/config.toml +5 -2
- Dockerfile +10 -9
- README.md +1 -2
- app.py +5 -62
.streamlit/config.toml
CHANGED
|
@@ -3,8 +3,11 @@ maxUploadSize = 500
|
|
| 3 |
headless = true
|
| 4 |
port = 7860
|
| 5 |
address = "0.0.0.0"
|
|
|
|
|
|
|
| 6 |
|
| 7 |
[browser]
|
| 8 |
gatherUsageStats = false
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
| 3 |
headless = true
|
| 4 |
port = 7860
|
| 5 |
address = "0.0.0.0"
|
| 6 |
+
enableCORS = false
|
| 7 |
+
enableXsrfProtection = false
|
| 8 |
|
| 9 |
[browser]
|
| 10 |
gatherUsageStats = false
|
| 11 |
+
|
| 12 |
+
[theme]
|
| 13 |
+
base = "light"
|
Dockerfile
CHANGED
|
@@ -21,9 +21,11 @@ COPY requirements_deploy.txt .
|
|
| 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 |
|
|
@@ -35,16 +37,15 @@ 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 weights using
|
| 39 |
-
RUN
|
| 40 |
-
|
| 41 |
-
|
| 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 |
|
| 49 |
# Create Streamlit config directory
|
| 50 |
RUN mkdir -p /root/.streamlit
|
|
|
|
| 21 |
RUN pip install --no-cache-dir --upgrade pip && \
|
| 22 |
pip install --no-cache-dir -r requirements_deploy.txt
|
| 23 |
|
| 24 |
+
# Clone SAM2 repository at a specific commit that has hieradet
|
| 25 |
+
# Using an older version that's compatible with the VREyeSAM weights
|
| 26 |
RUN git clone https://github.com/facebookresearch/segment-anything-2.git && \
|
| 27 |
cd segment-anything-2 && \
|
| 28 |
+
git checkout 7e1596c0b6462eb1d1ba7e1492430fed95023598 && \
|
| 29 |
pip install --no-cache-dir -e . && \
|
| 30 |
cd ..
|
| 31 |
|
|
|
|
| 37 |
https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_small.pt \
|
| 38 |
-O segment-anything-2/checkpoints/sam2_hiera_small.pt
|
| 39 |
|
| 40 |
+
# Download VREyeSAM weights using direct wget from HuggingFace
|
| 41 |
+
RUN wget --no-check-certificate \
|
| 42 |
+
"https://huggingface.co/devnagaich/VREyeSAM/resolve/main/VREyeSAM_uncertainity_best.torch" \
|
| 43 |
+
-O segment-anything-2/checkpoints/VREyeSAM_uncertainity_best.torch
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
# Verify files were downloaded
|
| 46 |
+
RUN ls -lh segment-anything-2/checkpoints/ && \
|
| 47 |
+
test -f segment-anything-2/checkpoints/sam2_hiera_small.pt && \
|
| 48 |
+
test -f segment-anything-2/checkpoints/VREyeSAM_uncertainity_best.torch
|
| 49 |
|
| 50 |
# Create Streamlit config directory
|
| 51 |
RUN mkdir -p /root/.streamlit
|
README.md
CHANGED
|
@@ -22,7 +22,6 @@ VREyeSAM is a robust iris segmentation framework designed specifically for non-f
|
|
| 22 |
|
| 23 |
- **Upload & Segment**: Upload any non-frontal iris image for instant segmentation
|
| 24 |
- **Binary Mask Generation**: Get precise binary segmentation masks
|
| 25 |
-
- **Iris Extraction**: Automatically extract and display the iris region as a rectangular strip
|
| 26 |
- **Visualization Options**: View overlay masks and probabilistic confidence maps
|
| 27 |
- **Download Results**: Save all segmentation outputs with one click
|
| 28 |
|
|
@@ -98,7 +97,7 @@ This project is licensed under the MIT License.
|
|
| 98 |
|
| 99 |
1. **Upload Image**: Click on the upload button and select a non-frontal iris image
|
| 100 |
2. **Segment**: Click the "Segment Iris" button to process the image
|
| 101 |
-
3. **View Results**: Explore the binary mask, overlay, and
|
| 102 |
4. **Download**: Save any of the results using the download buttons
|
| 103 |
|
| 104 |
## βοΈ Model Details
|
|
|
|
| 22 |
|
| 23 |
- **Upload & Segment**: Upload any non-frontal iris image for instant segmentation
|
| 24 |
- **Binary Mask Generation**: Get precise binary segmentation masks
|
|
|
|
| 25 |
- **Visualization Options**: View overlay masks and probabilistic confidence maps
|
| 26 |
- **Download Results**: Save all segmentation outputs with one click
|
| 27 |
|
|
|
|
| 97 |
|
| 98 |
1. **Upload Image**: Click on the upload button and select a non-frontal iris image
|
| 99 |
2. **Segment**: Click the "Segment Iris" button to process the image
|
| 100 |
+
3. **View Results**: Explore the binary mask, overlay, and probabilistic confidence map
|
| 101 |
4. **Download**: Save any of the results using the download buttons
|
| 102 |
|
| 103 |
## βοΈ Model Details
|
app.py
CHANGED
|
@@ -47,7 +47,8 @@ st.markdown("""
|
|
| 47 |
def load_model():
|
| 48 |
"""Load the VREyeSAM model"""
|
| 49 |
try:
|
| 50 |
-
#
|
|
|
|
| 51 |
model_cfg = "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"
|
|
@@ -113,37 +114,6 @@ def segment_iris(predictor, image):
|
|
| 113 |
|
| 114 |
return binary_mask, prob_mask
|
| 115 |
|
| 116 |
-
def extract_iris_strip(image, binary_mask):
|
| 117 |
-
"""Extract iris region and create a rectangular strip"""
|
| 118 |
-
# Find contours in binary mask
|
| 119 |
-
contours, _ = cv2.findContours(binary_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
| 120 |
-
|
| 121 |
-
if len(contours) == 0:
|
| 122 |
-
return None
|
| 123 |
-
|
| 124 |
-
# Get the largest contour (assumed to be the iris)
|
| 125 |
-
largest_contour = max(contours, key=cv2.contourArea)
|
| 126 |
-
x, y, w, h = cv2.boundingRect(largest_contour)
|
| 127 |
-
|
| 128 |
-
# Add some padding
|
| 129 |
-
padding = 10
|
| 130 |
-
x = max(0, x - padding)
|
| 131 |
-
y = max(0, y - padding)
|
| 132 |
-
w = min(image.shape[1] - x, w + 2 * padding)
|
| 133 |
-
h = min(image.shape[0] - y, h + 2 * padding)
|
| 134 |
-
|
| 135 |
-
# Extract the iris region
|
| 136 |
-
iris_region = image[y:y+h, x:x+w]
|
| 137 |
-
|
| 138 |
-
# Create a rectangular strip (normalize height)
|
| 139 |
-
strip_height = 150
|
| 140 |
-
aspect_ratio = w / h if h > 0 else 1
|
| 141 |
-
strip_width = int(strip_height * aspect_ratio)
|
| 142 |
-
|
| 143 |
-
iris_strip = cv2.resize(iris_region, (strip_width, strip_height))
|
| 144 |
-
|
| 145 |
-
return iris_strip
|
| 146 |
-
|
| 147 |
def overlay_mask_on_image(image, binary_mask, color=(0, 255, 0), alpha=0.5):
|
| 148 |
"""Overlay binary mask on original image"""
|
| 149 |
overlay = image.copy()
|
|
@@ -180,7 +150,6 @@ def main():
|
|
| 180 |
st.header("Settings")
|
| 181 |
show_overlay = st.checkbox("Show Mask Overlay", value=True)
|
| 182 |
show_probabilistic = st.checkbox("Show Probabilistic Mask", value=False)
|
| 183 |
-
show_iris_strip = st.checkbox("Show Iris Strip", value=True)
|
| 184 |
|
| 185 |
# Load model
|
| 186 |
with st.spinner("Loading VREyeSAM model..."):
|
|
@@ -220,9 +189,6 @@ def main():
|
|
| 220 |
# Perform segmentation
|
| 221 |
binary_mask, prob_mask = segment_iris(predictor, img_array)
|
| 222 |
|
| 223 |
-
# Extract iris strip
|
| 224 |
-
iris_strip = extract_iris_strip(img_array, binary_mask) if show_iris_strip else None
|
| 225 |
-
|
| 226 |
with col2:
|
| 227 |
st.subheader("π― Binary Mask")
|
| 228 |
binary_mask_img = (binary_mask * 255).astype(np.uint8)
|
|
@@ -232,7 +198,7 @@ def main():
|
|
| 232 |
st.markdown("---")
|
| 233 |
st.subheader("π Segmentation Results")
|
| 234 |
|
| 235 |
-
result_cols = st.columns(
|
| 236 |
|
| 237 |
with result_cols[0]:
|
| 238 |
if show_overlay:
|
|
@@ -246,18 +212,11 @@ def main():
|
|
| 246 |
prob_mask_img = (prob_mask * 255).astype(np.uint8)
|
| 247 |
st.image(prob_mask_img, use_container_width=True)
|
| 248 |
|
| 249 |
-
with result_cols[2]:
|
| 250 |
-
if show_iris_strip and iris_strip is not None:
|
| 251 |
-
st.markdown("**Extracted Iris Strip**")
|
| 252 |
-
st.image(iris_strip, use_container_width=True)
|
| 253 |
-
elif show_iris_strip:
|
| 254 |
-
st.warning("No iris region detected")
|
| 255 |
-
|
| 256 |
# Download options
|
| 257 |
st.markdown("---")
|
| 258 |
st.subheader("πΎ Download Results")
|
| 259 |
|
| 260 |
-
download_cols = st.columns(
|
| 261 |
|
| 262 |
with download_cols[0]:
|
| 263 |
# Binary mask download
|
|
@@ -284,23 +243,10 @@ def main():
|
|
| 284 |
mime="image/png"
|
| 285 |
)
|
| 286 |
|
| 287 |
-
with download_cols[2]:
|
| 288 |
-
if iris_strip is not None:
|
| 289 |
-
# Iris strip download
|
| 290 |
-
strip_pil = Image.fromarray(cv2.cvtColor(iris_strip, cv2.COLOR_BGR2RGB))
|
| 291 |
-
buf = io.BytesIO()
|
| 292 |
-
strip_pil.save(buf, format="PNG")
|
| 293 |
-
st.download_button(
|
| 294 |
-
label="Download Iris Strip",
|
| 295 |
-
data=buf.getvalue(),
|
| 296 |
-
file_name="iris_strip.png",
|
| 297 |
-
mime="image/png"
|
| 298 |
-
)
|
| 299 |
-
|
| 300 |
# Statistics
|
| 301 |
st.markdown("---")
|
| 302 |
st.subheader("π Segmentation Statistics")
|
| 303 |
-
stats_cols = st.columns(
|
| 304 |
|
| 305 |
mask_area = np.sum(binary_mask > 0)
|
| 306 |
total_area = binary_mask.shape[0] * binary_mask.shape[1]
|
|
@@ -312,9 +258,6 @@ def main():
|
|
| 312 |
st.metric("Image Size", f"{img_array.shape[1]}x{img_array.shape[0]}")
|
| 313 |
with stats_cols[2]:
|
| 314 |
st.metric("Mask Area (pixels)", f"{mask_area:,}")
|
| 315 |
-
with stats_cols[3]:
|
| 316 |
-
if iris_strip is not None:
|
| 317 |
-
st.metric("Strip Size", f"{iris_strip.shape[1]}x{iris_strip.shape[0]}")
|
| 318 |
|
| 319 |
except Exception as e:
|
| 320 |
st.error(f"β Error during segmentation: {str(e)}")
|
|
|
|
| 47 |
def load_model():
|
| 48 |
"""Load the VREyeSAM model"""
|
| 49 |
try:
|
| 50 |
+
# IMPORTANT: Hydra config system searches within sam2 package
|
| 51 |
+
# Use relative path without "segment-anything-2/" prefix
|
| 52 |
model_cfg = "configs/sam2/sam2_hiera_s.yaml"
|
| 53 |
sam2_checkpoint = "segment-anything-2/checkpoints/sam2_hiera_small.pt"
|
| 54 |
fine_tuned_weights = "segment-anything-2/checkpoints/VREyeSAM_uncertainity_best.torch"
|
|
|
|
| 114 |
|
| 115 |
return binary_mask, prob_mask
|
| 116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
def overlay_mask_on_image(image, binary_mask, color=(0, 255, 0), alpha=0.5):
|
| 118 |
"""Overlay binary mask on original image"""
|
| 119 |
overlay = image.copy()
|
|
|
|
| 150 |
st.header("Settings")
|
| 151 |
show_overlay = st.checkbox("Show Mask Overlay", value=True)
|
| 152 |
show_probabilistic = st.checkbox("Show Probabilistic Mask", value=False)
|
|
|
|
| 153 |
|
| 154 |
# Load model
|
| 155 |
with st.spinner("Loading VREyeSAM model..."):
|
|
|
|
| 189 |
# Perform segmentation
|
| 190 |
binary_mask, prob_mask = segment_iris(predictor, img_array)
|
| 191 |
|
|
|
|
|
|
|
|
|
|
| 192 |
with col2:
|
| 193 |
st.subheader("π― Binary Mask")
|
| 194 |
binary_mask_img = (binary_mask * 255).astype(np.uint8)
|
|
|
|
| 198 |
st.markdown("---")
|
| 199 |
st.subheader("π Segmentation Results")
|
| 200 |
|
| 201 |
+
result_cols = st.columns(2)
|
| 202 |
|
| 203 |
with result_cols[0]:
|
| 204 |
if show_overlay:
|
|
|
|
| 212 |
prob_mask_img = (prob_mask * 255).astype(np.uint8)
|
| 213 |
st.image(prob_mask_img, use_container_width=True)
|
| 214 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
# Download options
|
| 216 |
st.markdown("---")
|
| 217 |
st.subheader("πΎ Download Results")
|
| 218 |
|
| 219 |
+
download_cols = st.columns(2)
|
| 220 |
|
| 221 |
with download_cols[0]:
|
| 222 |
# Binary mask download
|
|
|
|
| 243 |
mime="image/png"
|
| 244 |
)
|
| 245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
# Statistics
|
| 247 |
st.markdown("---")
|
| 248 |
st.subheader("π Segmentation Statistics")
|
| 249 |
+
stats_cols = st.columns(3)
|
| 250 |
|
| 251 |
mask_area = np.sum(binary_mask > 0)
|
| 252 |
total_area = binary_mask.shape[0] * binary_mask.shape[1]
|
|
|
|
| 258 |
st.metric("Image Size", f"{img_array.shape[1]}x{img_array.shape[0]}")
|
| 259 |
with stats_cols[2]:
|
| 260 |
st.metric("Mask Area (pixels)", f"{mask_area:,}")
|
|
|
|
|
|
|
|
|
|
| 261 |
|
| 262 |
except Exception as e:
|
| 263 |
st.error(f"β Error during segmentation: {str(e)}")
|