Wall06 commited on
Commit
0aa3216
Β·
verified Β·
1 Parent(s): 81b0105

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +151 -129
app.py CHANGED
@@ -1,176 +1,198 @@
1
- # app.py
2
  import gradio as gr
3
  import easyocr
4
- import trimesh
5
  import numpy as np
6
  from PIL import Image
7
  import os
8
- import random
9
- import time
10
 
11
- # --- SETUP ---
12
- # Create folders to store generated 3D models
13
- os.makedirs("models", exist_ok=True)
14
 
15
- # Initialize OCR Reader (English)
16
  reader = easyocr.Reader(['en'])
17
 
18
- # --- LOGIC 1: 3D GENERATOR (2D to 3D Card) ---
19
- def create_3d_card(image, food_name):
20
  """
21
- Takes an image (numpy array or path) and converts it to a standing 3D GLB file.
22
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  try:
24
- # Convert numpy array to Image if needed
25
- if isinstance(image, np.ndarray):
26
- img = Image.fromarray(image).convert('RGB')
27
- else:
28
- img = Image.open(image).convert('RGB')
29
-
30
- # 1. Create 3D Board
31
- width, height = img.size
32
- aspect = width / height
33
- # Create a thin box (The "Card")
34
- mesh = trimesh.creation.box(extents=[aspect, 1.0, 0.05])
35
-
36
- # 2. Apply Texture
37
- material = trimesh.visual.texture.SimpleMaterial(image=img)
38
- uv = np.zeros((24, 2))
39
- # Map front face to image
40
- uv[0:4] = [[0, 0], [1, 0], [1, 1], [0, 1]]
41
- mesh.visual = trimesh.visual.TextureVisuals(uv=uv, image=img, material=material)
42
-
43
- # 3. Rotate to stand up (90 deg on X)
44
- rot = trimesh.transformations.rotation_matrix(np.radians(90), [1, 0, 0])
45
- mesh.apply_transform(rot)
46
-
47
- # 4. Save
48
- filename = f"models/{food_name.replace(' ', '_')}_{int(time.time())}.glb"
49
- mesh.export(filename)
50
- return filename
 
 
51
  except Exception as e:
52
- print(f"Error: {e}")
53
- return None
54
 
55
- # --- LOGIC 2: MENU SCANNING (OCR) ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  def scan_menu(image):
57
  if image is None:
58
  return "Please upload an image.", []
59
 
60
- # 1. Read text
61
  results = reader.readtext(image)
62
- text_list = [res[1] for res in results]
 
63
 
64
- # 2. Filter for things that look like food (Simple logic for demo)
65
- # In a real app, you'd verify against a food database.
66
- detected_items = [text for text in text_list if len(text) > 3 and not text.isdigit()]
67
-
68
- if not detected_items:
69
- return "No readable text found.", []
70
-
71
  status = f"βœ… Found {len(detected_items)} items!"
72
- # Return status and update the Dropdown choices
73
  return status, gr.update(choices=detected_items, value=detected_items[0] if detected_items else None)
74
 
75
- # --- LOGIC 3: GENERATE AR VIEW ---
76
- def generate_ar(selected_item, menu_image):
77
- # For this demo, we use the WHOLE menu image as the texture for the 3D card.
78
- # In a pro version, we would crop the specific part of the image.
79
- if menu_image is None:
80
- return None, "Please upload a menu first."
81
-
82
- glb_path = create_3d_card(menu_image, selected_item)
83
-
84
- return glb_path, f"✨ 3D Model for '{selected_item}' created! Download to view in AR."
85
-
86
- # --- LOGIC 4: GOOGLE MAPS SIMULATOR ---
87
- def search_maps(place_name):
88
- # Simulating a Google Maps API call
89
- time.sleep(1) # Fake loading
90
 
91
- # Mock Menu Images (In real life, this would scrape the place's photos)
92
- # We return a placeholder image for the demo
93
- return [
94
- ("https://cdn-icons-png.flaticon.com/512/1904/1904221.png", "Digital Menu Found")
95
- ], f"πŸ“ Found location: {place_name}. Menu retrieved."
96
-
97
- # --- LOGIC 5: AI CHAT ---
98
- def chat_response(message, history):
99
- message = message.lower()
100
- if "price" in message:
101
- return "Based on the menu scan, prices usually range from $10-$20."
102
- elif "recommend" in message:
103
- return "The Burgers seem popular at this location based on reviews!"
104
- elif "hello" in message:
105
- return "Hello! Upload a menu or search a place, and I'll help you visualize the food."
106
- else:
107
- return "I can help you analyze the menu or generate 3D previews. Just ask!"
108
-
109
- # --- UI BUILDING (GRADIO) ---
110
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
111
 
112
- gr.Markdown(
113
- """
114
- # πŸ” MenuVision AI
115
- ### AI-Powered Menu Scanner, Google Maps Finder & AR Visualizer
116
- """
117
- )
118
 
119
  with gr.Tabs():
120
 
121
- # TAB 1: SCAN MENU
122
- with gr.TabItem("πŸ“Έ Scan Menu"):
123
  with gr.Row():
124
- with gr.Column():
125
- menu_input = gr.Image(type="numpy", label="Upload Menu Photo")
126
- scan_btn = gr.Button("πŸ” Analyze Menu", variant="primary")
 
 
 
 
 
 
127
 
128
- with gr.Column():
129
- status_output = gr.Textbox(label="Status")
130
- food_dropdown = gr.Dropdown(label="Select Food Item", choices=[])
131
- generate_btn = gr.Button("✨ Create Real-World 3D", variant="stop")
132
-
133
- with gr.Row():
134
- # The 3D Output
135
- model_output = gr.Model3D(label="3D Preview (Rotate & Zoom)", clear_color=[1, 1, 1, 1])
136
- download_msg = gr.Textbox(label="Instructions", value="Select an item and click Create. Then download the .glb file to view on your table.")
137
-
138
- # TAB 2: GOOGLE MAPS
139
- with gr.TabItem("πŸ—ΊοΈ Google Maps Search"):
140
  with gr.Row():
141
- place_input = gr.Textbox(label="Search Restaurant/Cafe Name")
142
- search_btn = gr.Button("Search Place")
143
 
144
- map_status = gr.Textbox(label="Result")
145
- # We use a Gallery to mimic showing found menu photos
146
- menu_gallery = gr.Gallery(label="Found Menu Images")
147
 
148
- # TAB 3: AI GUIDE
149
- with gr.TabItem("πŸ’¬ AI Assistant"):
150
- chatbot = gr.ChatInterface(fn=chat_response, examples=["What is good here?", "Is it expensive?", "How do I use AR?"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
  # --- EVENT HANDLERS ---
153
 
154
- # 1. Scan Menu -> Get Text -> Populate Dropdown
155
  scan_btn.click(
156
  fn=scan_menu,
157
  inputs=menu_input,
158
  outputs=[status_output, food_dropdown]
159
  )
160
 
161
- # 2. Select Food -> Create 3D Model
162
- generate_btn.click(
163
- fn=generate_ar,
164
- inputs=[food_dropdown, menu_input],
165
- outputs=[model_output, download_msg]
166
  )
167
 
168
- # 3. Maps Search -> Show Fake Menu
169
- search_btn.click(
170
- fn=search_maps,
171
- inputs=place_input,
172
- outputs=[menu_gallery, map_status]
173
  )
174
 
175
- # Launch
176
  demo.launch()
 
 
1
  import gradio as gr
2
  import easyocr
 
3
  import numpy as np
4
  from PIL import Image
5
  import os
6
+ import folium
7
+ from huggingface_hub import InferenceClient
8
 
9
+ # --- CONFIGURATION ---
10
+ # Replace with your actual token
11
+ HF_TOKEN = "hf_..."
12
 
13
+ # Initialize Tools
14
  reader = easyocr.Reader(['en'])
15
 
16
+ # --- LOGIC 1: AI HEALTH ANALYZER & IMAGE GENERATOR ---
17
+ def analyze_food(food_name, language, api_key):
18
  """
