Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,266 +1,192 @@
|
|
1 |
import streamlit as st
|
2 |
-
import
|
3 |
-
import
|
4 |
from paddleocr import PaddleOCR
|
5 |
from tensorflow.keras.models import load_model
|
6 |
-
from tensorflow.keras.preprocessing.image import img_to_array
|
7 |
import numpy as np
|
8 |
-
from datetime import datetime, timedelta
|
9 |
import re
|
10 |
-
from
|
11 |
import pandas as pd
|
12 |
-
import cv2
|
13 |
-
from PIL import Image
|
14 |
|
15 |
-
#
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
object_model = YOLO('yolov5s.pt')
|
20 |
|
21 |
-
# Class names for
|
22 |
class_names = {
|
23 |
-
0: 'Banana_Bad',
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
4: 'FreshCucumber',
|
28 |
-
5: 'FreshMango',
|
29 |
-
6: 'FreshTomato',
|
30 |
-
7: 'Guava_Bad',
|
31 |
-
8: 'Guava_Good',
|
32 |
-
9: 'Lime_Bad',
|
33 |
-
10: 'Lime_Good',
|
34 |
-
11: 'Rotten',
|
35 |
-
12: 'RottenCarrot',
|
36 |
-
13: 'RottenCucumber',
|
37 |
-
14: 'RottenMango',
|
38 |
-
15: 'RottenTomato',
|
39 |
-
16: 'freshBread',
|
40 |
-
17: 'rottenBread'
|
41 |
}
|
42 |
|
43 |
-
# Helper
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
img_array = img_to_array(img)
|
47 |
img_array = np.expand_dims(img_array, axis=0)
|
48 |
img_array = img_array / 255.0
|
49 |
return img_array
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
r'EXPIRES ON[:\-]?\s*(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{4})', # Expires On
|
62 |
-
|
63 |
-
# DDMMMYYYY format
|
64 |
-
r'(\d{1,2}[A-Za-z]{3}\d{4})', # DDMMMYYYY format
|
65 |
-
|
66 |
-
# Short year formats
|
67 |
-
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2})', # Short year date format (DD/MM/YY)
|
68 |
-
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{4})', # General date format (DD/MM/YYYY)
|
69 |
-
|
70 |
-
# Year-month-day formats
|
71 |
-
r'(\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2})', # Year-month-day format (YYYY/MM/DD)
|
72 |
-
|
73 |
-
# Month/Year formats
|
74 |
-
r'(\d{1,2}[\/\-]\d{1,2})', # MM/DD format
|
75 |
-
r'(\d{1,2}[\/\-]\d{2})', # MM/YY format
|
76 |
-
|
77 |
-
# Month name formats
|
78 |
-
r'(\d{1,2}\s*[A-Za-z]{3,}\s*\d{4})', # Month name with day and year
|
79 |
-
r'(\d{1,2}\s*[A-Za-z]{3,}\s*\d{2})', # Month name with day and short year
|
80 |
-
|
81 |
-
# Year with month name
|
82 |
-
r'(\d{4}[A-Za-z]{3,}\d{1,2})', # Year with month name
|
83 |
-
r'(\d{1,2}[A-Za-z]{3,}\d{4})', # Day with month name and full year
|
84 |
-
|
85 |
-
# Additional formats
|
86 |
-
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2})', # MM/DD/YY format
|
87 |
-
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{4})', # MM/DD/YYYY format
|
88 |
-
r'(\d{1,2}[\/\-]\d{1,2})', # MM/DD format
|
89 |
-
r'(\d{1,2}[\/\-]\d{2})', # MM/YY format
|
90 |
-
|
91 |
-
# Best before phrases
|
92 |
-
r'Best before (\d+) months', # Best before in months
|
93 |
-
r'Expiration Date[:\-]?\s*(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{4})', # Expiration Date
|
94 |
-
r'Expires[:\-]?\s*(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{4})', # Expires
|
95 |
-
|
96 |
-
# Additional variations
|
97 |
-
r'(\d{1,2}\s*[A-Za-z]{3,}\s*\d{4})', # Month name with day and year
|
98 |
-
r'(\d{1,2}\s*[A-Za-z]{3,}\s*\d{2})', # Month name with day and short year
|
99 |
-
|
100 |
-
# More variations
|
101 |
-
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{4})', # MM/DD/YYYY format
|
102 |
-
r'(\d{1,2}[\/\-]\d{1,2})', # MM/DD format
|
103 |
-
r'(\d{1,2}[\/\-]\d{2})', # MM/YY format
|
104 |
-
|
105 |
-
# Additional expiry phrases
|
106 |
-
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{4})', # Expiry in various formats
|
107 |
-
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2})', # Expiry in short year formats
|
108 |
-
r'(\d{1,2}[\/\-]\d{1,2})', # Expiry in MM/DD format
|
109 |
-
r'(\d{1,2}[\/\-]\d{2})', # Expiry in MM/YY format
|
110 |
-
|
111 |
-
# Additional phrases
|
112 |
-
r'(\d{1,2}\s*[A-Za-z]{3,}\s*\d{4})', # Month name with day and year
|
113 |
-
r'(\d{1,2}\s*[A-Za-z]{3,}\s*\d{2})', # Month name with day and short year
|
114 |
-
r'(\d{4}[A-Za-z]{3,}\d{1,2})', # Year with month name
|
115 |
-
r'(\d{1,2}[A-Za-z]{3,}\d{4})', # Day with month name and full year
|
116 |
-
|
117 |
-
# Additional expiry phrases
|
118 |
-
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{4})', # Expiry in various formats
|
119 |
-
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2})', # Expiry in short year formats
|
120 |
-
r'(\d{1,2}[\/\-]\d{1,2})', # Expiry in MM/DD format
|
121 |
-
r'(\d{1,2}[\/\-]\d{2})', # Expiry in MM/YY format
|
122 |
-
]
|
123 |
-
|
124 |
-
current_date = datetime.now()
|
125 |
-
dates_info = []
|
126 |
-
|
127 |
-
for pattern in expiry_date_patterns:
|
128 |
-
match = re.search(pattern, text, re.IGNORECASE)
|
129 |
-
if match:
|
130 |
-
date_str = match.group(1)
|
131 |
-
try:
|
132 |
-
# Check for DDMMMYYYY format
|
133 |
-
if len(date_str) == 8 and date_str[2:5].isalpha(): # Check for DDMMMYYYY
|
134 |
-
expiry_date = datetime.strptime(date_str, '%d%b%Y')
|
135 |
-
# Check for MM/YY format
|
136 |
-
elif len(date_str) == 5 and date_str[2] == '/': # Check for MM/YY
|
137 |
-
expiry_date = datetime.strptime(date_str, '%m/%y')
|
138 |
-
# Check for DD-MM-YYYY or DD/MM/YYYY format
|
139 |
-
elif len(date_str) == 10 and (date_str[2] in ['-', '/'] and date_str[5] in ['-', '/']):
|
140 |
-
expiry_date = datetime.strptime(date_str, '%d/%m/%Y') if date_str[2] == '/' else datetime.strptime(date_str, '%d-%m-%Y')
|
141 |
-
# Check for DD-MM-YY or DD/MM/YY format
|
142 |
-
elif len(date_str) == 8 and (date_str[2] in ['-', '/'] and date_str[5] in ['-', '/']):
|
143 |
-
expiry_date = datetime.strptime(date_str, '%d/%m/%y') if date_str[2] == '/' else datetime.strptime(date_str, '%d-%m-%y')
|
144 |
else:
|
145 |
-
|
146 |
-
expiry_date = datetime.strptime(date_str, '%d/%m/%Y')
|
147 |
-
except ValueError:
|
148 |
-
continue
|
149 |
-
|
150 |
-
days_left = (expiry_date - current_date).days
|
151 |
-
if days_left < 0:
|
152 |
-
dates_info.append((date_str, "Expired"))
|
153 |
else:
|
154 |
-
|
155 |
-
break # Stop after finding the first valid date
|
156 |
-
|
157 |
-
return dates_info
|
158 |
-
|
159 |
-
# Streamlit app
|
160 |
-
st.title("Image Processing Application")
|
161 |
|
162 |
-
#
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
f.write(uploaded_file.getbuffer())
|
176 |
|
177 |
-
|
178 |
-
|
|
|
179 |
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
st.text(text)
|
187 |
|
188 |
-
#
|
189 |
-
st.
|
190 |
-
|
191 |
-
|
192 |
-
st.write("Expiry Dates Found:")
|
193 |
-
for date_str, days_left in expiry_dates_info:
|
194 |
-
st.text(f"{date_str} - {days_left}")
|
195 |
-
else:
|
196 |
-
st.write("No expiry dates found.")
|
197 |
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
detected_brands = []
|
202 |
-
for result in results:
|
203 |
-
boxes = result.boxes.data.cpu().numpy()
|
204 |
-
for box in boxes:
|
205 |
-
class_id = int(box[5])
|
206 |
-
confidence = box[4] # Assuming the confidence score is at index 4
|
207 |
-
detected_brands.append((result.names[class_id], confidence))
|
208 |
-
|
209 |
-
# Count occurrences and average confidence of each brand
|
210 |
-
brand_data = {}
|
211 |
-
for brand, confidence in detected_brands:
|
212 |
-
if brand in brand_data:
|
213 |
-
brand_data[brand]['count'] += 1
|
214 |
-
brand_data[brand]['total_confidence'] += confidence
|
215 |
-
else:
|
216 |
-
brand_data[brand] = {'count': 1, 'total_confidence': confidence}
|
217 |
-
|
218 |
-
# Prepare data for display
|
219 |
-
brand_display_data = [
|
220 |
-
{'Object': brand, 'Count': data['count'], 'Average Confidence': data['total_confidence'] / data['count']}
|
221 |
-
for brand, data in brand_data.items()
|
222 |
-
]
|
223 |
-
|
224 |
-
# Display detected brands in a table with column names
|
225 |
-
st.write("Detected Brands and Counts:")
|
226 |
-
st.table(pd.DataFrame(brand_display_data))
|
227 |
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
img_array = preprocess_image(image_path)
|
232 |
-
predictions = fruit_model.predict(img_array)
|
233 |
-
predicted_class = np.argmax(predictions, axis=1)[0]
|
234 |
-
confidence_score = predictions[0][predicted_class] # Get the confidence score for the predicted class
|
235 |
-
st.write("Predicted Freshness:", class_names[predicted_class])
|
236 |
-
st.write("Confidence Score:", f"{confidence_score * 100:.2f}%") # Display the confidence score as a percentage
|
237 |
|
238 |
-
elif task_choice == "Object Detection":
|
239 |
# Object Detection
|
240 |
-
|
241 |
-
results = object_model(image_path)
|
242 |
detected_objects = []
|
243 |
-
|
244 |
-
# Load the image using OpenCV
|
245 |
-
image = cv2.imread(image_path)
|
246 |
-
|
247 |
for result in results:
|
248 |
boxes = result.boxes.data.cpu().numpy()
|
249 |
for box in boxes:
|
250 |
class_id = int(box[5])
|
251 |
confidence = box[4] # Assuming the confidence score is at index 4
|
252 |
detected_objects.append((result.names[class_id], confidence))
|
253 |
-
|
254 |
# Draw bounding box and label on the image
|
255 |
x1, y1, x2, y2 = map(int, box[:4])
|
256 |
label = f"{result.names[class_id]} {confidence * 100:.2f}%"
|
257 |
cv2.rectangle(image, (x1, y1), (x2, y2), (255, 0, 0), 2)
|
258 |
cv2.putText(image, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
|
259 |
-
|
260 |
# Convert the image back to RGB for display in Streamlit
|
261 |
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
262 |
st.image(image_rgb, caption='Detected Objects', use_container_width=True)
|
263 |
-
|
264 |
# Count occurrences and average confidence of each object
|
265 |
object_data = {}
|
266 |
for obj, confidence in detected_objects:
|
@@ -269,13 +195,13 @@ if uploaded_file is not None:
|
|
269 |
object_data[obj]['total_confidence'] += confidence
|
270 |
else:
|
271 |
object_data[obj] = {'count': 1, 'total_confidence': confidence}
|
272 |
-
|
273 |
# Prepare data for display
|
274 |
object_display_data = [
|
275 |
{'Object': obj, 'Count': data['count'], 'Average Confidence': data['total_confidence'] / data['count']}
|
276 |
for obj, data in object_data.items()
|
277 |
]
|
278 |
-
|
279 |
# Display detected objects in a table with column names
|
280 |
st.write("Detected Objects and Counts:")
|
281 |
st.table(pd.DataFrame(object_display_data))
|
|
|
1 |
import streamlit as st
|
2 |
+
import cv2
|
3 |
+
from ultralytics import YOLO
|
4 |
from paddleocr import PaddleOCR
|
5 |
from tensorflow.keras.models import load_model
|
6 |
+
from tensorflow.keras.preprocessing.image import img_to_array
|
7 |
import numpy as np
|
|
|
8 |
import re
|
9 |
+
from datetime import datetime
|
10 |
import pandas as pd
|
|
|
|
|
11 |
|
12 |
+
# Load YOLO models
|
13 |
+
brand_model = YOLO('b.pt') # Replace 'b.pt' with the correct path to your YOLO model for brands
|
14 |
+
ocr = PaddleOCR(lang='en') # Initialize PaddleOCR
|
15 |
+
fruit_model = load_model('DenseNet20_model.h5') # Replace with the correct path to your fruit freshness model
|
16 |
+
object_model = YOLO('yolov5s.pt') # Add object detection model
|
17 |
|
18 |
+
# Class names for freshness detection
|
19 |
class_names = {
|
20 |
+
0: 'Banana_Bad', 1: 'Banana_Good', 2: 'Fresh', 3: 'FreshCarrot', 4: 'FreshCucumber',
|
21 |
+
5: 'FreshMango', 6: 'FreshTomato', 7: 'Guava_Bad', 8: 'Guava_Good', 9: 'Lime_Bad',
|
22 |
+
10: 'Lime_Good', 11: 'Rotten', 12: 'RottenCarrot', 13: 'RottenCucumber',
|
23 |
+
14: 'RottenMango', 15: 'RottenTomato', 16: 'freshBread', 17: 'rottenBread'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
}
|
25 |
|
26 |
+
# Helper function: Extract expiry dates
|
27 |
+
# Helper function: Extract unique expiry dates
|
28 |
+
def extract_expiry_dates(text):
|
29 |
+
patterns = [
|
30 |
+
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{4})', # 20/07/2024 or 20-07-2024
|
31 |
+
r'(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2})', # 20/07/24 or 20-07-24
|
32 |
+
r'(\d{1,2}\s*[A-Za-z]{3,}\s*\d{4})', # 20 MAY 2024
|
33 |
+
r'([A-Za-z]{3,}\s*\d{1,2}[,\s]*\d{4})', # July 20, 2024
|
34 |
+
r'(\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2})', # 2024/07/20 or 2024-07-20
|
35 |
+
r'([A-Za-z]{3}[\-]\d{1,2}[\-]\d{4})' # JAN-15-2024
|
36 |
+
]
|
37 |
+
# Helper function: Extract expiry dates
|
38 |
+
dates = []
|
39 |
+
for pattern in patterns:
|
40 |
+
matches = re.findall(pattern, text)
|
41 |
+
dates.extend(matches)
|
42 |
+
|
43 |
+
# Deduplicate and prioritize the longest (likely full year) date format
|
44 |
+
unique_dates = sorted(dates, key=lambda x: len(x), reverse=True)
|
45 |
+
return [unique_dates[0]] if unique_dates else [] # Return the most likely date
|
46 |
+
|
47 |
+
# Helper function: Preprocess image for fruit freshness
|
48 |
+
def preprocess_image(image):
|
49 |
+
img = cv2.resize(image, (128, 128))
|
50 |
img_array = img_to_array(img)
|
51 |
img_array = np.expand_dims(img_array, axis=0)
|
52 |
img_array = img_array / 255.0
|
53 |
return img_array
|
54 |
|
55 |
+
# Helper function: Calculate days to expiry
|
56 |
+
def calculate_days_to_expiry(expiry_dates):
|
57 |
+
results = []
|
58 |
+
today = datetime.now()
|
59 |
+
for date_str in expiry_dates:
|
60 |
+
try:
|
61 |
+
# Parse date
|
62 |
+
if '/' in date_str or '-' in date_str:
|
63 |
+
if len(date_str.split('/')[-1]) == 2 or len(date_str.split('-')[-1]) == 2:
|
64 |
+
date_obj = datetime.strptime(date_str, '%d/%m/%y') if '/' in date_str else datetime.strptime(date_str, '%d-%m-%y')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
else:
|
66 |
+
date_obj = datetime.strptime(date_str, '%d/%m/%Y') if '/' in date_str else datetime.strptime(date_str, '%d-%m-%Y')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
else:
|
68 |
+
date_obj = datetime.strptime(date_str, '%d %B %Y')
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
+
# Calculate difference
|
71 |
+
delta = (date_obj - today).days
|
72 |
+
if delta >= 0:
|
73 |
+
results.append(f"{date_str}: {delta} days to expire")
|
74 |
+
else:
|
75 |
+
results.append(f"{date_str}: Expired")
|
76 |
+
except ValueError:
|
77 |
+
results.append(f"{date_str}: Invalid date format")
|
78 |
+
return results
|
79 |
+
|
80 |
+
# Streamlit App
|
81 |
+
st.title("Flipkart Grid")
|
82 |
+
|
83 |
+
# Sidebar options
|
84 |
+
app_mode = st.sidebar.selectbox(
|
85 |
+
"Choose the mode",
|
86 |
+
["Home", "Brand & Text Detection", "Fruit Freshness Detection", "Object Detection"]
|
87 |
+
)
|
88 |
+
|
89 |
+
if app_mode == "Home":
|
90 |
+
st.markdown("""
|
91 |
+
## Welcome to the Detection App
|
92 |
+
Use the sidebar to choose between:
|
93 |
+
- *Brand & Text Detection*: Detect brands, extract text, and identify expiry dates from uploaded images.
|
94 |
+
- *Fruit Freshness Detection*: Detect and classify the freshness of fruits from uploaded images.
|
95 |
+
- *Object Detection*: Detect objects in uploaded images.
|
96 |
+
""")
|
97 |
+
|
98 |
+
elif app_mode == "Brand & Text Detection":
|
99 |
+
st.header("Brand & Text Detection")
|
100 |
+
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
|
101 |
+
|
102 |
+
if uploaded_file is not None:
|
103 |
+
file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
|
104 |
+
image = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
|
105 |
+
|
106 |
+
# Brand detection
|
107 |
+
results = brand_model.predict(source=image, stream=False)
|
108 |
+
detected_image = results[0].plot()
|
109 |
+
|
110 |
+
# OCR for text extraction
|
111 |
+
_, img_buffer = cv2.imencode('.jpg', image)
|
112 |
+
ocr_result = ocr.ocr(img_buffer.tobytes())
|
113 |
+
if ocr_result and isinstance(ocr_result[0], list) and len(ocr_result[0]) > 0:
|
114 |
+
extracted_text = ' '.join([line[1][0] for line in ocr_result[0]])
|
115 |
+
expiry_dates = extract_expiry_dates(extracted_text)
|
116 |
+
expiry_info = calculate_days_to_expiry(expiry_dates)
|
117 |
+
else:
|
118 |
+
extracted_text = "No text detected"
|
119 |
+
expiry_dates = []
|
120 |
+
expiry_info = []
|
121 |
+
|
122 |
+
# Count objects
|
123 |
+
object_counts = {}
|
124 |
+
for box in results[0].boxes.data.cpu().numpy():
|
125 |
+
label = results[0].names[int(box[5])]
|
126 |
+
object_counts[label] = object_counts.get(label, 0) + 1
|
127 |
+
|
128 |
+
# Display results
|
129 |
+
st.image(cv2.cvtColor(detected_image, cv2.COLOR_BGR2RGB), caption="Detected Image")
|
130 |
+
st.markdown(f"*Extracted Text:* {extracted_text}")
|
131 |
+
st.markdown(f"*Expiry Dates:*")
|
132 |
+
if expiry_info:
|
133 |
+
for info in expiry_info:
|
134 |
+
st.markdown(f"- {info}")
|
135 |
+
else:
|
136 |
+
st.markdown("None")
|
137 |
+
st.markdown("*Object Counts:*")
|
138 |
+
for label, count in object_counts.items():
|
139 |
+
st.markdown(f"- {label}: {count}")
|
140 |
|
141 |
+
elif app_mode == "Fruit Freshness Detection":
|
142 |
+
st.header("Fruit Freshness Detection")
|
143 |
+
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
|
|
|
144 |
|
145 |
+
if uploaded_file is not None:
|
146 |
+
file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
|
147 |
+
image = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
|
148 |
|
149 |
+
# Preprocess and predict
|
150 |
+
img_array = preprocess_image(image)
|
151 |
+
predictions = fruit_model.predict(img_array)
|
152 |
+
predicted_class = np.argmax(predictions, axis=1)[0]
|
153 |
+
label = class_names[predicted_class]
|
154 |
+
confidence = predictions[0][predicted_class] * 100
|
|
|
155 |
|
156 |
+
# Display results
|
157 |
+
st.image(cv2.cvtColor(image, cv2.COLOR_BGR2RGB), caption="Uploaded Image")
|
158 |
+
st.markdown(f"*Label:* {label}")
|
159 |
+
st.markdown(f"*Confidence:* {confidence:.2f}%")
|
|
|
|
|
|
|
|
|
|
|
160 |
|
161 |
+
elif app_mode == "Object Detection":
|
162 |
+
st.header("Object Detection")
|
163 |
+
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
|
165 |
+
if uploaded_file is not None:
|
166 |
+
file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
|
167 |
+
image = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
|
|
169 |
# Object Detection
|
170 |
+
results = object_model.predict(source=image, stream=False)
|
|
|
171 |
detected_objects = []
|
172 |
+
|
|
|
|
|
|
|
173 |
for result in results:
|
174 |
boxes = result.boxes.data.cpu().numpy()
|
175 |
for box in boxes:
|
176 |
class_id = int(box[5])
|
177 |
confidence = box[4] # Assuming the confidence score is at index 4
|
178 |
detected_objects.append((result.names[class_id], confidence))
|
179 |
+
|
180 |
# Draw bounding box and label on the image
|
181 |
x1, y1, x2, y2 = map(int, box[:4])
|
182 |
label = f"{result.names[class_id]} {confidence * 100:.2f}%"
|
183 |
cv2.rectangle(image, (x1, y1), (x2, y2), (255, 0, 0), 2)
|
184 |
cv2.putText(image, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
|
185 |
+
|
186 |
# Convert the image back to RGB for display in Streamlit
|
187 |
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
188 |
st.image(image_rgb, caption='Detected Objects', use_container_width=True)
|
189 |
+
|
190 |
# Count occurrences and average confidence of each object
|
191 |
object_data = {}
|
192 |
for obj, confidence in detected_objects:
|
|
|
195 |
object_data[obj]['total_confidence'] += confidence
|
196 |
else:
|
197 |
object_data[obj] = {'count': 1, 'total_confidence': confidence}
|
198 |
+
|
199 |
# Prepare data for display
|
200 |
object_display_data = [
|
201 |
{'Object': obj, 'Count': data['count'], 'Average Confidence': data['total_confidence'] / data['count']}
|
202 |
for obj, data in object_data.items()
|
203 |
]
|
204 |
+
|
205 |
# Display detected objects in a table with column names
|
206 |
st.write("Detected Objects and Counts:")
|
207 |
st.table(pd.DataFrame(object_display_data))
|