RaheelShah commited on
Commit
6538f2b
·
0 Parent(s):

deployment_push

Browse files
.gitattributes ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ *.tflite filter=lfs diff=lfs merge=lfs -text
2
+ *.jpg filter=lfs diff=lfs merge=lfs -text
3
+ *.jpeg filter=lfs diff=lfs merge=lfs -text
4
+ *.png filter=lfs diff=lfs merge=lfs -text
classifier.tflite ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6c7ab0a6e5dcbf38a8c33b960996a55a3b4300b36a018c4545801de3a3c8bde0
3
+ size 18582189
images/image_2.jpg ADDED

Git LFS Details

  • SHA256: 090157a8e2500b89ea924da628dce1767cecf93356e7d941b083ea293f67d9d6
  • Pointer size: 131 Bytes
  • Size of remote file: 235 kB
images/image_54.jpg ADDED

Git LFS Details

  • SHA256: c20e592ef57c7410c3f5f0b82d58533fff21c8891555e790a860f12dcd5c5f82
  • Pointer size: 130 Bytes
  • Size of remote file: 87 kB
images/image_62.jpg ADDED

Git LFS Details

  • SHA256: 243020f150f1be97d371b40bc034b31b9ff2b1a1c52232957ac5a801e2a8be48
  • Pointer size: 130 Bytes
  • Size of remote file: 37.5 kB
images/image_70.jpg ADDED

Git LFS Details

  • SHA256: 2abd8aa0c42acabf6261861ae7182c401de7ab8ec985775311e28a21e830435c
  • Pointer size: 131 Bytes
  • Size of remote file: 121 kB
