Spaces:
Build error
Build error
File size: 8,734 Bytes
5545aac 420125a 8e91210 5545aac 1983b27 5545aac 1983b27 5545aac 1983b27 5545aac 1983b27 5545aac 420125a 5545aac c46ae56 8e91210 c46ae56 8e91210 5545aac 8e91210 5545aac 1983b27 5545aac 1983b27 5545aac 8e91210 5545aac 1983b27 5545aac 1983b27 5545aac 1983b27 5545aac 1983b27 5545aac 8e91210 e3f3b73 5545aac 8e91210 5545aac 8e91210 5545aac 1983b27 |
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 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
import gradio as gr
import torch
from torchvision import transforms
from PIL import Image
import joblib
import base64
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
import os
import tempfile
# Load model and metadata
try:
model = torch.jit.load("resnet_grocery_model_scripted.pt", map_location="cpu")
model.eval()
except Exception as e:
print(f"Error loading model: {str(e)}")
raise
try:
assets = joblib.load("deployment_assets.joblib")
transform = assets['transform']
class_names = assets['class_names']
print(f"Loaded {len(class_names)} classes")
except Exception as e:
print(f"Error loading assets: {str(e)}")
raise
# Price list
items = [
'Bisconni Chocolate Chip Cookies 46.8gm', 'Coca Cola Can 250ml', 'Colgate Maximum Cavity Protection 75gm',
'Fanta 500ml', 'Fresher Guava Nectar 500ml', 'Fruita Vitals Red Grapes 200ml', 'Islamabad Tea 238gm',
'Kolson Slanty Jalapeno 18gm', 'Kurkure Chutney Chaska 62gm', 'LU Candi Biscuit 60gm', 'LU Oreo Biscuit 19gm',
'LU Prince Biscuit 55.2gm', 'Lays Masala 34gm', 'Lays Wavy Mexican Chili 34gm', 'Lifebuoy Total Protect Soap 96gm',
'Lipton Yellow Label Tea 95gm', 'Meezan Ultra Rich Tea 190gm', 'Peek Freans Sooper Biscuit 13.2gm',
'Safeguard Bar Soap Pure White 175gm', 'Shezan Apple 250ml', 'Sunsilk Shampoo Soft - Smooth 160ml',
'Super Crisp BBQ 30gm', 'Supreme Tea 95gm', 'Tapal Danedar 95gm', 'Vaseline Healthy White Lotion 100ml'
]
prices = [
55.20, 31.75, 90.00, 63.50, 50.00, 35.00, 150.00, 15.00, 25.00, 30.00, 10.00, 30.00, 20.00, 20.00, 44.50,
100.00, 200.00, 10.00, 70.00, 25.00, 120.00, 15.00, 100.00, 100.00, 120.00
]
pricelist = dict(zip(items, prices))
def classify_and_track(files, budget):
results = []
total_cost = 0
receipt_lines = []
receipt_lines.append("========================================")
receipt_lines.append(" π§Ύ OFFICIAL RECEIPT")
receipt_lines.append(" π SOBRANG TINDANG INA!")
receipt_lines.append(" π Online Smart Checkout")
receipt_lines.append("========================================")
receipt_lines.append(" ITEM PRICE")
receipt_lines.append("----------------------------------------")
for f in files:
try:
print(f"Processing file: {f.name}, Exists: {os.path.exists(f.name)}")
img = Image.open(f.name).convert("RGB")
except Exception as e:
print(f"Image loading error for {f.name}: {str(e)}")
results.append((None, f"Invalid image: {str(e)}"))
continue
try:
input_tensor = transform(img).unsqueeze(0)
print(f"Input tensor shape: {input_tensor.shape}")
with torch.no_grad():
outputs = model(input_tensor)
print(f"Model output shape: {outputs.shape}")
predicted_index = torch.argmax(outputs, dim=1).item()
if predicted_index >= len(class_names):
raise ValueError(f"Predicted index {predicted_index} out of range for class_names (len={len(class_names)})")
predicted_class = class_names[predicted_index]
price = pricelist.get(predicted_class, 0)
total_cost += price
results.append((img, f"{predicted_class} - β±{price:.2f}"))
name = predicted_class
if len(name) > 26:
name = name[:23] + "..."
receipt_lines.append(f" {name:<28} β±{price:>6.2f}")
except Exception as e:
print(f"Inference error for {f.name}: {str(e)}")
results.append((None, f"Inference error: {str(e)}"))
continue
remaining = budget - total_cost
receipt_lines.append("----------------------------------------")
receipt_lines.append(f" TOTAL{'':<24}β±{total_cost:>7.2f}")
receipt_lines.append(f" BUDGET{'':<23}β±{budget:>7.2f}")
receipt_lines.append(f" REMAINING{'':<20}β±{remaining:>7.2f}")
receipt_lines.append("========================================")
percent = min(100, int((total_cost / budget) * 100)) if budget else 0
status = f"**Total: β±{total_cost:.2f} / β±{budget:.2f}**"
if total_cost <= budget:
receipt_lines.append(" β
You're within budget! π")
status_msg = f"β
**Within Budget!** π\n{status}"
sound_path = "success.mp3"
else:
receipt_lines.append(" β Over budget! Remove some snacks!")
status_msg = f"π¨ **Over Budget!** πΈ\n{status}"
sound_path = "fail.mp3"
receipt_lines.append("========================================")
receipt_lines.append(" THANK YOU FOR SHOPPING WITH US!")
receipt_lines.append(" Come back for smarter buys! π§Ύ")
receipt_lines.append("========================================")
# Convert receipt to markdown
receipt_text = "```\n" + "\n".join(receipt_lines) + "\n```"
# Generate PDF
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_pdf:
c = canvas.Canvas(tmp_pdf.name, pagesize=letter)
width, height = letter
y = height - 40
for line in receipt_lines:
c.drawString(40, y, line)
y -= 15
c.save()
pdf_path = tmp_pdf.name
return results, status_msg, receipt_text, percent, sound_path, gr.update(value=pdf_path, visible=True), gr.update(value=receipt_text, visible=True)
def reset_ui():
return [], "", "", 0, None, gr.update(visible=False), gr.update(visible=False)
# Load and encode local background image
try:
with open("background.jpg", "rb") as img_file:
b64_string = base64.b64encode(img_file.read()).decode()
except Exception as e:
print(f"Error loading background image: {str(e)}")
b64_string = ""
html_style = f"""
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;800&display=swap" rel="stylesheet">
<style>
body {{
background-image: url("data:image/jpg;base64,{b64_string}");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
font-family: 'Poppins', sans-serif;
color: #222;
}}
.glass-card {{
background: rgba(255, 255, 255, 0.75);
border-radius: 20px;
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1.5px solid rgba(255, 255, 255, 0.2);
padding: 2rem;
margin-bottom: 1.5rem;
}}
h1 {{
text-align: center;
font-size: 2.6rem;
font-weight: 800;
color: #000 !important;
margin-bottom: 0.5rem;
font-family: 'Poppins', sans-serif;
}}
h2 {{
text-align: center;
font-size: 0.1rem;
font-weight: 0.5;
color: #000 !important;
font-family: 'Poppins', sans-serif;
}}
.gr-button {{
font-family: 'Poppins', sans-serif;
font-weight: 600;
}}
.gr-number input, .gr-file input {{
font-family: 'Poppins', sans-serif;
}}
</style>
"""
with gr.Blocks(title="Grocery Classifier") as app:
gr.HTML(html_style)
with gr.Column(elem_classes="glass-card"):
gr.Markdown("<h1>π§Ύ Budget Check! Know Before You Chow π₯</h1>")
gr.Markdown("<h2>Snap a snack, upload the pack, and find out if youβre on track β or flat broke. Shopping has never been so dramatic.</h2>")
with gr.Column(elem_classes="glass-card"):
with gr.Row():
file_input = gr.File(file_types=["image"], file_count="multiple", label="π· Upload Grocery Items")
budget_input = gr.Number(label="π° Budget (β±)", value=500.0, precision=2)
with gr.Row():
classify_btn = gr.Button("π Classify Items")
reset_btn = gr.Button("π Reset")
with gr.Column(elem_classes="glass-card"):
gallery = gr.Gallery(label="πΈ Classified Items", columns=3)
status_display = gr.Markdown()
progress_bar = gr.Slider(label="Budget Used (%)", minimum=0, maximum=100, interactive=False)
receipt_display = gr.Markdown(label="π§Ύ Grocery Receipt", visible=False)
download_receipt = gr.File(label="π₯ Download Receipt PDF", interactive=False, visible=False)
audio_output = gr.Audio(interactive=False, autoplay=True, visible=False)
classify_btn.click(
fn=classify_and_track,
inputs=[file_input, budget_input],
outputs=[gallery, status_display, receipt_display, progress_bar, audio_output, download_receipt, receipt_display]
)
reset_btn.click(
fn=reset_ui,
outputs=[gallery, status_display, receipt_display, progress_bar, audio_output, download_receipt, receipt_display]
)
app.launch() |