Abs6187 commited on
Commit
0ceebcd
·
verified ·
1 Parent(s): 7565b34

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -127
app.py CHANGED
@@ -23,137 +23,76 @@ model = YOLO("best.pt")
23
  class_names = {0: 'With Helmet', 1: 'Without Helmet', 2: 'License Plate'}
24
 
25
  def crop_license_plates(image, detections):
 
26
  cropped_plates = []
27
 
28
- try:
29
- if isinstance(image, str):
30
- if not os.path.exists(image):
31
- print(f"Error: Image file not found: {image}")
32
- return cropped_plates
33
- image = Image.open(image)
34
- elif isinstance(image, np.ndarray):
35
- image = Image.fromarray(image)
36
- elif not isinstance(image, Image.Image):
37
- print(f"Error: Unsupported image type: {type(image)}")
38
- return cropped_plates
39
-
40
- if image.size[0] == 0 or image.size[1] == 0:
41
- print("Error: Image has zero dimensions")
42
- return cropped_plates
43
-
44
- except Exception as e:
45
- print(f"Error loading image: {e}")
46
- return cropped_plates
47
 
48
- for i, detection in enumerate(detections):
49
- try:
50
- if detection['Object'] != 'License Plate':
51
- continue
52
-
53
- pos_str = detection['Position'].strip('()')
54
- if ',' not in pos_str:
55
- print(f"Error: Invalid position format for detection {i}: {detection['Position']}")
56
- continue
57
-
58
- x1, y1 = map(int, pos_str.split(', '))
59
-
60
- dims_str = detection['Dimensions']
61
- if 'x' not in dims_str:
62
- print(f"Error: Invalid dimensions format for detection {i}: {detection['Dimensions']}")
63
- continue
64
-
65
- width, height = map(int, dims_str.split('x'))
66
-
67
- if width <= 0 or height <= 0:
68
- print(f"Error: Invalid dimensions for detection {i}: {width}x{height}")
69
- continue
70
 
 
 
 
71
  x2, y2 = x1 + width, y1 + height
72
 
73
- if x1 < 0 or y1 < 0 or x2 > image.width or y2 > image.height:
74
- print(f"Warning: Bounding box extends beyond image boundaries for detection {i}")
75
- x1 = max(0, x1)
76
- y1 = max(0, y1)
77
- x2 = min(image.width, x2)
78
- y2 = min(image.height, y2)
79
-
80
- if x2 <= x1 or y2 <= y1:
81
- print(f"Error: Invalid crop coordinates for detection {i}: ({x1},{y1}) to ({x2},{y2})")
82
- continue
83
 
 
84
  cropped_plate = image.crop((x1, y1, x2, y2))
85
-
86
- if cropped_plate.size[0] == 0 or cropped_plate.size[1] == 0:
87
- print(f"Error: Cropped image has zero dimensions for detection {i}")
88
- continue
89
-
90
  cropped_plates.append({
91
  'image': cropped_plate,
92
  'confidence': detection['Confidence'],
93
- 'position': detection['Position'],
94
- 'crop_coords': f"({x1},{y1}) to ({x2},{y2})"
95
  })
96
-
97
- except ValueError as e:
98
- print(f"Error parsing coordinates for detection {i}: {e}")
99
- continue
100
- except Exception as e:
101
- print(f"Error cropping license plate {i}: {e}")
102
- continue
103
 
104
  return cropped_plates
105
 
106
  def create_download_files(annotated_image, cropped_plates, detections):
