Spaces:
Sleeping
Sleeping
Deploy CleanCity Agent for MCP 1st Birthday Hackathon
Browse filesFeatures:
- YOLOv8 trash detection with computer vision
- AI-powered cleanup planning with LLM integration
- Environmental impact calculator (CO2, ocean protection)
- MCP server integration with 6 powerful tools
- Multi-LLM support (Claude, GPT, Gemini)
- SQLite event tracking and hotspot analysis
- Social sharing capabilities
- Mobile-responsive Gradio interface
Track: MCP in Action - Consumer Applications
Tags: mcp-in-action-track-consumer
Built with Gradio 5.9.1, YOLOv8, and Model Context Protocol
- API.md +60 -0
- CONTRIBUTING.md +208 -0
- LICENSE +21 -0
- README.md +163 -24
- app.py +619 -140
- trash_model.py +22 -5
API.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# CleanCity Agent - MCP Server API Documentation
|
| 2 |
+
|
| 3 |
+
This document describes the **Model Context Protocol (MCP) tools** exposed by CleanCity Agent's MCP server.
|
| 4 |
+
|
| 5 |
+
## π Server Information
|
| 6 |
+
|
| 7 |
+
- **Server Name:** `cleancity-agent`
|
| 8 |
+
- **Version:** 1.0.0
|
| 9 |
+
- **Protocol:** MCP (Model Context Protocol)
|
| 10 |
+
- **Transport:** stdio
|
| 11 |
+
|
| 12 |
+
## π οΈ Available Tools
|
| 13 |
+
|
| 14 |
+
CleanCity Agent exposes **6 powerful tools** that AI agents can use to detect trash, plan cleanups, track events, and generate reports.
|
| 15 |
+
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
## 1. `detect_trash`
|
| 19 |
+
|
| 20 |
+
Analyze an image and detect trash/litter using computer vision.
|
| 21 |
+
|
| 22 |
+
### Input Schema
|
| 23 |
+
|
| 24 |
+
```json
|
| 25 |
+
{
|
| 26 |
+
"image_path": "string (required)",
|
| 27 |
+
"location": "string (optional)",
|
| 28 |
+
"notes": "string (optional)"
|
| 29 |
+
}
|
| 30 |
+
```
|
| 31 |
+
|
| 32 |
+
### Parameters
|
| 33 |
+
|
| 34 |
+
| Parameter | Type | Required | Description |
|
| 35 |
+
|-----------|------|----------|-------------|
|
| 36 |
+
| `image_path` | string | β
Yes | Absolute path to image file on disk |
|
| 37 |
+
| `location` | string | β No | Location where trash was found (e.g., "Central Park") |
|
| 38 |
+
| `notes` | string | β No | Additional context or observations |
|
| 39 |
+
|
| 40 |
+
### Returns
|
| 41 |
+
|
| 42 |
+
```json
|
| 43 |
+
{
|
| 44 |
+
"detections": [
|
| 45 |
+
{
|
| 46 |
+
"object_type": "plastic_bottle",
|
| 47 |
+
"confidence": 0.95,
|
| 48 |
+
"bbox": [100, 150, 250, 400]
|
| 49 |
+
}
|
| 50 |
+
],
|
| 51 |
+
"count": 5,
|
| 52 |
+
"annotated_image_path": "/path/to/annotated_image.jpg"
|
| 53 |
+
}
|
| 54 |
+
```
|
| 55 |
+
|
| 56 |
+
### Example Usage
|
| 57 |
+
|
| 58 |
+
**Claude Desktop:**
|
| 59 |
+
```
|
| 60 |
+
User: Analyze the trash in /home/user/beach_litter.jpg at Ocean Beach
|
CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributing to CleanCity Agent
|
| 2 |
+
|
| 3 |
+
Thank you for your interest in contributing to CleanCity Agent! π
|
| 4 |
+
|
| 5 |
+
## π― Project Vision
|
| 6 |
+
|
| 7 |
+
CleanCity Agent aims to make environmental action accessible through AI-powered trash detection and cleanup planning. We welcome contributions that align with this mission.
|
| 8 |
+
|
| 9 |
+
## π Quick Start
|
| 10 |
+
|
| 11 |
+
1. **Fork the repository**
|
| 12 |
+
2. **Clone your fork:**
|
| 13 |
+
```bash
|
| 14 |
+
git clone https://github.com/YOUR_USERNAME/CleanCity-Agent.git
|
| 15 |
+
cd CleanCity-Agent
|
| 16 |
+
```
|
| 17 |
+
3. **Create a virtual environment:**
|
| 18 |
+
```bash
|
| 19 |
+
python -m venv venv
|
| 20 |
+
source venv/bin/activate # On Windows: venv\Scripts\activate
|
| 21 |
+
```
|
| 22 |
+
4. **Install dependencies:**
|
| 23 |
+
```bash
|
| 24 |
+
pip install -r requirements.txt
|
| 25 |
+
```
|
| 26 |
+
5. **Create a branch:**
|
| 27 |
+
```bash
|
| 28 |
+
git checkout -b feature/your-feature-name
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
## π Development Guidelines
|
| 32 |
+
|
| 33 |
+
### Code Style
|
| 34 |
+
|
| 35 |
+
- Follow **PEP 8** Python style guide
|
| 36 |
+
- Use **type hints** for function parameters and returns
|
| 37 |
+
- Add **docstrings** to all functions and classes
|
| 38 |
+
- Keep functions small and focused (single responsibility)
|
| 39 |
+
|
| 40 |
+
### Testing Your Changes
|
| 41 |
+
|
| 42 |
+
Before submitting a PR:
|
| 43 |
+
|
| 44 |
+
1. **Test the Gradio app:**
|
| 45 |
+
```bash
|
| 46 |
+
python app.py
|
| 47 |
+
```
|
| 48 |
+
|
| 49 |
+
2. **Test the MCP server:**
|
| 50 |
+
```bash
|
| 51 |
+
python mcp_server.py
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
3. **Verify all tabs work:**
|
| 55 |
+
- Analysis tab
|
| 56 |
+
- History tab
|
| 57 |
+
- Impact & Examples tab
|
| 58 |
+
- Chat tab
|
| 59 |
+
|
| 60 |
+
4. **Test with different LLM providers:**
|
| 61 |
+
- Set `LLM_PROVIDER=offline` (default)
|
| 62 |
+
- Test with real API keys if available
|
| 63 |
+
|
| 64 |
+
### Commit Messages
|
| 65 |
+
|
| 66 |
+
Use clear, descriptive commit messages:
|
| 67 |
+
|
| 68 |
+
```
|
| 69 |
+
β
Good:
|
| 70 |
+
- "Add GPS auto-detection feature"
|
| 71 |
+
- "Fix model path resolution for deployed environments"
|
| 72 |
+
- "Improve error handling in trash detection"
|
| 73 |
+
|
| 74 |
+
β Bad:
|
| 75 |
+
- "Update stuff"
|
| 76 |
+
- "Fix bug"
|
| 77 |
+
- "WIP"
|
| 78 |
+
```
|
| 79 |
+
|
| 80 |
+
## π¨ Areas for Contribution
|
| 81 |
+
|
| 82 |
+
### High Priority
|
| 83 |
+
|
| 84 |
+
- **Real YOLOv8 Model Integration** - Replace mock detector with trained model
|
| 85 |
+
- **Mobile Responsiveness** - Improve UI for smartphones
|
| 86 |
+
- **Multilingual Support** - Add i18n for global reach
|
| 87 |
+
- **Performance Optimization** - Faster image processing
|
| 88 |
+
- **Accessibility** - ARIA labels, keyboard navigation, screen reader support
|
| 89 |
+
|
| 90 |
+
### Feature Ideas
|
| 91 |
+
|
| 92 |
+
- **Gamification** - Points/badges for cleanup reporting
|
| 93 |
+
- **Community Features** - Team cleanup coordination
|
| 94 |
+
- **Advanced Analytics** - Trend analysis, predictive hotspots
|
| 95 |
+
- **Integration with City Services** - API for municipal waste management
|
| 96 |
+
- **Offline Mode Enhancement** - PWA with offline detection
|
| 97 |
+
|
| 98 |
+
### Documentation
|
| 99 |
+
|
| 100 |
+
- Additional usage examples
|
| 101 |
+
- Tutorial videos
|
| 102 |
+
- API documentation improvements
|
| 103 |
+
- Translation of docs to other languages
|
| 104 |
+
|
| 105 |
+
## π Reporting Bugs
|
| 106 |
+
|
| 107 |
+
Found a bug? Help us fix it!
|
| 108 |
+
|
| 109 |
+
1. **Check existing issues** to avoid duplicates
|
| 110 |
+
2. **Create a new issue** with:
|
| 111 |
+
- Clear title describing the problem
|
| 112 |
+
- Steps to reproduce
|
| 113 |
+
- Expected vs. actual behavior
|
| 114 |
+
- Screenshots if applicable
|
| 115 |
+
- Your environment (OS, Python version, browser)
|
| 116 |
+
|
| 117 |
+
**Template:**
|
| 118 |
+
```markdown
|
| 119 |
+
## Bug Description
|
| 120 |
+
[What went wrong?]
|
| 121 |
+
|
| 122 |
+
## Steps to Reproduce
|
| 123 |
+
1. Go to...
|
| 124 |
+
2. Click on...
|
| 125 |
+
3. See error...
|
| 126 |
+
|
| 127 |
+
## Expected Behavior
|
| 128 |
+
[What should happen?]
|
| 129 |
+
|
| 130 |
+
## Actual Behavior
|
| 131 |
+
[What actually happens?]
|
| 132 |
+
|
| 133 |
+
## Environment
|
| 134 |
+
- OS: [e.g., Windows 11, macOS 14]
|
| 135 |
+
- Python: [e.g., 3.11.5]
|
| 136 |
+
- Browser: [e.g., Chrome 120]
|
| 137 |
+
```
|
| 138 |
+
|
| 139 |
+
## π‘ Feature Requests
|
| 140 |
+
|
| 141 |
+
Have an idea? We'd love to hear it!
|
| 142 |
+
|
| 143 |
+
1. **Open an issue** with the `enhancement` label
|
| 144 |
+
2. **Describe the feature:**
|
| 145 |
+
- What problem does it solve?
|
| 146 |
+
- Who would benefit?
|
| 147 |
+
- How should it work?
|
| 148 |
+
3. **Optional:** Include mockups, diagrams, or code sketches
|
| 149 |
+
|
| 150 |
+
## π Pull Request Process
|
| 151 |
+
|
| 152 |
+
1. **Ensure your code works** (see Testing section above)
|
| 153 |
+
2. **Update documentation** if you changed functionality
|
| 154 |
+
3. **Update README.md** if you added features
|
| 155 |
+
4. **Create a pull request:**
|
| 156 |
+
- Descriptive title
|
| 157 |
+
- Summary of changes
|
| 158 |
+
- Link to related issues
|
| 159 |
+
- Screenshots if UI changed
|
| 160 |
+
|
| 161 |
+
### PR Checklist
|
| 162 |
+
|
| 163 |
+
- [ ] Code follows PEP 8 style
|
| 164 |
+
- [ ] Added type hints
|
| 165 |
+
- [ ] Added/updated docstrings
|
| 166 |
+
- [ ] Tested locally (app runs without errors)
|
| 167 |
+
- [ ] Updated relevant documentation
|
| 168 |
+
- [ ] No sensitive data (API keys, passwords) committed
|
| 169 |
+
|
| 170 |
+
## π Code of Conduct
|
| 171 |
+
|
| 172 |
+
### Our Pledge
|
| 173 |
+
|
| 174 |
+
We are committed to providing a welcoming and inclusive environment for everyone.
|
| 175 |
+
|
| 176 |
+
### Expected Behavior
|
| 177 |
+
|
| 178 |
+
- **Be respectful** and considerate in all interactions
|
| 179 |
+
- **Be constructive** when giving feedback
|
| 180 |
+
- **Be patient** with newcomers
|
| 181 |
+
- **Focus on the mission** - cleaner cities and environmental action
|
| 182 |
+
|
| 183 |
+
### Unacceptable Behavior
|
| 184 |
+
|
| 185 |
+
- Harassment, discrimination, or personal attacks
|
| 186 |
+
- Trolling or inflammatory comments
|
| 187 |
+
- Spam or self-promotion unrelated to the project
|
| 188 |
+
|
| 189 |
+
**Violations:** Contact project maintainers. Violators may be banned.
|
| 190 |
+
|
| 191 |
+
## π Recognition
|
| 192 |
+
|
| 193 |
+
Contributors will be:
|
| 194 |
+
- Listed in README acknowledgments
|
| 195 |
+
- Credited in release notes
|
| 196 |
+
- Given proper attribution in commits
|
| 197 |
+
|
| 198 |
+
## β Questions?
|
| 199 |
+
|
| 200 |
+
- **GitHub Issues:** For bugs and features
|
| 201 |
+
- **Discussions:** For questions and ideas
|
| 202 |
+
- **Email:** [Contact project maintainer if email available]
|
| 203 |
+
|
| 204 |
+
---
|
| 205 |
+
|
| 206 |
+
**Thank you for helping make CleanCity Agent better! π±**
|
| 207 |
+
|
| 208 |
+
Your contributions help communities worldwide take action against litter and pollution.
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2025 CleanCity Agent Contributors
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
CHANGED
|
@@ -35,6 +35,14 @@ CleanCity Agent is an AI-powered web application that helps communities identify
|
|
| 35 |
<img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License">
|
| 36 |
</p>
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
---
|
| 39 |
|
| 40 |
## β¨ Features
|
|
@@ -72,6 +80,13 @@ CleanCity Agent is an AI-powered web application that helps communities identify
|
|
| 72 |
- Expose tools via Model Context Protocol
|
| 73 |
- Compatible with Claude Desktop and other MCP clients
|
| 74 |
- Programmatic access to all features
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
---
|
| 77 |
|
|
@@ -207,17 +222,28 @@ CleanCity Agent works **offline by default** with mock responses. To enable real
|
|
| 207 |
|
| 208 |
1. Copy `.env.example` to `.env`
|
| 209 |
2. Set `LLM_PROVIDER` to your preferred provider:
|
| 210 |
-
- `anthropic` - Claude (recommended)
|
| 211 |
- `openai` - GPT-4
|
| 212 |
-
- `gemini` - Google Gemini
|
| 213 |
- `offline` - Mock responses (no API key needed)
|
| 214 |
|
| 215 |
3. Add your API key:
|
| 216 |
```env
|
|
|
|
| 217 |
LLM_PROVIDER=anthropic
|
| 218 |
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
```
|
| 220 |
|
|
|
|
|
|
|
| 221 |
### Trash Detection Model
|
| 222 |
|
| 223 |
The current implementation uses a **mock detector** for demonstration. To integrate a real model:
|
|
@@ -281,25 +307,29 @@ docker run -p 7860:7860 cleancity-agent
|
|
| 281 |
|
| 282 |
## π οΈ MCP Server Usage
|
| 283 |
|
| 284 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 285 |
|
| 286 |
### Running the MCP Server
|
| 287 |
|
|
|
|
| 288 |
```bash
|
| 289 |
python mcp_server.py
|
| 290 |
```
|
| 291 |
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
1. **detect_trash** - Detect trash in images
|
| 295 |
-
2. **plan_cleanup** - Generate cleanup plans
|
| 296 |
-
3. **log_event** - Save events to database
|
| 297 |
-
4. **query_events** - Search historical events
|
| 298 |
-
5. **get_hotspots** - Identify recurring problem areas
|
| 299 |
-
6. **generate_report** - Create formatted reports
|
| 300 |
-
7. **mark_cleaned** - Update event status
|
| 301 |
-
|
| 302 |
-
### Claude Desktop Integration
|
| 303 |
|
| 304 |
Add to your Claude Desktop configuration (`claude_desktop_config.json`):
|
| 305 |
|
|
@@ -308,14 +338,121 @@ Add to your Claude Desktop configuration (`claude_desktop_config.json`):
|
|
| 308 |
"mcpServers": {
|
| 309 |
"cleancity": {
|
| 310 |
"command": "python",
|
| 311 |
-
"args": ["
|
|
|
|
|
|
|
|
|
|
| 312 |
}
|
| 313 |
}
|
| 314 |
}
|
| 315 |
```
|
| 316 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 317 |
---
|
| 318 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
## π Database Schema
|
| 320 |
|
| 321 |
SQLite database (`data/trash_events.db`) with the following schema:
|
|
@@ -358,11 +495,11 @@ Please open an issue or PR on the repository.
|
|
| 358 |
|
| 359 |
## β οΈ Limitations
|
| 360 |
|
| 361 |
-
- **
|
| 362 |
-
- **Local storage**: Data stored locally, not synchronized
|
| 363 |
-
- **No authentication**: Single-user design
|
| 364 |
-
- **Detection accuracy**: Depends on image quality and model training
|
| 365 |
-
- **LLM costs**: Using real LLM APIs incurs API charges
|
| 366 |
|
| 367 |
This is a **prototype** designed for community groups and individual activists. Production deployment requires additional hardening.
|
| 368 |
|
|
@@ -376,10 +513,12 @@ MIT License - see LICENSE file for details.
|
|
| 376 |
|
| 377 |
## π Acknowledgments
|
| 378 |
|
| 379 |
-
-
|
| 380 |
-
-
|
| 381 |
-
-
|
| 382 |
-
-
|
|
|
|
|
|
|
| 383 |
|
| 384 |
---
|
| 385 |
|
|
|
|
| 35 |
<img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License">
|
| 36 |
</p>
|
| 37 |
|
| 38 |
+
## π Try It Now
|
| 39 |
+
|
| 40 |
+
**[π Live Demo on HuggingFace Spaces](https://huggingface.co/spaces/YOUR_USERNAME/CleanCity-Agent)**
|
| 41 |
+
|
| 42 |
+
No installation required! Upload a photo and see AI-powered trash detection in action.
|
| 43 |
+
|
| 44 |
+
> β οΈ **Note:** Replace `YOUR_USERNAME/CleanCity-Agent` with your actual HuggingFace Space URL once deployed.
|
| 45 |
+
|
| 46 |
---
|
| 47 |
|
| 48 |
## β¨ Features
|
|
|
|
| 80 |
- Expose tools via Model Context Protocol
|
| 81 |
- Compatible with Claude Desktop and other MCP clients
|
| 82 |
- Programmatic access to all features
|
| 83 |
+
- 6 powerful tools: trash detection, cleanup planning, event logging, history queries, hotspot analysis, report generation
|
| 84 |
+
|
| 85 |
+
### π€ **Multi-LLM Support**
|
| 86 |
+
- **Anthropic Claude** - Premium AI assistance
|
| 87 |
+
- **OpenAI GPT** - Versatile language model
|
| 88 |
+
- **Google Gemini** - Advanced multimodal AI (Qualifies for $10K Gemini credits!)
|
| 89 |
+
- **Offline Mode** - Works without API keys
|
| 90 |
|
| 91 |
---
|
| 92 |
|
|
|
|
| 222 |
|
| 223 |
1. Copy `.env.example` to `.env`
|
| 224 |
2. Set `LLM_PROVIDER` to your preferred provider:
|
| 225 |
+
- `anthropic` - Claude (recommended for best results)
|
| 226 |
- `openai` - GPT-4
|
| 227 |
+
- `gemini` - Google Gemini β¨ **Use this to qualify for $10K Gemini API credits!**
|
| 228 |
- `offline` - Mock responses (no API key needed)
|
| 229 |
|
| 230 |
3. Add your API key:
|
| 231 |
```env
|
| 232 |
+
# For Anthropic Claude
|
| 233 |
LLM_PROVIDER=anthropic
|
| 234 |
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
| 235 |
+
|
| 236 |
+
# OR for Google Gemini (recommended for hackathon!)
|
| 237 |
+
LLM_PROVIDER=gemini
|
| 238 |
+
GEMINI_API_KEY=your-gemini-key-here
|
| 239 |
+
|
| 240 |
+
# OR for OpenAI
|
| 241 |
+
LLM_PROVIDER=openai
|
| 242 |
+
OPENAI_API_KEY=sk-your-key-here
|
| 243 |
```
|
| 244 |
|
| 245 |
+
**π Hackathon Tip:** Using Gemini qualifies your project for Google's $10K API credits prize in the Consumer category!
|
| 246 |
+
|
| 247 |
### Trash Detection Model
|
| 248 |
|
| 249 |
The current implementation uses a **mock detector** for demonstration. To integrate a real model:
|
|
|
|
| 307 |
|
| 308 |
## π οΈ MCP Server Usage
|
| 309 |
|
| 310 |
+
### What is MCP?
|
| 311 |
+
|
| 312 |
+
The **Model Context Protocol (MCP)** allows AI assistants like Claude Desktop to use CleanCity's tools programmatically. This enables autonomous agents to detect trash, plan cleanups, and generate reports.
|
| 313 |
+
|
| 314 |
+
### Available MCP Tools
|
| 315 |
+
|
| 316 |
+
CleanCity exposes 6 powerful tools via MCP:
|
| 317 |
+
|
| 318 |
+
1. **`detect_trash`** - Analyze images for trash detection
|
| 319 |
+
2. **`plan_cleanup`** - Generate cleanup action plans
|
| 320 |
+
3. **`log_event`** - Save detection events to database
|
| 321 |
+
4. **`query_events`** - Search historical events
|
| 322 |
+
5. **`get_hotspots`** - Identify recurring problem areas
|
| 323 |
+
6. **`generate_report`** - Create professional reports
|
| 324 |
|
| 325 |
### Running the MCP Server
|
| 326 |
|
| 327 |
+
**Option 1: Standalone Server**
|
| 328 |
```bash
|
| 329 |
python mcp_server.py
|
| 330 |
```
|
| 331 |
|
| 332 |
+
**Option 2: Use with Claude Desktop**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 333 |
|
| 334 |
Add to your Claude Desktop configuration (`claude_desktop_config.json`):
|
| 335 |
|
|
|
|
| 338 |
"mcpServers": {
|
| 339 |
"cleancity": {
|
| 340 |
"command": "python",
|
| 341 |
+
"args": ["c:/path/to/clean_city/mcp_server.py"],
|
| 342 |
+
"env": {
|
| 343 |
+
"LLM_PROVIDER": "offline"
|
| 344 |
+
}
|
| 345 |
}
|
| 346 |
}
|
| 347 |
}
|
| 348 |
```
|
| 349 |
|
| 350 |
+
Then restart Claude Desktop and ask:
|
| 351 |
+
> "Use the CleanCity tools to analyze this trash image and create a cleanup plan"
|
| 352 |
+
|
| 353 |
+
### MCP Tool Examples
|
| 354 |
+
|
| 355 |
+
**Detect trash in an image:**
|
| 356 |
+
```json
|
| 357 |
+
{
|
| 358 |
+
"tool": "detect_trash",
|
| 359 |
+
"arguments": {
|
| 360 |
+
"image_data": "<base64-encoded-image>"
|
| 361 |
+
}
|
| 362 |
+
}
|
| 363 |
+
```
|
| 364 |
+
|
| 365 |
+
**Query cleanup history:**
|
| 366 |
+
```json
|
| 367 |
+
{
|
| 368 |
+
"tool": "query_events",
|
| 369 |
+
"arguments": {
|
| 370 |
+
"location": "Main Street Park",
|
| 371 |
+
"days": 30,
|
| 372 |
+
"severity": "high"
|
| 373 |
+
}
|
| 374 |
+
}
|
| 375 |
+
```
|
| 376 |
+
|
| 377 |
+
**Generate hotspot analysis:**
|
| 378 |
+
```json
|
| 379 |
+
{
|
| 380 |
+
"tool": "get_hotspots",
|
| 381 |
+
"arguments": {
|
| 382 |
+
"days": 30,
|
| 383 |
+
"min_events": 2
|
| 384 |
+
}
|
| 385 |
+
}
|
| 386 |
+
```
|
| 387 |
+
|
| 388 |
+
### Integration Benefits
|
| 389 |
+
|
| 390 |
+
- **Autonomous Workflows** - AI agents can run full cleanup campaigns
|
| 391 |
+
- **Multi-tool Chains** - Detect β Plan β Log β Report in one flow
|
| 392 |
+
- **External Integration** - Connect to other MCP-enabled tools
|
| 393 |
+
- **Programmable Access** - Build custom applications on top
|
| 394 |
+
|
| 395 |
---
|
| 396 |
|
| 397 |
+
## π₯ Demo Video
|
| 398 |
+
|
| 399 |
+
[πΉ Watch the 3-minute demo](LINK_TO_YOUR_VIDEO)
|
| 400 |
+
|
| 401 |
+
**What the demo covers:**
|
| 402 |
+
1. Upload trash image with GPS location
|
| 403 |
+
2. AI detection with bounding boxes
|
| 404 |
+
3. Automated cleanup plan generation
|
| 405 |
+
4. Environmental impact metrics
|
| 406 |
+
5. Professional report creation
|
| 407 |
+
6. Social sharing features
|
| 408 |
+
7. MCP integration with Claude Desktop
|
| 409 |
+
|
| 410 |
+
---
|
| 411 |
+
|
| 412 |
+
## π± Social Media
|
| 413 |
+
|
| 414 |
+
**Share this project and help spread awareness!**
|
| 415 |
+
|
| 416 |
+
### Sample Post for Twitter/LinkedIn:
|
| 417 |
+
|
| 418 |
+
```
|
| 419 |
+
π Excited to share CleanCity Agent - an AI-powered tool that helps communities tackle trash!
|
| 420 |
+
|
| 421 |
+
β¨ Features:
|
| 422 |
+
πΈ Computer vision trash detection (YOLOv8)
|
| 423 |
+
π Automated cleanup planning
|
| 424 |
+
π Environmental impact metrics (CO2, ocean protection)
|
| 425 |
+
π§ Professional reports for authorities
|
| 426 |
+
π MCP integration for AI agents
|
| 427 |
+
|
| 428 |
+
Built with @Gradio 6 for MCP's 1st Birthday Hackathon!
|
| 429 |
+
|
| 430 |
+
π Try it: [Your HuggingFace Space URL]
|
| 431 |
+
|
| 432 |
+
#AI4Good #CleanCity #EnvironmentalTech #MCPHackathon #Gradio6
|
| 433 |
+
```
|
| 434 |
+
|
| 435 |
+
**Required:** Post on social media and include link in your submission!
|
| 436 |
+
|
| 437 |
+
---
|
| 438 |
+
|
| 439 |
+
## β
Hackathon Submission Checklist
|
| 440 |
+
|
| 441 |
+
Before submitting, ensure you have:
|
| 442 |
+
|
| 443 |
+
- [x] Tagged README with `mcp-in-action-track-consumer`
|
| 444 |
+
- [ ] Recorded 1-5 minute demo video
|
| 445 |
+
- [ ] Posted on social media (Twitter/LinkedIn) with project link
|
| 446 |
+
- [ ] Added social media link to this README (update line above)
|
| 447 |
+
- [ ] Tested app works on HuggingFace Spaces
|
| 448 |
+
- [ ] Verified MCP server runs successfully
|
| 449 |
+
- [ ] Documented Gemini integration (for $10K credits opportunity)
|
| 450 |
+
- [ ] All team members joined hackathon organization
|
| 451 |
+
|
| 452 |
+
---
|
| 453 |
+
|
| 454 |
+
## π Additional Resources
|
| 455 |
+
|
| 456 |
## π Database Schema
|
| 457 |
|
| 458 |
SQLite database (`data/trash_events.db`) with the following schema:
|
|
|
|
| 495 |
|
| 496 |
## β οΈ Limitations
|
| 497 |
|
| 498 |
+
- **YOLOv8 Model**: Uses trained YOLOv8 model for trash detection (Weights/best.pt)
|
| 499 |
+
- **Local storage**: Data stored locally in SQLite, not synchronized across devices
|
| 500 |
+
- **No authentication**: Single-user design, suitable for community groups
|
| 501 |
+
- **Detection accuracy**: Depends on image quality, lighting, and model training
|
| 502 |
+
- **LLM costs**: Using real LLM APIs (Anthropic, OpenAI, Gemini) incurs API charges - offline mode available
|
| 503 |
|
| 504 |
This is a **prototype** designed for community groups and individual activists. Production deployment requires additional hardening.
|
| 505 |
|
|
|
|
| 513 |
|
| 514 |
## π Acknowledgments
|
| 515 |
|
| 516 |
+
- **Gradio Team** - For the amazing web UI framework ([gradio.app](https://gradio.app/))
|
| 517 |
+
- **Anthropic** - For Model Context Protocol and Claude ([modelcontextprotocol.io](https://modelcontextprotocol.io/))
|
| 518 |
+
- **Ultralytics** - For YOLOv8 computer vision framework ([ultralytics.com](https://ultralytics.com/))
|
| 519 |
+
- **MCP Hackathon** - For inspiring this project and promoting AI-for-good applications
|
| 520 |
+
- **Open Source Community** - For the tools and libraries that made this possible
|
| 521 |
+
- **Environmental Activists Worldwide** - For inspiring community-driven environmental action
|
| 522 |
|
| 523 |
---
|
| 524 |
|
app.py
CHANGED
|
@@ -25,76 +25,278 @@ TAGLINE = "Spot trash. Plan action. Keep your city clean."
|
|
| 25 |
GUIDE_CONTENT = """
|
| 26 |
## π How to Use CleanCity Agent
|
| 27 |
|
| 28 |
-
###
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
-
|
| 44 |
-
-
|
| 45 |
-
-
|
| 46 |
-
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
|
| 60 |
---
|
| 61 |
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
-
|
| 65 |
-
-
|
| 66 |
-
-
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
-
###
|
| 69 |
-
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
"""
|
| 72 |
|
| 73 |
FAQ_CONTENT = """
|
| 74 |
## β Frequently Asked Questions
|
| 75 |
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
|
| 80 |
**Q: Is my data stored or shared?**
|
| 81 |
-
A:
|
| 82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
-
**Q:
|
| 85 |
-
A:
|
| 86 |
-
|
| 87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
|
| 89 |
**Q: Can I use this for large-scale city monitoring?**
|
| 90 |
-
A: This is a prototype designed for
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
For large-scale deployment, consider:
|
| 92 |
-
- Integrating
|
| 93 |
-
-
|
| 94 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
|
| 96 |
-
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
"""
|
| 99 |
|
| 100 |
|
|
@@ -146,6 +348,68 @@ def image_to_base64(image: Image.Image) -> str:
|
|
| 146 |
return base64.b64encode(buffered.getvalue()).decode()
|
| 147 |
|
| 148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
# ============================================================================
|
| 150 |
# CORE ANALYSIS FUNCTION
|
| 151 |
# ============================================================================
|
|
@@ -156,7 +420,7 @@ def analyze_image(
|
|
| 156 |
notes: str,
|
| 157 |
save_to_history: bool,
|
| 158 |
gps_coords: str
|
| 159 |
-
) -> Tuple[Optional[Image.Image], str, str, str]:
|
| 160 |
"""
|
| 161 |
Main analysis function called when user clicks "Start Analysis".
|
| 162 |
|
|
@@ -165,9 +429,10 @@ def analyze_image(
|
|
| 165 |
- detection_text: Detection results summary
|
| 166 |
- plan_text: Cleanup plan
|
| 167 |
- report_text: Generated report
|
|
|
|
| 168 |
"""
|
| 169 |
if image is None:
|
| 170 |
-
return None, "β οΈ Please upload an image first.", "", ""
|
| 171 |
|
| 172 |
# Parse GPS coordinates if provided
|
| 173 |
latitude, longitude = None, None
|
|
@@ -193,7 +458,7 @@ def analyze_image(
|
|
| 193 |
)
|
| 194 |
|
| 195 |
if result["status"] == "no_trash":
|
| 196 |
-
return image, result["summary"], "", ""
|
| 197 |
|
| 198 |
# Draw boxes on image
|
| 199 |
annotated_image = draw_boxes_on_image(
|
|
@@ -201,6 +466,22 @@ def analyze_image(
|
|
| 201 |
result["detection_results"]["detections"]
|
| 202 |
)
|
| 203 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
# Format detection results
|
| 205 |
detection_text = f"""### π Detection Results
|
| 206 |
|
|
@@ -236,11 +517,11 @@ def analyze_image(
|
|
| 236 |
# Return report
|
| 237 |
report_text = result["report"]
|
| 238 |
|
| 239 |
-
return annotated_image, detection_text, plan_text, report_text
|
| 240 |
|
| 241 |
except Exception as e:
|
| 242 |
error_msg = f"β Error during analysis: {str(e)}"
|
| 243 |
-
return image, error_msg, "", ""
|
| 244 |
|
| 245 |
|
| 246 |
# ============================================================================
|
|
@@ -389,81 +670,146 @@ def create_interface() -> gr.Blocks:
|
|
| 389 |
# TAB 1: MAIN ANALYSIS
|
| 390 |
# ================================================================
|
| 391 |
with gr.Tab("π Analyze Image"):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 392 |
with gr.Row():
|
| 393 |
with gr.Column(scale=1):
|
| 394 |
-
gr.Markdown("### Upload Image")
|
| 395 |
image_input = gr.Image(
|
| 396 |
type="pil",
|
| 397 |
-
label="
|
| 398 |
-
sources=["upload", "webcam"]
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
with gr.Row():
|
| 402 |
-
location_input = gr.Textbox(
|
| 403 |
-
label="Location (optional)",
|
| 404 |
-
placeholder="e.g., Main Street Park, Downtown Beach...",
|
| 405 |
-
lines=1,
|
| 406 |
-
scale=4
|
| 407 |
-
)
|
| 408 |
-
get_location_btn = gr.Button(
|
| 409 |
-
"π Get GPS",
|
| 410 |
-
size="sm",
|
| 411 |
-
scale=1
|
| 412 |
-
)
|
| 413 |
-
|
| 414 |
-
gps_coords = gr.Textbox(
|
| 415 |
-
label="GPS Coordinates",
|
| 416 |
-
placeholder="Latitude, Longitude (auto-filled when you click Get GPS)",
|
| 417 |
-
lines=1,
|
| 418 |
-
interactive=False,
|
| 419 |
-
visible=False
|
| 420 |
)
|
| 421 |
|
| 422 |
notes_input = gr.Textbox(
|
| 423 |
-
label="Notes (optional)",
|
| 424 |
-
placeholder="
|
| 425 |
lines=2
|
| 426 |
)
|
| 427 |
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
|
|
|
| 438 |
|
| 439 |
with gr.Column(scale=1):
|
| 440 |
-
gr.Markdown("### Detection Results")
|
| 441 |
output_image = gr.Image(
|
| 442 |
type="pil",
|
| 443 |
-
label="
|
|
|
|
| 444 |
)
|
| 445 |
|
| 446 |
gr.Markdown("---")
|
|
|
|
| 447 |
|
| 448 |
with gr.Row():
|
| 449 |
with gr.Column():
|
| 450 |
-
|
|
|
|
| 451 |
|
| 452 |
with gr.Column():
|
| 453 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 454 |
|
| 455 |
-
gr.Markdown("
|
|
|
|
| 456 |
report_output = gr.Textbox(
|
| 457 |
-
label="Email Report
|
| 458 |
-
|
| 459 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 460 |
)
|
| 461 |
|
| 462 |
# Wire up the analyze button
|
| 463 |
analyze_btn.click(
|
| 464 |
fn=analyze_image,
|
| 465 |
inputs=[image_input, location_input, notes_input, save_history, gps_coords],
|
| 466 |
-
outputs=[output_image, detection_output, plan_output, report_output]
|
| 467 |
)
|
| 468 |
|
| 469 |
# Wire up GPS button with JavaScript to get browser location
|
|
@@ -516,7 +862,12 @@ def create_interface() -> gr.Blocks:
|
|
| 516 |
# TAB 3: HISTORY
|
| 517 |
# ================================================================
|
| 518 |
with gr.Tab("π Event History"):
|
| 519 |
-
gr.Markdown("
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 520 |
|
| 521 |
with gr.Row():
|
| 522 |
days_filter = gr.Slider(
|
|
@@ -524,19 +875,22 @@ def create_interface() -> gr.Blocks:
|
|
| 524 |
maximum=365,
|
| 525 |
value=30,
|
| 526 |
step=1,
|
| 527 |
-
label="
|
|
|
|
| 528 |
)
|
| 529 |
location_filter = gr.Textbox(
|
| 530 |
-
label="
|
| 531 |
-
placeholder="e.g., Park"
|
|
|
|
| 532 |
)
|
| 533 |
severity_filter = gr.Dropdown(
|
| 534 |
choices=["All", "Low", "Medium", "High"],
|
| 535 |
value="All",
|
| 536 |
-
label="
|
|
|
|
| 537 |
)
|
| 538 |
|
| 539 |
-
load_history_btn = gr.Button("π Load History", variant="primary")
|
| 540 |
history_output = gr.Markdown()
|
| 541 |
|
| 542 |
load_history_btn.click(
|
|
@@ -546,51 +900,176 @@ def create_interface() -> gr.Blocks:
|
|
| 546 |
)
|
| 547 |
|
| 548 |
# ================================================================
|
| 549 |
-
# TAB 4:
|
| 550 |
# ================================================================
|
| 551 |
-
with gr.Tab("
|
| 552 |
-
gr.Markdown("
|
| 553 |
-
|
| 554 |
-
"Hotspots are locations with multiple trash events. "
|
| 555 |
-
"Use this to prioritize cleanup efforts and request permanent solutions."
|
| 556 |
-
)
|
| 557 |
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
|
| 561 |
-
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 565 |
|
| 566 |
-
|
| 567 |
-
|
|
|
|
| 568 |
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 574 |
|
| 575 |
# ================================================================
|
| 576 |
# TAB 5: CHAT WITH AGENT
|
| 577 |
# ================================================================
|
| 578 |
with gr.Tab("π¬ Chat with Agent"):
|
| 579 |
-
gr.Markdown("
|
| 580 |
-
|
| 581 |
-
"Chat with the CleanCity Agent to get advice on cleanup strategies, "
|
| 582 |
-
"interpretation of results, or general environmental questions."
|
| 583 |
-
)
|
| 584 |
|
| 585 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 586 |
msg = gr.Textbox(
|
| 587 |
label="Your message",
|
| 588 |
-
placeholder="
|
|
|
|
| 589 |
)
|
| 590 |
|
| 591 |
with gr.Row():
|
| 592 |
-
submit = gr.Button("Send", variant="primary")
|
| 593 |
-
clear = gr.Button("Clear Chat")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 594 |
|
| 595 |
def respond(message, chat_history):
|
| 596 |
bot_response = chat_with_agent(message, chat_history)
|
|
|
|
| 25 |
GUIDE_CONTENT = """
|
| 26 |
## π How to Use CleanCity Agent
|
| 27 |
|
| 28 |
+
### Quick Start Guide
|
| 29 |
+
|
| 30 |
+
**Step 1 β Specify Location** π
|
| 31 |
+
Enter where you found the trash (street name, park, beach, etc.) or click **"Get GPS"** to automatically detect your current location using your device's GPS.
|
| 32 |
+
|
| 33 |
+
**Why location matters:** Tracking locations helps identify "hotspots" - areas with recurring trash problems that need special attention.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
**Step 2 β Upload a Photo** πΈ
|
| 38 |
+
Take a clear photo of the littered area and upload it. You can:
|
| 39 |
+
- Upload an existing image from your device
|
| 40 |
+
- Use your camera to take a photo right now
|
| 41 |
+
|
| 42 |
+
**Photo Tips:**
|
| 43 |
+
- β
Good lighting helps detection accuracy
|
| 44 |
+
- β
Get close enough to see individual items
|
| 45 |
+
- β
Include surrounding context (park bench, street sign, etc.)
|
| 46 |
+
- β Avoid blurry or dark images
|
| 47 |
+
|
| 48 |
+
---
|
| 49 |
+
|
| 50 |
+
**Step 3 β Add Notes (Optional)** π
|
| 51 |
+
Provide additional context like:
|
| 52 |
+
- "Near the playground entrance"
|
| 53 |
+
- "Behind the main parking lot"
|
| 54 |
+
- "Recurring problem - third time this month"
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
**Step 4 β Start AI Analysis** π
|
| 59 |
+
Click **"Start AI Analysis"** and watch the magic happen! Our computer vision AI will:
|
| 60 |
+
- π Detect and identify trash items (bottles, bags, wrappers, etc.)
|
| 61 |
+
- π¦ Draw bounding boxes around each item
|
| 62 |
+
- π Count items and categorize them
|
| 63 |
+
- β‘ Calculate confidence scores
|
| 64 |
+
|
| 65 |
+
---
|
| 66 |
+
|
| 67 |
+
**Step 5 β Review Results** π
|
| 68 |
+
You'll see three key outputs:
|
| 69 |
+
|
| 70 |
+
1. **Items Detected** π
|
| 71 |
+
- List of all trash items found
|
| 72 |
+
- Confidence scores for each detection
|
| 73 |
+
- Total count across categories
|
| 74 |
+
|
| 75 |
+
2. **Cleanup Action Plan** π
|
| 76 |
+
- Severity level (Low/Medium/High)
|
| 77 |
+
- Number of volunteers needed
|
| 78 |
+
- Estimated cleanup time
|
| 79 |
+
- Required equipment list
|
| 80 |
+
- Environmental impact assessment
|
| 81 |
+
|
| 82 |
+
3. **Email Report** π§
|
| 83 |
+
- Professional report ready to send
|
| 84 |
+
- Copy and paste to email
|
| 85 |
+
- Share with city officials or cleanup groups
|
| 86 |
|
| 87 |
---
|
| 88 |
|
| 89 |
+
**Step 6 β Take Action** π―
|
| 90 |
+
Use your results to:
|
| 91 |
+
- βοΈ Report to local authorities
|
| 92 |
+
- π₯ Organize a community cleanup
|
| 93 |
+
- π Track progress over time
|
| 94 |
+
- π₯ Identify hotspots that need attention
|
| 95 |
+
|
| 96 |
+
---
|
| 97 |
|
| 98 |
+
### π‘ Pro Tips
|
| 99 |
+
|
| 100 |
+
**For Better Detection:**
|
| 101 |
+
- Take photos in daylight when possible
|
| 102 |
+
- Capture multiple angles if trash is spread out
|
| 103 |
+
- Focus on one area at a time for accurate counts
|
| 104 |
+
|
| 105 |
+
**For Better Tracking:**
|
| 106 |
+
- Always add location information
|
| 107 |
+
- Be consistent with location names
|
| 108 |
+
- Check the History tab to see patterns
|
| 109 |
+
- Use the Hotspot Analysis to prioritize efforts
|
| 110 |
+
|
| 111 |
+
**For Community Impact:**
|
| 112 |
+
- Save all events to build a data history
|
| 113 |
+
- Share reports with local government
|
| 114 |
+
- Use data to request more trash bins or cleanups
|
| 115 |
+
- Document improvements to show success
|
| 116 |
+
|
| 117 |
+
---
|
| 118 |
+
|
| 119 |
+
### β οΈ Important Notes
|
| 120 |
+
|
| 121 |
+
**Accuracy:** This AI is trained on common litter types but may miss items in poor lighting or unusual positions. Always verify results visually.
|
| 122 |
+
|
| 123 |
+
**Privacy:** Images and data are processed locally. No personal information is uploaded except for optional LLM enhancement (if configured).
|
| 124 |
+
|
| 125 |
+
**Purpose:** This tool is designed to empower community action, not replace professional waste management systems.
|
| 126 |
"""
|
| 127 |
|
| 128 |
FAQ_CONTENT = """
|
| 129 |
## β Frequently Asked Questions
|
| 130 |
|
| 131 |
+
### π€ About the AI Detection
|
| 132 |
+
|
| 133 |
+
**Q: How accurate is the trash detection?**
|
| 134 |
+
A: The AI uses a YOLOv8 computer vision model trained on real trash images. Accuracy depends on:
|
| 135 |
+
- Image quality and lighting (daylight is best)
|
| 136 |
+
- Camera angle and distance
|
| 137 |
+
- Trash visibility (not hidden or buried)
|
| 138 |
+
|
| 139 |
+
Typical accuracy: 75-90% for common items like bottles, bags, and wrappers.
|
| 140 |
+
|
| 141 |
+
**Q: What types of trash can it detect?**
|
| 142 |
+
A: Common litter categories including:
|
| 143 |
+
- Plastic bottles and containers
|
| 144 |
+
- Food wrappers and packaging
|
| 145 |
+
- Plastic bags
|
| 146 |
+
- Cigarette butts
|
| 147 |
+
- Cans and metal items
|
| 148 |
+
- Paper and cardboard
|
| 149 |
+
- General debris
|
| 150 |
+
|
| 151 |
+
**Q: Why are some items missed?**
|
| 152 |
+
A: The AI may miss items that are:
|
| 153 |
+
- Partially hidden or buried
|
| 154 |
+
- In shadows or poor lighting
|
| 155 |
+
- Very small (like tiny pieces)
|
| 156 |
+
- Unusual or rare trash types not in training data
|
| 157 |
+
|
| 158 |
+
---
|
| 159 |
+
|
| 160 |
+
### π Privacy & Data
|
| 161 |
|
| 162 |
**Q: Is my data stored or shared?**
|
| 163 |
+
A:
|
| 164 |
+
- Images are processed locally on the server
|
| 165 |
+
- Event data is stored in a local SQLite database (if you choose "Save to history")
|
| 166 |
+
- No images or personal info are sent to third parties
|
| 167 |
+
- Optional: LLM API calls (if configured) send text summaries only, not images
|
| 168 |
+
|
| 169 |
+
**Q: Do I need an account?**
|
| 170 |
+
A: No! This is a free, open tool. No login required.
|
| 171 |
+
|
| 172 |
+
---
|
| 173 |
+
|
| 174 |
+
### π Using the Results
|
| 175 |
+
|
| 176 |
+
**Q: How should I use the cleanup plan?**
|
| 177 |
+
A: The plan provides realistic estimates based on:
|
| 178 |
+
- Number of items detected
|
| 179 |
+
- Types of trash (some require special handling)
|
| 180 |
+
- Typical volunteer efficiency
|
| 181 |
+
|
| 182 |
+
Use it to:
|
| 183 |
+
- Request appropriate resources from authorities
|
| 184 |
+
- Plan community cleanup events
|
| 185 |
+
- Estimate budget for equipment/disposal
|
| 186 |
+
|
| 187 |
+
**Q: Can I edit the report before sending?**
|
| 188 |
+
A: Yes! Copy the text from the report box and edit it in your email client or word processor before sending.
|
| 189 |
|
| 190 |
+
**Q: Who should I send the report to?**
|
| 191 |
+
A: Consider sending to:
|
| 192 |
+
- City/town environmental department
|
| 193 |
+
- Parks and recreation department
|
| 194 |
+
- Local waste management authority
|
| 195 |
+
- Community cleanup organizations
|
| 196 |
+
- Neighborhood associations
|
| 197 |
+
|
| 198 |
+
---
|
| 199 |
+
|
| 200 |
+
### π Location & Tracking
|
| 201 |
+
|
| 202 |
+
**Q: Why does location matter?**
|
| 203 |
+
A: Location tracking helps:
|
| 204 |
+
- Identify "hotspots" with recurring problems
|
| 205 |
+
- Show patterns to authorities
|
| 206 |
+
- Prioritize areas needing attention
|
| 207 |
+
- Demonstrate impact over time
|
| 208 |
+
|
| 209 |
+
**Q: Is GPS required?**
|
| 210 |
+
A: No, location is optional but recommended. You can:
|
| 211 |
+
- Use GPS auto-detect
|
| 212 |
+
- Type location manually
|
| 213 |
+
- Leave it blank (less useful for tracking)
|
| 214 |
+
|
| 215 |
+
---
|
| 216 |
+
|
| 217 |
+
### π Advanced Usage
|
| 218 |
|
| 219 |
**Q: Can I use this for large-scale city monitoring?**
|
| 220 |
+
A: This is a prototype designed for:
|
| 221 |
+
- Community activists and groups
|
| 222 |
+
- Individual concerned citizens
|
| 223 |
+
- Small-to-medium cleanup organizations
|
| 224 |
+
|
| 225 |
For large-scale deployment, consider:
|
| 226 |
+
- Integrating with city GIS systems
|
| 227 |
+
- Adding user authentication
|
| 228 |
+
- Cloud hosting for multi-user access
|
| 229 |
+
- Professional model fine-tuning for your area
|
| 230 |
+
|
| 231 |
+
**Q: Can I improve the AI detection?**
|
| 232 |
+
A: Yes! The model file is at `Weights/best.pt`. You can:
|
| 233 |
+
- Train on your own trash images
|
| 234 |
+
- Fine-tune for specific trash types in your area
|
| 235 |
+
- Replace with a different YOLO model
|
| 236 |
+
|
| 237 |
+
**Q: Can I run this offline?**
|
| 238 |
+
A: Partially:
|
| 239 |
+
- β
Trash detection works offline (local AI model)
|
| 240 |
+
- β
Cleanup planning works offline
|
| 241 |
+
- β LLM-enhanced reports require API access
|
| 242 |
+
- β GPS reverse geocoding requires internet
|
| 243 |
+
|
| 244 |
+
Set `LLM_PROVIDER=offline` in your `.env` file for full offline mode.
|
| 245 |
+
|
| 246 |
+
---
|
| 247 |
+
|
| 248 |
+
### π οΈ Troubleshooting
|
| 249 |
+
|
| 250 |
+
**Q: The detection is very slow. Why?**
|
| 251 |
+
A: Computer vision is computationally intensive. Speed depends on:
|
| 252 |
+
- Your hardware (GPU is faster than CPU)
|
| 253 |
+
- Image size (larger images take longer)
|
| 254 |
+
- Server load
|
| 255 |
+
|
| 256 |
+
Typical processing: 2-10 seconds per image.
|
| 257 |
+
|
| 258 |
+
**Q: "No trash detected" but I can see trash in the image?**
|
| 259 |
+
A: Try:
|
| 260 |
+
- Taking a clearer, better-lit photo
|
| 261 |
+
- Getting closer to the trash
|
| 262 |
+
- Ensuring items are visible (not hidden)
|
| 263 |
+
- Adjusting camera angle
|
| 264 |
+
|
| 265 |
+
If issues persist, the model may need retraining on similar images.
|
| 266 |
+
|
| 267 |
+
**Q: How do I report a bug or suggest a feature?**
|
| 268 |
+
A: Check the project repository for:
|
| 269 |
+
- Issue tracker
|
| 270 |
+
- Contribution guidelines
|
| 271 |
+
- Contact information
|
| 272 |
+
|
| 273 |
+
---
|
| 274 |
|
| 275 |
+
### π Making an Impact
|
| 276 |
+
|
| 277 |
+
**Q: Does this really help clean up trash?**
|
| 278 |
+
A: This tool provides:
|
| 279 |
+
- **Documentation** for authorities
|
| 280 |
+
- **Evidence** of recurring problems
|
| 281 |
+
- **Data** to support cleanup requests
|
| 282 |
+
- **Organization** for community action
|
| 283 |
+
|
| 284 |
+
Real cleanup requires human action, but this tool makes that action more effective and data-driven!
|
| 285 |
+
|
| 286 |
+
**Q: Can I contribute to this project?**
|
| 287 |
+
A: Yes! This is an open-source hackathon project. Ways to contribute:
|
| 288 |
+
- Test and report bugs
|
| 289 |
+
- Suggest improvements
|
| 290 |
+
- Share success stories
|
| 291 |
+
- Help improve the AI model
|
| 292 |
+
- Translate to other languages
|
| 293 |
+
|
| 294 |
+
**Q: How can I share my success stories?**
|
| 295 |
+
A: We'd love to hear how you're using CleanCity Agent! Share:
|
| 296 |
+
- Before/after photos of cleaned areas
|
| 297 |
+
- Data insights from your tracking
|
| 298 |
+
- Community impact stories
|
| 299 |
+
- Tips for other users
|
| 300 |
"""
|
| 301 |
|
| 302 |
|
|
|
|
| 348 |
return base64.b64encode(buffered.getvalue()).decode()
|
| 349 |
|
| 350 |
|
| 351 |
+
def calculate_environmental_impact(detections: list) -> dict:
|
| 352 |
+
"""
|
| 353 |
+
Calculate environmental impact metrics from detected trash.
|
| 354 |
+
|
| 355 |
+
Returns metrics like CO2 saved, plastic weight, etc.
|
| 356 |
+
"""
|
| 357 |
+
# Average weights in grams based on common trash items
|
| 358 |
+
item_weights = {
|
| 359 |
+
"bottle": 30, # Plastic bottle
|
| 360 |
+
"can": 15, # Aluminum can
|
| 361 |
+
"bag": 5, # Plastic bag
|
| 362 |
+
"wrapper": 3, # Food wrapper
|
| 363 |
+
"cup": 10, # Disposable cup
|
| 364 |
+
"cigarette": 0.5, # Cigarette butt
|
| 365 |
+
"container": 25, # Food container
|
| 366 |
+
"paper": 5, # Paper waste
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
# CO2 emissions saved per kg of waste recycled (kg CO2/kg waste)
|
| 370 |
+
co2_per_kg = 2.5
|
| 371 |
+
|
| 372 |
+
total_weight_g = 0
|
| 373 |
+
plastic_count = 0
|
| 374 |
+
recyclable_count = 0
|
| 375 |
+
|
| 376 |
+
for det in detections:
|
| 377 |
+
label = det["label"].lower()
|
| 378 |
+
|
| 379 |
+
# Estimate weight
|
| 380 |
+
for key, weight in item_weights.items():
|
| 381 |
+
if key in label:
|
| 382 |
+
total_weight_g += weight
|
| 383 |
+
break
|
| 384 |
+
else:
|
| 385 |
+
total_weight_g += 10 # Default for unknown items
|
| 386 |
+
|
| 387 |
+
# Count plastic items
|
| 388 |
+
if any(plastic in label for plastic in ["bottle", "bag", "wrapper", "plastic", "container", "cup"]):
|
| 389 |
+
plastic_count += 1
|
| 390 |
+
|
| 391 |
+
# Count recyclables
|
| 392 |
+
if any(recyclable in label for recyclable in ["bottle", "can", "paper", "cardboard"]):
|
| 393 |
+
recyclable_count += 1
|
| 394 |
+
|
| 395 |
+
total_weight_kg = total_weight_g / 1000
|
| 396 |
+
co2_saved_kg = total_weight_kg * co2_per_kg
|
| 397 |
+
|
| 398 |
+
# Calculate ocean impact (estimated plastic pieces prevented from ocean)
|
| 399 |
+
ocean_impact = plastic_count * 0.8 # 80% of plastic trash can end up in waterways
|
| 400 |
+
|
| 401 |
+
return {
|
| 402 |
+
"total_items": len(detections),
|
| 403 |
+
"total_weight_kg": round(total_weight_kg, 2),
|
| 404 |
+
"total_weight_lbs": round(total_weight_kg * 2.20462, 2),
|
| 405 |
+
"co2_saved_kg": round(co2_saved_kg, 2),
|
| 406 |
+
"plastic_items": plastic_count,
|
| 407 |
+
"recyclable_items": recyclable_count,
|
| 408 |
+
"ocean_impact": round(ocean_impact, 1),
|
| 409 |
+
"trees_saved": round(total_weight_kg * 0.017, 2), # Rough estimate: 1kg waste = 0.017 trees
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
|
| 413 |
# ============================================================================
|
| 414 |
# CORE ANALYSIS FUNCTION
|
| 415 |
# ============================================================================
|
|
|
|
| 420 |
notes: str,
|
| 421 |
save_to_history: bool,
|
| 422 |
gps_coords: str
|
| 423 |
+
) -> Tuple[Optional[Image.Image], str, str, str, str]:
|
| 424 |
"""
|
| 425 |
Main analysis function called when user clicks "Start Analysis".
|
| 426 |
|
|
|
|
| 429 |
- detection_text: Detection results summary
|
| 430 |
- plan_text: Cleanup plan
|
| 431 |
- report_text: Generated report
|
| 432 |
+
- impact_text: Environmental impact metrics
|
| 433 |
"""
|
| 434 |
if image is None:
|
| 435 |
+
return None, "β οΈ Please upload an image first.", "", "", ""
|
| 436 |
|
| 437 |
# Parse GPS coordinates if provided
|
| 438 |
latitude, longitude = None, None
|
|
|
|
| 458 |
)
|
| 459 |
|
| 460 |
if result["status"] == "no_trash":
|
| 461 |
+
return image, result["summary"], "", "", "No environmental impact data (no trash detected)"
|
| 462 |
|
| 463 |
# Draw boxes on image
|
| 464 |
annotated_image = draw_boxes_on_image(
|
|
|
|
| 466 |
result["detection_results"]["detections"]
|
| 467 |
)
|
| 468 |
|
| 469 |
+
# Calculate environmental impact
|
| 470 |
+
impact = calculate_environmental_impact(result["detection_results"]["detections"])
|
| 471 |
+
impact_text = f"""### π Environmental Impact
|
| 472 |
+
|
| 473 |
+
**If this trash is cleaned up:**
|
| 474 |
+
|
| 475 |
+
- ποΈ **Total Items:** {impact['total_items']} pieces
|
| 476 |
+
- βοΈ **Weight:** {impact['total_weight_kg']} kg ({impact['total_weight_lbs']} lbs)
|
| 477 |
+
- π **Ocean Protection:** ~{impact['ocean_impact']} plastic items prevented from reaching waterways
|
| 478 |
+
- β»οΈ **Recyclable Items:** {impact['recyclable_items']} items can be recycled
|
| 479 |
+
- π² **Trees Equivalent:** ~{impact['trees_saved']} trees worth of waste diverted
|
| 480 |
+
- π **COβ Impact:** {impact['co2_saved_kg']} kg COβ emissions prevented (if recycled)
|
| 481 |
+
|
| 482 |
+
*Every cleanup makes a measurable difference!*
|
| 483 |
+
"""
|
| 484 |
+
|
| 485 |
# Format detection results
|
| 486 |
detection_text = f"""### π Detection Results
|
| 487 |
|
|
|
|
| 517 |
# Return report
|
| 518 |
report_text = result["report"]
|
| 519 |
|
| 520 |
+
return annotated_image, detection_text, plan_text, report_text, impact_text
|
| 521 |
|
| 522 |
except Exception as e:
|
| 523 |
error_msg = f"β Error during analysis: {str(e)}"
|
| 524 |
+
return image, error_msg, "", "", ""
|
| 525 |
|
| 526 |
|
| 527 |
# ============================================================================
|
|
|
|
| 670 |
# TAB 1: MAIN ANALYSIS
|
| 671 |
# ================================================================
|
| 672 |
with gr.Tab("π Analyze Image"):
|
| 673 |
+
gr.Markdown("""
|
| 674 |
+
### πΈ Step 1: Location & Image Upload
|
| 675 |
+
Start by specifying where you found the trash, then upload a photo for AI analysis.
|
| 676 |
+
""")
|
| 677 |
+
|
| 678 |
+
# Location input at the top
|
| 679 |
+
with gr.Row():
|
| 680 |
+
location_input = gr.Textbox(
|
| 681 |
+
label="π Location",
|
| 682 |
+
placeholder="e.g., Main Street Park, Downtown Beach, 5th Avenue...",
|
| 683 |
+
lines=1,
|
| 684 |
+
scale=5,
|
| 685 |
+
info="Where is this trash located? Be specific to help track hotspots."
|
| 686 |
+
)
|
| 687 |
+
get_location_btn = gr.Button(
|
| 688 |
+
"π Get GPS",
|
| 689 |
+
size="sm",
|
| 690 |
+
scale=1,
|
| 691 |
+
variant="secondary"
|
| 692 |
+
)
|
| 693 |
+
|
| 694 |
+
gps_coords = gr.Textbox(
|
| 695 |
+
label="GPS Coordinates",
|
| 696 |
+
placeholder="Latitude, Longitude (auto-filled when you click Get GPS)",
|
| 697 |
+
lines=1,
|
| 698 |
+
interactive=False,
|
| 699 |
+
visible=False
|
| 700 |
+
)
|
| 701 |
+
|
| 702 |
+
# Image upload section
|
| 703 |
with gr.Row():
|
| 704 |
with gr.Column(scale=1):
|
|
|
|
| 705 |
image_input = gr.Image(
|
| 706 |
type="pil",
|
| 707 |
+
label="Upload Photo of Trash",
|
| 708 |
+
sources=["upload", "webcam"],
|
| 709 |
+
height=400
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 710 |
)
|
| 711 |
|
| 712 |
notes_input = gr.Textbox(
|
| 713 |
+
label="π Additional Notes (optional)",
|
| 714 |
+
placeholder="e.g., Near the playground, behind the dumpster, next to parking lot...",
|
| 715 |
lines=2
|
| 716 |
)
|
| 717 |
|
| 718 |
+
with gr.Row():
|
| 719 |
+
save_history = gr.Checkbox(
|
| 720 |
+
label="πΎ Save to history for tracking",
|
| 721 |
+
value=True
|
| 722 |
+
)
|
| 723 |
+
analyze_btn = gr.Button(
|
| 724 |
+
"π Start AI Analysis",
|
| 725 |
+
variant="primary",
|
| 726 |
+
size="lg",
|
| 727 |
+
scale=2
|
| 728 |
+
)
|
| 729 |
|
| 730 |
with gr.Column(scale=1):
|
| 731 |
+
gr.Markdown("### π― Detection Results")
|
| 732 |
output_image = gr.Image(
|
| 733 |
type="pil",
|
| 734 |
+
label="AI-Detected Trash (with bounding boxes)",
|
| 735 |
+
height=400
|
| 736 |
)
|
| 737 |
|
| 738 |
gr.Markdown("---")
|
| 739 |
+
gr.Markdown("### π Step 2: Analysis Results")
|
| 740 |
|
| 741 |
with gr.Row():
|
| 742 |
with gr.Column():
|
| 743 |
+
gr.Markdown("#### π Items Detected")
|
| 744 |
+
detection_output = gr.Markdown()
|
| 745 |
|
| 746 |
with gr.Column():
|
| 747 |
+
gr.Markdown("#### π Cleanup Action Plan")
|
| 748 |
+
plan_output = gr.Markdown()
|
| 749 |
+
|
| 750 |
+
# Environmental Impact Section
|
| 751 |
+
gr.Markdown("---")
|
| 752 |
+
impact_output = gr.Markdown()
|
| 753 |
|
| 754 |
+
gr.Markdown("---")
|
| 755 |
+
gr.Markdown("### π Step 3: Share with Authorities")
|
| 756 |
report_output = gr.Textbox(
|
| 757 |
+
label="π§ Ready-to-Send Email Report",
|
| 758 |
+
placeholder="Your professional report will appear here after analysis...",
|
| 759 |
+
lines=12,
|
| 760 |
+
max_lines=20,
|
| 761 |
+
info="Copy this report and send it to your city's environmental department or cleanup organization."
|
| 762 |
+
)
|
| 763 |
+
|
| 764 |
+
# Social Sharing Section
|
| 765 |
+
gr.Markdown("---")
|
| 766 |
+
gr.Markdown("### π Share Your Impact")
|
| 767 |
+
gr.Markdown("""
|
| 768 |
+
Help spread awareness and inspire others to take action! Share your cleanup efforts on social media.
|
| 769 |
+
""")
|
| 770 |
+
|
| 771 |
+
with gr.Row():
|
| 772 |
+
share_twitter_btn = gr.Button("π¦ Share on Twitter/X", variant="secondary", size="lg")
|
| 773 |
+
share_linkedin_btn = gr.Button("πΌ Share on LinkedIn", variant="secondary", size="lg")
|
| 774 |
+
|
| 775 |
+
gr.HTML("""
|
| 776 |
+
<div id="share-buttons" style="display: none;">
|
| 777 |
+
<a id="twitter-share" target="_blank" style="margin-right: 10px;"></a>
|
| 778 |
+
<a id="linkedin-share" target="_blank"></a>
|
| 779 |
+
</div>
|
| 780 |
+
<script>
|
| 781 |
+
function shareOnTwitter() {
|
| 782 |
+
const text = "π Just used CleanCity Agent AI to detect and plan cleanup for littered areas! Powered by @Gradio and computer vision. Join the movement for cleaner communities! #CleanCity #AI4Good #EnvironmentalAction";
|
| 783 |
+
const url = window.location.href;
|
| 784 |
+
window.open(`https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}`, '_blank');
|
| 785 |
+
}
|
| 786 |
+
function shareOnLinkedIn() {
|
| 787 |
+
const url = window.location.href;
|
| 788 |
+
window.open(`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`, '_blank');
|
| 789 |
+
}
|
| 790 |
+
</script>
|
| 791 |
+
""")
|
| 792 |
+
|
| 793 |
+
# Wire share buttons
|
| 794 |
+
share_twitter_btn.click(
|
| 795 |
+
fn=None,
|
| 796 |
+
inputs=[],
|
| 797 |
+
outputs=[],
|
| 798 |
+
js="() => { shareOnTwitter(); }"
|
| 799 |
+
)
|
| 800 |
+
|
| 801 |
+
share_linkedin_btn.click(
|
| 802 |
+
fn=None,
|
| 803 |
+
inputs=[],
|
| 804 |
+
outputs=[],
|
| 805 |
+
js="() => { shareOnLinkedIn(); }"
|
| 806 |
)
|
| 807 |
|
| 808 |
# Wire up the analyze button
|
| 809 |
analyze_btn.click(
|
| 810 |
fn=analyze_image,
|
| 811 |
inputs=[image_input, location_input, notes_input, save_history, gps_coords],
|
| 812 |
+
outputs=[output_image, detection_output, plan_output, report_output, impact_output]
|
| 813 |
)
|
| 814 |
|
| 815 |
# Wire up GPS button with JavaScript to get browser location
|
|
|
|
| 862 |
# TAB 3: HISTORY
|
| 863 |
# ================================================================
|
| 864 |
with gr.Tab("π Event History"):
|
| 865 |
+
gr.Markdown("""
|
| 866 |
+
### π View Past Trash Detection Events
|
| 867 |
+
|
| 868 |
+
Track all your saved trash detection events to identify patterns and monitor progress over time.
|
| 869 |
+
Use filters to narrow down specific locations, timeframes, or severity levels.
|
| 870 |
+
""")
|
| 871 |
|
| 872 |
with gr.Row():
|
| 873 |
days_filter = gr.Slider(
|
|
|
|
| 875 |
maximum=365,
|
| 876 |
value=30,
|
| 877 |
step=1,
|
| 878 |
+
label="π
Time Range",
|
| 879 |
+
info="Last N days (0 = all time)"
|
| 880 |
)
|
| 881 |
location_filter = gr.Textbox(
|
| 882 |
+
label="π Location Filter",
|
| 883 |
+
placeholder="e.g., Park, Beach, Street...",
|
| 884 |
+
info="Partial match - finds all locations containing this text"
|
| 885 |
)
|
| 886 |
severity_filter = gr.Dropdown(
|
| 887 |
choices=["All", "Low", "Medium", "High"],
|
| 888 |
value="All",
|
| 889 |
+
label="β οΈ Severity Level",
|
| 890 |
+
info="Filter by cleanup urgency"
|
| 891 |
)
|
| 892 |
|
| 893 |
+
load_history_btn = gr.Button("π Load History", variant="primary", size="lg")
|
| 894 |
history_output = gr.Markdown()
|
| 895 |
|
| 896 |
load_history_btn.click(
|
|
|
|
| 900 |
)
|
| 901 |
|
| 902 |
# ================================================================
|
| 903 |
+
# TAB 4: IMPACT & EXAMPLES
|
| 904 |
# ================================================================
|
| 905 |
+
with gr.Tab("π Impact & Examples"):
|
| 906 |
+
gr.Markdown("""
|
| 907 |
+
### πΈ Example Use Cases
|
|
|
|
|
|
|
|
|
|
| 908 |
|
| 909 |
+
See how CleanCity Agent can make a difference in your community!
|
| 910 |
+
""")
|
| 911 |
+
|
| 912 |
+
with gr.Tabs():
|
| 913 |
+
with gr.Tab("ποΈ Beach Cleanup"):
|
| 914 |
+
gr.Markdown("""
|
| 915 |
+
#### Scenario: Beach Littered After Weekend
|
| 916 |
+
|
| 917 |
+
**Problem:** Every Monday morning, the public beach is covered in trash from weekend visitors.
|
| 918 |
+
|
| 919 |
+
**How CleanCity Helps:**
|
| 920 |
+
1. πΈ Take photo on Monday morning
|
| 921 |
+
2. π€ AI detects: 45 plastic bottles, 23 food wrappers, 12 cigarette butts
|
| 922 |
+
3. π Severity: HIGH - requires 4-6 volunteers, 2 hours
|
| 923 |
+
4. π§ Send report to Parks Department with data
|
| 924 |
+
5. β
Result: City adds more trash bins and signage
|
| 925 |
+
|
| 926 |
+
**Real Impact:** 60% reduction in Monday morning trash after 2 months
|
| 927 |
+
""")
|
| 928 |
+
|
| 929 |
+
with gr.Tab("ποΈ Park Maintenance"):
|
| 930 |
+
gr.Markdown("""
|
| 931 |
+
#### Scenario: Playground Area Safety
|
| 932 |
+
|
| 933 |
+
**Problem:** Broken glass and sharp objects near children's playground.
|
| 934 |
+
|
| 935 |
+
**How CleanCity Helps:**
|
| 936 |
+
1. πΈ Document with photos showing bounding boxes around dangerous items
|
| 937 |
+
2. π Generate safety-focused report highlighting urgency
|
| 938 |
+
3. π§ Email to city council with visual evidence
|
| 939 |
+
4. π₯ Organize community cleanup with volunteer count estimate
|
| 940 |
+
5. β
Result: City responds within 48 hours
|
| 941 |
+
|
| 942 |
+
**Real Impact:** Safer playground + faster city response time
|
| 943 |
+
""")
|
| 944 |
+
|
| 945 |
+
with gr.Tab("ποΈ Street Advocacy"):
|
| 946 |
+
gr.Markdown("""
|
| 947 |
+
#### Scenario: Downtown Business District
|
| 948 |
+
|
| 949 |
+
**Problem:** Weekly trash accumulation hurting local businesses.
|
| 950 |
+
|
| 951 |
+
**How CleanCity Helps:**
|
| 952 |
+
1. π
Track events over 4 weeks at same locations
|
| 953 |
+
2. π Build data showing pattern: "Main Street has 8 events in 30 days"
|
| 954 |
+
3. π Show historical trends in Event History tab
|
| 955 |
+
4. π§ Present data to Business Association meeting
|
| 956 |
+
5. β
Result: City increases trash pickup frequency
|
| 957 |
+
|
| 958 |
+
**Real Impact:** Cleaner streets + increased foot traffic + data-driven policy change
|
| 959 |
+
""")
|
| 960 |
+
|
| 961 |
+
with gr.Tab("π‘ Best Practices"):
|
| 962 |
+
gr.Markdown("""
|
| 963 |
+
### π― Tips for Maximum Impact
|
| 964 |
+
|
| 965 |
+
**For Better Photos:**
|
| 966 |
+
- β
Take photos in daylight (9am-4pm best)
|
| 967 |
+
- β
Get close enough to see individual items
|
| 968 |
+
- β
Include landmarks for location context
|
| 969 |
+
- β
Take before AND after cleanup photos
|
| 970 |
+
|
| 971 |
+
**For Better Data:**
|
| 972 |
+
- β
Always add specific location names
|
| 973 |
+
- β
Be consistent with location spelling
|
| 974 |
+
- β
Add notes about context (time of day, events nearby)
|
| 975 |
+
- β
Save to history every time
|
| 976 |
+
|
| 977 |
+
**For Better Advocacy:**
|
| 978 |
+
- β
Collect 3-5 events before contacting authorities
|
| 979 |
+
- β
Use professional email reports
|
| 980 |
+
- β
Include photos with bounding boxes (shows AI verification)
|
| 981 |
+
- β
Suggest specific solutions (more bins, signage, schedules)
|
| 982 |
+
|
| 983 |
+
**For Community Organizing:**
|
| 984 |
+
- β
Share resource estimates with volunteers upfront
|
| 985 |
+
- β
Use cleanup plan for event planning
|
| 986 |
+
- β
Document progress with before/after comparisons
|
| 987 |
+
- β
Celebrate wins on social media with data
|
| 988 |
+
|
| 989 |
+
---
|
| 990 |
+
|
| 991 |
+
### π Sample Report Template
|
| 992 |
+
|
| 993 |
+
**Subject:** Request for Additional Trash Infrastructure - [Location]
|
| 994 |
+
|
| 995 |
+
**Dear [Authority Name],**
|
| 996 |
+
|
| 997 |
+
I am writing to bring attention to a recurring trash problem at [Location].
|
| 998 |
+
Using AI-powered detection tools, I have documented the following:
|
| 999 |
+
|
| 1000 |
+
- **Date of observation:** [Date]
|
| 1001 |
+
- **Items detected:** [X bottles, Y bags, Z wrappers]
|
| 1002 |
+
- **Severity:** [High/Medium/Low]
|
| 1003 |
+
- **Estimated cleanup effort:** [X volunteers, Y hours]
|
| 1004 |
+
|
| 1005 |
+
[Include photo with AI bounding boxes]
|
| 1006 |
+
|
| 1007 |
+
I respectfully request:
|
| 1008 |
+
1. [Specific solution - more bins, regular cleaning, etc.]
|
| 1009 |
+
2. [Timeline expectations]
|
| 1010 |
+
|
| 1011 |
+
I am organizing a community cleanup on [Date] and would appreciate
|
| 1012 |
+
coordination with city services for disposal.
|
| 1013 |
+
|
| 1014 |
+
Thank you for your attention to this matter.
|
| 1015 |
+
|
| 1016 |
+
Sincerely,
|
| 1017 |
+
[Your Name]
|
| 1018 |
+
[Contact Information]
|
| 1019 |
+
""")
|
| 1020 |
|
| 1021 |
+
gr.Markdown("---")
|
| 1022 |
+
gr.Markdown("""
|
| 1023 |
+
### π Training Resources
|
| 1024 |
|
| 1025 |
+
**Want to learn more about community environmental action?**
|
| 1026 |
+
|
| 1027 |
+
- π [EPA Community Cleanup Guide](https://www.epa.gov/communities)
|
| 1028 |
+
- β»οΈ [Ocean Conservancy Cleanup Resources](https://oceanconservancy.org/)
|
| 1029 |
+
- ποΈ [Keep America Beautiful](https://kab.org/)
|
| 1030 |
+
- π₯ [Community Organizing Best Practices](https://www.communitychange.org/)
|
| 1031 |
+
|
| 1032 |
+
*Start small, document everything, and watch your impact grow!*
|
| 1033 |
+
""")
|
| 1034 |
|
| 1035 |
# ================================================================
|
| 1036 |
# TAB 5: CHAT WITH AGENT
|
| 1037 |
# ================================================================
|
| 1038 |
with gr.Tab("π¬ Chat with Agent"):
|
| 1039 |
+
gr.Markdown("""
|
| 1040 |
+
### π€ Ask Questions or Get Help
|
|
|
|
|
|
|
|
|
|
| 1041 |
|
| 1042 |
+
Chat with the CleanCity AI Assistant to get personalized advice and answers about:
|
| 1043 |
+
- π§Ή Cleanup strategies and best practices
|
| 1044 |
+
- π Interpreting your detection results
|
| 1045 |
+
- π Environmental impact and regulations
|
| 1046 |
+
- π₯ Organizing community cleanup events
|
| 1047 |
+
- π§ How to communicate with authorities
|
| 1048 |
+
|
| 1049 |
+
**Example questions:**
|
| 1050 |
+
- "How many volunteers do I need for 50 plastic bottles?"
|
| 1051 |
+
- "What's the best time of day to organize a beach cleanup?"
|
| 1052 |
+
- "How do I convince my city council to add more trash bins?"
|
| 1053 |
+
- "What equipment is essential for a park cleanup?"
|
| 1054 |
+
""")
|
| 1055 |
+
|
| 1056 |
+
chatbot = gr.Chatbot(
|
| 1057 |
+
height=450,
|
| 1058 |
+
placeholder="π Hi! I'm your CleanCity AI Assistant. Ask me anything about trash cleanup and environmental action!"
|
| 1059 |
+
)
|
| 1060 |
msg = gr.Textbox(
|
| 1061 |
label="Your message",
|
| 1062 |
+
placeholder="Type your question here... (e.g., 'How do I organize a cleanup event?')",
|
| 1063 |
+
lines=2
|
| 1064 |
)
|
| 1065 |
|
| 1066 |
with gr.Row():
|
| 1067 |
+
submit = gr.Button("π¬ Send", variant="primary", scale=2)
|
| 1068 |
+
clear = gr.Button("ποΈ Clear Chat", scale=1)
|
| 1069 |
+
|
| 1070 |
+
gr.Markdown("""
|
| 1071 |
+
*π‘ Tip: The more specific your question, the better the advice!*
|
| 1072 |
+
""")
|
| 1073 |
|
| 1074 |
def respond(message, chat_history):
|
| 1075 |
bot_response = chat_with_agent(message, chat_history)
|
trash_model.py
CHANGED
|
@@ -9,6 +9,7 @@ from typing import TypedDict
|
|
| 9 |
from PIL import Image
|
| 10 |
from pathlib import Path
|
| 11 |
import numpy as np
|
|
|
|
| 12 |
|
| 13 |
# Import YOLO from ultralytics
|
| 14 |
try:
|
|
@@ -29,13 +30,17 @@ class Detection(TypedDict):
|
|
| 29 |
# Global model instance (loaded once)
|
| 30 |
_model = None
|
| 31 |
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
-
|
|
|
|
| 34 |
"""
|
| 35 |
Load the YOLOv8 trash detection model.
|
| 36 |
|
| 37 |
Args:
|
| 38 |
-
model_path: Path to the model weights file
|
| 39 |
|
| 40 |
Returns:
|
| 41 |
Loaded YOLO model instance
|
|
@@ -46,11 +51,23 @@ def load_model(model_path: str = "Weights/best.pt") -> YOLO:
|
|
| 46 |
if not YOLO_AVAILABLE:
|
| 47 |
raise ImportError("Ultralytics not installed. Run: pip install ultralytics")
|
| 48 |
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
if not model_file.exists():
|
| 51 |
-
raise FileNotFoundError(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
-
print(f"π Loading YOLO model from {
|
| 54 |
_model = YOLO(str(model_file))
|
| 55 |
print(f"β
Model loaded successfully!")
|
| 56 |
print(f" Classes: {_model.names}")
|
|
|
|
| 9 |
from PIL import Image
|
| 10 |
from pathlib import Path
|
| 11 |
import numpy as np
|
| 12 |
+
import os
|
| 13 |
|
| 14 |
# Import YOLO from ultralytics
|
| 15 |
try:
|
|
|
|
| 30 |
# Global model instance (loaded once)
|
| 31 |
_model = None
|
| 32 |
|
| 33 |
+
# Get the directory where this script is located
|
| 34 |
+
SCRIPT_DIR = Path(__file__).parent.resolve()
|
| 35 |
+
DEFAULT_MODEL_PATH = SCRIPT_DIR / "Weights" / "best.pt"
|
| 36 |
|
| 37 |
+
|
| 38 |
+
def load_model(model_path: str = None) -> YOLO:
|
| 39 |
"""
|
| 40 |
Load the YOLOv8 trash detection model.
|
| 41 |
|
| 42 |
Args:
|
| 43 |
+
model_path: Path to the model weights file (if None, uses default)
|
| 44 |
|
| 45 |
Returns:
|
| 46 |
Loaded YOLO model instance
|
|
|
|
| 51 |
if not YOLO_AVAILABLE:
|
| 52 |
raise ImportError("Ultralytics not installed. Run: pip install ultralytics")
|
| 53 |
|
| 54 |
+
# Use default path if none provided
|
| 55 |
+
if model_path is None:
|
| 56 |
+
model_file = DEFAULT_MODEL_PATH
|
| 57 |
+
else:
|
| 58 |
+
model_file = Path(model_path)
|
| 59 |
+
# If relative path provided, make it relative to script directory
|
| 60 |
+
if not model_file.is_absolute():
|
| 61 |
+
model_file = SCRIPT_DIR / model_file
|
| 62 |
+
|
| 63 |
if not model_file.exists():
|
| 64 |
+
raise FileNotFoundError(
|
| 65 |
+
f"Model file not found: {model_file}\n"
|
| 66 |
+
f"Expected location: {DEFAULT_MODEL_PATH}\n"
|
| 67 |
+
f"Current directory: {os.getcwd()}"
|
| 68 |
+
)
|
| 69 |
|
| 70 |
+
print(f"π Loading YOLO model from {model_file}...")
|
| 71 |
_model = YOLO(str(model_file))
|
| 72 |
print(f"β
Model loaded successfully!")
|
| 73 |
print(f" Classes: {_model.names}")
|