Shakir60 commited on
Commit
598b1e5
Β·
verified Β·
1 Parent(s): b368d12

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +253 -147
app.py CHANGED
@@ -2,216 +2,322 @@ import streamlit as st
2
  from transformers import ViTForImageClassification, ViTImageProcessor
3
  from PIL import Image
4
  import torch
5
- import json
 
 
6
 
7
- # Embedded knowledge base
 
 
 
 
 
8
  KNOWLEDGE_BASE = {
9
  "spalling": [
 
 
 
 
 
 
 
 
 
 
 
10
  {
11
  "severity": "High",
12
- "description": "Severe concrete spalling with exposed reinforcement",
13
- "repair_method": ["Remove damaged concrete", "Clean exposed reinforcement", "Apply rust inhibitor", "Apply bonding agent", "Patch with repair mortar"],
14
- "estimated_cost": "High ($5,000-$10,000)",
15
  "timeframe": "2-3 weeks",
16
- "location": "Column/Beam",
17
  "required_expertise": "Structural Engineer",
18
- "immediate_action": "Area isolation and temporary support if structural",
19
- "prevention": "Regular maintenance, waterproofing, proper concrete cover"
20
- },
21
- {
22
- "severity": "Medium",
23
- "description": "Surface spalling without exposed reinforcement",
24
- "repair_method": ["Remove loose concrete", "Clean surface", "Apply repair mortar", "Surface treatment"],
25
- "estimated_cost": "Medium ($2,000-$5,000)",
26
- "timeframe": "1-2 weeks",
27
- "location": "Non-structural elements",
28
- "required_expertise": "Concrete Repair Specialist",
29
- "immediate_action": "Mark affected areas and monitor",
30
- "prevention": "Surface coating, regular inspections"
31
  }
32
  ],
33
  "reinforcement_corrosion": [
34
  {
35
  "severity": "Critical",
36
- "description": "Advanced corrosion with significant section loss",
37
- "repair_method": ["Install temporary support", "Remove damaged concrete", "Replace/supplement reinforcement", "Apply corrosion inhibitor", "Reconstruct concrete cover"],
38
- "estimated_cost": "Very High ($15,000+)",
39
- "timeframe": "3-4 weeks",
40
- "location": "Primary structural elements",
41
- "required_expertise": "Structural Engineer, Specialist Contractor",
42
- "immediate_action": "Immediate area evacuation and temporary support",
43
- "prevention": "Waterproofing, crack sealing, chloride protection"
44
  }
45
  ],
46
  "structural_crack": [
47
  {
48
  "severity": "High",
49
- "description": "Load-bearing element cracks >3mm",
50
- "repair_method": ["Structural assessment", "Crack injection with epoxy", "External reinforcement if needed", "Monitor crack progression"],
51
- "estimated_cost": "High ($8,000-$15,000)",
52
- "timeframe": "2-3 weeks",
53
- "location": "Load-bearing walls/beams",
54
  "required_expertise": "Structural Engineer",
55
- "immediate_action": "Install crack gauges, temporary support",
56
- "prevention": "proper design, load management, movement joints"
57
  }
58
  ],
59
  "dampness": [
60
  {
61
  "severity": "Medium",
62
- "description": "Persistent moisture penetration",
63
- "repair_method": ["Identify water source", "Install drainage system", "Apply waterproofing membrane", "Improve ventilation"],
64
- "estimated_cost": "Medium ($3,000-$7,000)",
65
  "timeframe": "1-2 weeks",
66
- "location": "Walls, floors",
67
  "required_expertise": "Waterproofing Specialist",
68
- "immediate_action": "Improve ventilation, dehumidification",
69
- "prevention": "Proper drainage, regular maintenance of water systems"
70
  }
71
  ],
72
  "no_damage": [
73
  {
74
  "severity": "Low",
75
- "description": "No visible structural issues",
76
- "repair_method": ["Regular inspection", "Preventive maintenance", "Document condition"],
77
- "estimated_cost": "Low ($500-$1,000)",
78
  "timeframe": "1-2 days",
79
- "location": "General structure",
80
  "required_expertise": "Building Inspector",
81
- "immediate_action": "Continue regular maintenance",
82
- "prevention": "Maintain inspection schedule"
83
  }
84
  ]
85
  }
86
 
87
  DAMAGE_TYPES = {
88
- 0: {'name': 'spalling', 'risk': 'High'},
89
- 1: {'name': 'reinforcement_corrosion', 'risk': 'Critical'},
90
- 2: {'name': 'structural_crack', 'risk': 'High'},
91
- 3: {'name': 'dampness', 'risk': 'Medium'},
92
- 4: {'name': 'no_damage', 'risk': 'Low'}
93
  }
