Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,8 +1,6 @@
|
|
1 |
import streamlit as st
|
2 |
import json
|
3 |
import os
|
4 |
-
import io
|
5 |
-
import base64
|
6 |
import boto3
|
7 |
from PIL import Image
|
8 |
import firebase_admin
|
@@ -47,7 +45,7 @@ FOOD_SUGGESTIONS = [
|
|
47 |
] # Extend this list with diverse cuisines
|
48 |
|
49 |
# Unit options for food weight/volume
|
50 |
-
UNIT_OPTIONS = ["grams", "ounces", "teaspoons", "tablespoons", "cups", "pieces"]
|
51 |
|
52 |
# Streamlit Layout - Authentication Section
|
53 |
st.sidebar.title("π User Authentication")
|
@@ -70,6 +68,7 @@ if auth_option == "Login":
|
|
70 |
try:
|
71 |
user = auth.get_user_by_email(email)
|
72 |
st.session_state["user_id"] = user.uid
|
|
|
73 |
st.sidebar.success("β
Logged in successfully!")
|
74 |
except Exception as e:
|
75 |
st.sidebar.error(f"Login failed: {e}")
|
@@ -94,21 +93,22 @@ st.write(
|
|
94 |
" You are responsible for ensuring you own the image and it does not violate any copyright laws."
|
95 |
" We do not guarantee when tokens will be redeemable. Keep track of your user ID."
|
96 |
)
|
97 |
-
st.checkbox("I agree to the terms and conditions", key="terms_accepted")
|
|
|
|
|
|
|
98 |
|
99 |
# Upload Image
|
100 |
uploaded_file = st.file_uploader("Upload an image of your food", type=["jpg", "png", "jpeg"])
|
101 |
-
|
102 |
-
# Ensure uploaded file is valid before proceeding
|
103 |
if uploaded_file:
|
104 |
original_img = Image.open(uploaded_file)
|
105 |
st.session_state["original_image"] = original_img
|
|
|
106 |
|
107 |
-
#
|
108 |
if "original_image" in st.session_state:
|
109 |
original_img = st.session_state["original_image"]
|
110 |
|
111 |
-
# Resize image while maintaining aspect ratio (longest side = 512)
|
112 |
def resize_image(image, max_size=512):
|
113 |
aspect_ratio = image.width / image.height
|
114 |
if image.width > image.height:
|
@@ -121,79 +121,35 @@ if "original_image" in st.session_state:
|
|
121 |
|
122 |
processed_img = resize_image(original_img)
|
123 |
|
124 |
-
|
125 |
-
col1, col2 = st.columns([2, 2])
|
126 |
-
|
127 |
with col1:
|
128 |
st.subheader("π· Original Image")
|
129 |
-
st.image(original_img, caption=f"Original ({original_img.width}x{original_img.height} pixels)",
|
130 |
-
|
131 |
with col2:
|
132 |
st.subheader("πΌοΈ Processed Image")
|
133 |
-
st.image(processed_img, caption=f"Processed ({processed_img.width}x{processed_img.height} pixels)",
|
134 |
-
|
135 |
-
# Store processed image in session state for annotations
|
136 |
st.session_state["processed_image"] = processed_img
|
137 |
|
138 |
-
#
|
139 |
-
st.
|
140 |
|
141 |
-
#
|
|
|
142 |
if "annotations" not in st.session_state:
|
143 |
st.session_state["annotations"] = []
|
144 |
|
145 |
-
|
146 |
-
|
|
|
|
|
|
|
147 |
|
148 |
-
|
149 |
-
def add_food_item():
|
150 |
st.session_state["annotations"].append({
|
151 |
-
"name":
|
152 |
-
"quantity":
|
153 |
-
"unit":
|
154 |
-
"ingredients": []
|
155 |
})
|
|
|
156 |
|
157 |
-
|
158 |
-
for i, food in enumerate(st.session_state["annotations"]):
|
159 |
-
cols = st.columns([2, 1, 1, 2]) # Adjust widths
|
160 |
-
|
161 |
-
# Food Item (Dropdown with Intellisense + Custom Input)
|
162 |
-
food["name"] = cols[0].selectbox(f"Food Item {i+1}", FOOD_SUGGESTIONS + ["Other..."], index=None, key=f"food_{i}")
|
163 |
-
|
164 |
-
# Quantity Input
|
165 |
-
food["quantity"] = cols[1].number_input(f"Qty {i+1}", min_value=0, step=1, key=f"qty_{i}")
|
166 |
-
|
167 |
-
# Unit Dropdown
|
168 |
-
food["unit"] = cols[2].selectbox(f"Unit {i+1}", UNIT_OPTIONS, key=f"unit_{i}")
|
169 |
-
|
170 |
-
# Ingredients Section
|
171 |
-
with cols[3]:
|
172 |
-
ing_input = st.text_input(f"Ingredient {i+1}", key=f"ing_{i}")
|
173 |
-
if st.button(f"+ Add Ingredient {i+1}", key=f"btn_ing_{i}"):
|
174 |
-
if ing_input:
|
175 |
-
food["ingredients"].append(ing_input)
|
176 |
-
|
177 |
-
# Display Added Ingredients
|
178 |
-
if food["ingredients"]:
|
179 |
-
st.write(f"Ingredients: {', '.join(food['ingredients'])}")
|
180 |
-
|
181 |
-
# Button to add new food row
|
182 |
-
if st.button("+ Add Another Food Item"):
|
183 |
-
add_food_item()
|
184 |
-
|
185 |
-
# Save annotations when user is done
|
186 |
-
if st.button("Save Annotations"):
|
187 |
-
metadata_table.update_item(
|
188 |
-
Key={"image_id": uploaded_file.name},
|
189 |
-
UpdateExpression="SET user_id = :u, annotations = :a, processing_status = :p, s3_url = :s, tokens_earned = :t",
|
190 |
-
ExpressionAttributeValues={
|
191 |
-
":u": st.session_state["user_id"],
|
192 |
-
":a": st.session_state["annotations"],
|
193 |
-
":p": "processed",
|
194 |
-
":s": f"s3://{S3_BUCKET_NAME}/raw-uploads/{uploaded_file.name}",
|
195 |
-
":t": len(st.session_state["annotations"]) # Tokens = total annotations
|
196 |
-
},
|
197 |
-
)
|
198 |
-
st.success(f"β
Annotations saved! You earned {len(st.session_state['annotations'])} tokens.")
|
199 |
-
|
|
|
1 |
import streamlit as st
|
2 |
import json
|
3 |
import os
|
|
|
|
|
4 |
import boto3
|
5 |
from PIL import Image
|
6 |
import firebase_admin
|
|
|
45 |
] # Extend this list with diverse cuisines
|
46 |
|
47 |
# Unit options for food weight/volume
|
48 |
+
UNIT_OPTIONS = ["grams", "ounces", "teaspoons", "tablespoons", "cups", "slices", "pieces"]
|
49 |
|
50 |
# Streamlit Layout - Authentication Section
|
51 |
st.sidebar.title("π User Authentication")
|
|
|
68 |
try:
|
69 |
user = auth.get_user_by_email(email)
|
70 |
st.session_state["user_id"] = user.uid
|
71 |
+
st.session_state["tokens"] = 0 # Initialize token count
|
72 |
st.sidebar.success("β
Logged in successfully!")
|
73 |
except Exception as e:
|
74 |
st.sidebar.error(f"Login failed: {e}")
|
|
|
93 |
" You are responsible for ensuring you own the image and it does not violate any copyright laws."
|
94 |
" We do not guarantee when tokens will be redeemable. Keep track of your user ID."
|
95 |
)
|
96 |
+
terms_accepted = st.checkbox("I agree to the terms and conditions", key="terms_accepted")
|
97 |
+
if not terms_accepted:
|
98 |
+
st.warning("β οΈ You must agree to the terms before proceeding.")
|
99 |
+
st.stop()
|
100 |
|
101 |
# Upload Image
|
102 |
uploaded_file = st.file_uploader("Upload an image of your food", type=["jpg", "png", "jpeg"])
|
|
|
|
|
103 |
if uploaded_file:
|
104 |
original_img = Image.open(uploaded_file)
|
105 |
st.session_state["original_image"] = original_img
|
106 |
+
st.session_state["tokens"] += 1 # Earn 1 token for upload
|
107 |
|
108 |
+
# If an image has been uploaded, process and display it
|
109 |
if "original_image" in st.session_state:
|
110 |
original_img = st.session_state["original_image"]
|
111 |
|
|
|
112 |
def resize_image(image, max_size=512):
|
113 |
aspect_ratio = image.width / image.height
|
114 |
if image.width > image.height:
|
|
|
121 |
|
122 |
processed_img = resize_image(original_img)
|
123 |
|
124 |
+
col1, col2 = st.columns(2)
|
|
|
|
|
125 |
with col1:
|
126 |
st.subheader("π· Original Image")
|
127 |
+
st.image(original_img, caption=f"Original ({original_img.width}x{original_img.height} pixels)", use_container_width=True)
|
|
|
128 |
with col2:
|
129 |
st.subheader("πΌοΈ Processed Image")
|
130 |
+
st.image(processed_img, caption=f"Processed ({processed_img.width}x{processed_img.height} pixels)", use_container_width=True)
|
|
|
|
|
131 |
st.session_state["processed_image"] = processed_img
|
132 |
|
133 |
+
# Display earned tokens
|
134 |
+
st.success(f"π Tokens Earned: {st.session_state['tokens']}")
|
135 |
|
136 |
+
# Annotation Table
|
137 |
+
st.subheader("π Add Annotations")
|
138 |
if "annotations" not in st.session_state:
|
139 |
st.session_state["annotations"] = []
|
140 |
|
141 |
+
new_food_item = st.selectbox("Food Item", FOOD_SUGGESTIONS + ["Other..."])
|
142 |
+
if new_food_item == "Other...":
|
143 |
+
new_food_item = st.text_input("Enter custom food item")
|
144 |
+
new_quantity = st.number_input("Quantity", min_value=0, step=1)
|
145 |
+
new_unit = st.selectbox("Unit", UNIT_OPTIONS)
|
146 |
|
147 |
+
if st.button("Add Annotation"):
|
|
|
148 |
st.session_state["annotations"].append({
|
149 |
+
"name": new_food_item,
|
150 |
+
"quantity": new_quantity,
|
151 |
+
"unit": new_unit
|
|
|
152 |
})
|
153 |
+
st.session_state["tokens"] += 1 # Earn 1 token per annotation
|
154 |
|
155 |
+
st.table(st.session_state["annotations"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|