Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,12 +1,11 @@
|
|
1 |
import streamlit as st
|
2 |
import torch
|
3 |
import torchvision.transforms as transforms
|
4 |
-
from torchvision import
|
5 |
from PIL import Image
|
6 |
import numpy as np
|
7 |
import cv2
|
8 |
from datetime import datetime
|
9 |
-
from torchvision.models.mobilenetv2 import MobileNetV2
|
10 |
from gtts import gTTS
|
11 |
import os
|
12 |
|
@@ -31,7 +30,7 @@ def speak_streamlit(text):
|
|
31 |
tts.save("temp.mp3")
|
32 |
st.audio("temp.mp3", format="audio/mp3")
|
33 |
|
34 |
-
# Prediction
|
35 |
def predict(image):
|
36 |
img = transform(image).unsqueeze(0)
|
37 |
with torch.no_grad():
|
@@ -44,44 +43,93 @@ def save_history(image, result):
|
|
44 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
45 |
image.save(f"history/{timestamp}_{result}.png")
|
46 |
|
47 |
-
# ======
|
48 |
-
st.set_page_config(page_title="Currency Detector", page_icon="💵")
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
if "PKR" not in currency_type:
|
54 |
-
st.warning("Currently only Pakistani Rupees (PKR) is supported. Other currencies coming soon!")
|
55 |
st.stop()
|
56 |
|
|
|
|
|
57 |
# Choose input method
|
58 |
-
option = st.radio("
|
59 |
|
60 |
-
# ===== Upload
|
61 |
if option == "Upload Image":
|
62 |
-
uploaded_file = st.file_uploader("Upload a currency image", type=["jpg", "jpeg", "png"])
|
63 |
if uploaded_file:
|
64 |
image = Image.open(uploaded_file).convert("RGB")
|
65 |
-
st.image(image, caption="Uploaded Image", use_column_width=True)
|
66 |
prediction = predict(image)
|
67 |
|
68 |
if prediction == "Not Currency":
|
69 |
-
st.
|
70 |
speak_streamlit("This is not a currency note.")
|
|
|
|
|
|
|
|
|
71 |
else:
|
72 |
-
st.
|
73 |
-
speak_streamlit(
|
74 |
save_history(image, prediction)
|
75 |
|
76 |
-
# =====
|
77 |
elif option == "Scan via Camera":
|
78 |
-
st.
|
79 |
-
|
|
|
80 |
cap = cv2.VideoCapture(0)
|
81 |
stframe = st.empty()
|
82 |
result_box = st.empty()
|
83 |
-
|
84 |
-
stop_button = st.button("Stop Camera")
|
85 |
|
86 |
while cap.isOpened():
|
87 |
ret, frame = cap.read()
|
@@ -92,13 +140,18 @@ elif option == "Scan via Camera":
|
|
92 |
stframe.image(pil_image, channels="RGB", use_column_width=True)
|
93 |
|
94 |
prediction = predict(pil_image)
|
95 |
-
result_box.markdown(f"### Prediction: **{prediction}**")
|
96 |
|
97 |
-
if prediction
|
98 |
-
|
|
|
|
|
|
|
|
|
99 |
save_history(pil_image, prediction)
|
100 |
else:
|
101 |
-
|
|
|
|
|
102 |
|
103 |
if stop_button:
|
104 |
break
|
@@ -107,11 +160,16 @@ elif option == "Scan via Camera":
|
|
107 |
stframe.empty()
|
108 |
result_box.empty()
|
109 |
|
110 |
-
# ===== History =====
|
111 |
if st.checkbox("📁 Show Scan History"):
|
112 |
-
st.
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
116 |
st.markdown("---")
|
117 |
-
st.markdown("
|
|
|
1 |
import streamlit as st
|
2 |
import torch
|
3 |
import torchvision.transforms as transforms
|
4 |
+
from torchvision.models.mobilenetv2 import MobileNetV2
|
5 |
from PIL import Image
|
6 |
import numpy as np
|
7 |
import cv2
|
8 |
from datetime import datetime
|
|
|
9 |
from gtts import gTTS
|
10 |
import os
|
11 |
|
|
|
30 |
tts.save("temp.mp3")
|
31 |
st.audio("temp.mp3", format="audio/mp3")
|
32 |
|
33 |
+
# Prediction
|
34 |
def predict(image):
|
35 |
img = transform(image).unsqueeze(0)
|
36 |
with torch.no_grad():
|
|
|
43 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
44 |
image.save(f"history/{timestamp}_{result}.png")
|
45 |
|
46 |
+
# ====== PAGE CONFIG & CUSTOM STYLING ======
|
47 |
+
st.set_page_config(page_title="Currency Authenticity Detector", page_icon="💵", layout="centered")
|
48 |
+
|
49 |
+
# Custom CSS
|
50 |
+
st.markdown("""
|
51 |
+
<style>
|
52 |
+
.main {
|
53 |
+
background-color: #f0f2f6;
|
54 |
+
}
|
55 |
+
.stButton button {
|
56 |
+
background-color: #2e86de;
|
57 |
+
color: white;
|
58 |
+
border-radius: 8px;
|
59 |
+
padding: 0.5em 1.5em;
|
60 |
+
margin: 0.3em 0;
|
61 |
+
transition: all 0.3s ease-in-out;
|
62 |
+
}
|
63 |
+
.stButton button:hover {
|
64 |
+
background-color: #1b4f72;
|
65 |
+
color: white;
|
66 |
+
transform: scale(1.05);
|
67 |
+
}
|
68 |
+
.result-box {
|
69 |
+
font-size: 20px;
|
70 |
+
padding: 10px;
|
71 |
+
border-radius: 10px;
|
72 |
+
background-color: #eaf2f8;
|
73 |
+
text-align: center;
|
74 |
+
}
|
75 |
+
.prediction-fake {
|
76 |
+
color: red;
|
77 |
+
font-weight: bold;
|
78 |
+
}
|
79 |
+
.prediction-real {
|
80 |
+
color: green;
|
81 |
+
font-weight: bold;
|
82 |
+
}
|
83 |
+
.prediction-unknown {
|
84 |
+
color: orange;
|
85 |
+
font-weight: bold;
|
86 |
+
}
|
87 |
+
</style>
|
88 |
+
""", unsafe_allow_html=True)
|
89 |
+
|
90 |
+
# ====== UI Layout ======
|
91 |
+
st.markdown("# 💵 Currency Authenticity Detector")
|
92 |
+
st.markdown("### ✅ Instantly check if your currency is **Real or Fake**!")
|
93 |
+
|
94 |
+
currency_type = st.selectbox("🔄 Select currency type:", ["PKR (Pakistani Rupees)", "USD (US Dollars)", "INR (Indian Rupees)"])
|
95 |
if "PKR" not in currency_type:
|
96 |
+
st.warning("⚠️ Currently only Pakistani Rupees (PKR) is supported. Other currencies coming soon!")
|
97 |
st.stop()
|
98 |
|
99 |
+
st.markdown("### 🖼️ Choose how to scan your currency note:")
|
100 |
+
|
101 |
# Choose input method
|
102 |
+
option = st.radio("🔍 Input Method:", ["Upload Image", "Scan via Camera"])
|
103 |
|
104 |
+
# ===== Upload Image =====
|
105 |
if option == "Upload Image":
|
106 |
+
uploaded_file = st.file_uploader("📤 Upload a currency image", type=["jpg", "jpeg", "png"])
|
107 |
if uploaded_file:
|
108 |
image = Image.open(uploaded_file).convert("RGB")
|
109 |
+
st.image(image, caption="🖼️ Uploaded Image", use_column_width=True)
|
110 |
prediction = predict(image)
|
111 |
|
112 |
if prediction == "Not Currency":
|
113 |
+
st.markdown('<div class="result-box prediction-unknown">⚠️ This does not appear to be a currency note.</div>', unsafe_allow_html=True)
|
114 |
speak_streamlit("This is not a currency note.")
|
115 |
+
elif prediction == "Fake":
|
116 |
+
st.markdown(f'<div class="result-box prediction-fake">❌ Prediction: {prediction} Currency</div>', unsafe_allow_html=True)
|
117 |
+
speak_streamlit("This is a fake currency note.")
|
118 |
+
save_history(image, prediction)
|
119 |
else:
|
120 |
+
st.markdown(f'<div class="result-box prediction-real">✔️ Prediction: {prediction} Currency</div>', unsafe_allow_html=True)
|
121 |
+
speak_streamlit("This is a real currency note.")
|
122 |
save_history(image, prediction)
|
123 |
|
124 |
+
# ===== Webcam Scan =====
|
125 |
elif option == "Scan via Camera":
|
126 |
+
st.markdown("🎥 Press the button below to start your webcam.")
|
127 |
+
start_camera = st.button("📷 Start Camera")
|
128 |
+
if start_camera:
|
129 |
cap = cv2.VideoCapture(0)
|
130 |
stframe = st.empty()
|
131 |
result_box = st.empty()
|
132 |
+
stop_button = st.button("🛑 Stop Camera")
|
|
|
133 |
|
134 |
while cap.isOpened():
|
135 |
ret, frame = cap.read()
|
|
|
140 |
stframe.image(pil_image, channels="RGB", use_column_width=True)
|
141 |
|
142 |
prediction = predict(pil_image)
|
|
|
143 |
|
144 |
+
if prediction == "Not Currency":
|
145 |
+
result_box.markdown('<div class="result-box prediction-unknown">⚠️ This does not appear to be a currency note.</div>', unsafe_allow_html=True)
|
146 |
+
speak_streamlit("This is not a currency note.")
|
147 |
+
elif prediction == "Fake":
|
148 |
+
result_box.markdown(f'<div class="result-box prediction-fake">❌ Prediction: {prediction} Currency</div>', unsafe_allow_html=True)
|
149 |
+
speak_streamlit("This is a fake currency note.")
|
150 |
save_history(pil_image, prediction)
|
151 |
else:
|
152 |
+
result_box.markdown(f'<div class="result-box prediction-real">✔️ Prediction: {prediction} Currency</div>', unsafe_allow_html=True)
|
153 |
+
speak_streamlit("This is a real currency note.")
|
154 |
+
save_history(pil_image, prediction)
|
155 |
|
156 |
if stop_button:
|
157 |
break
|
|
|
160 |
stframe.empty()
|
161 |
result_box.empty()
|
162 |
|
163 |
+
# ===== Scan History =====
|
164 |
if st.checkbox("📁 Show Scan History"):
|
165 |
+
st.markdown("### 🕘 Recent Scans")
|
166 |
+
history_files = sorted(os.listdir("history"))[::-1][:5]
|
167 |
+
if not history_files:
|
168 |
+
st.info("No scan history available.")
|
169 |
+
else:
|
170 |
+
for img_file in history_files:
|
171 |
+
st.image(f"history/{img_file}", caption=img_file, width=250)
|
172 |
+
|
173 |
+
# ===== Footer =====
|
174 |
st.markdown("---")
|
175 |
+
st.markdown("<center>👨💻 Designed by <b>MERAJ GRAPHICS</b></center>", unsafe_allow_html=True)
|