HMWCS commited on
Commit
be449ca
·
verified ·
1 Parent(s): 9e4559c

feat: add mixed garbage classification rules

Browse files
Files changed (3) hide show
  1. README.md +76 -25
  2. classifier.py +101 -76
  3. knowledge_base.py +22 -5
README.md CHANGED
@@ -1,25 +1,76 @@
1
- ---
2
- title: Gemma3n Challenge
3
- emoji: 🌍
4
- colorFrom: green
5
- colorTo: green
6
- sdk: gradio
7
- sdk_version: 5.37.0
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- ---
12
-
13
- # Garbage Classification System
14
-
15
- A Gradio app for classifying garbage into 4 categories using Gemma-3n model.
16
-
17
- ## Usage
18
- 1. Upload an image.
19
- 2. Click "Classify Garbage" or wait for auto-classification.
20
-
21
- ## Categories
22
- - Recyclable Waste
23
- - Food/Kitchen Waste
24
- - Hazardous Waste
25
- - Other Waste
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Waste Classification Application
2
+
3
+ This project is a web-based application that classifies waste materials from user-uploaded images. It identifies the type of waste (e.g., cardboard, glass, metal) and provides information on how to properly dispose of it.
4
+
5
+ ## 🚀 Live Demo
6
+
7
+ Try the application live on Hugging Face Spaces\!
8
+
9
+ **➡️ [Waste Classification Demo](https://huggingface.co/spaces/HMWCS/Gemma3n-challenge-demo)**
10
+
11
+ -----
12
+
13
+ ## Features
14
+
15
+ * **Image-based classification:** Upload an image of a waste item to have it automatically classified.
16
+ * **Multiple waste categories:** The application can identify a variety of waste materials.
17
+ * **Disposal information:** After classification, the app provides guidance on how to dispose of the identified waste material.
18
+ * **Web interface:** A user-friendly web interface built with Gradio makes the application easy to use.
19
+
20
+ -----
21
+
22
+ ## 💡 How it works
23
+
24
+ The application uses a pre-trained Gemma3n model to perform the image classification. The model has been fine-tuned on a dataset of waste images to accurately identify different materials. The disposal information is retrieved from a knowledge base within the application.
25
+
26
+ -----
27
+
28
+ ## 📓 Kaggle Notebook
29
+
30
+ Explore the model fine-tuning process and the underlying code in our detailed Kaggle Notebook.
31
+
32
+ **➡️ [Gemma3n Challenge Notebook](https://www.kaggle.com/code/yichuanhuang/gemma3n-garbage-classification)**
33
+
34
+ -----
35
+
36
+ ## 🛠️ Getting Started
37
+
38
+ ### Prerequisites
39
+
40
+ * Python 3.9+
41
+ * Pip
42
+ * Cuda (optional)
43
+
44
+ ### Installation
45
+
46
+ 1. Clone the repository:
47
+ ```bash
48
+ git clone https://github.com/yichuan-huang/gemma3n-challenge
49
+ ```
50
+ 2. Navigate to the project directory:
51
+ ```bash
52
+ cd gemma3n-challenge
53
+ ```
54
+ 3. Install the required dependencies:
55
+ ```bash
56
+ pip install -r requirements.txt
57
+ ```
58
+
59
+ ### Running the application
60
+
61
+ To start the application, run the following command:
62
+
63
+ ```bash
64
+ python app.py
65
+ ```
66
+
67
+ This will launch a Gradio web server. You can access the application by opening the provided URL in your web browser.
68
+
69
+ ## 📂 Project Structure
70
+
71
+ * `app.py`: The main application file, containing the Gradio interface and the classification logic.
72
+ * `classifier.py`: Handles the image classification using the pre-trained model.
73
+ * `config.py`: Contains configuration settings for the application, such as the model name and labels.
74
+ * `knowledge_base.py`: A simple knowledge base containing disposal information for different waste materials.
75
+ * `requirements.txt`: A list of the Python dependencies required to run the application.
76
+ * `test_images/`: A directory containing sample images for testing the application.
classifier.py CHANGED
@@ -7,13 +7,55 @@ from config import Config
7
  from knowledge_base import GarbageClassificationKnowledge
8
  import re
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  class GarbageClassifier:
11
  def __init__(self, config: Config = None):
12
  self.config = config or Config()
13
  self.knowledge = GarbageClassificationKnowledge()
14
  self.processor = None
15
  self.model = None
16
- self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
17
 
18
  # Setup logging
19
  logging.basicConfig(level=logging.INFO)
@@ -46,46 +88,6 @@ class GarbageClassifier:
46
  self.logger.error(f"Error loading model: {str(e)}")
47
  raise
48
 
49
- def preprocess_image(self, image: Image.Image) -> Image.Image:
50
- """
51
- Preprocess image to meet Gemma3n requirements (512x512)
52
- """
53
- # Convert to RGB if necessary
54
- if image.mode != "RGB":
55
- image = image.convert("RGB")
56
-
57
- # Resize to 512x512 as required by Gemma3n
58
- target_size = (512, 512)
59
-
60
- # Calculate aspect ratio preserving resize
61
- original_width, original_height = image.size
62
- aspect_ratio = original_width / original_height
63
-
64
- if aspect_ratio > 1:
65
- # Width is larger
66
- new_width = target_size[0]
67
- new_height = int(target_size[0] / aspect_ratio)
68
- else:
69
- # Height is larger or equal
70
- new_height = target_size[1]
71
- new_width = int(target_size[1] * aspect_ratio)
72
-
73
- # Resize image maintaining aspect ratio
74
- image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)
75
-
76
- # Create a new image with target size and paste the resized image
77
- processed_image = Image.new(
78
- "RGB", target_size, (255, 255, 255)
79
- ) # White background
80
-
81
- # Calculate position to center the image
82
- x_offset = (target_size[0] - new_width) // 2
83
- y_offset = (target_size[1] - new_height) // 2
84
-
85
- processed_image.paste(image, (x_offset, y_offset))
86
-
87
- return processed_image
88
-
89
  def classify_image(self, image: Union[str, Image.Image]) -> Tuple[str, str, int]:
90
  """
91
  Classify garbage in the image
@@ -107,7 +109,7 @@ class GarbageClassifier:
107
  raise ValueError("Image must be a PIL Image or file path")
108
 
109
  # Preprocess image to meet Gemma3n requirements
110
- processed_image = self.preprocess_image(image)
111
 
112
  # Prepare messages with system prompt and user query
113
  messages = [
@@ -239,71 +241,94 @@ class GarbageClassifier:
239
  # If no explicit score found, calculate based on classification indicators
240
  return self._calculate_confidence_heuristic(response_lower, classification)
241
 
242
-
243
  def _extract_classification(self, response: str) -> str:
244
  """Extract the main classification from the response"""
245
  response_lower = response.lower()
246
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  # First, look for positive waste category indicators
248
  # Check exact category matches first
249
  categories = self.knowledge.get_categories()
250
  waste_categories = [cat for cat in categories if cat != "Unable to classify"]
251
-
252
  for category in waste_categories:
253
  if category.lower() in response_lower:
254
  # Make sure it's not in a negative context
255
  category_index = response_lower.find(category.lower())
256
- context_before = response_lower[max(0, category_index-30):category_index]
257
-
258
  # Only skip if there's a clear negation right before
259
  if not any(neg in context_before[-10:] for neg in ["not", "cannot", "isn't", "doesn't"]):
260
  return category
261
-
262
- # Look for strong recyclable indicators
263
  recyclable_indicators = [
264
  "recyclable", "recycle", "aluminum", "plastic", "glass", "metal",
265
  "foil", "can", "bottle", "cardboard", "paper", "tin", "steel", "iron"
266
  ]
267
-
268
  if any(indicator in response_lower for indicator in recyclable_indicators):
269
- # Check if it's explicitly said to be recyclable
270
- recyclable_phrases = [
271
- "recyclable", "can be recycled", "made of recyclable",
272
- "recyclable material", "recyclable aluminum", "recyclable plastic"
273
- ]
274
- if any(phrase in response_lower for phrase in recyclable_phrases):
275
- return "Recyclable Waste"
276
-
277
- # Check for specific materials
278
- if any(material in response_lower for material in ["aluminum", "foil", "metal"]):
279
- return "Recyclable Waste"
280
- if any(material in response_lower for material in ["plastic", "bottle"]):
281
- return "Recyclable Waste"
282
- if any(material in response_lower for material in ["glass", "cardboard", "paper"]):
283
- return "Recyclable Waste"
284
-
 
 
 
285
  # Look for food waste indicators
286
  food_indicators = [
287
  "food", "fruit", "vegetable", "organic", "kitchen waste",
288
- "peel", "core", "scraps", "leftovers"
289
  ]
290
  if any(indicator in response_lower for indicator in food_indicators):
291
  return "Food/Kitchen Waste"
292
-
293
  # Look for hazardous waste indicators
294
  hazardous_indicators = [
295
  "battery", "chemical", "medicine", "paint", "toxic", "hazardous"
296
  ]
297
  if any(indicator in response_lower for indicator in hazardous_indicators):
298
  return "Hazardous Waste"
299
-
300
  # Look for other waste indicators
301
  other_waste_indicators = [
302
  "cigarette", "ceramic", "dust", "diaper", "tissue", "other waste"
303
  ]
304
  if any(indicator in response_lower for indicator in other_waste_indicators):
305
  return "Other Waste"
306
-
307
  # Only classify as "Unable to classify" if there are explicit indicators
308
  unable_phrases = [
309
  "unable to classify",
@@ -311,29 +336,29 @@ class GarbageClassifier:
311
  "cannot be classified as waste",
312
  "not garbage", "not waste", "not trash"
313
  ]
314
-
315
  if any(phrase in response_lower for phrase in unable_phrases):
316
  return "Unable to classify"
317
-
318
  # Check for non-garbage items (people, living things, etc.)
319
  non_garbage_indicators = [
320
  "person", "people", "human", "face", "man", "woman",
321
  "living", "alive", "animal", "pet",
322
  "portrait", "photo of a person"
323
  ]
324
-
325
  if any(indicator in response_lower for indicator in non_garbage_indicators):
326
  return "Unable to classify"
327
-
328
  # If we found waste-related content but no clear category, try to infer
329
  waste_related = any(word in response_lower for word in [
330
  "waste", "trash", "garbage", "discard", "throw", "bin"
331
  ])
332
-
333
  if waste_related:
334
  # Default to Other Waste if it's clearly waste but unclear category
335
  return "Other Waste"
336
-
337
  # If no clear classification found and no clear non-waste indicators,
338
  # default to "Unable to classify"
339
  return "Unable to classify"
 
7
  from knowledge_base import GarbageClassificationKnowledge
8
  import re
9
 
10
+
11
+ def preprocess_image(image: Image.Image) -> Image.Image:
12
+ """
13
+ Preprocess image to meet Gemma3n requirements (512x512)
14
+ """
15
+ # Convert to RGB if necessary
16
+ if image.mode != "RGB":
17
+ image = image.convert("RGB")
18
+
19
+ # Resize to 512x512 as required by Gemma3n
20
+ target_size = (512, 512)
21
+
22
+ # Calculate aspect ratio preserving resize
23
+ original_width, original_height = image.size
24
+ aspect_ratio = original_width / original_height
25
+
26
+ if aspect_ratio > 1:
27
+ # Width is larger
28
+ new_width = target_size[0]
29
+ new_height = int(target_size[0] / aspect_ratio)
30
+ else:
31
+ # Height is larger or equal
32
+ new_height = target_size[1]
33
+ new_width = int(target_size[1] * aspect_ratio)
34
+
35
+ # Resize image maintaining aspect ratio
36
+ image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)
37
+
38
+ # Create a new image with target size and paste the resized image
39
+ processed_image = Image.new(
40
+ "RGB", target_size, (255, 255, 255)
41
+ ) # White background
42
+
43
+ # Calculate position to center the image
44
+ x_offset = (target_size[0] - new_width) // 2
45
+ y_offset = (target_size[1] - new_height) // 2
46
+
47
+ processed_image.paste(image, (x_offset, y_offset))
48
+
49
+ return processed_image
50
+
51
+
52
  class GarbageClassifier:
53
  def __init__(self, config: Config = None):
54
  self.config = config or Config()
55
  self.knowledge = GarbageClassificationKnowledge()
56
  self.processor = None
57
  self.model = None
58
+ # self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
59
 
60
  # Setup logging
61
  logging.basicConfig(level=logging.INFO)
 
88
  self.logger.error(f"Error loading model: {str(e)}")
89
  raise
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  def classify_image(self, image: Union[str, Image.Image]) -> Tuple[str, str, int]:
92
  """
93
  Classify garbage in the image
 
109
  raise ValueError("Image must be a PIL Image or file path")
110
 
111
  # Preprocess image to meet Gemma3n requirements
112
+ processed_image = preprocess_image(image)
113
 
114
  # Prepare messages with system prompt and user query
115
  messages = [
 
241
  # If no explicit score found, calculate based on classification indicators
242
  return self._calculate_confidence_heuristic(response_lower, classification)
243
 
 
244
  def _extract_classification(self, response: str) -> str:
245
  """Extract the main classification from the response"""
246
  response_lower = response.lower()
247
+
248
+ # Check for mixed garbage warnings first
249
+ mixed_garbage_indicators = [
250
+ "multiple garbage types",
251
+ "separate items",
252
+ "mixed together",
253
+ "different types of garbage"
254
+ ]
255
+
256
+ if any(indicator in response_lower for indicator in mixed_garbage_indicators):
257
+ return "Unable to classify"
258
+
259
+ # Check for contaminated containers that should go to Food/Kitchen Waste
260
+ contamination_indicators = [
261
+ "food residue", "contaminated", "not empty", "not rinsed",
262
+ "tip: empty and rinse", "empty and rinse this container"
263
+ ]
264
+
265
+ if any(indicator in response_lower for indicator in contamination_indicators):
266
+ # If it mentions recycling tip but has contamination, it's Food/Kitchen Waste
267
+ return "Food/Kitchen Waste"
268
+
269
  # First, look for positive waste category indicators
270
  # Check exact category matches first
271
  categories = self.knowledge.get_categories()
272
  waste_categories = [cat for cat in categories if cat != "Unable to classify"]
273
+
274
  for category in waste_categories:
275
  if category.lower() in response_lower:
276
  # Make sure it's not in a negative context
277
  category_index = response_lower.find(category.lower())
278
+ context_before = response_lower[max(0, category_index - 30):category_index]
279
+
280
  # Only skip if there's a clear negation right before
281
  if not any(neg in context_before[-10:] for neg in ["not", "cannot", "isn't", "doesn't"]):
282
  return category
283
+
284
+ # Look for strong recyclable indicators (only if clean/empty)
285
  recyclable_indicators = [
286
  "recyclable", "recycle", "aluminum", "plastic", "glass", "metal",
287
  "foil", "can", "bottle", "cardboard", "paper", "tin", "steel", "iron"
288
  ]
289
+
290
  if any(indicator in response_lower for indicator in recyclable_indicators):
291
+ # Check if it's contaminated or has food content
292
+ if not any(cont in response_lower for cont in contamination_indicators):
293
+ # Check if it's explicitly said to be recyclable
294
+ recyclable_phrases = [
295
+ "recyclable", "can be recycled", "made of recyclable",
296
+ "recyclable material", "recyclable aluminum", "recyclable plastic",
297
+ "clean", "empty", "rinsed"
298
+ ]
299
+ if any(phrase in response_lower for phrase in recyclable_phrases):
300
+ return "Recyclable Waste"
301
+
302
+ # Check for specific materials
303
+ if any(material in response_lower for material in ["aluminum", "foil", "metal"]):
304
+ return "Recyclable Waste"
305
+ if any(material in response_lower for material in ["plastic", "bottle"]):
306
+ return "Recyclable Waste"
307
+ if any(material in response_lower for material in ["glass", "cardboard", "paper"]):
308
+ return "Recyclable Waste"
309
+
310
  # Look for food waste indicators
311
  food_indicators = [
312
  "food", "fruit", "vegetable", "organic", "kitchen waste",
313
+ "peel", "core", "scraps", "leftovers", "food content", "food residue"
314
  ]
315
  if any(indicator in response_lower for indicator in food_indicators):
316
  return "Food/Kitchen Waste"
317
+
318
  # Look for hazardous waste indicators
319
  hazardous_indicators = [
320
  "battery", "chemical", "medicine", "paint", "toxic", "hazardous"
321
  ]
322
  if any(indicator in response_lower for indicator in hazardous_indicators):
323
  return "Hazardous Waste"
324
+
325
  # Look for other waste indicators
326
  other_waste_indicators = [
327
  "cigarette", "ceramic", "dust", "diaper", "tissue", "other waste"
328
  ]
329
  if any(indicator in response_lower for indicator in other_waste_indicators):
330
  return "Other Waste"
331
+
332
  # Only classify as "Unable to classify" if there are explicit indicators
333
  unable_phrases = [
334
  "unable to classify",
 
336
  "cannot be classified as waste",
337
  "not garbage", "not waste", "not trash"
338
  ]
339
+
340
  if any(phrase in response_lower for phrase in unable_phrases):
341
  return "Unable to classify"
342
+
343
  # Check for non-garbage items (people, living things, etc.)
344
  non_garbage_indicators = [
345
  "person", "people", "human", "face", "man", "woman",
346
  "living", "alive", "animal", "pet",
347
  "portrait", "photo of a person"
348
  ]
349
+
350
  if any(indicator in response_lower for indicator in non_garbage_indicators):
351
  return "Unable to classify"
352
+
353
  # If we found waste-related content but no clear category, try to infer
354
  waste_related = any(word in response_lower for word in [
355
  "waste", "trash", "garbage", "discard", "throw", "bin"
356
  ])
357
+
358
  if waste_related:
359
  # Default to Other Waste if it's clearly waste but unclear category
360
  return "Other Waste"
361
+
362
  # If no clear classification found and no clear non-waste indicators,
363
  # default to "Unable to classify"
364
  return "Unable to classify"
knowledge_base.py CHANGED
@@ -5,6 +5,17 @@ class GarbageClassificationKnowledge:
5
 
6
  IMPORTANT: You should ONLY classify items that are actually garbage/waste. If the image contains people, living things, furniture, electronics in use, or other non-waste items, you should classify it as "Unable to classify" and explain that it's not garbage.
7
 
 
 
 
 
 
 
 
 
 
 
 
8
  Garbage classification standards:
9
 
10
  **Recyclable Waste**:
@@ -13,12 +24,14 @@ Garbage classification standards:
13
  - Metals: aluminum cans, tin cans, toothpaste tubes, metal toys, metal stationery, nails, metal sheets, aluminum foil, etc.
14
  - Glass: glass bottles, broken glass pieces, mirrors, light bulbs, vacuum flasks, etc.
15
  - Textiles: old clothing, textile products, shoes, curtains, towels, bags, etc.
 
16
 
17
  **Food/Kitchen Waste**:
18
  - Food scraps: rice, noodles, bread, meat, fish, shrimp shells, crab shells, bones, etc.
19
  - Fruit peels and cores: watermelon rinds, apple cores, orange peels, banana peels, nut shells, etc.
20
  - Plants: withered branches and leaves, flowers, traditional Chinese medicine residue, etc.
21
  - Expired food: expired canned food, cookies, candy, etc.
 
22
 
23
  **Hazardous Waste**:
24
  - Batteries: dry batteries, rechargeable batteries, button batteries, and all types of batteries
@@ -39,13 +52,17 @@ Garbage classification standards:
39
  - Furniture, appliances, electronics in normal use
40
  - Buildings, landscapes, vehicles
41
  - Any item that is not intended to be discarded as waste
 
42
 
43
  Please observe the items in the image carefully according to the above classification standards. If the image shows garbage/waste items, provide accurate garbage classification results. If the image does NOT show garbage/waste (e.g., people, living things, functioning items), classify it as "Unable to classify" and explain why it's not garbage.
44
 
45
- Format your response as:
 
 
46
 
47
  **Classification**: [Category Name or "Unable to classify"]
48
- **Reasoning**: [Brief explanation of why this item belongs to this category, or why it cannot be classified as garbage]"""
 
49
 
50
  @staticmethod
51
  def get_categories():
@@ -60,9 +77,9 @@ Format your response as:
60
  @staticmethod
61
  def get_category_descriptions():
62
  return {
63
- "Recyclable Waste": "Items that can be processed and reused, including paper, plastic, metal, glass, and textiles",
64
- "Food/Kitchen Waste": "Organic waste from food preparation and consumption",
65
  "Hazardous Waste": "Items containing harmful substances that require special disposal",
66
  "Other Waste": "Items that don't fit into other categories and go to general waste",
67
- "Unable to classify": "Items that are not garbage/waste, such as people, living things, or functioning objects",
68
  }
 
5
 
6
  IMPORTANT: You should ONLY classify items that are actually garbage/waste. If the image contains people, living things, furniture, electronics in use, or other non-waste items, you should classify it as "Unable to classify" and explain that it's not garbage.
7
 
8
+ **MIXED GARBAGE HANDLING RULES:**
9
+
10
+ 1. **Containers with Food Content**: For any container (bottles, cans, boxes, wrappers) that contains visible food residue or content:
11
+ - Classify as "Food/Kitchen Waste" due to contamination risk
12
+ - Always include this warning: "⚠️ Tip: Empty and rinse this container first, then it can be recycled!"
13
+ - Only completely empty and rinsed containers qualify as "Recyclable Waste"
14
+
15
+ 2. **Multiple Different Garbage Types**: If the image shows multiple different types of garbage mixed together (e.g., electronics with food, batteries with organic waste):
16
+ - Classify as "Unable to classify"
17
+ - Include warning: "⚠️ Warning: Multiple garbage types detected. Please separate items for proper classification."
18
+
19
  Garbage classification standards:
20
 
21
  **Recyclable Waste**:
 
24
  - Metals: aluminum cans, tin cans, toothpaste tubes, metal toys, metal stationery, nails, metal sheets, aluminum foil, etc.
25
  - Glass: glass bottles, broken glass pieces, mirrors, light bulbs, vacuum flasks, etc.
26
  - Textiles: old clothing, textile products, shoes, curtains, towels, bags, etc.
27
+ - NOTE: Only clean, empty containers qualify. Contaminated containers go to Food/Kitchen Waste.
28
 
29
  **Food/Kitchen Waste**:
30
  - Food scraps: rice, noodles, bread, meat, fish, shrimp shells, crab shells, bones, etc.
31
  - Fruit peels and cores: watermelon rinds, apple cores, orange peels, banana peels, nut shells, etc.
32
  - Plants: withered branches and leaves, flowers, traditional Chinese medicine residue, etc.
33
  - Expired food: expired canned food, cookies, candy, etc.
34
+ - Contaminated containers: any container with visible food residue or content
35
 
36
  **Hazardous Waste**:
37
  - Batteries: dry batteries, rechargeable batteries, button batteries, and all types of batteries
 
52
  - Furniture, appliances, electronics in normal use
53
  - Buildings, landscapes, vehicles
54
  - Any item that is not intended to be discarded as waste
55
+ - Multiple different garbage types mixed together
56
 
57
  Please observe the items in the image carefully according to the above classification standards. If the image shows garbage/waste items, provide accurate garbage classification results. If the image does NOT show garbage/waste (e.g., people, living things, functioning items), classify it as "Unable to classify" and explain why it's not garbage.
58
 
59
+ For mixed garbage situations, apply the special handling rules above and include appropriate warnings.
60
+
61
+ Format your response EXACTLY as follows:
62
 
63
  **Classification**: [Category Name or "Unable to classify"]
64
+ **Reasoning**: [Brief explanation of why this item belongs to this category, or why it cannot be classified as garbage]
65
+ **Confidence Score**: [Number from 1-10]"""
66
 
67
  @staticmethod
68
  def get_categories():
 
77
  @staticmethod
78
  def get_category_descriptions():
79
  return {
80
+ "Recyclable Waste": "Items that can be processed and reused, including paper, plastic, metal, glass, and textiles (must be clean and empty)",
81
+ "Food/Kitchen Waste": "Organic waste from food preparation and consumption, including contaminated containers",
82
  "Hazardous Waste": "Items containing harmful substances that require special disposal",
83
  "Other Waste": "Items that don't fit into other categories and go to general waste",
84
+ "Unable to classify": "Items that are not garbage/waste, such as people, living things, functioning objects, or mixed garbage types",
85
  }