Shakir60 commited on
Commit
9b091b5
Β·
verified Β·
1 Parent(s): 94b4ef9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +137 -198
app.py CHANGED
@@ -342,24 +342,19 @@ def get_groq_response(query: str, context: str) -> str:
342
  logger.error(f"Groq API error: {e}", exc_info=True)
343
  return f"Error: Unable to get response from AI model. Exception: {str(e)}"
344
 
 
 
 
 
345
 
346
- def create_plotly_confidence_chart(results, chart_id):
347
- """Create an interactive confidence chart using Plotly with unique ID"""
 
348
  colors = {
349
- 'light': {
350
- 'bg': 'white',
351
- 'text': 'black',
352
- 'grid': '#eee'
353
- },
354
- 'dark': {
355
- 'bg': '#262730',
356
- 'text': 'white',
357
- 'grid': '#333'
358
- }
359
  }
360
-
361
- theme = 'dark' if st.get_option('theme.base') == 'dark' else 'light'
362
-
363
  fig = go.Figure(data=[
364
  go.Bar(
365
  x=list(results.values()),
@@ -370,10 +365,10 @@ def create_plotly_confidence_chart(results, chart_id):
370
  textposition='auto',
371
  )
372
  ])
373
-
374
  fig.update_layout(
375
- title='Defect Detection Confidence Levels',
376
- xaxis_title='Confidence',
377
  yaxis_title='Defect Type',
378
  template='plotly_dark' if theme == 'dark' else 'plotly_white',
379
  height=400,
@@ -383,11 +378,13 @@ def create_plotly_confidence_chart(results, chart_id):
383
  paper_bgcolor=colors[theme]['bg'],
384
  font=dict(color=colors[theme]['text'])
385
  )
386
-
387
  return fig
388
 
389
  def create_defect_card(title, description, severity, repair_method):
390
- """Create a styled card for defect information with theme support"""
 
 
391
  severity_colors = {
392
  "Critical": "#ff4444",
393
  "High": "#ffa000",
@@ -395,16 +392,19 @@ def create_defect_card(title, description, severity, repair_method):
395
  "Low": "#4caf50"
396
  }
397
 
398
- # Get current theme
399
- is_dark = st.get_option('theme.base') == 'dark'
400
-
401
- bg_color = '#1e1e1e' if is_dark else '#ffffff'
402
- text_color = '#ffffff' if is_dark else '#000000'
403
- border_color = '#333333' if is_dark else '#dddddd'
404
 
405
  return f"""
406
- <div style="border: 1px solid {border_color}; border-radius: 10px; padding: 15px; margin: 10px 0; background-color: {bg_color}; color: {text_color};">
407
- <h3 style="color: {'#00a0dc' if is_dark else '#1f77b4'}; margin: 0 0 10px 0;">{title}</h3>
 
 
 
 
 
 
408
  <p><strong>Description:</strong> {description}</p>
409
  <p><strong>Severity:</strong>
410
  <span style="color: {severity_colors.get(severity, '#808080')}">
@@ -415,80 +415,49 @@ def create_defect_card(title, description, severity, repair_method):
415
  </div>
416
  """
417
 
418
- def get_theme_specific_styles():
419
- """Get theme-specific CSS styles"""
420
- is_dark = st.get_option('theme.base') == 'dark'
 
421
 
422
- if is_dark:
423
- return """
424
- <style>
425
- .stApp {
426
- background-color: #0e1117;
427
- }
428
- .upload-text {
429
- border: 2px dashed #444;
430
- background-color: #1e1e1e;
431
- }
432
- .info-box {
433
- background-color: #262730;
434
- border: 1px solid #333;
435
- }
436
- .stAlert {
437
- background-color: #262730;
438
- border: 1px solid #333;
439
- }
440
- </style>
441
- """
442
- else:
443
- return """
444
- <style>
445
- .stApp {
446
- background-color: #f8f9fa;
447
- }
448
- .upload-text {
449
- border: 2px dashed #ccc;
450
- background-color: #ffffff;
451
- }
452
- .info-box {
453
- background-color: #e9ecef;
454
- border: 1px solid #dee2e6;
455
- }
456
- </style>
457
- """
458
 
459
  def main():
