LuckyHappyFish commited on
Commit
6285522
·
1 Parent(s): 797572d
Files changed (1) hide show
  1. app.py +35 -111
app.py CHANGED
@@ -3,96 +3,22 @@ from transformers import pipeline
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,15 +27,21 @@ local_css() # Apply the CSS
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,69 +58,61 @@ def get_ingredients_qwen(food_name):
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,11 +120,11 @@ if uploaded_file is not None:
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,9 +135,10 @@ if uploaded_file is not None:
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,6 +149,5 @@ if uploaded_file is not None:
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.")
 
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
 
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
  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
  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
  "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
  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.")