File size: 6,186 Bytes
04f475a
e73380c
04f475a
29afa83
7b63336
f6d41de
7b63336
56732d1
 
 
 
1bec4ea
56732d1
 
 
 
1bec4ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56732d1
1bec4ea
56732d1
29afa83
e4d47cc
29afa83
 
 
 
f825898
04f475a
f825898
800f4d4
 
 
04f475a
 
f825898
 
29afa83
 
800f4d4
29afa83
3500d25
800f4d4
29afa83
 
 
 
 
 
 
4bfa63a
29afa83
 
 
 
 
 
 
f83534a
 
29afa83
1bec4ea
 
f83534a
 
1bec4ea
f83534a
 
56732d1
 
1bec4ea
 
 
 
56732d1
 
f83534a
1bec4ea
f83534a
 
 
 
 
56732d1
f83534a
1bec4ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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="Food Image Recognition with Ingredients",
    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 */
        .css-1y0tads {
            background-color: #ff4b4b;
            color: white;
            border: none;
            border-radius: 5px;
        }
        .css-1y0tads:hover {
            background-color: #e04343;
            color: white;
        }
        /* Button styling */
        .stButton>button {
            background-color: #ff4b4b;
            color: white;
            border: none;
            padding: 0.5rem 1rem;
            border-radius: 5px;
            font-size: 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;
        }
        /* Mobile responsiveness */
        @media only screen and (max-width: 600px) {
            .title h1 {
                font-size: 2rem;
            }
            .stButton>button {
                width: 100%;
            }
        }
        </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>Food Image Recognition with Ingredients</h1></div>', unsafe_allow_html=True)

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

# Sidebar for model information
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)

# File uploader
uploaded_file = st.file_uploader("Choose a food image...", type=["jpg", "png", "jpeg"])

if uploaded_file is not None:
    # Display the uploaded image
    image = Image.open(uploaded_file)
    st.image(image, caption="Uploaded Image", use_column_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}")