460
  st.set_page_config(
461
- page_title="Smart Construction Defect Analyzer",
462
  page_icon="πŸ—οΈ",
463
  layout="wide",
464
  initial_sidebar_state="expanded"
465
  )
466
-
467
- # Apply theme-specific styles
468
- st.markdown(get_theme_specific_styles(), unsafe_allow_html=True)
469
-
470
- # Base CSS that works for both themes
471
- st.markdown("""
472
- <style>
473
- .css-1d391kg {
474
- padding: 2rem 1rem;
475
- }
476
- .stButton>button {
477
- width: 100%;
478
- }
479
- .upload-text {
480
- text-align: center;
481
- padding: 2rem;
482
- border-radius: 10px;
483
- }
484
- .info-box {
485
- padding: 1rem;
486
- border-radius: 10px;
487
- margin: 1rem 0;
488
- }
489
- </style>
490
- """, unsafe_allow_html=True)
491
-
492
  # Initialize session state
493
  if 'analyzer' not in st.session_state:
494
  st.session_state.analyzer = ImageAnalyzer()
@@ -496,168 +465,138 @@ def main():
496
  st.session_state.rag_system = RAGSystem()
497
  if 'analysis_history' not in st.session_state:
498
  st.session_state.analysis_history = []
499
-
500
  # Sidebar
501
  with st.sidebar:
502
- colored_header(
503
- label="System Controls",
504
- description="Settings and Information",
505
- color_name="blue-70"
506
- )
507
 
508
  # Theme selector
509
  theme = st.selectbox(
510
- "Choose Theme",
511
- options=["Light", "Dark"],
512
- index=1 if st.get_option('theme.base') == 'dark' else 0
 
513
  )
514
 
 
 
 
 
 
 
 
515
  if os.getenv("GROQ_API_KEY"):
516
- st.success("🟒 AI System: Connected")
517
  else:
518
- st.error("πŸ”΄ AI System: Not configured")
519
-
520
- add_vertical_space(2)
521
-
522
  with st.expander("ℹ️ About", expanded=True):
523
  st.write("""
524
- ### Smart Construction Defect Analyzer
525
 
526
- This advanced tool combines computer vision and AI to:
527
- - Detect construction defects in images
528
- - Provide detailed repair recommendations
529
- - Answer technical questions
530
- - Track analysis history
531
  """)
532
-
533
- with st.expander("πŸ”§ Settings"):
534
- if st.button("Clear Analysis History"):
 
535
  st.session_state.analysis_history = []
536
  st.cache_data.clear()
537
  st.success("History cleared!")
538
-
539
- confidence_threshold = st.slider(
540
- "Detection Confidence Threshold",
541
- min_value=0.0,
542
- max_value=1.0,
543
- value=0.3,
544
- step=0.1
545
- )
546
-
547
  # Main content
548
- colored_header(
549
- label="Construction Defect Analyzer",
550
- description="Upload images and get instant defect analysis",
551
- color_name="blue-70"
552
- )
553
 
554
- tab1, tab2, tab3 = st.tabs(["πŸ“Έ Image Analysis", "❓ Ask Expert", "πŸ“Š Analysis History"])
555
 
556
- with tab1:
557
  col1, col2 = st.columns([1, 1])
558
 
559
  with col1:
560
- st.markdown('<div class="upload-text">', unsafe_allow_html=True)
561
  uploaded_file = st.file_uploader(
562
- "Drop your construction image here",
563
- type=["jpg", "jpeg", "png"],
564
- key="image_uploader"
565
  )
566
  st.markdown('</div>', unsafe_allow_html=True)
567
-
568
  if uploaded_file:
569
  try:
570
  with st.spinner('Processing image...'):
571
- processed_image = st.session_state.analyzer.preprocess_image(uploaded_file)
572
- if processed_image:
573
- st.image(processed_image, caption='Analyzed Image', use_column_width=True)
574
-
575
- results = st.session_state.analyzer.analyze_image(processed_image)
576
  if results:
577
- # Store analysis in history
578
  st.session_state.analysis_history.append({
579
  'timestamp': datetime.now(),
580
  'results': results,
581
- 'image': processed_image
582
  })
583
  except Exception as e:
584
  st.error(f"Error: {str(e)}")
585
-
586
  with col2:
587
- if uploaded_file and results:
588
  st.markdown("### Analysis Results")
589
 
