Hiridharan10 commited on
Commit
81dd782
·
verified ·
1 Parent(s): 93c3cb3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +149 -66
app.py CHANGED
@@ -1,4 +1,9 @@
1
- # Smart Parking System - Gradio UI for Hugging Face Spaces
 
 
 
 
 
2
 
3
  import torch
4
  import numpy as np
@@ -12,93 +17,171 @@ import gradio as gr
12
  import warnings
13
  warnings.filterwarnings('ignore')
14
 
 
15
  class StateOfTheArtParkingDetector:
16
  def __init__(self, total_spaces=50):
17
  self.total_spaces = total_spaces
18
  self.device = "cuda" if torch.cuda.is_available() else "cpu"
19
 
20
- print(f"🚀 Loading State-of-the-Art Models... Device: {self.device}")
21
-
22
- # Load Florence-2
 
23
  try:
24
- self.processor = AutoProcessor.from_pretrained(
25
- "microsoft/Florence-2-large",
26
- trust_remote_code=True
27
- )
28
  self.model = AutoModelForCausalLM.from_pretrained(
29
- "microsoft/Florence-2-large",
30
  torch_dtype=torch.float16 if self.device=="cuda" else torch.float32,
31
  trust_remote_code=True
32
  ).to(self.device)
33
  self.florence_available = True
 
34
  except:
35
- try:
36
- self.processor = AutoProcessor.from_pretrained(
37
- "microsoft/Florence-2-base",
38
- trust_remote_code=True
39
- )
40
- self.model = AutoModelForCausalLM.from_pretrained(
41
- "microsoft/Florence-2-base",
42
- torch_dtype=torch.float16 if self.device=="cuda" else torch.float32,
43
- trust_remote_code=True
44
- ).to(self.device)
45
- self.florence_available = True
46
- except:
47
- self.florence_available = False
48
-
49
- # Load YOLO-World
50
  try:
51
  from ultralytics import YOLO
52
  self.yolo_world = YOLO('yolov8x-worldv2.pt')
53
  self.yolo_world_available = True
54
- except:
 
 
55
  self.yolo_world_available = False
56
 
57
- # Detection methods remain the same as your original code
58
- # detect_with_florence, detect_with_yolo_world, advanced_cv_detection,
59
- # merge_all_detections, calculate_iou, create_annotated_image, process_image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
- # Initialize detector
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  detector = StateOfTheArtParkingDetector()
63
 
64
- # Gradio Interface
65
- with gr.Blocks(
66
- theme=gr.themes.Soft(primary_hue="purple", secondary_hue="blue"),
67
- css="""
68
- .gradio-container { font-family: 'Segoe UI', Arial, sans-serif; }
69
- .main-header { text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
70
- color: white; padding: 30px; border-radius: 10px; margin-bottom: 20px; }
71
- """
72
- ) as demo:
73
-
74
- gr.HTML("""
75
- <div class="main-header">
76
- <h1 style="margin:0; font-size:42px;">🅿️ Smart Parking Management System</h1>
77
- <p style="margin:10px 0 0 0; font-size:18px; opacity:0.9;">Powered by AI Vision Transformers • Real-time Detection</p>
78
- </div>
79
- """)
80
-
81
- with gr.Row():
82
- with gr.Column(scale=1):
83
- gr.Markdown("### 📤 Upload Parking Lot Image")
84
- input_image = gr.Image(label="Parking Lot Image", type="pil", height=400)
85
-
86
- total_spaces_slider = gr.Slider(minimum=10, maximum=200, value=50, step=5,
87
- label="🅿️ Total Parking Spaces",
88
- info="Set the total capacity of your parking lot")
89
-
90
- analyze_btn = gr.Button("🔍 Analyze Parking Lot", variant="primary", size="lg")
91
-
92
- with gr.Column(scale=1):
93
- gr.Markdown("### 🎯 Detection Results")
94
- output_image = gr.Image(label="Detected Vehicles", type="pil", height=400)
95
- status_html = gr.HTML(label="Parking Status")
96
-
97
  with gr.Row():
98
  with gr.Column():
99
- stats_output = gr.Textbox(label="📊 Detailed Statistics", lines=15, max_lines=20)
100
-
101
- analyze_btn.click(fn=detector.process_image, inputs=[input_image, total_spaces_slider],
102
- outputs=[output_image, status_html, stats_output])
 
 
 
 
103
 
104
  demo.launch()
 
