Sriomdash commited on
Commit
8e1d81b
Β·
verified Β·
1 Parent(s): 94311e9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -132
app.py CHANGED
@@ -1,133 +1,139 @@
1
- import streamlit as st
2
- import pandas as pd
3
- import numpy as np
4
- import tensorflow as tf
5
- from PIL import Image
6
- import os
7
- import glob
8
- import zipfile
9
- import time
10
-
11
- # --- PAGE CONFIG ---
12
- st.set_page_config(page_title="Cloud Inventory System", layout="wide")
13
-
14
- # --- 1. SETUP & UNZIP LOGIC ---
15
- # We check if the folder exists. If not, we unzip the uploaded file.
16
- IMAGES_DIR = "sample_fruits_50"
17
- ZIP_FILE = "sample_fruits_50.zip"
18
-
19
- if not os.path.exists(IMAGES_DIR):
20
- if os.path.exists(ZIP_FILE):
21
- with st.spinner("Unpacking image database..."):
22
- with zipfile.ZipFile(ZIP_FILE, 'r') as zip_ref:
23
- zip_ref.extractall(".") # Extract to current directory
24
- st.success("Database loaded!")
25
- else:
26
- st.warning(f"⚠️ Please upload '{ZIP_FILE}' to the Files tab!")
27
-
28
- # --- 2. LOAD MODEL ---
29
- @st.cache_resource
30
- def load_model():
31
- model_path = "fruit_classifier.h5"
32
- if not os.path.exists(model_path):
33
- return None
34
- return tf.keras.models.load_model(model_path)
35
-
36
- model = load_model()
37
-
38
- # --- 3. HELPER FUNCTIONS ---
39
- CLASS_NAMES = [
40
- 'fresh_apple', 'fresh_banana', 'fresh_grape', 'fresh_orange', 'fresh_pomegranate',
41
- 'rotten_apple', 'rotten_banana', 'rotten_grape', 'rotten_orange', 'rotten_pomegranate'
42
- ]
43
-
44
- def get_initial_db():
45
- fruits = ['Apple', 'Banana', 'Grape', 'Orange', 'Pomegranate']
46
- data = {fruit: {'Fresh Qty': 0, 'Rotten Qty': 0} for fruit in fruits}
47
- return data
48
-
49
- # --- 4. MAIN APP UI ---
50
- st.title("🏭 Cloud AI Inventory Scan")
51
- st.markdown("This system will scan the **50 test images** uploaded to the cloud.")
52
-
53
- if model is None:
54
- st.error("Model file not found. Please upload 'fruit_classifier_final.h5'.")
55
- st.stop()
56
-
57
- if st.button("πŸ” Start Cloud Scan"):
58
-
59
- # Get list of images
60
- if os.path.exists(IMAGES_DIR):
61
- all_images = glob.glob(os.path.join(IMAGES_DIR, "**", "*.*"), recursive=True)
62
- # Filter for valid images only
63
- files_to_scan = [f for f in all_images if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
64
- # Pick 15 random ones
65
- import random
66
- if len(files_to_scan) > 15:
67
- files_to_scan = random.sample(files_to_scan, 15)
68
- else:
69
- st.error("Image folder not found! Did the zip file unzip?")
70
- st.stop()
71
-
72
- # Layout
73
- col1, col2 = st.columns([1.5, 1])
74
- with col1:
75
- st.subheader("πŸ“¦ Live Inventory")
76
- table_placeholder = st.empty()
77
- with col2:
78
- st.subheader("πŸ“· Feed")
79
- image_placeholder = st.empty()
80
-
81
- # Init Data
82
- db_data = get_initial_db()
83
- current_df = pd.DataFrame.from_dict(db_data, orient='index')
84
- table_placeholder.table(current_df)
85
- progress_bar = st.progress(0)
86
-
87
- # LOOP
88
- for i, filepath in enumerate(files_to_scan):
89
- # 1. Display Image
90
- image_placeholder.image(filepath, caption=f"Item #{i+1}", width=400)
91
-
92
- # 2. Predict
93
- try:
94
- # Preprocess
95
- img = Image.open(filepath)
96
- img = img.resize((224, 224))
97
- img_arr = np.array(img)
98
- if img_arr.shape[-1] == 4: img_arr = img_arr[..., :3]
99
- img_arr = np.expand_dims(img_arr, axis=0) / 255.0
100
-
101
- # Inference
102
- preds = model.predict(img_arr, verbose=0)
103
- idx = np.argmax(preds[0])
104
- label = CLASS_NAMES[idx]
105
-
106
- # Parse
107
- parts = label.split('_')
108
- quality = parts[0]
109
- fruit = parts[1].title()
110
-
111
- # Update DB
112
- if quality == 'fresh':
113
- db_data[fruit]['Fresh Qty'] += 1
114
- else:
115
- db_data[fruit]['Rotten Qty'] += 1
116
-
117
- # Update Table
118
- current_df = pd.DataFrame.from_dict(db_data, orient='index')
119
- table_placeholder.table(current_df)
120
-
121
- time.sleep(0.2) # Visual delay
122
-
123
- except Exception as e:
124
- st.error(f"Error: {e}")
125
-
126
- progress_bar.progress((i + 1) / len(files_to_scan))
127
-
128
- st.success("Scan Complete!")
129
-
130
- # Graph
131
- st.divider()
132
- st.subheader("πŸ“Š Final Cloud Report")
 
 
 
 
 
 
133
  st.bar_chart(current_df, color=["#4CAF50", "#FF5252"])
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import tensorflow as tf
5
+ from PIL import Image
6
+ import os
7
+ import glob
8
+ import zipfile
9
+ import time
10
+
11
+ # --- PAGE CONFIG ---
12
+ st.set_page_config(page_title="Cloud Inventory System", layout="wide")
13
+
14
+ # --- 1. SETUP & UNZIP LOGIC ---
15
+ IMAGES_DIR = "sample_fruits_50"
16
+ ZIP_FILE = "sample_fruits_50.zip"
17
+
18
+ # FIX 1: Force creation of the directory
19
+ if not os.path.exists(IMAGES_DIR):
20
+ if os.path.exists(ZIP_FILE):
21
+ with st.spinner("Unpacking image database..."):
22
+ # Create the folder explicitly
23
+ os.makedirs(IMAGES_DIR, exist_ok=True)
24
+ with zipfile.ZipFile(ZIP_FILE, 'r') as zip_ref:
25
+ # Extract INSIDE the folder to handle "flat" zip files
26
+ zip_ref.extractall(IMAGES_DIR)
27
+ st.success("Database loaded!")
28
+ else:
29
+ st.warning(f"⚠️ Please upload '{ZIP_FILE}' to the Files tab!")
30
+
31
+ # --- 2. LOAD MODEL ---
32
+ @st.cache_resource
33
+ def load_model():
34
+ # FIX 2: Updated filename to match your screenshot ('fruit_classifier.h5')
35
+ model_path = "fruit_classifier.h5"
36
+ if not os.path.exists(model_path):
37
+ return None
38
+ return tf.keras.models.load_model(model_path)
39
+
40
+ model = load_model()
41
+
42
+ # --- 3. HELPER FUNCTIONS ---
43
+ CLASS_NAMES = [
44
+ 'fresh_apple', 'fresh_banana', 'fresh_grape', 'fresh_orange', 'fresh_pomegranate',
45
+ 'rotten_apple', 'rotten_banana', 'rotten_grape', 'rotten_orange', 'rotten_pomegranate'
46
+ ]
47
+
48
+ def get_initial_db():
49
+ fruits = ['Apple', 'Banana', 'Grape', 'Orange', 'Pomegranate']
50
+ data = {fruit: {'Fresh Qty': 0, 'Rotten Qty': 0} for fruit in fruits}
51
+ return data
52
+
53
+ # --- 4. MAIN APP UI ---
54
+ st.title("🏭 Cloud AI Inventory Scan")
55
+ st.markdown("This system will scan the **50 test images** uploaded to the cloud.")
56
+
57
+ if model is None:
58
+ st.error("Model file 'fruit_classifier.h5' not found in Files tab.")
59
+ st.stop()
60
+
61
+ if st.button("πŸ” Start Cloud Scan"):
62
+
63
+ # Get list of images
64
+ files_to_scan = []
65
+ if os.path.exists(IMAGES_DIR):
66
+ all_images = glob.glob(os.path.join(IMAGES_DIR, "**", "*.*"), recursive=True)
67
+ files_to_scan = [f for f in all_images if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
68
+
69
+ # Pick 15 random ones
70
+ import random
71
+ if len(files_to_scan) > 15:
72
+ files_to_scan = random.sample(files_to_scan, 15)
73
+
74
+ if not files_to_scan:
75
+ st.error("No images found! The zip file might be empty or failed to unzip.")
76
+ st.stop()
77
+
78
+ # Layout
79
+ col1, col2 = st.columns([1.5, 1])
80
+ with col1:
81
+ st.subheader("πŸ“¦ Live Inventory")
82
+ table_placeholder = st.empty()
83
+ with col2:
84
+ st.subheader("πŸ“· Feed")
85
+ image_placeholder = st.empty()
86
+
87
+ # Init Data
88
+ db_data = get_initial_db()
89
+ current_df = pd.DataFrame.from_dict(db_data, orient='index')
90
+ table_placeholder.table(current_df)
91
+ progress_bar = st.progress(0)
92
+
93
+ # LOOP
94
+ for i, filepath in enumerate(files_to_scan):
95
+ # 1. Display Image (Updated to use_container_width to fix warnings)
96
+ image_placeholder.image(filepath, caption=f"Item #{i+1}", use_container_width=True)
97
+
98
+ # 2. Predict
99
+ try:
100
+ # Preprocess
101
+ img = Image.open(filepath)
102
+ img = img.resize((224, 224))
103
+ img_arr = np.array(img)
104
+ if img_arr.shape[-1] == 4: img_arr = img_arr[..., :3]
105
+ img_arr = np.expand_dims(img_arr, axis=0) / 255.0
106
+
107
+ # Inference
108
+ preds = model.predict(img_arr, verbose=0)
109
+ idx = np.argmax(preds[0])
110
+ label = CLASS_NAMES[idx]
111
+
112
+ # Parse
113
+ parts = label.split('_')
114
+ quality = parts[0]
115
+ fruit = parts[1].title()
116
+
117
+ # Update DB
118
+ if quality == 'fresh':
119
+ db_data[fruit]['Fresh Qty'] += 1
120
+ else:
121
+ db_data[fruit]['Rotten Qty'] += 1
122
+
123
+ # Update Table
124
+ current_df = pd.DataFrame.from_dict(db_data, orient='index')
125
+ table_placeholder.table(current_df)
126
+
127
+ time.sleep(0.2) # Visual delay
128
+
129
+ except Exception as e:
130
+ st.error(f"Error: {e}")
131
+
132
+ progress_bar.progress((i + 1) / len(files_to_scan))
133
+
134
+ st.success("Scan Complete!")
135
+
136
+ # Graph
137
+ st.divider()
138
+ st.subheader("πŸ“Š Final Cloud Report")
139
  st.bar_chart(current_df, color=["#4CAF50", "#FF5252"])