590
- # Interactive confidence chart with unique ID
591
  fig = create_plotly_confidence_chart(results, "main_analysis")
592
  st.plotly_chart(fig, use_container_width=True, key="main_chart")
593
 
594
- # Most critical defect
595
- most_likely_defect = max(results.items(), key=lambda x: x[1])[0]
596
- st.info(f"πŸ” Primary Defect Detected: {most_likely_defect}")
597
 
598
- # Get detailed information about the defect
599
- context = st.session_state.rag_system.get_relevant_context(most_likely_defect)
600
  if context:
601
- st.markdown("### Defect Details")
602
  st.markdown(create_defect_card(
603
- most_likely_defect,
604
- context.split('\n')[2].split(': ')[1],
605
- context.split('\n')[1].split(': ')[1],
606
- context.split('\n')[3].split(': ')[1]
607
  ), unsafe_allow_html=True)
608
-
609
- with tab2:
610
- st.markdown("### Ask the Construction Expert")
611
-
612
- query_placeholder = "Example: What are the best repair methods for structural cracks?"
613
- user_query = st.text_input("Your Question:", placeholder=query_placeholder)
 
614
 
615
- if user_query:
616
  with st.spinner('Consulting AI expert...'):
617
- context = st.session_state.rag_system.get_relevant_context(user_query)
618
  if context:
619
- response = get_groq_response(user_query, context)
620
-
621
  if not response.startswith("Error"):
622
  st.markdown("### Expert Response")
623
  st.markdown(response)
624
-
625
- with st.expander("View Source Information"):
626
  st.markdown(context)
627
  else:
628
  st.error(response)
629
-
630
- with tab3:
631
  if st.session_state.analysis_history:
632
  for i, analysis in enumerate(reversed(st.session_state.analysis_history)):
633
- with st.expander(f"Analysis {i+1} - {analysis['timestamp'].strftime('%Y-%m-%d %H:%M')}"):
634
- col1, col2 = st.columns([1, 1])
635
- with col1:
636
- st.image(analysis['image'], caption='Analyzed Image', use_column_width=True)
637
- with col2:
638
- # Create chart with unique ID for history items
639
- fig = create_plotly_confidence_chart(analysis['results'], f"history_{i}")
640
- st.plotly_chart(fig, use_container_width=True, key=f"history_chart_{i}")
 
 
 
 
641
  else:
642
  st.info("No analysis history available")
643
 
644
- # Handle theme change
645
- if theme == "Dark" and st.get_option('theme.base') != 'dark':
646
- st.markdown("""
647
- <script>
648
- var elements = window.parent.document.getElementsByTagName('iframe');
649
- for (var i = 0; i < elements.length; i++) {
650
- if (elements[i].height === '0') {
651
- elements[i].remove();
652
- }
653
- }
654
- </script>
655
- """, unsafe_allow_html=True)
656
- st.experimental_set_query_params(theme='dark')
657
- st.experimental_rerun()
658
- elif theme == "Light" and st.get_option('theme.base') != 'light':
659
- st.experimental_set_query_params(theme='light')
660
- st.experimental_rerun()
661
-
662
  if __name__ == "__main__":
663
  main()
 
342
  logger.error(f"Groq API error: {e}", exc_info=True)
343
  return f"Error: Unable to get response from AI model. Exception: {str(e)}"
344
 
345
+ def get_theme():
346
+ """Get current theme from query parameters"""
347
+ theme = st.query_params.get("theme", "light")
348
+ return "dark" if theme == "dark" else "light"
349
 
350
+ def create_plotly_confidence_chart(results, unique_key):
351
+ """Create an interactive confidence chart using Plotly"""
352
+ theme = get_theme()
353
  colors = {
354
+ 'light': {'bg': 'white', 'text': 'black', 'grid': '#eee'},
355
+ 'dark': {'bg': '#2d2d2d', 'text': 'white', 'grid': '#444'}
 
 
 
 
 
 
 
 
356
  }
357
+
 
 
358
  fig = go.Figure(data=[
359
  go.Bar(
360
  x=list(results.values()),
 
365
  textposition='auto',
366
  )
367
  ])
