Spaces:
Running
Running
File size: 6,687 Bytes
fb7b242 f468e41 4bb6cdf fb7b242 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
import gradio as gr
import cv2
import numpy as np
import pytesseract
import groq
import os
import tempfile
from gtts import gTTS # Google Text-to-Speech
from PIL import Image
from dotenv import load_dotenv
# Initialize Groq Client
load_dotenv() # Load environment variables from .env file
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
groq_client = groq.Client(api_key=GROQ_API_KEY)
# Set Tesseract OCR path (Update if needed)
if not os.path.exists("/usr/bin/tesseract"):
os.system("apt-get update && apt-get install -y tesseract-ocr")
# Now set the correct Tesseract path
pytesseract.pytesseract.tesseract_cmd = "/usr/bin/tesseract"
# Global storage for chat history & last floorplan analysis
chat_history = []
last_floorplan_context = {"features": "No floorplan uploaded yet.", "text": "No text detected."}
latest_audio_file = None # Stores the latest AI voice response
### π **Floorplan Feature Detection**
def detect_floorplan_features(image):
"""Detect walls, rooms, and extract text using OpenCV & OCR."""
# Convert PIL Image to OpenCV format
image_cv = np.array(image.convert("RGB"))
gray = cv2.cvtColor(image_cv, cv2.COLOR_RGB2GRAY)
# Apply edge detection
edges = cv2.Canny(gray, 50, 150)
# Detect walls using Hough Transform
lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=120, minLineLength=80, maxLineGap=10)
wall_count = len(lines) if lines is not None else 0 # Ensure it is always defined
# Detect rooms using contours
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
room_count = sum(1 for c in contours if cv2.contourArea(c) > 1000) # Ensure it is always defined
# Extract text labels using OCR
extracted_text = pytesseract.image_to_string(gray, config='--psm 6').strip()
detected_features = f"Walls: {wall_count}, Rooms: {room_count}"
return detected_features, extracted_text, edges, wall_count, room_count
### π **Analyze Floorplan (AI Processing)**
def analyze_floorplan(image):
"""Analyze the floorplan, update chat history, and generate AI response."""
global last_floorplan_context, chat_history, latest_audio_file
# Call feature detection function
detected_features, extracted_text, edges, wall_count, room_count = detect_floorplan_features(image)
# Convert edges to a PIL Image
edges_pil = Image.fromarray(cv2.cvtColor(edges, cv2.COLOR_GRAY2RGB))
# Store context for chat
last_floorplan_context = {
"features": detected_features,
"text": extracted_text if extracted_text else "No text detected"
}
# AI Architectural Analysis Prompt (Improved)
prompt = f"""
π **Architectural Floorplan Analysis**
**Detected Structural Features**
- **Rooms Identified:** {room_count}
- **Walls Detected:** {wall_count} (Load-bearing & Partition)
- **Extracted Text:** {extracted_text if extracted_text else "No text found"}
**Design & Efficiency Insights**
- **Traffic Flow & Accessibility**: Are room transitions efficient?
- **Lighting & Ventilation**: Where can natural light be optimized?
- **Space Utilization**: Are there underutilized or congested areas?
- **Expansion Feasibility**: Which walls could be removed for better space efficiency?
- **Modernization Potential**: Can smart home features be integrated?
Provide **a structured, expert-level architectural assessment**.
"""
response = groq_client.chat.completions.create(
model="llama3-70b-8192",
messages=[{"role": "system", "content": prompt}],
max_tokens=500
)
ai_reply = response.choices[0].message.content
# Update chat history (New Format)
chat_history.clear()
chat_history.append({"role": "assistant", "content": ai_reply}) # New format
# Generate AI Voice
latest_audio_file = text_to_speech(ai_reply)
return edges_pil, chat_history, latest_audio_file
### π **Text-to-Speech AI Response**
def text_to_speech(text):
"""Convert AI response to speech using gTTS and return an audio file path."""
temp_dir = tempfile.gettempdir() # Get system temp folder
file_path = os.path.join(temp_dir, "speech_output.mp3") # Fixed filename
# Remove old file if exists
if os.path.exists(file_path):
os.remove(file_path)
# Generate speech
tts = gTTS(text=text, lang="en")
tts.save(file_path)
return file_path
### π¬ **AI Chatbot for Floorplan Analysis**
def chat_with_ai(user_input):
"""Handles user chat with AI."""
global latest_audio_file
floorplan_context = f"**Floorplan Summary**: {last_floorplan_context['features']}" if last_floorplan_context["features"] != "No floorplan uploaded yet." else ""
updated_input = f"""
User Question: {user_input}
{floorplan_context}
Provide an **expert-level architectural response** considering previous chat history.
"""
# AI Response with Context
response = groq_client.chat.completions.create(
model="llama3-70b-8192",
messages=[{"role": "user", "content": updated_input}],
max_tokens=500
)
ai_reply = response.choices[0].message.content
# Append to chat history (New Format)
chat_history.append({"role": "user", "content": user_input})
chat_history.append({"role": "assistant", "content": ai_reply})
# Generate voice response for latest AI reply
latest_audio_file = text_to_speech(ai_reply)
return chat_history, latest_audio_file # Return updated chat & voice
### **π₯ Gradio UI - Light Themed & Modernized**
with gr.Blocks() as demo:
gr.Markdown("# π Virtual Architect - AI Floorplan Chat (Voice Enabled)")
with gr.Row():
with gr.Column():
image_input = gr.Image(type="pil", label="Upload Floorplan")
analyze_btn = gr.Button("Analyze Floorplan")
with gr.Column():
result_image = gr.Image(type="pil", label="Edge Detection Output")
chatbox = gr.Chatbot(label="AI Chat (Starts with Floorplan Analysis)", type="messages")
# **SINGLE AI VOICE RESPONSE COMPONENT**
ai_voice_response = gr.Audio(label="AI Voice Response")
# AI recommendation appears in chatbox (Single Voice Response)
analyze_btn.click(analyze_floorplan, inputs=image_input, outputs=[result_image, chatbox, ai_voice_response])
# Text input directly under chatbox
user_input = gr.Textbox(label="Ask a Question Here")
send_btn = gr.Button("Send")
send_btn.click(chat_with_ai, inputs=user_input, outputs=[chatbox, ai_voice_response])
# Launch Gradio App (Fixes Theme Issue)
demo.launch()
|