-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathserver.py
More file actions
113 lines (89 loc) · 3.73 KB
/
server.py
File metadata and controls
113 lines (89 loc) · 3.73 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
import cv2
import pickle
import cvzone
import numpy as np
from probability import calculate_probability, load_database, save_database
# Load saved parking positions (custom rectangles)
with open('CarParkPos', 'rb') as f:
posList = pickle.load(f) # [(cam_id, x1, y1, x2, y2, color), ...]
# Open multiple cameras
cameras = {
0: cv2.VideoCapture(0),
5: cv2.VideoCapture(5)
}
# Different thresholds for each camera
thresholds = {
0: 300, # Camera 0 threshold
5: 250 # Camera 5 threshold (example)
}
def checkParkingSpace(imgPro, img, cam_id, threshold):
free_spaces = 0
occupied_spaces = 0
for idx, pos in enumerate(posList):
try:
p_cam, x1, y1, x2, y2, color = pos
if p_cam != cam_id:
continue
imgCrop = imgPro[y1:y2, x1:x2]
count = cv2.countNonZero(imgCrop)
if count < threshold:
rect_color = (0, 255, 0)
free_spaces += 1
else:
rect_color = (0, 0, 255)
occupied_spaces += 1
cv2.rectangle(img, (x1, y1), (x2, y2), rect_color, 2)
label = f"ID-{idx + 1}"
cvzone.putTextRect(img, label, (x1 + 5, y2 + 15), scale=0.5,
thickness=1, offset=3, colorR=rect_color)
except Exception as e:
print(f"Error processing parking space {pos}: {e}")
return free_spaces, occupied_spaces
# Load database
data = load_database()
total_spaces = len(posList)
while True:
free_total, occ_total = 0, 0
frames = []
for cam_id, cap in cameras.items():
success, img = cap.read()
if not success:
img = np.zeros((480, 640, 3), dtype=np.uint8)
cv2.putText(img, f"Camera {cam_id} not available",
(50, 240), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
else:
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgBlur = cv2.GaussianBlur(imgGray, (3, 3), 1)
imgThreshold = cv2.adaptiveThreshold(imgBlur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 25, 16)
imgMedian = cv2.medianBlur(imgThreshold, 5)
kernel = np.ones((3, 3), np.uint8)
imgDilate = cv2.dilate(imgMedian, kernel, iterations=1)
# Get threshold for this camera
cam_threshold = thresholds.get(cam_id, 300) # default = 300
free, occ = checkParkingSpace(imgDilate, img, cam_id, cam_threshold)
free_total += free
occ_total += occ
cvzone.putTextRect(img, f"Cam {cam_id} | Free: {free} Occ: {occ} Th={cam_threshold}",
(30, 30), scale=1, thickness=2, offset=5, colorR=(255, 200, 0))
frames.append(cv2.resize(img, (640, 480)))
# Combine all cameras side by side
combined = np.hstack(frames)
probability = calculate_probability()
# Update DB
data["parking_lot"]["total_spaces"] = total_spaces
data["parking_lot"]["free_spaces"] = free_total
data["parking_lot"]["occupied_spaces"] = occ_total
data["parking_lot"]["probability"] = probability
save_database(data)
print(f"Total: {total_spaces}, Free: {free_total}, "
f"Occupied: {occ_total}, Probability: {probability}%", flush=True)
cvzone.putTextRect(combined, f"Total: {total_spaces} Free: {free_total} "
f"Occupied: {occ_total} Prob: {probability}%",
(50, 470), scale=1, thickness=2, offset=5, colorR=(0, 100, 255))
cv2.imshow("Live Parking (Multi-Cam)", combined)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
for cap in cameras.values():
cap.release()
cv2.destroyAllWindows()