rlgondong commited on
Commit
32c09cb
Β·
verified Β·
1 Parent(s): 937b7d9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -126
app.py CHANGED
@@ -3,22 +3,14 @@ import torch
3
  from torchvision import transforms
4
  from PIL import Image
5
  import joblib
6
- import base64
7
- import os
8
 
9
  # Load model and metadata
10
- try:
11
- model = torch.jit.load("resnet_grocery_model_scripted.pt", map_location=torch.device("cpu"))
12
- model.eval()
13
- except FileNotFoundError:
14
- raise FileNotFoundError("Model file 'resnet_grocery_model_scripted.pt' not found. Ensure it is in the working directory.")
15
-
16
- try:
17
- assets = joblib.load("deployment_assets.joblib")
18
- transform = assets['transform']
19
- class_names = assets['class_names']
20
- except FileNotFoundError:
21
- raise FileNotFoundError("Assets file 'deployment_assets.joblib' not found. Ensure it is in the working directory.")
22
 
23
  # Item names and prices
24
  items = ['Bisconni Chocolate Chip Cookies 46.8gm', 'Coca Cola Can 250ml', 'Colgate Maximum Cavity Protection 75gm',
@@ -81,121 +73,113 @@ def classify_and_track(images, budget):
81
  if total_cost <= budget:
82
  receipt_lines.append(" βœ… You're within budget! πŸŽ‰")
83
  receipt_lines.append(" πŸ›οΈ Happy Shopping!")
84
- sound_path = "success.mp3" if os.path.exists("success.mp3") else None
85
  else:
86
  receipt_lines.append(" ❌ Over budget! Try removing items 😬")
87
- sound_path = "fail.mp3" if os.path.exists("fail.mp3") else None
 
 
88
 
89
  receipt_text = "\n".join(receipt_lines)
90
- percent = min(100, int((total_cost / budget) * 100)) if budget else 0
91
- status_msg = f"**Total: β‚±{total_cost:.2f} / β‚±{budget:.2f}**"
92
- summary = "\n".join([f"πŸ›’ **{r[1].split(' - ')[0]}** β€” β‚±{float(r[1].split(' - ')[1][1:]):.2f}" for r in results])
93
-
94
- return results, status_msg, summary, percent, sound_path, receipt_text
95
-
96
- def reset_ui():
97
- return [], "", "", 0, None, ""
98
-
99
- # Read and encode the local background image as base64
100
- b64_string = ""
101
- try:
102
- with open("background.jpg", "rb") as img_file:
103
- b64_string = base64.b64encode(img_file.read()).decode()
104
- except FileNotFoundError:
105
- print("Warning: 'background.jpg' not found. Using fallback background color.")
106
- b64_string = "" # Fallback to a solid color
107
-
108
- # Embed base64 image in CSS or use a fallback
109
- html_style = f"""
110
- <style>
111
- body {{
112
- {"background-image: url('data:image/jpg;base64," + b64_string + "');" if b64_string else "background-color: #ffe5e5;"}
113
- background-size: cover;
114
- background-position: center;
115
- background-repeat: no-repeat;
116
- font-family: 'Segoe UI', sans-serif;
117
- }}
118
- .glass-card {{
119
- background: rgba(255, 255, 255, 0.75);
120
- border-radius: 20px;
121
- box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);
122
- backdrop-filter: blur(10px);
123
- -webkit-backdrop-filter: blur(10px);
124
- border: 1px solid rgba(255, 255, 255, 0.2);
125
- padding: 2rem;
126
- margin-bottom: 1.5rem;
127
- }}
128
- h1 {{
129
- text-align: center;
130
- font-size: 2.2em;
131
- font-weight: 800;
132
- color: #2c2f8f;
133
- }}
134
- p {{
135
- text-align: center;
136
- font-size: 1.1em;
137
- font-weight: 400;
138
- color: #333;
139
- max-width: 800px;
140
- margin: 0 auto;
141
- }}
142
- .upload-box {{
143
- background-color: #1a1a1a !important;
144
- color: #ffffff !important;
145
- text-align: center !important;
146
- padding: 20px !important;
147
- border-radius: 5px !important;
148
- width: 100% !important;
149
- height: 150px !important;
150
- display: flex !important;
151
- flex-direction: column !important;
152
- justify-content: center !important;
153
- }}
154
- .budget-box {{
155
- background-color: #1a1a1a !important;
156
- color: #ffffff !important;
157
- text-align: center !important;
158
- padding: 20px !important;
159
- border-radius: 5px !important;
160
- width: 100% !important;
161
- height: 150px !important;
162
- display: flex !important;
163
- flex-direction: column !important;
164
- justify-content: center !important;
165
- }}
166
- .button-row button {{
167
- background-color: #4a4a4a !important;
168
- color: #ffffff !important;
169
- margin: 0 10px !important;
170
- padding: 10px 20px !important;
171
- border-radius: 5px !important;
172
- border: none !important;
173
- }}
174
- </style>
175
- """
176
 
177
  # Gradio Interface
178
- with gr.Blocks(title="ScanCart", css=html_style) as iface:
179
- with gr.Column(elem_classes="glass-card"):
180
- gr.Markdown("<h1>πŸ›’ ScanCart 🧾</h1>")
181
- gr.Markdown("<p>Upload images of your grocery items, and ScanCart will identify them, calculate the total cost, and check if it fits within your budget. πŸ›’πŸ“Έ</p>")
182
-
183
- with gr.Column(elem_classes="glass-card"):
184
- with gr.Row():
185
- image_input = gr.Image(type="pil", label="Upload Grocery Items 🍎", elem_classes="upload-box", height=150)
186
- budget_input = gr.Number(label="Budget (β‚±) 🍊", value=500.0, precision=2, elem_classes="budget-box")
187
- gallery_output = gr.Gallery(label="Cart Preview", columns=3, height="auto", object_fit="contain")
188
- with gr.Row(elem_classes="button-row"):
189
- add_btn = gr.Button("Add Items πŸš€")
190
- remove_btn = gr.Button("Reset πŸ”„")
191
- classify_btn = gr.Button("Generate Receipt 🧾")
192
-
193
- with gr.Column(elem_classes="glass-card"):
194
- status_text = gr.Markdown()
195
- details = gr.Markdown()
196
- progress = gr.Slider(0, 100, value=0, label="πŸ“Š Budget Usage", interactive=False)
197
- sound_player = gr.Audio(label="πŸ”Š Sound Feedback", visible=True, interactive=False)
198
- receipt_output = gr.Textbox(label="Receipt", lines=20, interactive=False, show_copy_button=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
  image_list_state = gr.State([])
201
 
@@ -208,14 +192,13 @@ with gr.Blocks(title="ScanCart", css=html_style) as iface:
208
  remove_btn.click(
209
  remove_last_image,
210
  inputs=image_list_state,
211
- outputs=[image_list_state, gallery_output, status_text, details, progress, sound_player, receipt_output],
212
- _js="() => {return [[]]}"
213
  )
214
 
215
  classify_btn.click(
216
  classify_and_track,
217
  inputs=[image_list_state, budget_input],
218
- outputs=[gallery_output, status_text, details, progress, sound_player, receipt_output]
219
  )
220
 
221
  iface.launch()
 
3
  from torchvision import transforms
4
  from PIL import Image
5
  import joblib
 
 
6
 
7
  # Load model and metadata
8
+ model = torch.jit.load("resnet_grocery_model_scripted.pt", map_location=torch.device("cpu"))
9
+ model.eval()
10
+
11
+ assets = joblib.load("deployment_assets.joblib")
12
+ transform = assets['transform']
13
+ class_names = assets['class_names']
 
 
 
 
 
 
14
 
15
  # Item names and prices
16
  items = ['Bisconni Chocolate Chip Cookies 46.8gm', 'Coca Cola Can 250ml', 'Colgate Maximum Cavity Protection 75gm',
 
73
  if total_cost <= budget:
74
  receipt_lines.append(" βœ… You're within budget! πŸŽ‰")
75
  receipt_lines.append(" πŸ›οΈ Happy Shopping!")
 
76
  else:
77
  receipt_lines.append(" ❌ Over budget! Try removing items 😬")
78
+ receipt_lines.append(" ==============================")
79
+ receipt_lines.append(" THANK YOU FOR SHOPPING WITH US!")
80
+ receipt_lines.append(" Come back for smarter buys! 🧾")
81
 
82
  receipt_text = "\n".join(receipt_lines)
83
+ return results, receipt_text
84
+
85
+ # Custom Theme
86
+ custom_theme = gr.themes.Base(
87
+ primary_hue="rose",
88
+ secondary_hue="amber",
89
+ neutral_hue="stone",
90
+ font=[gr.themes.GoogleFont("Helvetica")]
91
+ ).set(
92
+ body_background_fill="#ffe5e5"
93
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  # Gradio Interface
96
+ with gr.Blocks(
97
+ theme=custom_theme,
98
+ css="""
99
+ .center-column {
100
+ display: flex !important;
101
+ justify-content: center !important;
102
+ align-items: center !important;
103
+ width: 100% !important;
104
+ margin: 0 auto !important;
105
+ }
106
+ #title {
107
+ width: 100% !important;
108
+ margin: 0 auto !important;
109
+ text-align: center !important;
110
+ padding: 20px !important;
111
+ border: 1px solid #ccc !important; /* Remove this line after confirming centering */
112
+ }
113
+ #title h1 {
114
+ font-size: 2.2em !important;
115
+ margin: 0 auto 0.2em !important;
116
+ text-align: center !important;
117
+ }
118
+ #title p {
119
+ font-size: 1.1em !important;
120
+ margin: 0 auto !important;
121
+ text-align: center !important;
122
+ max-width: 800px !important;
123
+ }
124
+ .upload-box {
125
+ background-color: #1a1a1a !important;
126
+ color: #ffffff !important;
127
+ text-align: center !important;
128
+ padding: 20px !important;
129
+ border-radius: 5px !important;
130
+ width: 100% !important;
131
+ height: 150px !important;
132
+ display: flex !important;
133
+ flex-direction: column !important;
134
+ justify-content: center !important;
135
+ }
136
+ .budget-box {
137
+ background-color: #1a1a1a !important;
138
+ color: #ffffff !important;
139
+ text-align: center !important;
140
+ padding: 20px !important;
141
+ border-radius: 5px !important;
142
+ width: 100% !important;
143
+ height: 150px !important;
144
+ display: flex !important;
145
+ flex-direction: column !important;
146
+ justify-content: center !important;
147
+ }
148
+ .button-row button {
149
+ background-color: #4a4a4a !important;
150
+ color: #ffffff !important;
151
+ margin: 0 10px !important;
152
+ padding: 10px 20px !important;
153
+ border-radius: 5px !important;
154
+ border: none !important;
155
+ }
156
+ """
157
+ ) as iface:
158
+ with gr.Row():
159
+ with gr.Column(scale=1, min_width=0, elem_classes="center-column"):
160
+ gr.Markdown(
161
+ """
162
+ <div style="width: 100%; margin: 0 auto; text-align: center; padding: 20px;">
163
+ <h1 style="font-size: 2.2em; margin: 0 auto 0.2em; text-align: center;">ScanCart 🧾</h1>
164
+ <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>
165
+ </div>
166
+ """,
167
+ elem_id="title"
168
+ )
169
+
170
+ with gr.Row():
171
+ with gr.Column(scale=1):
172
+ with gr.Row():
173
+ image_input = gr.Image(type="pil", label="Upload Grocery Items 🍎", elem_classes="upload-box", height=150)
174
+ budget_input = gr.Number(label="Budget (β‚±) 🍊", value=500.0, precision=2, elem_classes="budget-box")
175
+ gallery_output = gr.Gallery(label="Cart Preview", columns=3, height="auto", object_fit="contain")
176
+ with gr.Row(elem_classes="button-row"):
177
+ add_btn = gr.Button("Add Items πŸš€")
178
+ remove_btn = gr.Button("Reset πŸ”„")
179
+ classify_btn = gr.Button("Generate Receipt 🧾")
180
+
181
+ with gr.Column(scale=2):
182
+ receipt_output = gr.Textbox(label="Receipt", lines=20, interactive=False, show_copy_button=True)
183
 
184
  image_list_state = gr.State([])
185
 
 
192
  remove_btn.click(
193
  remove_last_image,
194
  inputs=image_list_state,
195
+ outputs=[image_list_state, gallery_output]
 
196
  )
197
 
198
  classify_btn.click(
199
  classify_and_track,
200
  inputs=[image_list_state, budget_input],
201
+ outputs=[gallery_output, receipt_output]
202
  )
203
 
204
  iface.launch()