File size: 6,435 Bytes
4a71223
 
0765475
4e4a97a
4a71223
0765475
 
 
037d23a
bea0719
 
0515ad4
bea0719
ffdb7d5
 
0515ad4
ffdb7d5
0765475
0515ad4
0765475
0515ad4
4a71223
 
0765475
4a71223
 
0515ad4
 
 
 
 
a612cca
4e4a97a
0515ad4
 
 
 
de69472
 
 
 
0515ad4
4a71223
de69472
0515ad4
0765475
 
 
4a71223
4e4a97a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0515ad4
4e4a97a
0515ad4
 
4e4a97a
 
0515ad4
4e4a97a
0765475
4e4a97a
0765475
4e4a97a
0765475
 
4e4a97a
0765475
 
0515ad4
4e4a97a
0515ad4
4e4a97a
 
 
 
0515ad4
4e4a97a
 
0515ad4
 
4e4a97a
0765475
4e4a97a
 
 
0765475
 
 
4e4a97a
0515ad4
 
0765475
 
 
 
 
 
 
 
0515ad4
4e4a97a
 
 
 
 
 
0515ad4
 
4e4a97a
 
 
0515ad4
 
 
0765475
 
 
 
 
4e4a97a
0765475
4e4a97a
 
 
 
 
 
 
 
 
0515ad4
4e4a97a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import streamlit as st
import torch
import torchvision.transforms as transforms
from torchvision.models.mobilenetv2 import MobileNetV2
from PIL import Image
import numpy as np
import cv2
from datetime import datetime
from gtts import gTTS
import os

# ====== Setup ======
os.makedirs("history", exist_ok=True)
torch.serialization.add_safe_globals({'MobileNetV2': MobileNetV2})

# Load model
model = torch.load("pkr_currency_classifier.pt", map_location='cpu', weights_only=False)
model.eval()
class_names = ['Fake', 'Not Currency', 'Real']

# Transforms
transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor()
])

# Text-to-speech
def speak_streamlit(text):
    tts = gTTS(text=text, lang='en')
    tts.save("temp.mp3")
    st.audio("temp.mp3", format="audio/mp3")

# Prediction
def predict(image):
    img = transform(image).unsqueeze(0)
    with torch.no_grad():
        outputs = model(img)
        probs = torch.nn.functional.softmax(outputs, dim=1)
        confidence, predicted = torch.max(probs, 1)
        print("Probabilities:", probs.numpy())
        print("Confidence:", confidence.item())
    return class_names[predicted.item()]


# Save history
def save_history(image, result):
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    image.save(f"history/{timestamp}_{result}.png")

# ====== PAGE CONFIG & CUSTOM STYLING ======
st.set_page_config(page_title="Currency Authenticity Detector", page_icon="💵", layout="centered")

# Custom CSS
st.markdown("""
    <style>
        .main {
            background-color: #f0f2f6;
        }
        .stButton button {
            background-color: #2e86de;
            color: white;
            border-radius: 8px;
            padding: 0.5em 1.5em;
            margin: 0.3em 0;
            transition: all 0.3s ease-in-out;
        }
        .stButton button:hover {
            background-color: #1b4f72;
            color: white;
            transform: scale(1.05);
        }
        .result-box {
            font-size: 20px;
            padding: 10px;
            border-radius: 10px;
            background-color: #eaf2f8;
            text-align: center;
        }
        .prediction-fake {
            color: red;
            font-weight: bold;
        }
        .prediction-real {
            color: green;
            font-weight: bold;
        }
        .prediction-unknown {
            color: orange;
            font-weight: bold;
        }
    </style>
""", unsafe_allow_html=True)

# ====== UI Layout ======
st.markdown("# 💵 Currency Authenticity Detector")
st.markdown("### ✅ Instantly check if your currency is **Real or Fake**!")

currency_type = st.selectbox("🔄 Select currency type:", ["PKR (Pakistani Rupees)", "USD (US Dollars)", "INR (Indian Rupees)"])
if "PKR" not in currency_type:
    st.warning("⚠️ Currently only Pakistani Rupees (PKR) is supported. Other currencies coming soon!")
    st.stop()

st.markdown("### 🖼️ Choose how to scan your currency note:")

# Choose input method
option = st.radio("🔍 Input Method:", ["Upload Image", "Scan via Camera"])

# ===== Upload Image =====
if option == "Upload Image":
    uploaded_file = st.file_uploader("📤 Upload a currency image", type=["jpg", "jpeg", "png"])
    if uploaded_file:
        image = Image.open(uploaded_file).convert("RGB")
        st.image(image, caption="🖼️ Uploaded Image", use_column_width=True)
        prediction = predict(image)

        if prediction == "Not Currency":
            st.markdown('<div class="result-box prediction-unknown">⚠️ This does not appear to be a currency note.</div>', unsafe_allow_html=True)
            speak_streamlit("This is not a currency note.")
        elif prediction == "Fake":
            st.markdown(f'<div class="result-box prediction-fake">❌ Prediction: {prediction} Currency</div>', unsafe_allow_html=True)
            speak_streamlit("This is a fake currency note.")
            save_history(image, prediction)
        else:
            st.markdown(f'<div class="result-box prediction-real">✔️ Prediction: {prediction} Currency</div>', unsafe_allow_html=True)
            speak_streamlit("This is a real currency note.")
            save_history(image, prediction)

# ===== Webcam Scan =====
elif option == "Scan via Camera":
    st.markdown("🎥 Press the button below to start your webcam.")
    start_camera = st.button("📷 Start Camera")
    if start_camera:
        cap = cv2.VideoCapture(0)
        stframe = st.empty()
        result_box = st.empty()
        stop_button = st.button("🛑 Stop Camera")

        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break
            frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            pil_image = Image.fromarray(frame_rgb)
            stframe.image(pil_image, channels="RGB", use_column_width=True)

            prediction = predict(pil_image)

            if prediction == "Not Currency":
                result_box.markdown('<div class="result-box prediction-unknown">⚠️ This does not appear to be a currency note.</div>', unsafe_allow_html=True)
                speak_streamlit("This is not a currency note.")
            elif prediction == "Fake":
                result_box.markdown(f'<div class="result-box prediction-fake">❌ Prediction: {prediction} Currency</div>', unsafe_allow_html=True)
                speak_streamlit("This is a fake currency note.")
                save_history(pil_image, prediction)
            else:
                result_box.markdown(f'<div class="result-box prediction-real">✔️ Prediction: {prediction} Currency</div>', unsafe_allow_html=True)
                speak_streamlit("This is a real currency note.")
                save_history(pil_image, prediction)

            if stop_button:
                break

        cap.release()
        stframe.empty()
        result_box.empty()

# ===== Scan History =====
if st.checkbox("📁 Show Scan History"):
    st.markdown("### 🕘 Recent Scans")
    history_files = sorted(os.listdir("history"))[::-1][:5]
    if not history_files:
        st.info("No scan history available.")
    else:
        for img_file in history_files:
            st.image(f"history/{img_file}", caption=img_file, width=250)

# ===== Footer =====
st.markdown("---")
st.markdown("<center>👨‍💻 Designed by <b>MERAJ GRAPHICS</b></center>", unsafe_allow_html=True)