1
+ # Smart Parking System - Hugging Face Spaces Version
2
+ # Run this in Hugging Face Spaces
3
+
4
+ !pip install -q torch torchvision transformers pillow matplotlib numpy opencv-python-headless timm einops gradio
5
+ !pip install -q git+https://github.com/facebookresearch/segment-anything-2.git
6
+ !pip install -q ultralytics supervision
7
 
8
  import torch
9
  import numpy as np
 
17
  import warnings
18
  warnings.filterwarnings('ignore')
19
 
20
+
21
  class StateOfTheArtParkingDetector:
22
  def __init__(self, total_spaces=50):
23
  self.total_spaces = total_spaces
24
  self.device = "cuda" if torch.cuda.is_available() else "cpu"
25
 
26
+ print(f"🚀 Loading Models... Device: {self.device}")
27
+
28
+ # Try Florence-2 (optional, can skip if CPU)
29
+ self.florence_available = False
30
  try:
31
+ self.processor = AutoProcessor.from_pretrained("microsoft/Florence-2-base", trust_remote_code=True)
 
 
 
32
  self.model = AutoModelForCausalLM.from_pretrained(
33
+ "microsoft/Florence-2-base",
34
  torch_dtype=torch.float16 if self.device=="cuda" else torch.float32,
35
  trust_remote_code=True
36
  ).to(self.device)
37
  self.florence_available = True
38
+ print("✅ Florence-2 loaded")
39
  except:
40
+ print("⚠️ Florence-2 unavailable, skipping")
41
+
42
+ # YOLO-World
 
 
 
 
 
 
 
 
 
 
 
 
43
  try:
44
  from ultralytics import YOLO
45
  self.yolo_world = YOLO('yolov8x-worldv2.pt')
46
  self.yolo_world_available = True
47
+ print("✅ YOLO-World loaded")
48
+ except Exception as e:
49
+ print(f"⚠️ YOLO-World unavailable: {e}")
50
  self.yolo_world_available = False
51
 
52
+ # Florence detection
53
+ def detect_with_florence(self, image):
54
+ if not self.florence_available:
55
+ return []
56
+ # Minimal placeholder to avoid crash
57
+ return []
58
+
59
+ # YOLO-World detection
60
+ def detect_with_yolo_world(self, image):
61
+ if not self.yolo_world_available:
62
+ return []
63
+ self.yolo_world.set_classes([
64
+ "car", "vehicle", "automobile", "truck", "van",
65
+ "SUV", "sedan", "parked car", "parking space with car"
66
+ ])
67
+ img_array = np.array(image)
68
+ results = self.yolo_world(img_array, conf=0.15, iou=0.3, verbose=False)
69
+ detections = []
70
+ for result in results:
71
+ boxes = result.boxes
72
+ for box in boxes:
73
+ x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
74
+ conf = float(box.conf[0])
75
+ detections.append({'box':[int(x1), int(y1), int(x2), int(y2)],
76
+ 'label':'car', 'score':conf, 'method':'yolo-world'})
77
+ return detections
78
+
79
+ # Simple CV detection fallback
80
+ def advanced_cv_detection(self, image):
81
+ img_array = np.array(image)
82
+ gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
83
+ edges = cv2.Canny(gray, 30, 100)
84
+ kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))
85
+ closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel, iterations=2)
86
+ contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
87
+ h, w = gray.shape
88
+ min_area, max_area = (h*w)//600, (h*w)//20
89
+ detections = []
90
+ for contour in contours:
91
+ area = cv2.contourArea(contour)
92
+ if min_area < area < max_area:
93
+ x, y, cw, ch = cv2.boundingRect(contour)
94
+ aspect_ratio = cw/ch if ch>0 else 0
95
+ if 0.4<aspect_ratio<3.5:
96
+ hull = cv2.convexHull(contour)
97
+ hull_area = cv2.contourArea(hull)
98
+ solidity = area/hull_area if hull_area>0 else 0
99
+ if solidity > 0.4:
100
+ detections.append({'box':[x, y, x+cw, y+ch], 'label':'car', 'score':0.7, 'method':'cv'})
101
+ return detections
102
 