19
+ Generates a real-world image AND detailed health analysis in the selected language.
20
  """
21
+ if not food_name:
22
+ return None, "Please select a food item.", ""
23
+
24
+ token = api_key if api_key else HF_TOKEN
25
+ client = InferenceClient(token=token)
26
+
27
+ # 1. Generate Image (Visual)
28
+ img_prompt = (
29
+ f"Professional food photography of {food_name}, "
30
+ "8k resolution, hyperrealistic, cinematic lighting, "
31
+ "macro details, steam rising, delicious, gourmet plating, "
32
+ "unreal engine 5 render style, depth of field."
33
+ )
34
+
35
  try:
36
+ print(f"Generating image for {food_name}...")
37
+ generated_image = client.text_to_image(
38
+ prompt=img_prompt,
39
+ model="stabilityai/stable-diffusion-xl-base-1.0",
40
+ negative_prompt="cartoon, drawing, anime, text, blurry, low quality",
41
+ width=1024, height=1024
42
+ )
43
+ except Exception as e:
44
+ print(f"Image Error: {e}")
45
+ generated_image = None
46
+
47
+ # 2. Generate Health Info (Text) in Selected Language
48
+ text_prompt = (
49
+ f"Act as a nutritionist. Analyze the food item '{food_name}'. "
50
+ f"Provide the response in {language} language. "
51
+ "Format the response strictly with two sections:\n"
52
+ "1. Health Benefits\n"
53
+ "2. Potential Consequences or Cons (e.g., high calories, allergies).\n"
54
+ "Keep it concise and bulleted."
55
+ )
56
+
57
+ try:
58
+ response = client.text_generation(
59
+ prompt=text_prompt,
60
+ model="tiiuae/falcon-7b-instruct", # Using a fast text model
61
+ max_new_tokens=400,
62
+ temperature=0.7
63
+ )
64
+ health_info = response
65
  except Exception as e:
66
+ health_info = f"Could not retrieve health data: {e}"
 
67
 
68
+ return generated_image, health_info
69
+
70
+ # --- LOGIC 2: INTERACTIVE MAP (SCROLLABLE) ---
71
+ def get_map_html(location_name="Bahawalpur"):
72
+ """
73
+ Creates an interactive HTML map centered on a location.
74
+ """
75
+ # Default coordinates (Bahawalpur)
76
+ start_coords = [29.3544, 71.6911]
77
+
78
+ # If user searches specific place, we could geocode it (Mocking change for demo)
79
+ if location_name.lower() == "islamabad":
80
+ start_coords = [33.6844, 73.0479]
81
+ elif location_name.lower() == "lahore":
82
+ start_coords = [31.5497, 74.3436]
83
+
84
+ # Create Map
85
+ m = folium.Map(location=start_coords, zoom_start=13)
86
+
87
+ # Add Marker
88
+ folium.Marker(
89
+ start_coords,
90
+ popup=f"<i>{location_name}</i>",
91
+ tooltip="Click me!"
92
+ ).add_to(m)
93
+
94
+ return m._repr_html_()
95
+
96
+ # --- LOGIC 3: MENU SCANNING ---
97
  def scan_menu(image):
98
  if image is None:
99
  return "Please upload an image.", []
100
 
 
101
  results = reader.readtext(image)
102
+ # Filter for food-like text (longer than 3 chars, not numbers)
103
+ detected_items = [res[1] for res in results if len(res[1]) > 3 and not res[1].isdigit()]
104
 
 
 
 
 
 
 
 
105
  status = f"βœ… Found {len(detected_items)} items!"
 
106
  return status, gr.update(choices=detected_items, value=detected_items[0] if detected_items else None)
107
 
108
+ # --- UI LAYOUT ---
109
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="gray")) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
+ gr.Markdown("# πŸ₯— MenuVision AI: Health & visual Analyzer")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
+ with gr.Row():
114
+ api_input = gr.Textbox(label="Hugging Face Token (Optional)", type="password", placeholder="Paste token here if not hardcoded")
115
+ language_drop = gr.Dropdown(label="🌐 Select Language", choices=["English", "Urdu", "French", "Spanish", "Arabic"], value="English")
 
 
 
116
 
117
  with gr.Tabs():
118
 
119
+ # --- TAB 1: SCAN & HEALTH ANALYSIS ---
120
+ with gr.TabItem("πŸ“Έ Scan & Analyze"):
121
  with gr.Row():
122
+ # LEFT COLUMN: INPUT
123
+ with gr.Column(scale=1):
124
+ menu_input = gr.Image(type="numpy", label="1. Upload Menu Photo")
125
+ scan_btn = gr.Button("πŸ” Scan Text", variant="secondary")
126
+
127
+ gr.Markdown("---")
128
+ status_output = gr.Textbox(label="Status", interactive=False)
129
+ food_dropdown = gr.Dropdown(label="2. Select Detected Food", choices=[])
130
+ analyze_btn = gr.Button("✨ Analyze Health & Generate Image", variant="primary")
131
 
132
+ # RIGHT COLUMN: OUTPUT
133
+ with gr.Column(scale=2):
134
+ # 1. Real World Image
135
+ result_image = gr.Image(label="Real-World Representation", type="pil", height=400)
136
+
137
+ # 2. Health Columns
138
+ gr.Markdown("### 🩺 Nutritional Analysis")
139
+ health_output = gr.Textbox(label="Benefits & Consequences", lines=10)
140
+
141
+ # --- TAB 2: INTERACTIVE MAPS ---
142
+ with gr.TabItem("πŸ—ΊοΈ Interactive Map"):
 
143
  with gr.Row():
144
+ place_search = gr.Textbox(label="Search Location (e.g., Islamabad)", placeholder="Type a city...")
145
+ map_btn = gr.Button("Update Map")
146
 
147
+ # This HTML component holds the interactive scrollable map
148
+ map_html = gr.HTML(value=get_map_html(), label="Scrollable Map")
 
149
 
150
+ # --- TAB 3: ABOUT ME ---
151
+ with gr.TabItem("πŸ‘¨β€πŸ’» About Developer"):
152
+ with gr.Row():
153
+ with gr.Column(scale=1):
154
+ # Placeholder for your profile pic
155
+ gr.Image("https://cdn-icons-png.flaticon.com/512/4140/4140048.png", width=200, show_label=False, show_download_button=False)
156
+
157
+ with gr.Column(scale=3):
158
+ gr.Markdown("""
159
+ ### πŸ‘‹ Hi, I'm Abdullah!
160
+
161
+ **Computer Engineering Student | AI Enthusiast | Web Developer**
162
+
163
+ I am currently an undergraduate student at **COMSATS University Islamabad**, specializing in Computer Engineering.
164
+ I have a passion for merging **Embedded Systems** with **Generative AI** to create real-world solutions.
165
+
166
+ * **Role:** Intern Web Developer at MyK Global Forwarding.
167
+ * **Focus:** TinyML, IoT, and GenAI Applications.
168
+ * **Location:** Bahawalpur / Islamabad.
169
+
170
+ **About MenuVision AI:**
171
+ This project was designed to help people make better dietary choices by visualizing food from plain text menus and understanding the health implications immediately.
172
+ """)
173
 
174
  # --- EVENT HANDLERS ---
175
 
176
+ # 1. Scan Button
177
  scan_btn.click(
178
  fn=scan_menu,
179
  inputs=menu_input,
180
  outputs=[status_output, food_dropdown]
181
  )
182
 
183
+ # 2. Analyze Button (Image + Health Info)
184
+ analyze_btn.click(
185
+ fn=analyze_food,
186
+ inputs=[food_dropdown, language_drop, api_input],
187
+ outputs=[result_image, health_output]
188
  )
189
 
190
+ # 3. Map Update
191
+ map_btn.click(
192
+ fn=get_map_html,
193
+ inputs=place_search,
194
+ outputs=map_html
195
  )
196
 
197
+ # Launch App
198
  demo.launch()