selvaneyas commited on
Commit
50a9866
Β·
verified Β·
1 Parent(s): 2faa5b2

Upload 5 files

Browse files
Files changed (5) hide show
  1. .gitattributes +38 -35
  2. Dockerfile +20 -20
  3. README.md +19 -19
  4. requirements.txt +2 -2
  5. streamlit_app.py +226 -0
.gitattributes CHANGED
@@ -1,35 +1,38 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.keras filter=lfs diff=lfs merge=lfs -text
37
+ *.jpg filter=lfs diff=lfs merge=lfs -text
38
+ *.png filter=lfs diff=lfs merge=lfs -text
Dockerfile CHANGED
@@ -1,20 +1,20 @@
1
- FROM python:3.13.5-slim
2
-
3
- WORKDIR /app
4
-
5
- RUN apt-get update && apt-get install -y \
6
- build-essential \
7
- curl \
8
- git \
9
- && rm -rf /var/lib/apt/lists/*
10
-
11
- COPY requirements.txt ./
12
- COPY src/ ./src/
13
-
14
- RUN pip3 install -r requirements.txt
15
-
16
- EXPOSE 8501
17
-
18
- HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
19
-
20
- ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
 
1
+ FROM python:3.13.5-slim
2
+
3
+ WORKDIR /app
4
+
5
+ RUN apt-get update && apt-get install -y \
6
+ build-essential \
7
+ curl \
8
+ git \
9
+ && rm -rf /var/lib/apt/lists/*
10
+
11
+ COPY requirements.txt ./
12
+ COPY src/ ./src/
13
+
14
+ RUN pip3 install -r requirements.txt
15
+
16
+ EXPOSE 8501
17
+
18
+ HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
19
+
20
+ ENTRYPOINT ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
README.md CHANGED
@@ -1,19 +1,19 @@
1
- ---
2
- title: Smart Election Verification
3
- emoji: πŸš€
4
- colorFrom: red
5
- colorTo: red
6
- sdk: docker
7
- app_port: 8501
8
- tags:
9
- - streamlit
10
- pinned: false
11
- short_description: Streamlit template space
12
- ---
13
-
14
- # Welcome to Streamlit!
15
-
16
- Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
17
-
18
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
19
- forums](https://discuss.streamlit.io).
 
1
+ ---
2
+ title: Smart Election Verification
3
+ emoji: πŸš€
4
+ colorFrom: red
5
+ colorTo: red
6
+ sdk: docker
7
+ app_port: 8501
8
+ tags:
9
+ - streamlit
10
+ pinned: false
11
+ short_description: Streamlit template space
12
+ ---
13
+
14
+ # Welcome to Streamlit!
15
+
16
+ Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
17
+
18
+ If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
19
+ forums](https://discuss.streamlit.io).
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
- altair
2
- pandas
3
  streamlit
 
1
+ altair
2
+ pandas
3
  streamlit
streamlit_app.py ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import cv2
3
+ import numpy as np
4
+ import pandas as pd
5
+ import tensorflow as tf
6
+
7
+ from src.siamese_model import build_siamese_model
8
+ from src.inference import verify_images
9
+
10
+ # ==============================
11
+ # PAGE CONFIG
12
+ # ==============================
13
+ st.set_page_config(
14
+ page_title="Smart Election Verification System",
15
+ page_icon="πŸ—³οΈ",
16
+ layout="centered"
17
+ )
18
+
19
+ st.title("πŸ—³οΈ Multimodal Biometric verification System")
20
+
21
+ # ==============================
22
+ # GLOBAL CONSTANTS
23
+ # ==============================
24
+ IMG_SIZE = 128
25
+ THRESHOLD = 0.5
26
+
27
+ # ==============================
28
+ # MODE SELECTION (MUST BE FIRST)
29
+ # ==============================
30
+ MODE = st.selectbox(
31
+ "Select Verification Mode",
32
+ ["Iris Verification", "Fingerprint Verification"]
33
+ )
34
+
35
+ # ==============================
36
+ # MODEL LOADING
37
+ # ==============================
38
+ model_path = (
39
+ "models/iris_siamese.keras"
40
+ if MODE == "Iris Verification"
41
+ else "models/finger_siamese.keras"
42
+ )
43
+
44
+ @st.cache_resource
45
+ def load_model(path):
46
+ model = build_siamese_model()
47
+ model.load_weights(path)
48
+ return model
49
+
50
+ model = load_model(model_path)
51
+
52
+ # ==============================
53
+ # SIDEBAR – DATASET INSPECTOR
54
+ # ==============================
55
+ st.sidebar.header("πŸ“‚ Dataset Inspector")
56
+
57
+ csv_path = (
58
+ "pairs/iris_pairs.csv"
59
+ if MODE == "Iris Verification"
60
+ else "pairs/finger_pairs.csv"
61
+ )
62
+
63
+ if st.sidebar.checkbox("View Pair Dataset"):
64
+ df = pd.read_csv(csv_path)
65
+
66
+ st.subheader("πŸ“Š Full Pair Dataset")
67
+ st.write(f"Total Pairs: {len(df)}")
68
+ st.write(
69
+ f"Genuine: {df['label'].sum()} | "
70
+ f"Impostor: {len(df) - df['label'].sum()}"
71
+ )
72
+
73
+ # ===== INTERACTIVE TABLE =====
74
+ selection = st.dataframe(
75
+ df,
76
+ use_container_width=True,
77
+ selection_mode="single-row",
78
+ on_select="rerun"
79
+ )
80
+
81
+ # ===== ROW CLICK β†’ IMAGE VIEW =====
82
+ if selection and selection["selection"]["rows"]:
83
+ row_idx = selection["selection"]["rows"][0]
84
+ row = df.iloc[row_idx]
85
+
86
+ img1 = cv2.imread(row["img1"], cv2.IMREAD_GRAYSCALE)
87
+ img2 = cv2.imread(row["img2"], cv2.IMREAD_GRAYSCALE)
88
+
89
+ st.subheader("πŸ–ΌοΈ Selected Pair Visualization")
90
+
91
+ st.image(
92
+ [img1, img2],
93
+ caption=["Image 1", "Image 2"],
94
+ width=220
95
+ )
96
+
97
+ st.info(
98
+ "Label: "
99
+ + ("βœ… Same Person" if row["label"] == 1 else "❌ Different Person")
100
+ )
101
+
102
+ # st.sidebar.header("πŸ“‚ Dataset Inspector")
103
+
104
+ # df = None # SAFE DEFAULT
105
+
106
+ # if st.sidebar.checkbox("View Pair Dataset"):
107
+ # csv_path = (
108
+ # "pairs/iris_pairs.csv"
109
+ # if MODE == "Iris Verification"
110
+ # else "pairs/finger_pairs.csv"
111
+ # )
112
+
113
+ # df = pd.read_csv(csv_path)
114
+
115
+ # st.subheader("πŸ” Dataset Preview")
116
+ # st.write(f"Total Pairs: {len(df)}")
117
+ # st.write(f"Genuine: {df['label'].sum()} | Impostor: {len(df) - df['label'].sum()}")
118
+
119
+ # st.dataframe(df.head(20), use_container_width=True)
120
+
121
+ # if df is not None and st.sidebar.checkbox("View Sample Image Pairs"):
122
+ # sample = df.sample(1).iloc[0]
123
+
124
+ # img1 = cv2.imread(sample["img1"], cv2.IMREAD_GRAYSCALE)
125
+ # img2 = cv2.imread(sample["img2"], cv2.IMREAD_GRAYSCALE)
126
+
127
+ # st.image([img1, img2], caption=["Image 1", "Image 2"], width=200)
128
+ # st.write("Label:", "Same Person" if sample["label"] == 1 else "Different Person")
129
+
130
+ # ==============================
131
+ # SIDEBAR – MODEL INFO
132
+ # ==============================
133
+
134
+ def get_model_summary(model):
135
+ summary = []
136
+ model.summary(print_fn=lambda x: summary.append(x))
137
+ return "\n".join(summary)
138
+
139
+ st.divider()
140
+ st.subheader("🧠 Model Information")
141
+
142
+ show_model_info = st.checkbox("Show Model Information")
143
+
144
+ if show_model_info:
145
+
146
+ # ===== Model Architecture =====
147
+ with st.expander("πŸ“ Architecture Summary", expanded=False):
148
+ st.code(get_model_summary(model), language="text")
149
+
150
+ # ===== Model Statistics =====
151
+ with st.expander("πŸ“Š Model Statistics", expanded=True):
152
+ col1, col2 = st.columns(2)
153
+
154
+ with col1:
155
+ st.metric("Input Shape", "128 Γ— 128 Γ— 1")
156
+ st.metric("Embedding Size", "128")
157
+
158
+ with col2:
159
+ st.metric("Total Parameters", f"{model.count_params():,}")
160
+ st.metric(
161
+ "Trainable Parameters",
162
+ f"{sum(tf.size(w).numpy() for w in model.trainable_weights):,}"
163
+ )
164
+
165
+ if st.sidebar.checkbox("Show Model Stats"):
166
+ st.write("**Input Shape:**", model.input_shape)
167
+ st.write("**Output Shape:**", model.output_shape)
168
+ st.write("**Parameters:**", model.count_params())
169
+
170
+ if st.checkbox("Show Model Diagram"):
171
+ tf.keras.utils.plot_model(
172
+ model,
173
+ show_shapes=True,
174
+ expand_nested=True,
175
+ to_file="siamese_architecture.png"
176
+ )
177
+ st.image("siamese_architecture.png", caption="Siamese Network Architecture")
178
+
179
+ # ==============================
180
+ # SIDEBAR – SYSTEM STATUS
181
+ # ==============================
182
+ st.sidebar.header("βš™οΈ System Status")
183
+ st.sidebar.write("Mode:", MODE)
184
+ st.sidebar.write("Threshold:", THRESHOLD)
185
+ st.sidebar.write("Model Loaded:", "βœ… Yes")
186
+ st.sidebar.write("Framework:", "TensorFlow + Streamlit")
187
+
188
+ # ==============================
189
+ # IMAGE UPLOAD & VERIFICATION
190
+ # ==============================
191
+ st.subheader("πŸ” Identity Verification")
192
+
193
+ img1_file = st.file_uploader("Upload Registered Image", type=["jpg", "png"])
194
+ img2_file = st.file_uploader("Upload Live Image", type=["jpg", "png"])
195
+
196
+ def preprocess(img):
197
+ img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))
198
+ img = img / 255.0
199
+ img = np.expand_dims(img, axis=-1)
200
+ img = np.expand_dims(img, axis=0)
201
+ return img
202
+
203
+ if img1_file and img2_file:
204
+ img1 = cv2.imdecode(
205
+ np.frombuffer(img1_file.read(), np.uint8),
206
+ cv2.IMREAD_GRAYSCALE
207
+ )
208
+ img2 = cv2.imdecode(
209
+ np.frombuffer(img2_file.read(), np.uint8),
210
+ cv2.IMREAD_GRAYSCALE
211
+ )
212
+
213
+ p1 = preprocess(img1)
214
+ p2 = preprocess(img2)
215
+
216
+ similarity = model.predict([p1, p2])[0][0]
217
+ verified = similarity > THRESHOLD
218
+
219
+ st.image([img1, img2], caption=["Registered", "Live"], width=200)
220
+ st.metric("Similarity Score", f"{similarity:.4f}")
221
+
222
+ if verified:
223
+ st.success("βœ… VERIFIED – VOTE ALLOWED")
224
+ else:
225
+ st.error("❌ NOT VERIFIED – ACCESS DENIED")
226
+