File size: 6,218 Bytes
29f6ccc 3f0ccc8 29f6ccc af98bbd 3f0ccc8 af98bbd 3f0ccc8 af98bbd 3f0ccc8 |
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 |
import streamlit as st
from PIL import Image
from predictor import predict_image
# π PAGE SETUP
st.set_page_config(page_title="Image Classifier App", page_icon="π€", layout="centered")
st.html("""
<style>
.stMainBlockContainer {
max-width: 70rem;
}
</style>
""")
# π INITIALIZE SESSION STATE
# We initialize session state variables to manage app state
if "selected_image" not in st.session_state:
st.session_state["selected_image"] = None
if "prediction_placeholder" not in st.session_state:
st.session_state["prediction_placeholder"] = {"label": "A Dog", "score": 0.9558}
# π MAIN APP LAYOUT
with st.container():
st.title(
body="πΌοΈ Image Classifier with CNN",
help="An interactive application to classify images into over 1000 categories.",
)
st.html("<br>")
# Use tabs for different sections of the app
tab_app, tab_description = st.tabs(["**App**", "**Description**"])
# π APP TAB
with tab_app:
# Create a two-column layout for the app interface
col_upload, col_results = st.columns(2, gap="large")
# π IMAGE UPLOAD & EXAMPLE SELECTION
with col_upload:
st.header("Upload an Image", divider=True)
# File uploader widget
uploaded_image = st.file_uploader(
label="Drag and drop an image here or click to browse",
type=["jpg", "jpeg", "png"],
help="Maximum file size is 200MB",
key="image_uploader",
)
st.html("<br>")
st.subheader("Or Try an Example", divider=True)
# Segmented control for selecting example images
selected_example = st.segmented_control(
label="Categories",
options=["Animal", "Vehicle", "Object", "Building"],
default="Animal",
help="Select one of the pre-loaded examples",
)
st.html("<br>")
# --- THE SINGLE CLASSIFY BUTTON ---
classify_button = st.button(
label="Classify Image",
key="classify_btn",
type="primary",
icon="β¨",
)
# π PREDICTION RESULTS
with col_results:
st.header("Results", divider=True)
# This message is shown before any image is processed
if st.session_state["selected_image"] is None and not classify_button:
st.info("Choose an image to get a prediction.")
# If the button is clicked, run the prediction logic
if classify_button:
# Check if an image is selected before running prediction
if uploaded_image is not None:
# st.session_state["selected_image"] = uploaded_image
# Use Image.open() to convert the UploadedFile object into a PIL.Image object
st.session_state["selected_image"] = Image.open(uploaded_image)
st.session_state["uploaded_file"] = uploaded_image
elif selected_example:
# Load the selected example image
try:
img_path = f"./assets/{selected_example.lower()}.jpg"
st.session_state["selected_image"] = Image.open(img_path)
except FileNotFoundError:
st.error(
f"Error: The example image '{selected_example.lower()}.jpg' was not found."
)
st.stop()
if st.session_state["selected_image"] is not None:
st.image(
st.session_state["selected_image"],
caption="Image to be classified",
)
# Call the prediction function and display results
with st.spinner("Analyzing image..."):
# Call our modularized prediction function!
try:
predicted_label, predicted_score = predict_image(
st.session_state["selected_image"]
)
st.metric(
label="Prediction",
value=f"{predicted_label.replace('_', ' ').title()}",
delta=f"{predicted_score * 100:.2f}%",
help="The predicted category and its confidence score.",
delta_color="normal",
)
st.balloons()
except Exception as e:
st.error(f"An error occurred during prediction: {e}")
else:
st.error("Please upload an image or select an example to classify.")
# π DESCRIPTION TAB
with tab_description:
st.header("About This Project", divider=True)
st.markdown(
"""
This project showcases a Convolutional Neural Network (CNN) model that automatically
classifies images into over 1000 different categories.
### Original Architecture
The original project was built as a multi-service architecture, featuring:
* **Streamlit:** For the web user interface.
* **FastAPI:** As a RESTful API to handle image processing and model serving.
* **Redis:** A message broker for communication between the services.
### Portfolio Adaptation
For a live and cost-effective demo, this application has been adapted into a single-service
solution. The core logic of the FastAPI backend has been integrated directly into
the Streamlit app. This demonstrates the ability to adapt a solution for
specific deployment and resource constraints.
### Technologies Used
* **Streamlit:** For the interactive web interface.
* **TensorFlow:** For loading and running the pre-trained CNN model.
* **Pre-trained Model:** ResNet50 with weights trained on the ImageNet dataset.
"""
)
|