capradeepgujaran commited on
Commit
e47ba84
·
verified ·
1 Parent(s): 1ccde3e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -54
app.py CHANGED
@@ -47,7 +47,7 @@ def encode_image(image):
47
  def resize_image(image, max_size=(800, 800)):
48
  """Resize image to avoid exceeding the API size limits."""
49
  try:
50
- image.thumbnail(max_size, Image.Resampling.LANCZOS) # Use LANCZOS resampling for better quality
51
  return image
52
  except Exception as e:
53
  logger.error(f"Error resizing image: {str(e)}")
@@ -70,29 +70,29 @@ def extract_frames_from_video(video, frame_points=[0, 0.5, 1], max_size=(800, 80
70
  cap.release()
71
  return frames
72
 
73
- def analyze_file(file):
74
- """Analyze a single file (image or video)"""
75
  try:
76
  file_type = file.name.split('.')[-1].lower()
77
  if file_type in ['jpg', 'jpeg', 'png', 'bmp']:
78
- return analyze_image(file)
79
  elif file_type in ['mp4', 'avi', 'mov', 'webm']:
80
- return analyze_video(file)
81
  else:
82
  return "Unsupported file type. Please upload an image or video file."
83
  except Exception as e:
84
- logger.error(f"Error analyzing file: {str(e)}")
85
- return f"Error analyzing file: {str(e)}"
86
 
87
- def analyze_image(image_file):
88
  image = Image.open(image_file.name)
89
  resized_image = resize_image(image)
90
  image_data_url = f"data:image/png;base64,{encode_image(resized_image)}"
91
 
92
- instruction = ("You are an AI assistant specialized in analyzing images for safety issues. "
93
- "Your task is first to explain what you see in the image and determine if the image shows a construction site. "
94
- "If it does, identify any safety issues or hazards, categorize them, and provide a detailed description, "
95
- "and suggest steps to resolve them. If it's not a construction site, simply state that")
96
 
97
  messages = [
98
  {
@@ -100,7 +100,7 @@ def analyze_image(image_file):
100
  "content": [
101
  {
102
  "type": "text",
103
- "text": f"{instruction}\n\nAnalyze this image. First, determine if it's a construction site. If it is, explain the image in detail, focusing on safety aspects. If it's not, briefly describe what you see."
104
  },
105
  {
106
  "type": "image_url",
@@ -124,14 +124,14 @@ def analyze_image(image_file):
124
 
125
  return completion.choices[0].message.content
126
 
127
- def analyze_video(video_file):
128
  frames = extract_frames_from_video(video_file.name)
129
  results = []
130
 
131
- instruction = ("You are an AI assistant specialized in analyzing images for safety issues. "
132
- "Your task is first to explain what you see in the image and determine if the image shows a construction site. "
133
- "If it does, identify any safety issues or hazards, categorize them, and provide a detailed description, "
134
- "and suggest steps to resolve them. If it's not a construction site, simply state that")
135
 
136
  for i, frame in enumerate(frames):
137
  image_data_url = f"data:image/png;base64,{encode_image(frame)}"
@@ -141,7 +141,7 @@ def analyze_video(video_file):
141
  "content": [
142
  {
143
  "type": "text",
144
- "text": f"{instruction}\n\nAnalyze this frame from a video (Frame {i+1}/{len(frames)}). First, explain the video and then determine if it's a construction site. If it is, explain what you observe, focusing on safety aspects. If it's not, briefly describe what you see."
145
  },
146
  {
147
  "type": "image_url",
@@ -165,26 +165,20 @@ def analyze_video(video_file):
165
 
166
  return "\n".join(results)
167
 
168
-
169
-
170
- def chat_about_image(message, chat_history):
171
  try:
172
- # Prepare the conversation history for the API
173
  messages = [
174
- {"role": "system", "content": "You are an AI assistant specialized in analyzing construction site images and answering questions about them. Use the information from the initial analysis to answer user queries."},
175
  ]
176
 
177
- # Add chat history to messages
178
  for human, ai in chat_history:
179
  if human:
180
  messages.append({"role": "user", "content": human})
181
  if ai:
182
  messages.append({"role": "assistant", "content": ai})
183
 
184
- # Add the new user message
185
  messages.append({"role": "user", "content": message})
186
 
187
- # Make API call
188
  completion = client.chat.completions.create(
189
  model="llama-3.2-90b-vision-preview",
190
  messages=messages,
@@ -203,11 +197,11 @@ def chat_about_image(message, chat_history):
203
  logger.error(f"Error during chat: {str(e)}")
204
  return "", chat_history + [(message, f"Error: {str(e)}")]
205
 
206
- def generate_summary_report(chat_history):
207
  """
208
- Generate a summary report from the chat history.
209
  """
210
- report = "Construction Site Safety Analysis Report\n"
211
  report += "=" * 40 + "\n"
212
  report += f"Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
213
 
@@ -220,22 +214,20 @@ def generate_summary_report(chat_history):
220
 
221
  return report
222
 
223
- def download_report(chat_history):
224
  """
225
- Generate and provide a download link for the summary report.
226
  """
227
- report = generate_summary_report(chat_history)
228
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
229
- filename = f"safety_analysis_report_{timestamp}.txt"
230
 
231
- # Create a temporary file
232
  with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".txt") as temp_file:
233
  temp_file.write(report)
234
  temp_file_path = temp_file.name
235
 
236
  return temp_file_path
237
 
238
-
239
  # Custom CSS for improved styling
240
  custom_css = """
241
  .container { max-width: 1200px; margin: auto; padding-top: 1.5rem; }
@@ -269,14 +261,13 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as iface:
269
  """
270
  <div class="container">
271
  <div class="header">
272
- <h1>🏗️ Construction Site Safety Analyzer</h1>
273
  </div>
274
- <p class="subheader">Enhance workplace safety and compliance with AI-powered image and video analysis using Llama 3.2 90B Vision and expert chat assistance.</p>
275
  </div>
276
  """
277
  )
278
 
279
- # First row: Combined file upload for images and videos
280
  with gr.Row():
281
  file_input = gr.File(
282
  label="Upload Construction Site Images or Videos",
@@ -285,40 +276,35 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as iface:
285
  elem_classes="file-container"
286
  )
287
 
288
- # Second row: Analyze Safety Hazards Button
289
  with gr.Row():
290
- analyze_button = gr.Button("🔍 Analyze Safety Hazards", elem_classes="analyze-button")
291
 
292
- # Third row: Chat Interface (Safety Analysis Results)
293
  with gr.Row():
294
  chatbot = gr.Chatbot(
295
- label="Safety Analysis Results and Expert Chat",
296
  elem_classes="chatbot",
297
- show_share_button=False, # Remove share button
298
- show_copy_button=False # Remove copy button
299
  )
300
 
301
- # Fourth row: Question Bar
302
  with gr.Row():
303
  msg = gr.Textbox(
304
- label="Ask about safety measures or regulations",
305
- placeholder="E.g., 'Ask follow-up question and press ENTER'",
306
  show_label=False,
307
  elem_classes="chat-input"
308
  )
309
 
310
- # Fifth row: Clear Chat and Download Report Buttons
311
  with gr.Row():
312
  clear = gr.Button("🗑️ Clear Chat", elem_classes="clear-button")
313
  download_button = gr.Button("📥 Download Report", elem_classes="download-button")
314
 
315
- # Add a file component to handle the download
316
- report_file = gr.File(label="Download Safety Analysis Report")
317
 
318
  def process_files(files):
319
  results = []
320
  for file in files:
321
- result = analyze_file(file)
322
  results.append((file.name, result))
323
  return results
324
 
@@ -335,11 +321,11 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as iface:
335
  postprocess=lambda x: update_chat(chatbot.value, x)
336
  )
337
 
338
- msg.submit(chat_about_image, [msg, chatbot], [msg, chatbot])
339
  clear.click(lambda: None, None, chatbot, queue=False)
340
 
341
  download_button.click(
342
- download_report,
343
  inputs=[chatbot],
344
  outputs=[report_file]
345
  )
 
47
  def resize_image(image, max_size=(800, 800)):
48
  """Resize image to avoid exceeding the API size limits."""
49
  try:
50
+ image.thumbnail(max_size, Image.Resampling.LANCZOS)
51
  return image
52
  except Exception as e:
53
  logger.error(f"Error resizing image: {str(e)}")
 
70
  cap.release()
71
  return frames
72
 
73
+ def detect_snags(file):
74
+ """Detect snags in a single file (image or video)"""
75
  try:
76
  file_type = file.name.split('.')[-1].lower()
77
  if file_type in ['jpg', 'jpeg', 'png', 'bmp']:
78
+ return detect_snags_in_image(file)
79
  elif file_type in ['mp4', 'avi', 'mov', 'webm']:
80
+ return detect_snags_in_video(file)
81
  else:
82
  return "Unsupported file type. Please upload an image or video file."
83
  except Exception as e:
84
+ logger.error(f"Error detecting snags: {str(e)}")
85
+ return f"Error detecting snags: {str(e)}"
86
 
87
+ def detect_snags_in_image(image_file):
88
  image = Image.open(image_file.name)
89
  resized_image = resize_image(image)
90
  image_data_url = f"data:image/png;base64,{encode_image(resized_image)}"
91
 
92
+ instruction = ("You are an AI assistant specialized in detecting snags in construction sites. "
93
+ "Your task is to analyze the image and identify any construction defects, unfinished work, "
94
+ "or quality issues. List each snag, categorize it, and provide a brief description. "
95
+ "If no snags are detected, state that the area appears to be free of visible issues.")
96
 
97
  messages = [
98
  {
 
100
  "content": [
101
  {
102
  "type": "text",
103
+ "text": f"{instruction}\n\nAnalyze this image for construction snags and provide a detailed report."
104
  },
105
  {
106
  "type": "image_url",
 
124
 
125
  return completion.choices[0].message.content
126
 
127
+ def detect_snags_in_video(video_file):
128
  frames = extract_frames_from_video(video_file.name)
129
  results = []
130
 
131
+ instruction = ("You are an AI assistant specialized in detecting snags in construction sites. "
132
+ "Your task is to analyze the video frame and identify any construction defects, unfinished work, "
133
+ "or quality issues. List each snag, categorize it, and provide a brief description. "
134
+ "If no snags are detected, state that the area appears to be free of visible issues.")
135
 
136
  for i, frame in enumerate(frames):
137
  image_data_url = f"data:image/png;base64,{encode_image(frame)}"
 
141
  "content": [
142
  {
143
  "type": "text",
144
+ "text": f"{instruction}\n\nAnalyze this frame from a video (Frame {i+1}/{len(frames)}) for construction snags and provide a detailed report."
145
  },
146
  {
147
  "type": "image_url",
 
165
 
166
  return "\n".join(results)
167
 
168
+ def chat_about_snags(message, chat_history):
 
 
169
  try:
 
170
  messages = [
171
+ {"role": "system", "content": "You are an AI assistant specialized in analyzing construction site snags and answering questions about them. Use the information from the initial analysis to answer user queries."},
172
  ]
173
 
 
174
  for human, ai in chat_history:
175
  if human:
176
  messages.append({"role": "user", "content": human})
177
  if ai:
178
  messages.append({"role": "assistant", "content": ai})
179
 
 
180
  messages.append({"role": "user", "content": message})
181
 
 
182
  completion = client.chat.completions.create(
183
  model="llama-3.2-90b-vision-preview",
184
  messages=messages,
 
197
  logger.error(f"Error during chat: {str(e)}")
198
  return "", chat_history + [(message, f"Error: {str(e)}")]
199
 
200
+ def generate_snag_report(chat_history):
201
  """
202
+ Generate a snag report from the chat history.
203
  """
204
+ report = "Construction Site Snag Detection Report\n"
205
  report += "=" * 40 + "\n"
206
  report += f"Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
207
 
 
214
 
215
  return report
216
 
217
+ def download_snag_report(chat_history):
218
  """
219
+ Generate and provide a download link for the snag report.
220
  """
221
+ report = generate_snag_report(chat_history)
222
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
223
+ filename = f"snag_detection_report_{timestamp}.txt"
224
 
 
225
  with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".txt") as temp_file:
226
  temp_file.write(report)
227
  temp_file_path = temp_file.name
228
 
229
  return temp_file_path
230
 
 
231
  # Custom CSS for improved styling
232
  custom_css = """
233
  .container { max-width: 1200px; margin: auto; padding-top: 1.5rem; }
 
261
  """
262
  <div class="container">
263
  <div class="header">
264
+ <h1>🔍 Construction Site Snag Detector</h1>
265
  </div>
266
+ <p class="subheader">Enhance quality control and project management with AI-powered snag detection using Llama 3.2 90B Vision and expert chat assistance.</p>
267
  </div>
268
  """
269
  )
270
 
 
271
  with gr.Row():
272
  file_input = gr.File(
273
  label="Upload Construction Site Images or Videos",
 
276
  elem_classes="file-container"
277
  )
278
 
 
279
  with gr.Row():
280
+ analyze_button = gr.Button("🔍 Detect Snags", elem_classes="analyze-button")
281
 
 
282
  with gr.Row():
283
  chatbot = gr.Chatbot(
284
+ label="Snag Detection Results and Expert Chat",
285
  elem_classes="chatbot",
286
+ show_share_button=False,
287
+ show_copy_button=False
288
  )
289
 
 
290
  with gr.Row():
291
  msg = gr.Textbox(
292
+ label="Ask about detected snags or quality issues",
293
+ placeholder="E.g., 'What are the most critical snags detected?'",
294
  show_label=False,
295
  elem_classes="chat-input"
296
  )
297
 
 
298
  with gr.Row():
299
  clear = gr.Button("🗑️ Clear Chat", elem_classes="clear-button")
300
  download_button = gr.Button("📥 Download Report", elem_classes="download-button")
301
 
302
+ report_file = gr.File(label="Download Snag Detection Report")
 
303
 
304
  def process_files(files):
305
  results = []
306
  for file in files:
307
+ result = detect_snags(file)
308
  results.append((file.name, result))
309
  return results
310
 
 
321
  postprocess=lambda x: update_chat(chatbot.value, x)
322
  )
323
 
324
+ msg.submit(chat_about_snags, [msg, chatbot], [msg, chatbot])
325
  clear.click(lambda: None, None, chatbot, queue=False)
326
 
327
  download_button.click(
328
+ download_snag_report,
329
  inputs=[chatbot],
330
  outputs=[report_file]
331
  )