File size: 6,314 Bytes
8a7a466
8bb74bc
 
8f31dd0
8bb74bc
 
8f31dd0
34fb86a
 
9d30b87
8bb74bc
a6c5937
094dc67
 
865085d
496c07a
a6c5937
496c07a
865085d
a6c5937
496c07a
34fb86a
 
 
 
 
a6c5937
 
 
 
 
496c07a
8bb74bc
a6c5937
34fb86a
a6c5937
34fb86a
a6c5937
 
 
8bb74bc
9d30b87
 
 
 
 
 
 
 
 
 
34fb86a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a6c5937
 
9d30b87
8a7a466
094dc67
 
 
 
 
 
 
 
 
a6c5937
 
522835b
a6c5937
522835b
 
a6c5937
522835b
a6c5937
 
522835b
 
 
 
 
 
 
 
 
 
 
9d30b87
522835b
9d30b87
522835b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9d30b87
 
572428a
 
9d30b87
572428a
 
9d30b87
572428a
 
9d30b87
572428a
 
9d30b87
572428a
 
9d30b87
572428a
 
 
 
 
 
 
9d30b87
572428a
9d30b87
572428a
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import json
import os
import io
import base64
import boto3
from PIL import Image
import firebase_admin
from firebase_admin import credentials, auth
import pandas as pd

# Load AWS credentials using correct HF Secrets
AWS_ACCESS_KEY = os.getenv("AWS_ACCESS_KEY")
AWS_SECRET_KEY = os.getenv("AWS_SECRET_KEY")
AWS_REGION = os.getenv("AWS_REGION", "us-east-1")
S3_BUCKET_NAME = os.getenv("S3_BUCKET_NAME", "food-image-crowdsourcing")
DYNAMODB_TABLE = os.getenv("DYNAMODB_TABLE", "image_metadata")

# Load Firebase credentials
FIREBASE_CONFIG = json.loads(os.getenv("FIREBASE_CONFIG", "{}"))

# Initialize Firebase Admin SDK (Prevent multiple initialization)
if not firebase_admin._apps:
    cred = credentials.Certificate(FIREBASE_CONFIG)
    firebase_admin.initialize_app(cred)

# Initialize AWS Services (S3 & DynamoDB)
s3 = boto3.client(
    "s3",
    aws_access_key_id=AWS_ACCESS_KEY,
    aws_secret_access_key=AWS_SECRET_KEY,
)

dynamodb = boto3.resource(
    "dynamodb", 
    region_name=AWS_REGION, 
    aws_access_key_id=AWS_ACCESS_KEY, 
    aws_secret_access_key=AWS_SECRET_KEY,
)
metadata_table = dynamodb.Table(DYNAMODB_TABLE)

# Food Intellisense List
FOOD_SUGGESTIONS = [
    "Apple", "Banana", "Pizza", "Burger", "Pasta", "Sushi", "Tacos", "Salad",
    "Chicken Curry", "Steak", "Fish & Chips", "Dumplings", "Kimchi", "Pancakes",
    "Biryani", "Croissant", "Baguette", "Miso Soup", "Ramen", "Pierogi"
]  # Extend this list with diverse cuisines

# Unit options for food weight/volume
UNIT_OPTIONS = ["grams", "ounces", "teaspoons", "tablespoons", "cups", "pieces"]

# Streamlit Layout - Authentication Section
st.sidebar.title("πŸ”‘ User Authentication")
auth_option = st.sidebar.radio("Select an option", ["Login", "Sign Up", "Logout"])

if auth_option == "Sign Up":
    email = st.sidebar.text_input("Email")
    password = st.sidebar.text_input("Password", type="password")
    if st.sidebar.button("Sign Up"):
        try:
            user = auth.create_user(email=email, password=password)
            st.sidebar.success("βœ… User created successfully! Please log in.")
        except Exception as e:
            st.sidebar.error(f"Error: {e}")