368
+
369
  fig.update_layout(
370
+ title='Defect Detection Confidence',
371
+ xaxis_title='Confidence Level',
372
  yaxis_title='Defect Type',
373
  template='plotly_dark' if theme == 'dark' else 'plotly_white',
374
  height=400,
 
378
  paper_bgcolor=colors[theme]['bg'],
379
  font=dict(color=colors[theme]['text'])
380
  )
381
+
382
  return fig
383
 
384
  def create_defect_card(title, description, severity, repair_method):
385
+ """Create a styled card for defect information"""
386
+ theme = get_theme()
387
+
388
  severity_colors = {
389
  "Critical": "#ff4444",
390
  "High": "#ffa000",
 
392
  "Low": "#4caf50"
393
  }
394
 
395
+ bg_color = '#1e1e1e' if theme == 'dark' else '#ffffff'
396
+ text_color = '#ffffff' if theme == 'dark' else '#000000'
397
+ border_color = '#333333' if theme == 'dark' else '#dddddd'
 
 
 
398
 
399
  return f"""
400
+ <div style="border: 1px solid {border_color};
401
+ border-radius: 10px;
402
+ padding: 15px;
403
+ margin: 10px 0;
404
+ background-color: {bg_color};
405
+ color: {text_color};">
406
+ <h3 style="color: {'#00a0dc' if theme == 'dark' else '#1f77b4'};
407
+ margin: 0 0 10px 0;">{title}</h3>
408
  <p><strong>Description:</strong> {description}</p>
409
  <p><strong>Severity:</strong>
410
  <span style="color: {severity_colors.get(severity, '#808080')}">
 
415
  </div>
416
  """
417
 
418
+ def apply_theme_styles():
419
+ """Apply theme-specific CSS styles"""
420
+ theme = get_theme()
421
+ is_dark = theme == "dark"
422
 