107
- try:
108
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
109
-
110
- os.makedirs("temp", exist_ok=True)
111
-
112
- annotated_path = f"temp/annotated_image_{timestamp}.jpg"
113
- try:
114
- annotated_image.save(annotated_path, quality=95)
115
- except Exception as e:
116
- print(f"Error saving annotated image: {e}")
117
- return None, None, []
118
-
119
- plate_paths = []
120
- for i, plate_data in enumerate(cropped_plates):
121
- try:
122
- plate_path = f"temp/license_plate_{i+1}_{timestamp}.jpg"
123
- plate_data['image'].save(plate_path, quality=95)
124
- plate_paths.append(plate_path)
125
- except Exception as e:
126
- print(f"Error saving license plate {i+1}: {e}")
127
- continue
128
-
129
- report_path = f"temp/detection_report_{timestamp}.csv"
130
- if detections:
131
- try:
132
- df = pd.DataFrame(detections)
133
- df.to_csv(report_path, index=False)
134
- except Exception as e:
135
- print(f"Error creating detection report: {e}")
136
- report_path = None
137
-
138
- zip_path = f"temp/detection_results_{timestamp}.zip"
139
- try:
140
- with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
141
- if os.path.exists(annotated_path):
142
- zipf.write(annotated_path, f"annotated_image_{timestamp}.jpg")
143
- for plate_path in plate_paths:
144
- if os.path.exists(plate_path):
145
- zipf.write(plate_path, os.path.basename(plate_path))
146
- if report_path and os.path.exists(report_path):
147
- zipf.write(report_path, f"detection_report_{timestamp}.csv")
148
- except Exception as e:
149
- print(f"Error creating ZIP file: {e}")
150
- return None, annotated_path, plate_paths
151
-
152
- return zip_path, annotated_path, plate_paths
153
-
154
- except Exception as e:
155
- print(f"Error in create_download_files: {e}")
156
- return None, None, []
157
 