103
+ # Merge detections (NMS)
104
+ def merge_all_detections(self, all_detections):
105
+ if len(all_detections)==0: return []
106
+ normalized = []
107
+ for det in all_detections:
108
+ x1, y1, x2, y2 = det['box']
109
+ normalized.append({'box':[x1,y1,x2,y2], 'score':det['score'], 'method':det.get('method','unknown')})
110
+ normalized.sort(key=lambda x: x['score'], reverse=True)
111
+ keep=[]
112
+ while normalized:
113
+ best = normalized.pop(0)
114
+ keep.append(best)
115
+ normalized = [d for d in normalized if self.calculate_iou(best['box'], d['box'])<0.5]
116
+ return keep
117
+
118
+ def calculate_iou(self, box1, box2):
119
+ x1_1, y1_1, x2_1, y2_1 = box1
120
+ x1_2, y1_2, x2_2, y2_2 = box2
121
+ x1_i, y1_i = max(x1_1,x1_2), max(y1_1,y1_2)
122
+ x2_i, y2_i = min(x2_1,x2_2), min(y2_1,y2_2)
123
+ if x2_i<x1_i or y2_i<y1_i: return 0.0
124
+ inter = (x2_i-x1_i)*(y2_i-y1_i)
125
+ area1 = (x2_1-x1_1)*(y2_1-y1_1)
126
+ area2 = (x2_2-x1_2)*(y2_2-y1_2)
127
+ union = area1+area2-inter
128
+ return inter/union if union>0 else 0
129
+
130
+ def create_annotated_image(self, image, detections):
131
+ img_array = np.array(image)
132
+ fig, ax = plt.subplots(1, figsize=(12,8))
133
+ ax.imshow(img_array)
134
+ for i, det in enumerate(detections, 1):
135
+ x1, y1, x2, y2 = det['box']
136
+ rect = patches.Rectangle((x1,y1,x2-x1,y2-y1), linewidth=3, edgecolor='#00ff00', facecolor='none')
137
+ ax.add_patch(rect)
138
+ ax.text(x1+(x2-x1)/2, y1+(y2-y1)/2, f"{i}",
139
+ bbox=dict(facecolor='#00ff00', alpha=0.9, boxstyle='circle,pad=0.3'),
140
+ fontsize=12, color='black', weight='bold', ha='center', va='center')
141
+ ax.axis('off')
142
+ plt.tight_layout()
143
+ fig.canvas.draw()
144
+ img_plot = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
145
+ img_plot = img_plot.reshape(fig.canvas.get_width_height()[::-1]+(3,))
146
+ plt.close(fig)
147
+ return Image.fromarray(img_plot)
148
+
149
+ # --- Main function for Gradio ---
150
+ def process_image(self, image, total_spaces):
151
+ if image is None: return None, "Upload an image", ""
152
+ self.total_spaces = total_spaces
153
+ if isinstance(image, np.ndarray): image = Image.fromarray(image)
154
+ all_dets=[]
155
+ all_dets.extend(self.detect_with_florence(image))
156
+ all_dets.extend(self.detect_with_yolo_world(image))
157
+ all_dets.extend(self.advanced_cv_detection(image))
158
+ final_dets = self.merge_all_detections(all_dets)
159
+ count = len(final_dets)
160
+ annotated_img = self.create_annotated_image(image, final_dets)
161
+ occupancy_rate = min((count/total_spaces)*100, 100)
162
+ available = max(total_spaces-count,0)
163
+ status = "🟢 AVAILABLE" if occupancy_rate<50 else "🟡 BUSY" if occupancy_rate<70 else "🟠 CRITICAL" if occupancy_rate<90 else "🔴 FULL"
164
+ pred_time = (datetime.now()+timedelta(hours=available/5)).strftime('%I:%M %p')
165
+ status_html = f"<h2 style='color:green'>{status}</h2>"
166
+ stats_text = f"Total Vehicles: {count}\nAvailable: {available}\nOccupancy: {occupancy_rate:.1f}%"
167
+ return annotated_img, status_html, stats_text
168
+
169
+
170
+ # --- Initialize Detector ---
171
  detector = StateOfTheArtParkingDetector()
172
 
173
+ # --- Gradio Interface ---
174
+ with gr.Blocks() as demo:
175
+ gr.Markdown("## 🅿️ Smart Parking Management System")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  with gr.Row():
177
  with gr.Column():
178
+ input_image = gr.Image(label="Parking Lot Image", type="pil")
179
+ total_spaces_slider = gr.Slider(10, 200, value=50, step=5, label="Total Spaces")
180
+ analyze_btn = gr.Button("Analyze Parking Lot")
181
+ with gr.Column():
182
+ output_image = gr.Image(label="Detected Vehicles", type="pil")
183
+ status_html = gr.HTML(label="Parking Status")
184
+ stats_output = gr.Textbox(label="Detailed Stats", lines=10)
185
+ analyze_btn.click(fn=detector.process_image, inputs=[input_image,total_spaces_slider], outputs=[output_image,status_html,stats_output])
186
 
187
  demo.launch()