Sriomdash commited on
Commit
94311e9
Β·
verified Β·
1 Parent(s): 32a2a79

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +133 -0
  2. fruit_classifier.h5 +3 -0
  3. requirements.txt +5 -0
  4. sample_fruits_50.zip +3 -0
app.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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"])
fruit_classifier.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bef1973c85d090d7afcc41b9ed470e4d7fb102907b4a24ee5dd73cdeb92d2af3
3
+ size 40457400
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ streamlit
2
+ tensorflow
3
+ numpy
4
+ pandas
5
+ pillow
sample_fruits_50.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7432d38dfcff2e9ad3ab61baea11bb1b0834571e78a06e5ac9bbf68f918208ec
3
+ size 19822959