File size: 4,559 Bytes
aae87aa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28c9014
 
 
 
 
 
 
aae87aa
28c9014
aae87aa
476c0f9
 
3280007
476c0f9
3280007
476c0f9
3280007
476c0f9
28c9014
3280007
9542674
3280007
9542674
28c9014
9542674
 
 
 
 
 
 
 
 
 
 
 
 
28c9014
aae87aa
3280007
476c0f9
9542674
3280007
 
aae87aa
 
 
 
 
 
28c9014
476c0f9
9542674
 
 
 
476c0f9
 
aae87aa
476c0f9
9542674
476c0f9
 
 
9542674
476c0f9
 
 
 
aae87aa
 
28c9014
aae87aa
9542674
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aae87aa
 
9542674
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
import streamlit as st
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import plotly.express as px
from PIL import Image

def analyze_crack(image):
    # Convert image to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # Edge detection
    edges = cv2.Canny(gray, 50, 150)
    
    # Finding contours
    contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    # Calculate crack metrics
    crack_data = []
    for cnt in contours:
        length = cv2.arcLength(cnt, True)
        x, y, w, h = cv2.boundingRect(cnt)
        width = w
        severity = classify_crack(length, width)
        crack_data.append({"Length": length, "Width": width, "Severity": severity, "X": x, "Y": y})
    
    return edges, crack_data

def classify_crack(length, width):
    if length > 150 or width > 20:
        return "πŸ”΄ Major"
    elif length > 80 or width > 10:
        return "🟠 Moderate"
    else:
        return "🟒 Minor"

def generate_description(severity):
    if "Major" in severity:
        return "🚨 This crack is classified as **Major**, indicating significant structural distress. Immediate intervention is required."
    elif "Moderate" in severity:
        return "⚠️ This crack is classified as **Moderate**. Monitoring and remedial measures should be considered."
    else:
        return "βœ… This crack is **Minor** and likely due to surface shrinkage or thermal expansion. Periodic monitoring is recommended."

def determine_structure_safety(crack_data):
    if not crack_data:
        return "βœ… Structure is Safe", "green"
    
    major_count = sum(1 for crack in crack_data if "Major" in crack["Severity"])
    moderate_count = sum(1 for crack in crack_data if "Moderate" in crack["Severity"])
    
    if major_count > 0 or moderate_count > 3:
        return "🚨 Structure is NOT Safe", "red"
    
    return "⚠️ Structure Needs Monitoring", "orange"

def main():
    st.set_page_config(page_title='πŸ—οΈ Structural Integrity Analyst', layout='wide', initial_sidebar_state='expanded')
    
    st.markdown("<h1 style='text-align: center; color: #003366;'>πŸ—οΈ Structural Integrity Analyst</h1>", unsafe_allow_html=True)
    
    st.sidebar.header("πŸ“‚ Upload Crack Image")
    uploaded_file = st.sidebar.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
    
    if uploaded_file is not None:
        image = Image.open(uploaded_file)
        image = np.array(image)
        
        edges, crack_data = analyze_crack(image)
        
        # Determine Structural Safety
        structure_status, status_color = determine_structure_safety(crack_data)
        st.markdown(f"<h2 style='text-align: center; color: {status_color};'>{structure_status}</h2>", unsafe_allow_html=True)
        
        # Organize layout
        col1, col2 = st.columns(2)
        
        with col1:
            st.subheader("πŸ“Έ Uploaded Image")
            st.image(uploaded_file, caption="Uploaded Image", use_column_width=True)
        
        with col2:
            st.subheader("πŸ” Processed Crack Detection")
            fig, ax = plt.subplots()
            ax.imshow(edges, cmap='gray')
            ax.axis("off")
            st.pyplot(fig)
        
        # Data Analysis
        data = pd.DataFrame(crack_data)
        
        if not data.empty:
            st.subheader("πŸ“Š Crack Metrics & Classification")
            st.dataframe(data.style.applymap(lambda val: 'background-color: #FFDDC1' if 'Major' in str(val) else ('background-color: #FFF3CD' if 'Moderate' in str(val) else 'background-color: #D4EDDA')))
            
            # Description of Cracks
            st.subheader("πŸ“ Crack Analysis & Recommendations")
            for _, row in data.iterrows():
                st.markdown(f"**Crack at (X: {row['X']}, Y: {row['Y']})** - {generate_description(row['Severity'])}")
            
            # Visualization
            fig1 = px.histogram(data, x="Length", color="Severity", title="πŸ“ Crack Length Distribution", nbins=10, color_discrete_map={"πŸ”΄ Major": "red", "🟠 Moderate": "orange", "🟒 Minor": "green"})
            fig2 = px.histogram(data, x="Width", color="Severity", title="πŸ“ Crack Width Distribution", nbins=10, color_discrete_map={"πŸ”΄ Major": "red", "🟠 Moderate": "orange", "🟒 Minor": "green"})
            
            st.plotly_chart(fig1, use_container_width=True)
            st.plotly_chart(fig2, use_container_width=True)
    
if __name__ == "__main__":
    main()