main.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import os
3
+ import mediapipe as mp
4
+
5
+ # --- Initialize MediaPipe Image Classifier ---
6
+ BaseOptions = mp.tasks.BaseOptions
7
+ ImageClassifier = mp.tasks.vision.ImageClassifier
8
+ ImageClassifierOptions = mp.tasks.vision.ImageClassifierOptions
9
+ VisionRunningMode = mp.tasks.vision.RunningMode
10
+
11
+ # ✅ Load model
12
+ model_path = "classifier.tflite"
13
+ # model_path = "2.tflite"
14
+ # https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt
15
+
16
+ options = ImageClassifierOptions(
17
+ base_options=BaseOptions(model_asset_path=model_path),
18
+ max_results=3
19
+ )
20
+ classifier = ImageClassifier.create_from_options(options)
21
+
22
+ # --- Load images from folder ---
23
+ folder = r"C:\Users\R c\PycharmProjects\BG_Remover\images"
24
+ images = [os.path.join(folder, f) for f in os.listdir(folder)
25
+ if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
26
+
27
+ if not images:
28
+ print("❌ No images found in folder.")
29
+ exit()
30
+
31
+ index = 0
32
+
33
+ # --- Main Loop ---
34
+ while True:
35
+ image_path = images[index]
36
+ frame = cv2.imread(image_path)
37
+
38
+ if frame is None:
39
+ print(f"⚠️ Skipping unreadable image: {image_path}")
40
+ index = (index + 1) % len(images)
41
+ continue
42
+
43
+ # ✅ Scale down image (20% of original size)
44
+ frame = cv2.resize(frame, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
45
+
46
+ # Convert to RGB for MediaPipe
47
+ rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
48
+ mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=rgb)
49
+
50
+ # Classify the image
51
+ result = classifier.classify(mp_image)
52
+
53
+ # --- Get top label and score ---
54
+ if result.classifications:
55
+ category = result.classifications[0].categories[0]
56
+ label = category.category_name
57
+ score = category.score
58
+ text = f"{label} ({score:.2f})"
59
+ else:
60
+ text = "No classification"
61
+
62
+ # Draw label on image
63
+ cv2.putText(frame, text, (20, 40),
64
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
65
+
66
+ cv2.imshow("E-Commerce Image Classification", frame)
67
+
68
+ key = cv2.waitKey(0) & 0xFF
69
+ if key == 27: # ESC → exit
70
+ break
71
+ elif key == 32: # SPACE → next image
72
+ index = (index + 1) % len(images)
73
+
74
+ cv2.destroyAllWindows()
75
+
76
+
77
+ # put this as deafult address r"C:\Users\R c\PycharmProjects\BG_Remover\images"
mobilenet_v2_1.0_224.tflite ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9f3bc29e38e90842a852bfed957dbf5e36f2d97a91dd17736b1e5c0aca8d3303
3
+ size 13978596
streamlit_app.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import cv2
3
+ import mediapipe as mp
4
+ import numpy as np
5
+ import os
6
+ from PIL import Image
7
+
8
+ # -------------------------------
9
+ # MediaPipe Classifier Setup
10
+ # -------------------------------
11
+ BaseOptions = mp.tasks.BaseOptions
12
+ ImageClassifier = mp.tasks.vision.ImageClassifier
13
+ ImageClassifierOptions = mp.tasks.vision.ImageClassifierOptions
14
+
15
+ model_path = "classifier.tflite"
16
+ options = ImageClassifierOptions(
17
+ base_options=BaseOptions(model_asset_path=model_path),
18
+ max_results=5
19
+ )
20
+ classifier = ImageClassifier.create_from_options(options)
21
+
22
+ # -------------------------------
23
+ # Streamlit UI Setup
24
+ # -------------------------------
25
+ st.set_page_config(page_title="Image Classifier", layout="wide", page_icon="🛒")
26
+
27
+ # Compact layout fix — title fully visible
28
+ st.markdown(
29
+ """
30
+ <style>
31
+ div.block-container {
32
+ padding-top: 1.5rem;
33
+ padding-bottom: 0.5rem;
34
+ max-width: 100%;
35
+ }
36
+ h1, h2, h3, h4, h5 {font-size: 1rem;}
37
+ img {max-width: 100%; height: auto;}
38
+ .stSlider {margin-top: 0.2rem;}
39
+ </style>
40
+ """,
41
+ unsafe_allow_html=True
42
+ )
43
+
44
+ st.title("E-Commerce Image Classifier")
45
+ st.write(
46
+ "Try uploading an image or a folder to see automatic classification results. "
47
+ "You can navigate between images using the arrow buttons below. "
48
+ "This project is open source — check it out on [GitHub](https://github.com/travelmateen/ImageClassifier). 🚀"
49
+ )
50
+ st.markdown("<style> div[data-testid='stStatusWidget']{display:none}</style>", unsafe_allow_html=True)
51
+
52
+ # ✅ Sidebar uploader and controls
53
+ with st.sidebar:
54
+ st.title("User Configuration")
55
+
56
+ num_classes = st.number_input(
57
+ "Number of classes to display",
58
+ min_value=1,
59
+ max_value=5,
60
+ value=3,
61
+ help="Choose how many classification results to show (1-5)"
62
+ )
63
+
64
+ # Selection mode (Images or Directory)
65
+ selection_mode = st.radio(
66
+ "Choose upload type:",
67
+ ["Directory", "Select Images"],
68
+ index=0,
69
+ horizontal=True,
70
+ )
71
+
72
+ st.header("Upload Your Files")
73
+
74
+ if selection_mode == "Directory":
75
+ uploaded_files = st.file_uploader(
76
+ "Upload images from directory",
77
+ accept_multiple_files="directory",
78
+ type=["jpg", "jpeg", "png"],
79
+ )
80
+ else:
81
+ uploaded_files = st.file_uploader(
82
+ "Select individual images",
83
+ type=["jpg", "jpeg", "png"],
84
+ accept_multiple_files=True
85
+ )
86
+
87
+ with st.sidebar.expander("⚠️ Limitations & Tips"):
88
+ st.write("""
89
+ **Known Limitations:**
90
+ - Pre-trained MediaPipe general classifier
91
+ - 1000 ImageNet categories only
92
+ - Not customized for specific domains
93
+ - Max 10MB per image
94
+
95
+ **For Best Results:**
96
+ - Clear, single-subject images
97
+ - Common objects and scenes
98
+ - Good lighting and focus
99
+ - Avoid ambiguous or complex scenes
100
+ """)
101
+
102
+ # -------------------------------
103
+ # Default folder handling
104
+ # -------------------------------
105
+ if not uploaded_files:
106
+ default_folder = "images"
107
+ if os.path.exists(default_folder):
108
+ image_files = [
109
+ os.path.join(default_folder, f)
110
+ for f in os.listdir(default_folder)
111
+ if f.lower().endswith((".jpg", ".jpeg", ".png"))
112
+ ]
113
+ if image_files:
114
+ uploaded_files = [open(img, "rb") for img in image_files]
115
+
116
+ # -------------------------------
117
+ # Classification Logic
118
+ # -------------------------------
119
+ if uploaded_files:
120
+ total_images = len(uploaded_files)
121
+
122
+ if 'foo' not in st.session_state:
123
+ st.session_state['foo'] = 0
124
+
125
+ current_index = st.session_state['foo']
126
+ # Prevent out-of-range errors
127
+ if current_index >= len(uploaded_files):
128
+ current_index = len(uploaded_files) - 1
129
+ st.session_state['foo'] = current_index
130
+ elif current_index < 0:
131
+ current_index = 0
132
+ st.session_state['foo'] = 0
133
+
134
+ current_image = uploaded_files[current_index]
135
+
136
+ # --- Read image ---
137
+ file_bytes = np.asarray(bytearray(current_image.read()), dtype=np.uint8)
138
+ frame = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
139
+ if frame is None:
140
+ st.error("⚠️ Unable to read image.")
141
+ st.stop()
142
+
143
+ # --- Fixed smaller image for full window fit ---
144
+ display_width = 450
145
+ display_height = 300
146
+ frame = cv2.resize(frame, (display_width, display_height))
147
+ rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
148
+
149
+ # --- Classify image ---
150
+ mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=rgb)
151
+ result = classifier.classify(mp_image)
152
+
153
+ # --- Layout: image + classification ---
154
+ col1, col2 = st.columns([1, 1])
155
+
156
+ with col1:
157
+ st.subheader("Original Image")
158
+ st.image(rgb, width=display_width)
159
+
160
+ nav_col1, nav_col2, nav_col3 = st.columns([3, 4, 1], gap="small")
161
+ with nav_col1:
162
+ st.markdown("<div style='text-align:left; margin-top:2px;'>", unsafe_allow_html=True)
163
+ if st.button("⬅️", key="prev") and current_index > 0:
164
+ st.session_state['foo'] = current_index - 1
165
+ st.rerun()
166
+ st.markdown("</div>", unsafe_allow_html=True)
167
+ with nav_col2:
168
+ st.caption(f"🖼️ Image {current_index + 1} of {total_images}")
169
+ with nav_col3:
170
+ st.markdown("<div style='text-align:right; margin-top:2px;'>", unsafe_allow_html=True)
171
+ if st.button("➡️", key="next") and current_index < total_images - 1:
172
+ st.session_state['foo'] = current_index + 1
173
+ st.rerun()
174
+ st.markdown("</div>", unsafe_allow_html=True)
175
+
176
+ with col2:
177
+ st.subheader("Classification Results")
178
+ if result.classifications:
179
+ categories = result.classifications[0].categories
180
+ for cat in categories[:num_classes]:
181
+ st.write(f"**{cat.category_name}** ({cat.score:.2f})")
182
+ st.progress(float(cat.score))
183
+ else:
184
+ st.write("No classification detected.")
185
+ else:
186
+ st.info("📂 Please upload images using the sidebar to begin classification, or place images in the 'images' folder.")
187
+
188
+ # -------------------------------
189
+ # Footer
190
+ # -------------------------------
191
+ st.markdown("""
192
+ <hr style="border:0;border-top:1px solid #e6eef8;margin:8px 0 4px 0;">
193
+ <div style='text-align:center;color:#111F68;margin:0;padding:0;'>
194
+ <p style="margin:0;">Made by <a href='https://techtics.ai' target='_blank' style='color:#042AFF;text-decoration:none;font-weight:700;'>Techtics.ai</a></p>
195
+ </div>
196
+ """, unsafe_allow_html=True)