158
  def yoloV8_func(
159
  image=None,
@@ -209,19 +148,16 @@ def yoloV8_func(
209
  download_files = None
210
 
211
  if crop_plates and detections:
212
- try:
213
- cropped_plates = crop_license_plates(image, detections)
214
- license_plate_gallery = [plate_data['image'] for plate_data in cropped_plates]
215
-
216
- if cropped_plates or detections:
 
217
  download_files, _, _ = create_download_files(annotated_image, cropped_plates, detections)
218
- if download_files is None:
219
- print("Warning: Could not create download files")
220
- except Exception as e:
221
- print(f"Error in license plate processing: {e}")
222
- cropped_plates = []
223
- license_plate_gallery = []
224
- download_files = None
225
 
226
  # Create stats text
227
  stats_text = ""
@@ -232,6 +168,7 @@ def yoloV8_func(
232
  for obj, count in counts.items():
233
  stats_text += f"- {obj}: {count}\n"
234
 
 
235
  if cropped_plates:
236
  stats_text += f"\nLicense Plates Cropped: {len(cropped_plates)}\n"
237
 
@@ -243,13 +180,16 @@ def yoloV8_func(
243
  except:
244
  font = ImageFont.load_default()
245
 
 
246
  text_bbox = draw.textbbox((0, 0), stats_text, font=font)
247
  text_width = text_bbox[2] - text_bbox[0]
248
  text_height = text_bbox[3] - text_bbox[1]
249
  draw.rectangle([10, 10, 20 + text_width, 20 + text_height], fill=(0, 0, 0, 128))
250
 
 
251
  draw.text((15, 15), stats_text, font=font, fill=(255, 255, 255))
252
 
 
253
  detection_table = pd.DataFrame(detections) if detections else pd.DataFrame(columns=["Object", "Confidence", "Position", "Dimensions"])
254
 
255
  return annotated_image, detection_table, stats_text, license_plate_gallery, download_files
 
23
  class_names = {0: 'With Helmet', 1: 'Without Helmet', 2: 'License Plate'}
24
 
25
  def crop_license_plates(image, detections):
26
+ """Crop license plates from the image based on detections"""
27
  cropped_plates = []
28
 
29
+ if isinstance(image, str): # If image is a file path
30
+ image = Image.open(image)
31
+ elif isinstance(image, np.ndarray): # If image is numpy array
32
+ image = Image.fromarray(image)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ for detection in detections:
35
+ if detection['Object'] == 'License Plate':
36
+ # Parse coordinates from position string
37
+ pos = detection['Position'].strip('()')
38
+ x1, y1 = map(int, pos.split(', '))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ # Parse dimensions
41
+ dims = detection['Dimensions']
42
+ width, height = map(int, dims.split('x'))
43
  x2, y2 = x1 + width, y1 + height
44
 
45
+ # Add some padding around the license plate
46
+ padding = 10
47
+ x1 = max(0, x1 - padding)
48
+ y1 = max(0, y1 - padding)
49
+ x2 = min(image.width, x2 + padding)
50
+ y2 = min(image.height, y2 + padding)
 
 
 
 
51
 
52
+ # Crop the license plate
53
  cropped_plate = image.crop((x1, y1, x2, y2))
 
 
 
 
 
54
  cropped_plates.append({
55
  'image': cropped_plate,
56
  'confidence': detection['Confidence'],
57
+ 'position': detection['Position']
 
58
  })
 
 
 
 
 
 
 
59
 
60
  return cropped_plates
61
 
62
  def create_download_files(annotated_image, cropped_plates, detections):
63
+ """Create downloadable files including annotated image and cropped plates"""
64
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
65
+
66
+ # Create a temporary directory for files
67
+ os.makedirs("temp_downloads", exist_ok=True)
68
+
69
+ # Save annotated image
70
+ annotated_path = f"temp_downloads/annotated_image_{timestamp}.jpg"
71
+ annotated_image.save(annotated_path)
72
+
73
+ # Save cropped license plates
74
+ plate_paths = []
75
+ for i, plate_data in enumerate(cropped_plates):
76
+ plate_path = f"temp_downloads/license_plate_{i+1}_{timestamp}.jpg"
77
+ plate_data['image'].save(plate_path)
78
+ plate_paths.append(plate_path)
79
+
80
+ # Create detection report
81
+ report_path = f"temp_downloads/detection_report_{timestamp}.csv"
82
+ if detections:
83
+ df = pd.DataFrame(detections)
84
+ df.to_csv(report_path, index=False)
85
+
86
+ # Create zip file with all results
87
+ zip_path = f"temp_downloads/detection_results_{timestamp}.zip"
88
+ with zipfile.ZipFile(zip_path, 'w') as zipf:
89
+ zipf.write(annotated_path, f"annotated_image_{timestamp}.jpg")
90
+ for plate_path in plate_paths:
91
+ zipf.write(plate_path, os.path.basename(plate_path))
92
+ if os.path.exists(report_path):
93
+ zipf.write(report_path, f"detection_report_{timestamp}.csv")
94
+
95
+ return zip_path, annotated_path, plate_paths
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  def yoloV8_func(
98
  image=None,
 
148
  download_files = None
149
 
150
  if crop_plates and detections:
151
+ cropped_plates = crop_license_plates(image, detections)
152
+ license_plate_gallery = [plate_data['image'] for plate_data in cropped_plates]
153
+
154
+ # Create download files
155
+ if cropped_plates or detections:
156
+ try:
157
  download_files, _, _ = create_download_files(annotated_image, cropped_plates, detections)
158
+ except Exception as e:
159
+ print(f"Error creating download files: {e}")
160
+ download_files = None
 
 
 
 
161
 
162
  # Create stats text
163
  stats_text = ""
 
168
  for obj, count in counts.items():
169
  stats_text += f"- {obj}: {count}\n"
170
 
171
+ # Add license plate info
172
  if cropped_plates:
173
  stats_text += f"\nLicense Plates Cropped: {len(cropped_plates)}\n"
174
 
 
180
  except:
181
  font = ImageFont.load_default()
182
 
183
+ # Add semi-transparent background for text
184
  text_bbox = draw.textbbox((0, 0), stats_text, font=font)
185
  text_width = text_bbox[2] - text_bbox[0]
186
  text_height = text_bbox[3] - text_bbox[1]
187
  draw.rectangle([10, 10, 20 + text_width, 20 + text_height], fill=(0, 0, 0, 128))
188
 
189
+ # Add text
190
  draw.text((15, 15), stats_text, font=font, fill=(255, 255, 255))
191
 
192
+ # Create a detection table for display
193
  detection_table = pd.DataFrame(detections) if detections else pd.DataFrame(columns=["Object", "Confidence", "Position", "Dimensions"])
194
 
195
  return annotated_image, detection_table, stats_text, license_plate_gallery, download_files