LuckyHappyFish commited on
Commit
a42c8a8
·
1 Parent(s): 17e1302
Files changed (1) hide show
  1. app.py +111 -35
app.py CHANGED
@@ -3,22 +3,96 @@ from transformers import pipeline
3
  from PIL import Image
4
  from huggingface_hub import InferenceClient
5
  import os
6
- import openai # Added import
7
- from openai.error import OpenAIError # For specific exception handling
8
 
9
  # Set page configuration
10
  st.set_page_config(
11
  page_title="Plate Mate - Your Culinary Assistant",
12
  page_icon="🍽️",
13
- layout="centered",
14
- initial_sidebar_state="expanded",
15
  )
16
 
17
  def local_css():
18
  st.markdown(
19
  """
20
  <style>
21
- /* Your existing CSS styles here */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  </style>
23
  """, unsafe_allow_html=True
24
  )
@@ -27,21 +101,15 @@ local_css() # Apply the CSS
27
 
28
  # Hugging Face API key
29
  API_KEY = st.secrets["HF_API_KEY"]
30
-
31
- # Initialize the Hugging Face Inference Client
32
  client = InferenceClient(api_key=API_KEY)
33
 
34
- # Load the image classification pipeline
35
  @st.cache_resource
36
  def load_image_classification_pipeline():
37
- """ Load the image classification pipeline using a pretrained model. """
38
  return pipeline("image-classification", model="Shresthadev403/food-image-classification")
39
 
40
  pipe_classification = load_image_classification_pipeline()
41
 
42
- # Function to generate ingredients using Hugging Face Inference Client
43
  def get_ingredients_qwen(food_name):
