File size: 6,003 Bytes
4f93965
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d7d460
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4f93965
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d7d460
 
 
 
 
 
4f93965
 
1d7d460
9d8fac7
 
 
 
 
 
 
5b33cad
9d8fac7
 
1d7d460
9d8fac7
1d7d460
9d8fac7
 
5b33cad
9d8fac7
 
 
1d7d460
f6f137b
 
 
9d8fac7
f6f137b
1d7d460
 
9d8fac7
 
 
 
5b33cad
9d8fac7
 
 
 
 
 
 
f6f137b
 
 
 
 
1d7d460
9d8fac7
1d7d460
 
9d8fac7
1d7d460
 
 
 
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import streamlit as st
import os
import glob
import base64
import json
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from langchain_openai import ChatOpenAI
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.runnables import chain
from PIL import Image as PILImage
from io import BytesIO

# Streamlit title
st.title("πŸš— Vehicle Information Extraction from Images πŸš™")

# Custom CSS Styling for the app
st.markdown("""
    <style>
        body {
            background-color: #f0f8ff;
            font-family: 'Arial', sans-serif;
            color: #333;
        }

        .stButton button {
            background-color: #1E90FF;
            color: white;
            border-radius: 5px;
            font-size: 16px;
            padding: 10px 20px;
            transition: transform 0.2s ease-in-out;
        }

        .stButton button:hover {
            background-color: #4682b4;
            transform: scale(1.05);
        }

        .stTitle {
            font-size: 36px;
            font-weight: bold;
            color: #1E90FF;
        }

        .stSubheader {
            color: #4682b4;
            font-size: 24px;
            font-weight: 600;
            text-align: center;
        }

        .stImage {
            border-radius: 10px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }

        .stJson {
            background-color: #f8f9fa;
            padding: 15px;
            border-radius: 5px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            font-size: 16px;
        }

        .grid-container {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 10px;
            padding: 10px;
        }

        .grid-container img {
            border-radius: 10px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            transition: transform 0.2s ease-in-out;
        }

        .grid-container img:hover {
            transform: scale(1.05);
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
            }
            to {
                opacity: 1;
            }
        }

        .fade-in {
            animation: fadeIn 1s ease-in-out;
        }

    </style>
""", unsafe_allow_html=True)

# Image display function with animation
def display_image_grid(image_paths, rows=2, cols=3, figsize=(10, 7)):
    fig = plt.figure(figsize=figsize)
    max_images = rows * cols
    image_paths = image_paths[:max_images]

    for idx, path in enumerate(image_paths):
        ax = fig.add_subplot(rows, cols, idx + 1)
        img = mpimg.imread(path)
        ax.imshow(img)
        ax.axis('off')
        filename = path.split('/')[-1]
        ax.set_title(filename)

    plt.tight_layout()
    st.pyplot(fig)

# Image encoding function
def image_encoding(inputs):
    """Load and convert image to base64 encoding"""
    with open(inputs["image_path"], "rb") as image_file:
        image_base64 = base64.b64encode(image_file.read()).decode("utf-8")
    return {"image": image_base64}

# Streamlit Interface for uploading images and showing results
st.header("πŸš— Upload Vehicle Images for Information Extraction πŸš™")

# Option to select either single or batch image upload
upload_option = st.radio("Select Upload Type", ["Single Image Upload", "Batch Images Upload"])

# Single Image Upload
if upload_option == "Single Image Upload":
    st.subheader("Upload a Single Vehicle Image")
    uploaded_image = st.file_uploader("Choose an Image (JPEG, PNG, GIF, BMP, etc.)", type=["jpeg", "png", "gif", "bmp", "jpg"])

    if uploaded_image is not None:
        # Display the uploaded image with animation
        image = PILImage.open(uploaded_image)
        st.image(image, caption="Uploaded Image", use_container_width=True, class_="fade-in")

        # Convert the uploaded image to base64
        image_path = "/tmp/uploaded_image" + os.path.splitext(uploaded_image.name)[1]
        with open(image_path, "wb") as f:
            f.write(uploaded_image.getbuffer())

        # Add button to trigger information extraction with animated hover effect
        if st.button("Extract Vehicle Information"):
            # Process the image through the pipeline
            output = pipeline.invoke({"image_path": image_path})

            # Show the results in a user-friendly format
            st.subheader("Extracted Vehicle Information", class_="fade-in")
            st.json(output, class_="fade-in")

# Batch Images Upload
elif upload_option == "Batch Images Upload":
    st.sidebar.header("Batch Image Upload")
    batch_images = st.sidebar.file_uploader("Upload Images (JPEG, PNG, GIF, BMP, etc.)", type=["jpeg", "png", "gif", "bmp", "jpg"], accept_multiple_files=True)

    if batch_images:
        batch_input = [{"image_path": f"/tmp/{file.name}"} for file in batch_images]
        for file in batch_images:
            with open(f"/tmp/{file.name}", "wb") as f:
                f.write(file.getbuffer())

        # Add button to trigger batch information extraction
        if st.button("Extract Vehicle Information from Batch"):
            # Process the batch and display the results in a DataFrame
            batch_output = pipeline.batch(batch_input)
            df = pd.DataFrame(batch_output)
            st.dataframe(df, use_container_width=True)

        # Display batch images in a grid with animation
        st.subheader("Images in Grid", class_="fade-in")
        image_paths = [f"/tmp/{file.name}" for file in batch_images]
        st.markdown('<div class="grid-container">', unsafe_allow_html=True)
        for image_path in image_paths:
            st.markdown(f'<img src="data:image/jpeg;base64,{base64.b64encode(open(image_path, "rb").read()).decode()}" class="fade-in"/>', unsafe_allow_html=True)
        st.markdown('</div>', unsafe_allow_html=True)