File size: 5,300 Bytes
aae87aa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28c9014
 
 
 
 
 
 
aae87aa
28c9014
aae87aa
476c0f9
 
3280007
476c0f9
3280007
476c0f9
3280007
476c0f9
28c9014
3280007
 
 
 
28c9014
3280007
28c9014
aae87aa
3280007
476c0f9
3280007
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aae87aa
3280007
 
 
aae87aa
 
 
 
 
 
28c9014
476c0f9
 
 
aae87aa
476c0f9
3280007
476c0f9
 
 
3280007
476c0f9
 
 
 
aae87aa
 
28c9014
aae87aa
3280007
 
aae87aa
28c9014
3280007
28c9014
3280007
28c9014
 
3280007
 
 
 
476c0f9
aae87aa
3280007
 
aae87aa
 
 
 
 
28c9014
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
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. Major cracks can compromise the integrity of the structure and require **immediate intervention**. These are typically caused by foundation settlement, excessive load, or material failure. **Professional assessment is advised.**"
    elif "Moderate" in severity:
        return "⚠️ This crack is classified as **Moderate**. While not immediately critical, it suggests progressive structural movement or material fatigue. **Monitoring and remedial measures**, such as crack sealing or reinforcement, should be considered."
    else:
        return "βœ… This crack is **Minor** and likely due to **surface shrinkage or thermal expansion**. While not structurally concerning, periodic monitoring is recommended to ensure it does not propagate further."

def main():
    st.set_page_config(page_title='πŸ—οΈ Structural Integrity Analyst', layout='wide', initial_sidebar_state='expanded')
    
    # Custom Styling
    st.markdown(
        """
        <style>
            .title {
                text-align: center;
                font-size: 36px;
                font-weight: bold;
                color: #003366;
            }
            .subheader {
                font-size: 24px;
                font-weight: bold;
                color: #00509E;
            }
        </style>
        """, unsafe_allow_html=True
    )
    
    st.markdown("<h1 class='title'>πŸ—οΈ 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)
        
        # Organize layout
        col1, col2 = st.columns(2)
        
        with col1:
            st.markdown("<h2 class='subheader'>πŸ“Έ Uploaded Image</h2>", unsafe_allow_html=True)
            st.image(uploaded_file, caption="Uploaded Image", use_column_width=True)
        
        with col2:
            st.markdown("<h2 class='subheader'>πŸ” Processed Crack Detection</h2>", unsafe_allow_html=True)
            fig, ax = plt.subplots()
            ax.imshow(edges, cmap='gray')
            ax.axis("off")
            st.pyplot(fig)
        
        # Data Analysis
        data = pd.DataFrame(crack_data)
        
        st.markdown("<h2 class='subheader'>πŸ“Š Crack Metrics & Classification</h2>", unsafe_allow_html=True)
        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.markdown("<h2 class='subheader'>πŸ“ Crack Analysis & Recommendations</h2>", unsafe_allow_html=True)
        for _, row in data.iterrows():
            st.markdown(f"**Crack at (X: {row['X']}, Y: {row['Y']})** - {generate_description(row['Severity'])}")
        
        # Discussion
        st.markdown("<h2 class='subheader'>πŸ’‘ Discussion on Crack Severity</h2>", unsafe_allow_html=True)
        st.write("- πŸ”΄ **Major:** Significant structural impact, requires **immediate repair and engineering assessment.**")
        st.write("- 🟠 **Moderate:** Moderate concern, monitoring required, may need **localized reinforcement.**")
        st.write("- 🟒 **Minor:** Surface-level cracks, **not structurally critical** but should be observed over time.")
        
        # 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()