94
 
 
 
 
 
 
 
95
  @st.cache_resource
96
  def load_model():
97
- model = ViTForImageClassification.from_pretrained(
98
- "google/vit-base-patch16-224",
99
- num_labels=len(DAMAGE_TYPES),
100
- ignore_mismatched_sizes=True
101
- )
102
- processor = ViTImageProcessor.from_pretrained("google/vit-base-patch16-224")
103
- return model, processor
 
 
 
 
104
 
105
  def analyze_damage(image, model, processor):
106
- image = image.convert('RGB')
107
- inputs = processor(images=image, return_tensors="pt")
108
- outputs = model(**inputs)
109
- probs = torch.nn.functional.softmax(outputs.logits, dim=1)[0]
110
- return probs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
  def main():
 
113
  st.set_page_config(
114
- page_title="Structural Damage Analyzer",
115
  page_icon="πŸ—οΈ",
116
  layout="wide",
117
  initial_sidebar_state="expanded"
118
  )
119
 
120
- # Custom CSS
121
- st.markdown("""
122
- <style>
123
- .main {
124
- padding: 2rem;
125
- }
126
- .stProgress > div > div > div > div {
127
- background-image: linear-gradient(to right, #ff6b6b, #f06595);
128
- }
129
- .damage-card {
130
- padding: 1.5rem;
131
- border-radius: 0.5rem;
132
- background: #f8f9fa;
133
- margin-bottom: 1rem;
134
- }
135
- </style>
136
- """, unsafe_allow_html=True)
137
 
138
- col1, col2, col3 = st.columns([1, 3, 1])
139
- with col2:
140
- st.title("πŸ—οΈ Structural Damage Analyzer")
141
- st.markdown("### Upload a photo of structural damage for instant analysis")
 
 
 
 
142
 
143
- model, processor = load_model()
144
-
145
- upload_col1, upload_col2, upload_col3 = st.columns([1, 2, 1])
146
- with upload_col2:
147
- uploaded_file = st.file_uploader("Choose an image file", type=['jpg', 'jpeg', 'png'])
 
148
 
149
  if uploaded_file:
150
- image = Image.open(uploaded_file)
151
-
152
- analysis_col1, analysis_col2 = st.columns(2)
153
-
154
- with analysis_col1:
155
- st.image(image, caption="Uploaded Structure", use_column_width=True)
156
-
157
- with analysis_col2:
158
- with st.spinner("πŸ” Analyzing structural damage..."):
159
- predictions = analyze_damage(image, model, processor)
160
-
161
- st.markdown("### πŸ“Š Damage Assessment Results")
162
-
163
- for idx, prob in enumerate(predictions):
164
- confidence = float(prob) * 100
165
- if confidence > 15:
166
- damage_type = DAMAGE_TYPES[idx]['name']
167
- cases = KNOWLEDGE_BASE[damage_type]
168
-
169
- st.markdown(f"""
170
- <div class="damage-card">
171
- <h4>{damage_type.replace('_', ' ').title()} Detected</h4>
172
- </div>
173
- """, unsafe_allow_html=True)
174
 
175
- col1, col2 = st.columns([3, 1])
176
- with col1:
177
- st.progress(confidence / 100)
178
- with col2:
179
- st.write(f"Confidence: {confidence:.1f}%")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
- tabs = st.tabs(["Details", "Repair Methods", "Recommendations"])
 
182
 
183
- with tabs[0]:
184
- for case in cases:
185
- st.markdown(f"""
186
- - **Severity:** {case['severity']}
187
- - **Description:** {case['description']}
188
- - **Location:** {case['location']}
189
- - **Required Expertise:** {case['required_expertise']}
190
- """)
191
-
192
- with tabs[1]:
193
- st.markdown("#### Repair Steps")
194
- for step in cases[0]['repair_method']:
195
- st.markdown(f"- {step}")
196
- st.markdown(f"""
197
- - **Estimated Cost:** {cases[0]['estimated_cost']}
198
- - **Timeframe:** {cases[0]['timeframe']}
199
- """)
200
-
201
- with tabs[2]:
202
- st.markdown("#### Immediate Actions")
203
- st.warning(cases[0]['immediate_action'])
204
-
205
- st.markdown("#### Prevention Measures")
206
- st.info(cases[0]['prevention'])
207
 
208
  # Footer
209
  st.markdown("---")
