SURESHBEEKHANI commited on
Commit
5982e62
Β·
verified Β·
1 Parent(s): eb52265

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -53
app.py CHANGED
@@ -26,60 +26,54 @@ ALLOWED_FILE_TYPES = ['png', 'jpg', 'jpeg']
26
  # ======================
27
 
28
  def initialize_api_client():
29
- """Initialize Groq API client"""
30
  load_dotenv()
31
  api_key = os.getenv("GROQ_API_KEY")
32
  if not api_key:
33
- st.error("API key not found. Please verify .env configuration.")
34
  st.stop()
35
  return Groq(api_key=api_key)
36
 
37
-
38
  def encode_image(image_path):
39
- """Encode an image to base64"""
40
  try:
41
  with open(image_path, "rb") as img_file:
42
  return base64.b64encode(img_file.read()).decode("utf-8")
43
  except FileNotFoundError:
44
  return ""
45
 
46
-
47
  def process_image(uploaded_file):
48
- """Convert image to base64 string"""
49
  try:
50
  image = Image.open(uploaded_file)
51
  buffer = io.BytesIO()
52
  image.save(buffer, format=image.format)
53
  return base64.b64encode(buffer.getvalue()).decode('utf-8'), image.format
54
  except Exception as e:
55
- st.error(f"Image processing error: {e}")
56
  return None, None
57
 
58
-
59
  def generate_pdf(report_text, logo_b64):
60
- """Generate a PDF report with logo"""
61
  buffer = io.BytesIO()
62
  doc = SimpleDocTemplate(buffer, pagesize=letter)
63
  styles = getSampleStyleSheet()
64
 
65
- # Decode the base64 logo image
66
  logo_data = base64.b64decode(logo_b64)
67
  logo_image = Image.open(io.BytesIO(logo_data))
68
-
69
- # Resize the logo to fit the page width (you can adjust size if necessary)
70
  logo_width, logo_height = logo_image.size
71
  logo_aspect = logo_height / logo_width
72
  max_logo_width = 150 # Adjust as needed
73
  logo_width = min(logo_width, max_logo_width)
74
  logo_height = int(logo_width * logo_aspect)
75
 
76
- # Create a ReportLab Image element to add the logo to the PDF
77
  logo = ReportLabImage(io.BytesIO(logo_data), width=logo_width, height=logo_height)
78
 