423
+ styles = """
424
+ <style>
425
+ .stApp {
426
+ background-color: """ + ('#0e1117' if is_dark else '#f8f9fa') + """;
427
+ }
428
+ .upload-area {
429
+ text-align: center;
430
+ padding: 2rem;
431
+ border-radius: 10px;
432
+ border: 2px dashed """ + ('#444' if is_dark else '#ccc') + """;
433
+ background-color: """ + ('#1e1e1e' if is_dark else '#ffffff') + """;
434
+ margin-bottom: 1rem;
435
+ }
436
+ .info-box {
437
+ padding: 1rem;
438
+ border-radius: 10px;
439
+ margin: 1rem 0;
440
+ background-color: """ + ('#262730' if is_dark else '#e9ecef') + """;
441
+ border: 1px solid """ + ('#333' if is_dark else '#dee2e6') + """;
442
+ }
443
+ .stButton>button {
444
+ width: 100%;
445
+ }
446
+ </style>
447
+ """
448
+ st.markdown(styles, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
449
 
450
  def main():
451
  st.set_page_config(
452
+ page_title="Construction Defect Analyzer",
453
  page_icon="πŸ—οΈ",
454
  layout="wide",
455
  initial_sidebar_state="expanded"
456
  )
457
+
458
+ # Apply theme styles
459
+ apply_theme_styles()
460
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  # Initialize session state
462
  if 'analyzer' not in st.session_state:
463
  st.session_state.analyzer = ImageAnalyzer()
 
465
  st.session_state.rag_system = RAGSystem()
466
  if 'analysis_history' not in st.session_state:
467
  st.session_state.analysis_history = []
468
+
469
  # Sidebar
470
  with st.sidebar:
471
+ st.title("πŸ”§ Controls")
 
 
 
 
472
 
473
  # Theme selector
474
  theme = st.selectbox(
475
+ "Theme",
476
+ options=["light", "dark"],
477
+ index=0 if get_theme() == "light" else 1,
478
+ key="theme_selector"
479
  )
480
 
481
+ if theme != get_theme():
482
+ st.query_params["theme"] = theme
483
+ st.rerun()
484
+
485
+ st.divider()
486
+
487
+ # API Status
488
  if os.getenv("GROQ_API_KEY"):
489
+ st.success("🟒 AI System Connected")
490
  else:
491
+ st.error("πŸ”΄ AI System Not Connected")
492
+
 
 
493
  with st.expander("ℹ️ About", expanded=True):
494
  st.write("""
495
+ ### Construction Defect Analyzer
496
 
497
+ Advanced AI-powered tool for:
498
+ - Visual defect detection
499
+ - Repair recommendations
500
+ - Expert consultations
501
+ - Analysis tracking
502
  """)
503
+
504
+ # Settings
505
+ with st.expander("βš™οΈ Settings"):
506
+ if st.button("Clear History"):
507
  st.session_state.analysis_history = []
508
  st.cache_data.clear()
509
  st.success("History cleared!")
510
+
 
 
 
 
 
 
 
 
511
  # Main content
512
+ st.title("Construction Defect Analyzer")
 
 
 
 
513
 
514
+ tabs = st.tabs(["πŸ“Έ Analysis", "❓ Expert Help", "πŸ“Š History"])
515
 
516
+ with tabs[0]: # Analysis Tab
517
  col1, col2 = st.columns([1, 1])
518
 
519
  with col1:
520
+ st.markdown('<div class="upload-area">', unsafe_allow_html=True)
521
  uploaded_file = st.file_uploader(
522
+ "Upload construction image",
523
+ type=["jpg", "jpeg", "png"]
 
524
  )
525
  st.markdown('</div>', unsafe_allow_html=True)
526
+
527
  if uploaded_file:
528
  try:
529
  with st.spinner('Processing image...'):
530
+ image = st.session_state.analyzer.preprocess_image(uploaded_file)
531
+ if image:
532
+ st.image(image, caption='Analyzed Image', use_column_width=True)
533
+ results = st.session_state.analyzer.analyze_image(image)
 
534
  if results:
 
535
  st.session_state.analysis_history.append({
536
  'timestamp': datetime.now(),
537
  'results': results,
538
+ 'image': image
539
  })
540
  except Exception as e:
541
  st.error(f"Error: {str(e)}")
542
+
543
  with col2:
544
+ if uploaded_file and 'results' in locals():
545
  st.markdown("### Analysis Results")
546
 
 
547
  fig = create_plotly_confidence_chart(results, "main_analysis")
548
  st.plotly_chart(fig, use_container_width=True, key="main_chart")
549
 
550
+ primary_defect = max(results.items(), key=lambda x: x[1])[0]
551
+ st.info(f"πŸ” Primary Defect: {primary_defect}")
 
552
 
553
+ context = st.session_state.rag_system.get_relevant_context(primary_defect)
 
554
  if context:
555
+ lines = context.split('\n')
556
  st.markdown(create_defect_card(
557
+ primary_defect,
558
+ next((line.split(': ')[1] for line in lines if 'description' in line.lower()), ''),
559
+ next((line.split(': ')[1] for line in lines if 'severity' in line.lower()), ''),
560
+ next((line.split(': ')[1] for line in lines if 'repair_method' in line.lower()), '')
561
  ), unsafe_allow_html=True)
562
+
563
+ with tabs[1]: # Expert Help Tab
564
+ st.markdown("### Ask Our Expert")
565
+ query = st.text_input(
566
+ "Your Question:",
567
+ placeholder="Example: What are the best repair methods for spalling?"
568
+ )
569
 
570
+ if query:
571
  with st.spinner('Consulting AI expert...'):
572
+ context = st.session_state.rag_system.get_relevant_context(query)
573
  if context:
574
+ response = get_groq_response(query, context)
 
575
  if not response.startswith("Error"):
576
  st.markdown("### Expert Response")
577
  st.markdown(response)
578
+ with st.expander("View Source"):
 
579
  st.markdown(context)
580
  else:
581
  st.error(response)
582
+
583
+ with tabs[2]: # History Tab
584
  if st.session_state.analysis_history:
585
  for i, analysis in enumerate(reversed(st.session_state.analysis_history)):
586
+ with st.expander(
587
+ f"Analysis {i+1} - {analysis['timestamp'].strftime('%Y-%m-%d %H:%M')}"
588
+ ):
589
+ cols = st.columns([1, 1])
590
+ with cols[0]:
591
+ st.image(analysis['image'], caption='Image', use_column_width=True)
592
+ with cols[1]:
593
+ fig = create_plotly_confidence_chart(
594
+ analysis['results'],
595
+ f"history_{i}"
596
+ )
597
+ st.plotly_chart(fig, use_container_width=True, key=f"history_{i}")
598
  else:
599
  st.info("No analysis history available")
600
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
  if __name__ == "__main__":
602
  main()