if auth_option == "Login":
    email = st.sidebar.text_input("Email")
    password = st.sidebar.text_input("Password", type="password")
    if st.sidebar.button("Login"):
        try:
            user = auth.get_user_by_email(email)
            st.session_state["user_id"] = user.uid
            st.sidebar.success("βœ… Logged in successfully!")
        except Exception as e:
            st.sidebar.error(f"Login failed: {e}")

if auth_option == "Logout" and "user_id" in st.session_state:
    del st.session_state["user_id"]
    st.sidebar.success("βœ… Logged out successfully!")

# Ensure user is logged in before uploading
if "user_id" not in st.session_state:
    st.warning("⚠️ Please log in to upload images.")
    st.stop()

# Streamlit Layout - Three Panel Design
st.title("🍽️ Food Image Review & Annotation")
col1, col2 = st.columns([1, 1])

# Compliance & Disclaimer Section
st.markdown("### **Terms & Conditions**")
st.write(
    "By uploading an image, you agree to transfer full copyright to the research team for AI training purposes."
    " You are responsible for ensuring you own the image and it does not violate any copyright laws."
    " We do not guarantee when tokens will be redeemable. Keep track of your user ID."
)
st.checkbox("I agree to the terms and conditions", key="terms_accepted")

# Upload Image
uploaded_file = st.file_uploader("Upload an image of your food", type=["jpg", "png", "jpeg"])
# Ensure an image is uploaded before displaying
if uploaded_file:
    original_img = Image.open(uploaded_file)
    st.session_state["original_image"] = original_img

# If an image has been uploaded, process and display it
if "original_image" in st.session_state:
    original_img = st.session_state["original_image"]
    
    # Resize while maintaining aspect ratio (longest side = 512)
    def resize_image(image, max_size=512):
        aspect_ratio = image.width / image.height
        if image.width > image.height:
            new_width = max_size
            new_height = int(max_size / aspect_ratio)
        else:
            new_height = max_size
            new_width = int(max_size * aspect_ratio)
        return image.resize((new_width, new_height))

    processed_img = resize_image(original_img)

    # UI Layout: Two Columns for Images
    col1, col2 = st.columns(2)

    with col1:
        st.subheader("πŸ“· Original Image")
        st.image(original_img, caption=f"Original ({original_img.width}x{original_img.height} pixels)", use_column_width=True)

    with col2:
        st.subheader("πŸ–ΌοΈ Processed Image")
        st.image(processed_img, caption=f"Processed ({processed_img.width}x{processed_img.height} pixels)", use_column_width=True)
        
    # Store processed image in session state for annotations
    st.session_state["processed_image"] = processed_img
else:
    st.warning("⚠️ Please upload an image first.")


# Create a table-like structure for food annotation
st.subheader("πŸ“ Add Annotations")

# Define columns for table structure
col_food, col_qty, col_unit, col_ing = st.columns([2, 1, 1, 2])  # Define column widths

# Food Item Dropdown (with Intellisense)
food_item = col_food.selectbox("Food Item", options=suggested_foods, index=None, placeholder="Select or enter food")

# Quantity Input
quantity = col_qty.number_input("Qty", min_value=0, step=1)

# Unit Dropdown (Grams, Ounces, etc.)
unit = col_unit.selectbox("Unit", ["g", "oz", "tsp", "tbsp", "cup", "slice", "piece"])

# Ingredients Section with Expandable Input
with col_ing:
    ingredients = []
    if st.button("+ Add Ingredients"):
        ingredient = st.text_input("Enter ingredient")
        if ingredient:
            ingredients.append(ingredient)

# Display added annotations in a structured format
if st.button("Save Annotations"):
    new_entry = {
        "name": food_item,
        "quantity": quantity,
        "unit": unit,
        "ingredients": ingredients,
    }
    st.session_state["annotations"].append(new_entry)
    st.success("βœ… Annotation saved!")

# Show existing annotations
st.write("### Current Annotations")
st.table(st.session_state["annotations"])