210
- st.markdown("""
 
211
  <div style='text-align: center'>
212
- <p>πŸ—οΈ Structural Damage Analysis Tool | Built with Streamlit</p>
 
213
  </div>
214
- """, unsafe_allow_html=True)
 
 
215
 
216
  if __name__ == "__main__":
217
  main()
 
2
  from transformers import ViTForImageClassification, ViTImageProcessor
3
  from PIL import Image
4
  import torch
5
+ import time
6
+ import io
7
+ import base64
8
 
9
+ # Cache the model globally
10
+ MODEL = None
11
+ PROCESSOR = None
12
+
13
+ # Embedded knowledge base (using previous KNOWLEDGE_BASE)
14
+ # Knowledge base
15
  KNOWLEDGE_BASE = {
16
  "spalling": [
17
+ {
18
+ "severity": "Critical",
19
+ "description": "Severe concrete spalling with exposed reinforcement and section loss",
20
+ "repair_method": ["Install temporary support", "Remove deteriorated concrete", "Clean and treat reinforcement", "Apply corrosion inhibitor", "Apply bonding agent", "High-strength repair mortar"],
21
+ "estimated_cost": "Very High ($15,000+)",
22
+ "timeframe": "3-4 weeks",
23
+ "location": "Primary structural elements",
24
+ "required_expertise": "Structural Engineer + Specialist Contractor",
25
+ "immediate_action": "Evacuate area, install temporary support, prevent access",
26
+ "prevention": "Regular inspections, waterproofing, chloride protection"
27
+ },
28
  {
29
  "severity": "High",
30
+ "description": "Surface spalling with visible reinforcement",
31
+ "repair_method": ["Remove damaged concrete", "Treat reinforcement", "Apply repair mortar", "Surface treatment"],
32
+ "estimated_cost": "High ($8,000-$15,000)",
33
  "timeframe": "2-3 weeks",
34
+ "location": "Structural elements",
35
  "required_expertise": "Structural Engineer",
36
+ "immediate_action": "Area isolation, temporary support assessment",
37
+ "prevention": "Protective coatings, drainage improvement"
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
  ],
40
  "reinforcement_corrosion": [
41
  {
42
  "severity": "Critical",
43
+ "description": "Severe corrosion with >30% section loss",
44
+ "repair_method": ["Structural support", "Remove concrete", "Replace reinforcement", "Corrosion protection", "Concrete repair"],
45
+ "estimated_cost": "Critical ($20,000+)",
46
+ "timeframe": "4-6 weeks",
47
+ "location": "Load-bearing elements",
48
+ "required_expertise": "Senior Structural Engineer",
49
+ "immediate_action": "Immediate evacuation, emergency shoring",
50
+ "prevention": "Waterproofing, cathodic protection"
51
  }
52
  ],
53
  "structural_crack": [
54
  {
55
  "severity": "High",
56
+ "description": "Cracks >5mm in structural elements",
57
+ "repair_method": ["Structural analysis", "Epoxy injection", "Carbon fiber reinforcement", "Crack monitoring"],
58
+ "estimated_cost": "High ($10,000-$20,000)",
59
+ "timeframe": "2-4 weeks",
60
+ "location": "Primary structure",
61
  "required_expertise": "Structural Engineer",
62
+ "immediate_action": "Install crack monitors, load restriction",
63
+ "prevention": "Load management, joint maintenance"
64
  }
65
  ],
66
  "dampness": [
67
  {
68
  "severity": "Medium",
69
+ "description": "Active water penetration with efflorescence",
70
+ "repair_method": ["Water source identification", "Drainage improvement", "Waterproof membrane", "Ventilation"],
71
+ "estimated_cost": "Medium ($5,000-$10,000)",
72
  "timeframe": "1-2 weeks",
73
+ "location": "Various",
74
  "required_expertise": "Waterproofing Specialist",
75
+ "immediate_action": "Dehumidification, efflorescence cleaning",
76
+ "prevention": "Proper drainage, vapor barriers"
77
  }
78
  ],
79
  "no_damage": [
80
  {
81
  "severity": "Low",
82
+ "description": "No significant structural issues",
83
+ "repair_method": ["Regular inspection", "Preventive maintenance"],
84
+ "estimated_cost": "Low ($500-$2,000)",
85
  "timeframe": "1-2 days",
86
+ "location": "General",
87
  "required_expertise": "Building Inspector",
88
+ "immediate_action": "Continue monitoring",
89
+ "prevention": "Regular maintenance schedule"
90
  }
91
  ]
92
  }
93
 
94
  DAMAGE_TYPES = {
95
+ 0: {'name': 'spalling', 'risk': 'High', 'color': '#ff4d4d'},
96
+ 1: {'name': 'reinforcement_corrosion', 'risk': 'Critical', 'color': '#800000'},
97
+ 2: {'name': 'structural_crack', 'risk': 'High', 'color': '#ff6b6b'},
98
+ 3: {'name': 'dampness', 'risk': 'Medium', 'color': '#4dabf7'},
99
+ 4: {'name': 'no_damage', 'risk': 'Low', 'color': '#40c057'}
100
  }
101
 
102
+ def init_session_state():
103
+ if 'history' not in st.session_state:
104
+ st.session_state.history = []
105
+ if 'dark_mode' not in st.session_state:
106
+ st.session_state.dark_mode = False
107
+
108
  @st.cache_resource
109
  def load_model():
110
+ try:
111
+ model = ViTForImageClassification.from_pretrained(
112
+ "google/vit-base-patch16-224",
113
+ num_labels=len(DAMAGE_TYPES),
114
+ ignore_mismatched_sizes=True
115
+ )
116
+ processor = ViTImageProcessor.from_pretrained("google/vit-base-patch16-224")
117
+ return model, processor
118
+ except Exception as e:
119
+ st.error(f"Error loading model: {str(e)}")
120
+ return None, None
121
 
122
  def analyze_damage(image, model, processor):
123
+ try:
124
+ image = image.convert('RGB')
125
+ inputs = processor(images=image, return_tensors="pt")
126
+ outputs = model(**inputs)
127
+ probs = torch.nn.functional.softmax(outputs.logits, dim=1)[0]
128
+ return probs
129
+ except Exception as e:
130
+ st.error(f"Error analyzing image: {str(e)}")
131
+ return None
132
+
133
+ def get_custom_css():
134
+ return """
135
+ <style>
136
+ .main {
137
+ padding: 2rem;
138
+ }
139
+ .stProgress > div > div > div > div {
140
+ background-image: linear-gradient(to right, var(--progress-color, #ff6b6b), var(--progress-color-end, #f06595));
141
+ }
142
+ .damage-card {
143
+ padding: 1.5rem;
144
+ border-radius: 0.5rem;
145
+ background: var(--card-bg, #f8f9fa);
146
+ margin-bottom: 1rem;
147
+ border: 1px solid var(--border-color, #dee2e6);
148
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
149
+ }
150
+ .damage-header {
151
+ font-size: 1.25rem;
152
+ font-weight: bold;
153
+ margin-bottom: 1rem;
154
+ color: var(--text-color, #212529);
155
+ }
156
+ .dark-mode {
157
+ background-color: #1a1a1a;
158
+ color: #ffffff;
159
+ }
160
+ .dark-mode .damage-card {
161
+ background: #2d2d2d;
162
+ border-color: #404040;
163
+ }
164
+ .tooltip {
165
+ position: relative;
166
+ display: inline-block;
167
+ border-bottom: 1px dotted #ccc;
168
+ }
169
+ .tooltip .tooltiptext {
170
+ visibility: hidden;
171
+ background-color: #555;
172
+ color: #fff;
173
+ text-align: center;
174
+ border-radius: 6px;
175
+ padding: 5px;
176
+ position: absolute;
177
+ z-index: 1;
178
+ bottom: 125%;
179
+ left: 50%;
180
+ margin-left: -60px;
181
+ opacity: 0;
182
+ transition: opacity 0.3s;
183
+ }
184
+ </style>
185
+ """
186
+
187
+ def display_header():
188
+ st.markdown(
189
+ """
190
+ <div style='text-align: center; padding: 1rem;'>
191
+ <h1>πŸ—οΈ Structural Damage Analyzer Pro</h1>
192
+ <p style='font-size: 1.2rem;'>Advanced AI-powered structural damage assessment tool</p>
193
+ </div>
194
+ """,
195
+ unsafe_allow_html=True
196
+ )
197
 
198
  def main():
199
+ init_session_state()
200
  st.set_page_config(
201
+ page_title="Structural Damage Analyzer Pro",
202
  page_icon="πŸ—οΈ",
203
  layout="wide",
204
  initial_sidebar_state="expanded"
205
  )
206
 
207
+ st.markdown(get_custom_css(), unsafe_allow_html=True)
208
+
209
+ # Sidebar
210
+ with st.sidebar:
211
+ st.markdown("### βš™οΈ Settings")
212
+ st.session_state.dark_mode = st.toggle("Dark Mode", st.session_state.dark_mode)
213
+ st.markdown("### πŸ“– Analysis History")
214
+ if st.session_state.history:
215
+ for item in st.session_state.history[-5:]:
216
+ st.markdown(f"- {item}")
217
+
218
+ display_header()
 
 
 
 
 
219
 
220
+ # Load model
221
+ global MODEL, PROCESSOR
222
+ if MODEL is None or PROCESSOR is None:
223
+ with st.spinner("Loading AI model..."):
224
+ MODEL, PROCESSOR = load_model()
225
+ if MODEL is None:
226
+ st.error("Failed to load model. Please refresh the page.")
227
+ return
228
 
229
+ # File upload with drag and drop
230
+ uploaded_file = st.file_uploader(
231
+ "Drag and drop or click to upload an image",
232
+ type=['jpg', 'jpeg', 'png'],
233
+ help="Supported formats: JPG, JPEG, PNG"
234
+ )
235
 
236
  if uploaded_file:
237
+ try:
238
+ # Image display and analysis
239
+ image = Image.open(uploaded_file)
240
+ col1, col2 = st.columns([1, 1])
241
+
242
+ with col1:
243
+ st.image(image, caption="Uploaded Structure", use_column_width=True)
244
+
245
+ with col2:
246
+ with st.spinner("πŸ” Analyzing damage..."):
247
+ start_time = time.time()
248
+ predictions = analyze_damage(image, MODEL, PROCESSOR)
249
+ analysis_time = time.time() - start_time
250
+
251
+ if predictions is not None:
252
+ st.markdown("### πŸ“Š Analysis Results")
253
+ st.markdown(f"*Analysis completed in {analysis_time:.2f} seconds*")
 
 
 
 
 
 
 
254
 
255
+ detected = False
256
+ for idx, prob in enumerate(predictions):
257
+ confidence = float(prob) * 100
258
+ if confidence > 15:
259
+ detected = True
260
+ damage_type = DAMAGE_TYPES[idx]['name']
261
+ cases = KNOWLEDGE_BASE[damage_type]
262
+
263
+ with st.expander(f"{damage_type.replace('_', ' ').title()} - {confidence:.1f}%", expanded=True):
264
+ # Progress bar with custom color
265
+ st.markdown(
266
+ f"""
267
+ <style>
268
+ .stProgress > div > div > div > div {{
269
+ background-color: {DAMAGE_TYPES[idx]['color']} !important;
270
+ }}
271
+ </style>
272
+ """,
273
+ unsafe_allow_html=True
274
+ )
275
+ st.progress(confidence / 100)
276
+
277
+ tabs = st.tabs(["πŸ“‹ Details", "πŸ”§ Repairs", "⚠️ Actions"])
278
+
279
+ with tabs[0]:
280
+ for case in cases:
281
+ st.markdown(f"""
282
+ - **Severity:** {case['severity']}
283
+ - **Description:** {case['description']}
284
+ - **Location:** {case['location']}
285
+ - **Required Expertise:** {case['required_expertise']}
286
+ """)
287
+
288
+ with tabs[1]:
289
+ for step in cases[0]['repair_method']:
290
+ st.markdown(f"βœ“ {step}")
291
+ st.info(f"**Estimated Cost:** {cases[0]['estimated_cost']}")
292
+ st.info(f"**Timeframe:** {cases[0]['timeframe']}")
293
+
294
+ with tabs[2]:
295
+ st.warning("**Immediate Actions Required:**")
296
+ st.markdown(cases[0]['immediate_action'])
297
+ st.success("**Prevention Measures:**")
298
+ st.markdown(cases[0]['prevention'])
299
 
300
+ if not detected:
301
+ st.info("No significant structural damage detected. Regular maintenance recommended.")
302
 
303
+ # Add to history
304
+ st.session_state.history.append(f"Analyzed image: {uploaded_file.name}")
305
+
306
+ except Exception as e:
307
+ st.error(f"Error processing image: {str(e)}")
308
+ st.info("Please try uploading a different image.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
 
310
  # Footer
311
  st.markdown("---")
312
+ st.markdown(
313
+ """
314
  <div style='text-align: center'>
315
+ <p>πŸ—οΈ Structural Damage Analyzer Pro | Built with Streamlit & Transformers</p>
316
+ <p style='font-size: 0.8rem;'>For professional use only. Always consult with a structural engineer.</p>
317
  </div>
318
+ """,
319
+ unsafe_allow_html=True
320
+ )
321
 
322
  if __name__ == "__main__":
323
  main()