-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode.py
More file actions
261 lines (209 loc) · 8.1 KB
/
Copy pathcode.py
File metadata and controls
261 lines (209 loc) · 8.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# -*- coding: utf-8 -*-
"""
Garbage Classification System
A desktop application for household waste classification using image recognition
"""
import tkinter as tk
import tkinter.filedialog
from PIL import Image, ImageTk
import oss2
from alibabacloud_imagerecog20190930.client import Client as imagerecog20190930Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_imagerecog20190930 import models as imagerecog_20190930_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_util.client import Client as UtilClient
import csv
import os
# Import configuration
try:
from config import ACCESS_KEY_ID, ACCESS_KEY_SECRET, OSS_ENDPOINT, OSS_BUCKET
except ImportError:
print("Error: config.py not found!")
print("Please copy config.py.example to config.py and fill in your credentials")
exit(1)
# Window dimensions
WINDOW_WIDTH = 500
WINDOW_HEIGHT = 600
APP_WIDTH = 400
APP_HEIGHT = 400
def show_welcome_screen():
"""Display welcome screen for 5 seconds"""
app = tk.Tk()
screenwidth = app.winfo_screenwidth()
screenheight = app.winfo_screenheight()
size = '%dx%d+%d+%d' % (WINDOW_WIDTH, WINDOW_HEIGHT,
(screenwidth - WINDOW_WIDTH) / 2,
(screenheight - WINDOW_HEIGHT) / 2)
app.geometry(size)
# Load welcome image
try:
img = Image.open('./home.png')
app.overrideredirect(True)
photo = ImageTk.PhotoImage(img.resize((WINDOW_WIDTH, WINDOW_HEIGHT)))
image_label = tk.Label(app, image=photo)
image_label.pack()
except FileNotFoundError:
print("Warning: home.png not found")
welcome_title = 'Welcome to the Garbage Classification Program'
welcome_description = '''
This program is an auxiliary tool for household garbage classification,
helping people to properly sort their waste. Users can upload a photo
of garbage, and the program will identify and classify it automatically.
There are four types of garbage:
- Dry Garbage
- Household Food Waste
- Recyclable Garbage
- Hazardous Garbage
'''
label_description = tk.Label(app, anchor='w', justify='left', text=welcome_description)
label_description.place(x=0, y=450)
label_title = tk.Label(app, anchor='w', justify='center', text=welcome_title,
font=('Fixdsys', 15, 'bold'))
label_title.place(x=0, y=440)
# Auto-close after 5 seconds
app.after(5000, app.destroy)
app.mainloop()
# Show welcome screen
show_welcome_screen()
# Load cache data
CACHE_FILE = 'data.csv'
cache_data = []
if os.path.exists(CACHE_FILE):
try:
with open(CACHE_FILE, 'r', encoding='utf-8') as csv_file:
reader = csv.reader(csv_file)
for item in reader:
cache_data.append(item)
except Exception as e:
print(f"Error loading cache: {e}")
class GarbageClassifier:
"""Handle Alibaba Cloud image recognition API calls"""
@staticmethod
def create_client(access_key_id: str, access_key_secret: str) -> imagerecog20190930Client:
"""Create and configure the image recognition client"""
config = open_api_models.Config(
access_key_id=access_key_id,
access_key_secret=access_key_secret
)
config.endpoint = 'imagerecog.cn-shanghai.aliyuncs.com'
return imagerecog20190930Client(config)
@staticmethod
def classify_image(image_url: str):
"""
Classify garbage image using Alibaba Cloud API
Args:
image_url: URL of the image to classify
Returns:
API response with classification result
"""
client = GarbageClassifier.create_client(ACCESS_KEY_ID, ACCESS_KEY_SECRET)
request = imagerecog_20190930_models.ClassifyingRubbishRequest(
image_url=image_url
)
runtime = util_models.RuntimeOptions()
try:
response = client.classifying_rubbish_with_options(request, runtime)
return response
except Exception as error:
print(f"Classification error: {error}")
return None
def select_picture():
"""Open file dialog to select an image"""
file_path = tk.filedialog.askopenfilename(
title="Select a garbage image",
filetypes=[("Image files", "*.png *.jpg *.jpeg *.gif *.bmp"), ("All files", "*.*")]
)
if not file_path:
return
path_var.set(file_path)
try:
img_open = Image.open(entry_path.get())
img = ImageTk.PhotoImage(img_open.resize((200, 200)))
label_image.config(image=img)
label_image.image = img
except Exception as e:
print(f"Error loading image: {e}")
def classify_garbage():
"""Classify the selected garbage image"""
image_path = entry_path.get()
if not image_path:
label_result["text"] = 'Please select an image first'
return
# Check cache first
for item in cache_data:
if item[0] == image_path:
label_result["text"] = item[1]
return
# Upload to OSS and classify
try:
auth = oss2.Auth(ACCESS_KEY_ID, ACCESS_KEY_SECRET)
bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET)
upload_name = "test.png"
with open(image_path, 'rb') as fileobj:
bucket.put_object(upload_name, fileobj)
image_url = f'https://{OSS_BUCKET}.{OSS_ENDPOINT}/{upload_name}'
# Call classification API
response = GarbageClassifier.classify_image(image_url)
if response and response.body.data.elements:
category = response.body.data.elements[0].category
if not category:
label_result["text"] = 'Unknown'
return
# Translate Chinese categories to English
# API returns: recyclable, dry, wet, hazardous (in Chinese)
category_mapping = {
"\u53ef\u56de\u6536\u5783\u573e": "Recyclable Garbage", # Recyclable
"\u5e72\u5783\u573e": "Dry Garbage", # Dry
"\u6e7f\u5783\u573e": "Household Food Waste", # Wet
"\u6709\u5bb3\u5783\u573e": "Hazardous Garbage" # Hazardous
}
english_category = category_mapping.get(category, "Unknown")
label_result["text"] = english_category
# Save to cache
cache_data.append([image_path, english_category])
with open(CACHE_FILE, 'w', newline='', encoding='utf-8') as csv_file:
writer = csv.writer(csv_file)
for row in cache_data:
writer.writerow(row)
else:
label_result["text"] = 'Unknown'
except Exception as e:
print(f"Classification error: {e}")
label_result["text"] = 'Identification failed, please try again'
# Create main application window
root = tk.Tk()
root.title('Garbage Classification System')
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
size = '%dx%d+%d+%d' % (APP_WIDTH, APP_HEIGHT,
(screenwidth - WINDOW_WIDTH) / 2,
(screenheight - WINDOW_HEIGHT) / 2)
root.geometry(size)
# Path variable and entry
path_var = tk.StringVar()
entry_path = tk.Entry(root, state='readonly', textvariable=path_var, width=100)
entry_path.pack()
# Image display label
label_image = tk.Label(root)
label_image.pack()
# Load default placeholder image
try:
img_open = Image.open('./add.png')
img = ImageTk.PhotoImage(img_open.resize((200, 200)))
label_image.config(image=img)
label_image.image = img
except FileNotFoundError:
print("Warning: add.png not found")
# Select picture button
button_select = tk.Button(root, text='Select Picture', command=select_picture)
button_select.place(x=100, y=250)
# Classification button
button_classify = tk.Button(root, text='Classification', command=classify_garbage)
button_classify.place(x=200, y=250)
# Result labels
label_category_title = tk.Label(root, text='Category:')
label_category_title.place(x=50, y=320)
label_result = tk.Label(root, text='Unknown')
label_result.place(x=120, y=320)
# Start the main loop
root.mainloop()