File size: 5,267 Bytes
15526fe 3db0aec 9814e5f 3db0aec d9a6878 3db0aec d774ee6 3db0aec d774ee6 3db0aec d774ee6 3db0aec d774ee6 3db0aec 7030681 d774ee6 3db0aec d604335 3db0aec d774ee6 3db0aec d774ee6 3db0aec d774ee6 3db0aec d604335 dbd2162 60dab82 3db0aec d774ee6 3db0aec 7030681 3db0aec d774ee6 3db0aec 7030681 3db0aec d9a6878 d604335 d774ee6 d604335 d774ee6 3db0aec 15526fe 9814e5f d774ee6 3db0aec d774ee6 d604335 d774ee6 3db0aec d774ee6 9814e5f d604335 |
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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
import streamlit as st
from transformers import ViTForImageClassification, ViTImageProcessor
from PIL import Image
import torch
import time
import gc
# Constants
MAX_FILE_SIZE = 5 * 1024 * 1024 # 5MB
MAX_IMAGE_SIZE = 1024 # Maximum dimension for images
def cleanup_memory():
"""Clean up memory and GPU cache"""
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
def init_session_state():
"""Initialize session state variables"""
if 'history' not in st.session_state:
st.session_state.history = []
if 'dark_mode' not in st.session_state:
st.session_state.dark_mode = False
@st.cache_resource(show_spinner="Loading AI model...")
def load_model():
"""Load and cache the model and processor"""
try:
model_name = "google/vit-base-patch16-224"
processor = ViTImageProcessor.from_pretrained(model_name)
device = "cuda" if torch.cuda.is_available() else "cpu"
model = ViTForImageClassification.from_pretrained(
model_name,
num_labels=len(DAMAGE_TYPES),
ignore_mismatched_sizes=True,
).to(device)
model.eval()
return model, processor
except Exception as e:
st.error(f"Error loading model: {str(e)}")
return None, None
def validate_image(image):
"""Validate image size and format"""
if image.size[0] * image.size[1] > 1024 * 1024:
st.warning("Large image detected. The image will be resized for better performance.")
if image.format not in ['JPEG', 'PNG']:
st.warning("Image format not optimal. Consider using JPEG or PNG for better performance.")
def preprocess_image(uploaded_file):
"""Preprocess and validate uploaded image"""
try:
image = Image.open(uploaded_file)
if max(image.size) > MAX_IMAGE_SIZE:
ratio = MAX_IMAGE_SIZE / max(image.size)
new_size = tuple([int(dim * ratio) for dim in image.size])
image = image.resize(new_size, Image.Resampling.LANCZOS)
return image
except Exception as e:
st.error(f"Error processing image: {str(e)}")
return None
def analyze_damage(image, model, processor):
"""Analyze structural damage in the image"""
try:
device = next(model.parameters()).device
with torch.no_grad():
image = image.convert('RGB')
inputs = processor(images=image, return_tensors="pt")
inputs = {k: v.to(device) for k, v in inputs.items()}
outputs = model(**inputs)
probs = torch.nn.functional.softmax(outputs.logits, dim=1)[0]
cleanup_memory()
return probs.cpu()
except RuntimeError as e:
if "out of memory" in str(e):
cleanup_memory()
st.error("Out of memory. Please try with a smaller image.")
else:
st.error(f"Error analyzing image: {str(e)}")
return None
def main():
st.set_page_config(
page_title="Structural Damage Analyzer Pro",
page_icon="ποΈ",
layout="wide",
initial_sidebar_state="expanded"
)
# Initialize session state
init_session_state()
# Display header
st.markdown(
"""
<div style='text-align: center; padding: 1rem;'>
<h1>ποΈ Structural Damage Analyzer Pro</h1>
<p style='font-size: 1.2rem;'>Advanced AI-powered structural damage assessment tool</p>
</div>
""",
unsafe_allow_html=True
)
# Load model
model, processor = load_model()
if model is None:
st.error("Failed to load model. Please refresh the page.")
return
# File upload
uploaded_file = st.file_uploader(
"Upload an image for analysis",
type=['jpg', 'jpeg', 'png'],
help="Supported formats: JPG, JPEG, PNG"
)
if uploaded_file:
try:
if uploaded_file.size > MAX_FILE_SIZE:
st.error("File size too large. Please upload an image smaller than 5MB.")
return
image = preprocess_image(uploaded_file)
if image is None:
return
validate_image(image)
# Display image and analyze
st.image(image, caption="Uploaded Structure", use_column_width=True)
with st.spinner("π Analyzing damage..."):
predictions = analyze_damage(image, model, processor)
if predictions is not None:
st.success("Analysis complete!")
# Add analysis display logic here based on your DAMAGE_TYPES
except Exception as e:
cleanup_memory()
st.error(f"Error processing image: {str(e)}")
st.info("Please try uploading a different image.")
# Footer
st.markdown("---")
st.markdown(
"""
<div style='text-align: center'>
<p>ποΈ Structural Damage Analyzer Pro | Built with Streamlit & Transformers</p>
<p style='font-size: 0.8rem;'>For professional use only. Always consult with a structural engineer.</p>
</div>
""",
unsafe_allow_html=True
)
if __name__ == "__main__":
main() |