File size: 7,413 Bytes
04f475a
e73380c
04f475a
29afa83
7b63336
f6d41de
7b63336
56732d1
 
b1f272d
 
1bec4ea
56732d1
 
 
 
07326b1
 
 
1bec4ea
07326b1
df033c3
 
1bec4ea
 
 
 
07326b1
1bec4ea
 
 
df033c3
1bec4ea
07326b1
1bec4ea
 
 
 
df033c3
1bec4ea
 
07326b1
 
df033c3
 
 
1bec4ea
b1f272d
07326b1
b1f272d
 
 
07326b1
b6dc022
b1f272d
1bec4ea
df033c3
07326b1
b1f272d
07326b1
1bec4ea
df033c3
1bec4ea
07326b1
 
 
 
 
 
1bec4ea
2759f88
07326b1
2759f88
07326b1
 
 
2759f88
df033c3
2759f88
df033c3
 
 
2759f88
df033c3
 
07326b1
df033c3
 
07326b1
2759f88
df033c3
 
 
 
2759f88
df033c3
2759f88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
07326b1
2759f88
 
df033c3
07326b1
 
 
 
 
 
29afa83
07326b1
 
29afa83
f825898
04f475a
f825898
df033c3
04f475a
 
f825898
 
29afa83
 
df033c3
29afa83
 
 
 
 
 
 
4bfa63a
07326b1
df033c3
29afa83
 
 
f83534a
 
29afa83
1bec4ea
b1f272d
f83534a
 
b1f272d
f83534a
b1f272d
56732d1
 
1bec4ea
 
 
 
56732d1
 
f83534a
b1f272d
 
 
 
 
 
 
 
 
 
 
 
07326b1
b1f272d
1bec4ea
b1f272d
 
07326b1
 
df033c3
07326b1
df033c3
07326b1
b1f272d
07326b1
 
 
 
 
 
 
 
 
df033c3
07326b1
 
 
 
 
 
 
 
 
 
 
 
df033c3
07326b1
 
 
 
b1f272d
 
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
import streamlit as st
from transformers import pipeline
from PIL import Image
from huggingface_hub import InferenceClient
import os
from gradio_client import Client

# Set page configuration
st.set_page_config(
    page_title="DelishAI - Your Culinary Assistant",
    page_icon="🍽️",
    layout="centered",
    initial_sidebar_state="expanded",
)

# Custom CSS to improve styling and responsiveness
def local_css():
    st.markdown(
        """
        <style>
        /* Main layout */
        .main { background-color: #f0f2f6; }

        /* Title styling */
        .title h1 {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            text-align: center;
            color: #ff4b4b;
            font-size: 3rem;
            margin-bottom: 20px;
        }

        /* Image styling */
        .st-image img {
            border-radius: 15px;
            margin-bottom: 20px;
            max-width: 100%;
        }

        /* Sidebar styling */
        [data-testid="stSidebar"] {
            background-color: #ff4b4b;
        }
        [data-testid="stSidebar"] .css-ng1t4o { color: white; }
        [data-testid="stSidebar"] .css-1d391kg { color: white; }

        /* File uploader styling */
        .stFileUploader {
            border: 2px dashed #ff4b4b;
            border-radius: 10px;
            padding: 20px;
            text-align: center;
            color: #ff4b4b;
            background-color: #ffffff;
            font-weight: bold;
        }

        /* File uploader hover effect */
        .stFileUploader:hover {
            background-color: #ffe5e5;
        }

        /* Button styling */
        .stButton>button {
            background-color: #ff4b4b;
            color: white;
            border: none;
            padding: 0.7rem 1.5rem;
            border-radius: 5px;
            font-size: 1.1rem;
            font-weight: bold;
            margin-top: 10px;
        }
        .stButton>button:hover {
            background-color: #e04343;
            color: white;
        }

        /* Headers styling */
        h2 { color: #ff4b4b; margin-top: 30px; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
        h3 { color: #ff4b4b; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }

        /* Text styling */
        .stMarkdown p { font-size: 1.1rem; }

        /* Footer styling */
        footer { visibility: hidden; }

        /* Hide sidebar on small screens */
        @media only screen and (max-width: 600px) {
            [data-testid="stSidebar"] { display: none; }
            .main .block-container { padding-left: 1rem; padding-right: 1rem; }
            .title h1 { font-size: 2rem; }
            .stButton>button { width: 100%; }
        }

        /* Sample images grid */
        .sample-images {
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            gap: 10px;
        }
        .sample-images img {
            width: 150px;
            height: 150px;
            object-fit: cover;
            border-radius: 10px;
            cursor: pointer;
            border: 2px solid transparent;
        }
        .sample-images img:hover {
            border: 2px solid #ff4b4b;
        }
        </style>
        """, unsafe_allow_html=True
    )

