Wall06 commited on
Commit
caf00f4
·
verified ·
1 Parent(s): d463e69

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +158 -77
app.py CHANGED
@@ -1,95 +1,176 @@
1
  # app.py
 
 
 
 
 
2
  import os
3
- from flask import Flask, render_template, request, jsonify, send_from_directory
4
- from graphviz import Digraph
5
  import random
 
6
 
7
- app = Flask(__name__)
 
 
8
 
9
- # CONFIGURATION
10
- UPLOAD_FOLDER = 'static/uploads'
11
- DIAGRAM_FOLDER = 'static/diagrams'
12
- MODEL_FOLDER = 'static/models'
13
- os.makedirs(UPLOAD_FOLDER, exist_ok=True)
14
- os.makedirs(DIAGRAM_FOLDER, exist_ok=True)
15
 
16
- # --- FEATURE 1: AI CODE VISUALIZATION ENGINE ---
17
- @app.route('/generate_code_diagram', methods=['POST'])
18
- def generate_code_diagram():
19
  """
20
- Takes code/logic text and creates a visual flowchart image.
21
- In a real app, you would use an LLM to parse complex code.
22
- Here, we simulate the visualization of logic flow.
23
  """
24
- data = request.json
25
- code_text = data.get('code', '')
26
-
27
- # Create a visual graph (The "Code Image")
28
- dot = Digraph(comment='Code Flow', format='png')
29
- dot.attr(rankdir='TB', size='8,5')
30
-
31
- # Logic to turn text into nodes (Simulated AI parsing)
32
- dot.node('A', 'Start: User Input')
33
- dot.node('B', 'AI Analysis')
34
- dot.node('C', 'Generate 3D Asset')
35
- dot.node('D', 'AR Deployment')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
- dot.edge('A', 'B', label='Upload Image')
38
- dot.edge('B', 'C', label='Identify Food')
39
- dot.edge('C', 'D', label='Render GLB')
40
 
41
- # Save the diagram
42
- filename = f"flow_{random.randint(1000,9999)}"
43
- filepath = os.path.join(DIAGRAM_FOLDER, filename)
44
- dot.render(filepath)
45
 
46
- return jsonify({'diagram_url': f"/{filepath}.png"})
 
 
 
 
 
47
 
48
- # --- FEATURE 2: AI FOOD ANALYSIS & 3D SELECTOR ---
49
- @app.route('/analyze_food', methods=['POST'])
50
- def analyze_food():
51
- """
52
- 1. Receives food image.
53
- 2. 'AI' identifies it (Simulated for this demo).
54
- 3. Returns the correct 3D model file for the table.
55
- """
56
- if 'image' not in request.files:
57
- return jsonify({'error': 'No image uploaded'}), 400
58
-
59
- file = request.files['image']
60
- # Save file logic here...
61
-
62
- # MOCK AI RECOGNITION LOGIC
63
- # In a real app, use TensorFlow/YOLO here to detect "Pizza" or "Burger"
64
- # For demo, we randomly detect one to show the switching capability.
65
- detected_food = random.choice(['burger', 'pizza'])
66
 
67
- response_data = {
68
- 'food_detected': detected_food,
69
- 'confidence': '98%',
70
- 'model_url': f"/static/models/{detected_food}.glb", # Returns the 3D file path
71
- 'calories': '450 kcal'
72
- }
73
- return jsonify(response_data)
74
-
75
- # --- FEATURE 3: AI GUIDE CHAT ---
76
- @app.route('/chat_guide', methods=['POST'])
77
- def chat_guide():
78
- user_msg = request.json.get('message', '').lower()
79
 
80
- if "price" in user_msg:
81
- reply = "This dish costs $12.99 based on the portion size shown."
82
- elif "spicy" in user_msg:
83
- reply = "This dish is rated 2/5 on the spice scale."
 
 
 
 
 
 
 
 
 
 
 
84
  else:
85
- reply = "I am your MenuVision Assistant. Upload a photo to see it in 3D on your table!"
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
- return jsonify({'reply': reply})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
- @app.route('/')
90
- def index():
91
- return render_template('index.html')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
- if __name__ == '__main__':
94
- # Run on 0.0.0.0 so you can access it from your phone
95
- app.run(host='0.0.0.0', port=5000, debug=True)
 
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()