File size: 7,944 Bytes
8286d24 3ddd5e3 32c09cb 8286d24 6af692f ee43fd1 3ddd5e3 ee43fd1 3ddd5e3 ee43fd1 8042272 8516823 ee43fd1 3ddd5e3 8516823 ee43fd1 3ddd5e3 ee43fd1 3ddd5e3 8516823 3ddd5e3 8516823 3ddd5e3 7e2991d 3ddd5e3 7e2991d 32c09cb 3ddd5e3 32c09cb e3ca06a 8042272 32c09cb 8286d24 ee43fd1 8286d24 8516823 ee43fd1 8286d24 8516823 32c09cb 8516823 8286d24 8516823 ee43fd1 32c09cb 6af692f 072d644 |
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 |
import gradio as gr
import torch
from torchvision import transforms
from PIL import Image
import joblib
# Load model and metadata
model = torch.jit.load("resnet_grocery_model_scripted.pt", map_location=torch.device("cpu"))
model.eval()
assets = joblib.load("deployment_assets.joblib")
transform = assets['transform']
class_names = assets['class_names']
# Item names and prices
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))
# Functions
def add_image(new_img, image_list):
if new_img:
image_list.append(new_img)
return image_list, image_list
def remove_last_image(image_list):
if image_list:
image_list.pop()
return image_list, image_list
def classify_and_track(images, budget):
results = []
total_cost = 0
receipt_lines = []
receipt_lines.append(" π SCANCART SUPERMARKET π")
receipt_lines.append(" π Online Smart Checkout")
receipt_lines.append(" ==============================")
receipt_lines.append(" ITEM PRICE")
receipt_lines.append(" ==============================")
for img in images:
if isinstance(img, Image.Image):
input_tensor = transform(img).unsqueeze(0)
with torch.no_grad():
outputs = model(input_tensor)
predicted_index = torch.argmax(outputs, dim=1).item()
predicted_class = class_names[predicted_index]
price = pricelist.get(predicted_class, 0)
total_cost += price
results.append((img, f"{predicted_class} - β±{price:.2f}"))
item_name = (predicted_class[:22] + '...') if len(predicted_class) > 25 else predicted_class
receipt_lines.append(f" {item_name:<25} β±{price:>6.2f}")
else:
results.append((None, "Invalid image"))
remaining = budget - total_cost
receipt_lines.append(" ==============================")
receipt_lines.append(f" TOTAL:{'':>20}β±{total_cost:>7.2f}")
receipt_lines.append(f" BUDGET:{'':>19}β±{budget:>7.2f}")
receipt_lines.append(f" REMAINING:{'':>16}β±{remaining:>7.2f}")
receipt_lines.append(" ==============================")
if total_cost <= budget:
receipt_lines.append(" β
You're within budget! π")
receipt_lines.append(" ποΈ Happy Shopping!")
else:
receipt_lines.append(" β Over budget! Try removing items π¬")
receipt_lines.append(" ==============================")
receipt_lines.append(" THANK YOU FOR SHOPPING WITH US!")
receipt_lines.append(" Come back for smarter buys! π§Ύ")
receipt_text = "\n".join(receipt_lines)
return results, receipt_text
# Custom Theme
custom_theme = gr.themes.Base(
primary_hue="rose",
secondary_hue="amber",
neutral_hue="stone",
font=[gr.themes.GoogleFont("Helvetica")]
).set(
body_background_fill="#ffe5e5"
)
# Gradio Interface
with gr.Blocks(
theme=custom_theme,
css="""
.center-column {
display: flex !important;
justify-content: center !important;
align-items: center !important;
width: 100% !important;
margin: 0 auto !important;
}
#title {
width: 100% !important;
margin: 0 auto !important;
text-align: center !important;
padding: 20px !important;
border: 1px solid #ccc !important; /* Remove this line after confirming centering */
}
#title h1 {
font-size: 2.2em !important;
margin: 0 auto 0.2em !important;
text-align: center !important;
}
#title p {
font-size: 1.1em !important;
margin: 0 auto !important;
text-align: center !important;
max-width: 800px !important;
}
.upload-box {
background-color: #1a1a1a !important;
color: #ffffff !important;
text-align: center !important;
padding: 20px !important;
border-radius: 5px !important;
width: 100% !important;
height: 150px !important;
display: flex !important;
flex-direction: column !important;
justify-content: center !important;
}
.budget-box {
background-color: #1a1a1a !important;
color: #ffffff !important;
text-align: center !important;
padding: 20px !important;
border-radius: 5px !important;
width: 100% !important;
height: 150px !important;
display: flex !important;
flex-direction: column !important;
justify-content: center !important;
}
.button-row button {
background-color: #4a4a4a !important;
color: #ffffff !important;
margin: 0 10px !important;
padding: 10px 20px !important;
border-radius: 5px !important;
border: none !important;
}
"""
) as iface:
with gr.Row():
with gr.Column(scale=1, min_width=0, elem_classes="center-column"):
gr.Markdown(
"""
<div style="width: 100%; margin: 0 auto; text-align: center; padding: 20px;">
<h1 style="font-size: 2.2em; margin: 0 auto 0.2em; text-align: center;">ScanCart π§Ύ</h1>
<p style="font-size: 1.1em; margin: 0 auto; text-align: center; max-width: 800px;">Upload images of your grocery items, and ScanCart will identify them, calculate the total cost, and check if it fits within your budget. ππΈ</p>
</div>
""",
elem_id="title"
)
with gr.Row():
with gr.Column(scale=1):
with gr.Row():
image_input = gr.Image(type="pil", label="Upload Grocery Items π", elem_classes="upload-box", height=150)
budget_input = gr.Number(label="Budget (β±) π", value=500.0, precision=2, elem_classes="budget-box")
gallery_output = gr.Gallery(label="Cart Preview", columns=3, height="auto", object_fit="contain")
with gr.Row(elem_classes="button-row"):
add_btn = gr.Button("Add Items π")
remove_btn = gr.Button("Reset π")
classify_btn = gr.Button("Generate Receipt π§Ύ")
with gr.Column(scale=2):
receipt_output = gr.Textbox(label="Receipt", lines=20, interactive=False, show_copy_button=True)
image_list_state = gr.State([])
add_btn.click(
add_image,
inputs=[image_input, image_list_state],
outputs=[image_list_state, gallery_output]
)
remove_btn.click(
remove_last_image,
inputs=image_list_state,
outputs=[image_list_state, gallery_output]
)
classify_btn.click(
classify_and_track,
inputs=[image_list_state, budget_input],
outputs=[gallery_output, receipt_output]
)
iface.launch() |