local_css()

# Hugging Face API key
API_KEY = st.secrets["HF_API_KEY"]

# Initialize the Hugging Face Inference Client
client = InferenceClient(api_key=API_KEY)

# Load the image classification pipeline
@st.cache_resource
def load_image_classification_pipeline():
    """ Load the image classification pipeline using a pretrained model. """
    return pipeline("image-classification", model="Shresthadev403/food-image-classification")

pipe_classification = load_image_classification_pipeline()

# Function to generate ingredients using Hugging Face Inference Client
def get_ingredients_qwen(food_name):
    """ Generate a list of ingredients for the given food item using Qwen NLP model. Returns a clean, comma-separated list of ingredients. """
    messages = [
        {
            "role": "user",
            "content": f"List only the main ingredients for {food_name}. "
                       f"Respond in a concise, comma-separated list without any extra text or explanations."
        }
    ]
    try:
        completion = client.chat.completions.create(
            model="Qwen/Qwen2.5-Coder-32B-Instruct", messages=messages, max_tokens=50
        )
        generated_text = completion.choices[0].message["content"].strip()
        return generated_text
    except Exception as e:
        return f"Error generating ingredients: {e}"

# Main content
st.markdown('<div class="title"><h1>DelishAI - Your Culinary Assistant</h1></div>', unsafe_allow_html=True)

# Add banner image
st.image("IR_IMAGE.png", use_container_width=True)

# Sidebar for model information (hidden on small screens)
with st.sidebar:
    st.title("Model Information")
    st.write("**Image Classification Model**")
    st.write("Shresthadev403/food-image-classification")
    st.write("**LLM for Ingredients**")
    st.write("Qwen/Qwen2.5-Coder-32B-Instruct")
    st.markdown("---")
    st.markdown("<p style='text-align: center;'>Developed by Muhammad Hassan Butt.</p>", unsafe_allow_html=True)

# Sample images
st.subheader("Or try one of these sample images:")
sample_images = {
    "Burger": "sample_images/burger.jpg",
    "Pizza": "sample_images/pizza.jpg",
    "Sushi": "sample_images/sushi.jpg",
    "Salad": "sample_images/salad.jpg"
}
cols = st.columns(len(sample_images))
for idx, (name, file_path) in enumerate(sample_images.items()):
    with cols[idx]:
        if st.button(f"{name}", key=name):
            uploaded_file = file_path

# File uploader
st.subheader("Upload a food image:")
uploaded_file = st.file_uploader("", type=["jpg", "png", "jpeg"])
if 'uploaded_file' in locals() and uploaded_file is not None:
    # Display the uploaded image
    if isinstance(uploaded_file, str):  # Sample image selected
        image = Image.open(uploaded_file)
    else:  # User uploaded image
        image = Image.open(uploaded_file)
    st.image(image, caption="Uploaded Image", use_container_width=True)

    # Classification button
    if st.button("Classify"):
        with st.spinner("Classifying..."):
            # Make predictions
            predictions = pipe_classification(image)
            # Display only the top prediction
            top_food = predictions[0]['label']
            st.header(f"🍽️ Food: {top_food}")
            
            # Generate and display ingredients for the top prediction
            st.subheader("📝 Ingredients")
            try:
                ingredients = get_ingredients_qwen(top_food)
                st.write(ingredients)
            except Exception as e:
                st.error(f"Error generating ingredients: {e}")

            st.subheader("💡 Healthier Alternatives")
            try:
                client_gradio = Client("https://8a56cb969da1f9d721.gradio.live/")
                result = client_gradio.predict(
                    query=f"What's a healthy {top_food} recipe, and why is it healthy?", api_name="/get_response"
                )
                st.write(result)
            except Exception as e:
                st.error(f"Unable to contact RAG: {e}")
else:
    st.info("Please select or upload an image to get started.")