79
- # Build the PDF content
80
  story = [
81
- logo, # Add the logo at the top of the page
82
- Spacer(1, 12), # Space after the logo
83
  Paragraph("<b>Nutrition Analysis Report</b>", styles['Title']),
84
  Spacer(1, 12),
85
  Paragraph(report_text.replace('\n', '<br/>'), styles['BodyText'])
@@ -89,9 +83,8 @@ def generate_pdf(report_text, logo_b64):
89
  buffer.seek(0)
90
  return buffer
91
 
92
-
93
  def generate_analysis(uploaded_file, client):
94
- """Generate AI-powered food analysis"""
95
  base64_image, img_format = process_image(uploaded_file)
96
  if not base64_image:
97
  return None
@@ -101,33 +94,24 @@ def generate_analysis(uploaded_file, client):
101
  try:
102
  response = client.chat.completions.create(
103
  model="llama-3.2-11b-vision-preview",
104
- messages=[
105
- {
106
- "role": "user",
107
- "content": [
108
- {"type": "text", "text": """
109
- You are an expert nutritionist with advanced image analysis capabilities.
110
- Your task is to analyze the provided image, identify all visible food items, and estimate their calorie content as accurately as possible.
111
-
112
- **Instructions:**
113
- - List each identified food item separately.
114
- - Use known nutritional data to provide accurate calorie estimates.
115
- - Consider portion size, cooking method, and density of food.
116
- - Clearly specify if an item's calorie count is an estimate due to ambiguity.
117
- - Provide the total estimated calorie count for the entire meal.
118
-
119
- **Output Format:**
120
- - Food Item 1: [Name] – Estimated Calories: [value] kcal
121
- - Food Item 2: [Name] – Estimated Calories: [value] kcal
122
- - ...
123
- - **Total Estimated Calories:** [value] kcal
124
-
125
- If the image is unclear or lacks enough details, state the limitations and provide a confidence percentage for the estimation.
126
- """},
127
- {"type": "image_url", "image_url": {"url": image_url}}
128
- ]
129
- }
130
- ],
131
  temperature=0.2,
132
  max_tokens=400,
133
  top_p=0.5
@@ -142,10 +126,10 @@ def generate_analysis(uploaded_file, client):
142
  # ======================
143
 
144
  def display_main_interface():
145
- """Render primary application interface"""
146
  logo_b64 = encode_image("src/logo.png")
147
 
148
- # HTML with inline styles to change text colors
149
  st.markdown(f"""
150
  <div style="text-align: center;">
151
  <img src="data:image/png;base64,{logo_b64}" width="100">
@@ -156,16 +140,16 @@ def display_main_interface():
156
 
157
  st.markdown("---")
158
 
 
159
  if st.session_state.get('analysis_result'):
160
- # Create two columns: one for download and one for clear button
161
  col1, col2 = st.columns([1, 1])
162
 
163
- # Left column for the Download button
164
  with col1:
165
  pdf_report = generate_pdf(st.session_state.analysis_result, logo_b64)
166
  st.download_button("πŸ“„ Download Nutrition Report", data=pdf_report, file_name="nutrition_report.pdf", mime="application/pdf")
167
 
168
- # Right column for the Clear button
169
  with col2:
170
  if st.button("Clear Analysis πŸ—‘οΈ"):
171
  st.session_state.pop('analysis_result')
@@ -175,9 +159,8 @@ def display_main_interface():
175
  st.markdown("### 🎯 Nutrition Analysis Report")
176
  st.info(st.session_state.analysis_result)
177
 
178
-
179
  def render_sidebar(client):
180
- """Create sidebar UI elements"""
181
  with st.sidebar:
182
  st.subheader("Image Upload")
183
  uploaded_file = st.file_uploader("Upload Food Image", type=ALLOWED_FILE_TYPES)
@@ -195,7 +178,7 @@ def render_sidebar(client):
195
  # ======================
196
 
197
  def main():
198
- """Primary application controller"""
199
  client = initialize_api_client()
200
  display_main_interface()
201
  render_sidebar(client)
 
26
  # ======================
27
 
28
  def initialize_api_client():
29
+ """Initialize Groq API client with environment variables"""
30
  load_dotenv()
31
  api_key = os.getenv("GROQ_API_KEY")
32
  if not api_key:
33
+ st.error("API key not found. Please check the .env configuration.")
34
  st.stop()
35
  return Groq(api_key=api_key)
36
 
 
37
  def encode_image(image_path):
38
+ """Convert image file to base64"""
39
  try:
40
  with open(image_path, "rb") as img_file:
41
  return base64.b64encode(img_file.read()).decode("utf-8")
42
  except FileNotFoundError:
43
  return ""
44
 
 
45
  def process_image(uploaded_file):
46
+ """Convert uploaded image file to base64 string"""
47
  try:
48
  image = Image.open(uploaded_file)
49
  buffer = io.BytesIO()
50
  image.save(buffer, format=image.format)
51
  return base64.b64encode(buffer.getvalue()).decode('utf-8'), image.format
52
  except Exception as e:
53
+ st.error(f"Error processing image: {e}")
54
  return None, None
55
 
 
56
  def generate_pdf(report_text, logo_b64):
57
+ """Generate PDF report with nutrition analysis and logo"""
58
  buffer = io.BytesIO()
59
  doc = SimpleDocTemplate(buffer, pagesize=letter)
60
  styles = getSampleStyleSheet()
61
 
62
+ # Decode logo image from base64 and resize
63
  logo_data = base64.b64decode(logo_b64)
64
  logo_image = Image.open(io.BytesIO(logo_data))
 
 
65
  logo_width, logo_height = logo_image.size
66
  logo_aspect = logo_height / logo_width
67
  max_logo_width = 150 # Adjust as needed
68
  logo_width = min(logo_width, max_logo_width)
69
  logo_height = int(logo_width * logo_aspect)
70
 
 
71
  logo = ReportLabImage(io.BytesIO(logo_data), width=logo_width, height=logo_height)
72
 
73
+ # Build PDF content
74
  story = [
75
+ logo,
76
+ Spacer(1, 12),
77
  Paragraph("<b>Nutrition Analysis Report</b>", styles['Title']),
78
  Spacer(1, 12),
79
  Paragraph(report_text.replace('\n', '<br/>'), styles['BodyText'])
 
83
  buffer.seek(0)
84
  return buffer
85
 
 
86
  def generate_analysis(uploaded_file, client):
87
+ """Generate nutrition analysis using AI (Groq API)"""
88
  base64_image, img_format = process_image(uploaded_file)
89
  if not base64_image:
90
  return None
 
94
  try:
95
  response = client.chat.completions.create(
96
  model="llama-3.2-11b-vision-preview",
97
+ messages=[{
98
+ "type": "text",
99
+ "text": """
100
+ You are an expert nutritionist with advanced image analysis capabilities.
101
+ Your task is to analyze the provided image, identify all visible food items, and estimate their calorie content with high accuracy.
102
+ **Instructions:**
103
+ - Identify and list each food item visible in the image.
104
+ - For each item, estimate the calorie content based on standard nutritional data, considering portion size, cooking method, and food density.
105
+ - Clearly mark any calorie estimate as "approximate" if based on assumptions due to unclear details.
106
+ - Calculate and provide the total estimated calories for the entire meal.
107
+ **Output Format:**
108
+ - Food Item 1: [Name] – Estimated Calories: [value] kcal
109
+ - Food Item 2: [Name] – Estimated Calories: [value] kcal
110
+ - ...
111
+ - **Total Estimated Calories:** [value] kcal
112
+ If the image lacks sufficient detail or is unclear, specify the limitations and include your confidence level in the estimate as a percentage.
113
+ """
114
+ }],
 
 
 
 
 
 
 
 
 
115
  temperature=0.2,
116
  max_tokens=400,
117
  top_p=0.5
 
126
  # ======================
127
 
128
  def display_main_interface():
129
+ """Render the primary user interface"""
130
  logo_b64 = encode_image("src/logo.png")
131
 
132
+ # Display logo and title
133
  st.markdown(f"""
134
  <div style="text-align: center;">
135
  <img src="data:image/png;base64,{logo_b64}" width="100">
 
140
 
141
  st.markdown("---")
142
 
143
+ # Display analysis results if available
144
  if st.session_state.get('analysis_result'):
 
145
  col1, col2 = st.columns([1, 1])
146
 
147
+ # Column for download button
148
  with col1:
149
  pdf_report = generate_pdf(st.session_state.analysis_result, logo_b64)
150
  st.download_button("πŸ“„ Download Nutrition Report", data=pdf_report, file_name="nutrition_report.pdf", mime="application/pdf")
151
 
152
+ # Column for clear button
153
  with col2:
154
  if st.button("Clear Analysis πŸ—‘οΈ"):
155
  st.session_state.pop('analysis_result')
 
159
  st.markdown("### 🎯 Nutrition Analysis Report")
160
  st.info(st.session_state.analysis_result)
161
 
 
162
  def render_sidebar(client):
163
+ """Render the sidebar with image upload and analysis functionality"""
164
  with st.sidebar:
165
  st.subheader("Image Upload")
166
  uploaded_file = st.file_uploader("Upload Food Image", type=ALLOWED_FILE_TYPES)
 
178
  # ======================
179
 
180
  def main():
181
+ """Main application controller"""
182
  client = initialize_api_client()
183
  display_main_interface()
184
  render_sidebar(client)