44
- """ Generate a list of ingredients for the given food item using Qwen NLP model. Returns a clean, comma-separated list of ingredients. """
45
  messages = [
46
  {
47
  "role": "user",
@@ -58,61 +126,69 @@ def get_ingredients_qwen(food_name):
58
  except Exception as e:
59
  return f"Error generating ingredients: {e}"
60
 
61
- # **Set OpenAI API Key**
62
- openai.api_key = st.secrets["openai"] # Ensure you have this in your secrets
63
 
64
- # Main content
65
  st.markdown('<div class="title"><h1>PlateMate - Your Culinary Assistant</h1></div>', unsafe_allow_html=True)
66
 
67
- # Add banner image with existence check
68
  banner_image_path = "IR_IMAGE.png"
69
  if os.path.exists(banner_image_path):
70
- st.image(banner_image_path, use_container_width=True)
 
 
 
71
  else:
72
  st.warning(f"Banner image '{banner_image_path}' not found.")
73
 
74
- # Sidebar for model information (hidden on small screens)
75
  with st.sidebar:
76
  st.title("Model Information")
77
- st.write("**Image Classification Model**")
78
  st.write("Shresthadev403/food-image-classification")
79
- st.write("**LLM for Ingredients**")
80
  st.write("Qwen/Qwen2.5-Coder-32B-Instruct")
81
  st.markdown("---")
82
  st.markdown("<p style='text-align: center;'>Developed by Muhammad Hassan Butt.</p>", unsafe_allow_html=True)
83
 
84
-
85
- # File uploader
86
  st.subheader("Upload a food image:")
87
- uploaded_file = st.file_uploader("", type=["jpg", "png", "jpeg"])
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  if uploaded_file is not None:
90
- # Display the uploaded image
91
- if isinstance(uploaded_file, str): # Sample image selected
92
  if os.path.exists(uploaded_file):
93
  image = Image.open(uploaded_file)
94
  else:
95
  st.error(f"Sample image '{uploaded_file}' not found.")
96
  image = None
97
- else: # User uploaded image
98
  image = Image.open(uploaded_file)
99
 
100
  if image:
101
- st.image(image, caption="Uploaded Image", use_container_width=True)
102
 
103
- # Classification button
104
  if st.button("Classify"):
105
  with st.spinner("Classifying..."):
106
  try:
107
- # Make predictions
108
  predictions = pipe_classification(image)
109
  if predictions:
110
- # Display only the top prediction
111
  top_food = predictions[0]['label']
112
  confidence = predictions[0]['score']
113
  st.header(f"🍽️ Food: {top_food} ({confidence*100:.2f}% confidence)")
114
 
115
- # Generate and display ingredients for the top prediction
116
  st.subheader("📝 Ingredients")
117
  try:
118
  ingredients = get_ingredients_qwen(top_food)
@@ -120,11 +196,11 @@ if uploaded_file is not None:
120
  except Exception as e:
121
  st.error(f"Error generating ingredients: {e}")
122
 
123
- # **Healthier Alternatives using OpenAI API**
124
  st.subheader("💡 Healthier Alternatives")
125
  try:
126
  response = openai.ChatCompletion.create(
127
- model="gpt-4", # You can choose the model you prefer
128
  messages=[
129
  {
130
  "role": "system",
@@ -135,10 +211,9 @@ if uploaded_file is not None:
135
  "content": f"What's a healthy {top_food} recipe, and why is it healthy?"
136
  }
137
  ],
138
- max_tokens=200, # Adjust as needed
139
- temperature=0.7, # Adjust creativity level as needed
140
  )
141
- # Corrected access to 'content'
142
  result = response['choices'][0]['message']['content'].strip()
143
  st.write(result)
144
  except OpenAIError as e:
@@ -149,5 +224,6 @@ if uploaded_file is not None:
149
  st.error("No predictions returned from the classification model.")
150
  except Exception as e:
151
  st.error(f"Error during classification: {e}")
 
152
  else:
153
  st.info("Please select or upload an image to get started.")
 
3
  from PIL import Image
4
  from huggingface_hub import InferenceClient
5
  import os
6
+ import openai
7
+ from openai.error import OpenAIError
8
 
9
  # Set page configuration
10
  st.set_page_config(
11
  page_title="Plate Mate - Your Culinary Assistant",
12
  page_icon="🍽️",
13
+ layout="centered", # center content for better mobile experience
14
+ initial_sidebar_state="collapsed",
15
  )
16
 
17
  def local_css():
18
  st.markdown(
19
  """
20
  <style>
21
+ /* General resets */
22
+ body, html {
23
+ margin: 0;
24
+ padding: 0;
25
+ font-family: "Helvetica Neue", Arial, sans-serif;
26
+ background-color: #f9f9f9;
27
+ }
28
+
29
+ /* Container and spacing */
30
+ .css-1aumxhk, .css-keje6w, .css-18e3th9, .css-12oz5g7 {
31
+ padding-left: 0 !important;
32
+ padding-right: 0 !important;
33
+ }
34
+
35
+ /* Title styling */
36
+ .title h1 {
37
+ text-align: center;
38
+ font-size: 2.5em;
39
+ margin-bottom: 0.5em;
40
+ color: #333;
41
+ }
42
+
43
+ /* Subheader styling */
44
+ h2, h3, h4, h5, h6 {
45
+ color: #555;
46
+ margin-bottom: 0.5em;
47
+ }
48
+
49
+ /* Adjust image styling */
50
+ img {
51
+ max-width: 100%;
52
+ height: auto;
53
+ border-radius: 8px;
54
+ }
55
+
56
+ /* On mobile, reduce font sizes and margins */
57
+ @media (max-width: 600px) {
58
+ .title h1 {
59
+ font-size: 1.8em;
60
+ }
61
+
62
+ h2, h3, h4 {
63
+ font-size: 1em;
64
+ }
65
+
66
+ .stButton button {
67
+ width: 100%;
68
+ }
69
+ }
70
+
71
+ /* Sidebar adjustments */
72
+ [data-testid="stSidebar"] {
73
+ width: 250px;
74
+ background: #fff;
75
+ }
76
+
77
+ /* Preset images container */
78
+ .preset-container {
79
+ display: flex;
80
+ flex-wrap: wrap;
81
+ gap: 10px;
82
+ justify-content: center;
83
+ margin: 1em 0;
84
+ }
85
+ .preset-container img {
86
+ width: 80px;
87
+ height: 80px;
88
+ object-fit: cover;
89
+ cursor: pointer;
90
+ border: 2px solid transparent;
91
+ }
92
+ .preset-container img:hover {
93
+ border: 2px solid #007BFF;
94
+ }
95
+
96
  </style>
97
  """, unsafe_allow_html=True
98
  )
 
101
 
102
  # Hugging Face API key
103
  API_KEY = st.secrets["HF_API_KEY"]
 
 
104
  client = InferenceClient(api_key=API_KEY)
105
 
 
106
  @st.cache_resource
107
  def load_image_classification_pipeline():
 
108
  return pipeline("image-classification", model="Shresthadev403/food-image-classification")
109
 
110
  pipe_classification = load_image_classification_pipeline()
111
 
 
112
  def get_ingredients_qwen(food_name):
 
113
  messages = [
114
  {
115
  "role": "user",
 
126
  except Exception as e:
127
  return f"Error generating ingredients: {e}"
128
 
129
+ openai.api_key = st.secrets["openai"]
 
130
 
 
131
  st.markdown('<div class="title"><h1>PlateMate - Your Culinary Assistant</h1></div>', unsafe_allow_html=True)
132
 
133
+ # Banner Image (Smaller or optional)
134
  banner_image_path = "IR_IMAGE.png"
135
  if os.path.exists(banner_image_path):
136
+ # Display a smaller version of the banner
137
+ col1, col2, col3 = st.columns([1,3,1])
138
+ with col2:
139
+ st.image(banner_image_path, use_container_width=True)
140
  else:
141
  st.warning(f"Banner image '{banner_image_path}' not found.")
142
 
143
+ # Sidebar Info
144
  with st.sidebar:
145
  st.title("Model Information")
146
+ st.write("**Image Classification Model:**")
147
  st.write("Shresthadev403/food-image-classification")
148
+ st.write("**LLM for Ingredients:**")
149
  st.write("Qwen/Qwen2.5-Coder-32B-Instruct")
150
  st.markdown("---")
151
  st.markdown("<p style='text-align: center;'>Developed by Muhammad Hassan Butt.</p>", unsafe_allow_html=True)
152
 
 
 
153
  st.subheader("Upload a food image:")
154
+
155
+ # Preset Images
156
+ preset_images = {
157
+ "Pizza": "sample_pizza.jpg",
158
+ "Salad": "sample_salad.jpg",
159
+ "Sushi": "sample_sushi.jpg"
160
+ }
161
+
162
+ selected_preset = st.selectbox("Or choose a preset sample image:", ["None"] + list(preset_images.keys()))
163
+ if selected_preset != "None":
164
+ uploaded_file = preset_images[selected_preset]
165
+ else:
166
+ uploaded_file = st.file_uploader("", type=["jpg", "png", "jpeg"])
167
 
168
  if uploaded_file is not None:
169
+ if isinstance(uploaded_file, str):
170
+ # Use the preset image
171
  if os.path.exists(uploaded_file):
172
  image = Image.open(uploaded_file)
173
  else:
174
  st.error(f"Sample image '{uploaded_file}' not found.")
175
  image = None
176
+ else:
177
  image = Image.open(uploaded_file)
178
 
179
  if image:
180
+ st.image(image, caption="Selected Image", use_container_width=True)
181
 
 
182
  if st.button("Classify"):
183
  with st.spinner("Classifying..."):
184
  try:
 
185
  predictions = pipe_classification(image)
186
  if predictions:
 
187
  top_food = predictions[0]['label']
188
  confidence = predictions[0]['score']
189
  st.header(f"🍽️ Food: {top_food} ({confidence*100:.2f}% confidence)")
190
 
191
+ # Generate ingredients
192
  st.subheader("📝 Ingredients")
193
  try:
194
  ingredients = get_ingredients_qwen(top_food)
 
196
  except Exception as e:
197
  st.error(f"Error generating ingredients: {e}")
198
 
199
+ # Healthier Alternatives
200
  st.subheader("💡 Healthier Alternatives")
201
  try:
202
  response = openai.ChatCompletion.create(
203
+ model="gpt-4",
204
  messages=[
205
  {
206
  "role": "system",
 
211
  "content": f"What's a healthy {top_food} recipe, and why is it healthy?"
212
  }
213
  ],
214
+ max_tokens=200,
215
+ temperature=0.7,
216
  )
 
217
  result = response['choices'][0]['message']['content'].strip()
218
  st.write(result)
219
  except OpenAIError as e:
 
224
  st.error("No predictions returned from the classification model.")
225
  except Exception as e:
226
  st.error(f"Error during classification: {e}")
227
+
228
  else:
229
  st.info("Please select or upload an image to get started.")