-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcountvehicle.py
122 lines (108 loc) · 5.54 KB
/
countvehicle.py
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
import cv2
from ultralytics import YOLO
from pathlib import Path
import pandas as pd
import os
import shutil
# loading YOLO model
model = YOLO('yolov8x.pt')
# getting all object class names
dict_classes = model.model.names
#print("YOLO classes:", dict_classes)
def resize_frame(frame, scale_percent):
"""Function to resize an image in a percent scale"""
width = int(frame.shape[1] * scale_percent / 100)
height = int(frame.shape[0] * scale_percent / 100)
dim = (width, height)
resized = cv2.resize(frame, dim, interpolation = cv2.INTER_AREA)
return resized
def count_vehicle(inputpath, scale_percent):
video = cv2.VideoCapture(inputpath)
# Vehicle Objects to detect by Yolo model
class_IDS = [2, 3, 5, 7]
veiculos_contador_in = dict.fromkeys(class_IDS, 0)
contador_in = 0
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
fps = video.get(cv2.CAP_PROP_FPS)
#print('[INFO] - Original Video Dim and FPS: ', (width, height), fps)
# Scaling Video for better performance
if scale_percent != 100:
#print('[INFO] - Scaling change may cause errors in pixels lines ')
width = int(width * scale_percent / 100)
height = int(height * scale_percent / 100)
#print('[INFO] - Dim Scaled Video: ', (width, height))
video_name = 'result.mp4'
output_video = cv2.VideoWriter(video_name,
cv2.VideoWriter_fourcc('m', 'p', '4', 'v'),
fps, (width, height))
success = 1
while success:
# vidObj object calls read function to extract frames
success, frame = video.read()
if success:
# Applying resizing of read frame
frame = resize_frame(frame, scale_percent)
#print("frame shape: ", frame.shape)
referenceline = int(3*frame.shape[0] / 4)
offset = int(fps)
#print(referenceline, frame.shape[1], offset)
# Getting predictions from the model
y_hat = model.predict(frame, conf=0.7, classes=class_IDS, device='cpu', verbose=False)
classes = y_hat[0].boxes.cls.cpu().numpy()
# Storing the above information in a dataframe
positions_frame = pd.DataFrame(y_hat[0].cpu().numpy().boxes.boxes,
columns=['xmin', 'ymin', 'xmax', 'ymax', 'conf', 'class'])
# Translating the numeric class labels to text
labels = [dict_classes[i] for i in classes]
# Drawing transition line for Total Vehicles Counting
cv2.line(frame, (0, referenceline), (frame.shape[1], referenceline), (255, 255, 0), 1)
for ix, row in enumerate(positions_frame.iterrows()):
# Getting the coordinates of each vehicle (row)
xmin, ymin, xmax, ymax, confidence, category, = row[1].astype('int')
# Calculating the center of the bounding-box
center_x, center_y = int(((xmax + xmin)) / 2), int((ymax + ymin) / 2)
# drawing center and bounding-box of vehicle in the given frame
cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (255, 0, 0), 1) # box
cv2.circle(frame, (center_x, center_y), 1, (255, 0, 0), -1) # center of box
# Drawing above the bounding-box the name of class recognized.
cv2.putText(img=frame, text=labels[ix],
org=(xmin, ymin), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(255, 0, 0),
thickness=1)
if (center_y > (referenceline - offset)) and (center_y < referenceline):
contador_in += 1
veiculos_contador_in[category] += 1
# updating the counting type of vehicles
contador_in_plt = [f'{dict_classes[k]}: {i}' for k, i in veiculos_contador_in.items()]
# drawing the counting of type of vehicles in the corners of frame
xt = 10
cv2.putText(img=frame, text="Total Vehicles: " + str(contador_in),
org=(0, xt), fontFace=cv2.FONT_HERSHEY_DUPLEX,
fontScale=0.5, color=(255, 255, 0), thickness=1)
for txt in range(len(contador_in_plt)):
xt += 15
cv2.putText(img=frame, text=contador_in_plt[txt],
org=(0, xt), fontFace=cv2.FONT_HERSHEY_DUPLEX,
fontScale=0.5, color=(255, 255, 0), thickness=1)
# saving transformed frames in a output video format
output_video.write(frame)
# Releasing the video
output_video.release()
print("Total count of vehicles in file: ", inputpath, " :=", contador_in)
return video_name
if __name__ == '__main__':
curdir = Path.cwd()
#print(curdir, type(curdir))
videodir = Path.joinpath(curdir, "inputdir")
videolist = os.listdir(videodir)
outdir = Path.joinpath(curdir, "resultdir")
shutil.rmtree(outdir, ignore_errors=True)
Path(outdir).mkdir(parents=True, exist_ok=True)
for vdfile in videolist:
vdpath = str(Path.joinpath(videodir, vdfile))
#print(vdpath, type(vdpath))
# Scaling percentage of original frame
scale_percent = 70
outvdfile = count_vehicle(vdpath, scale_percent)
outpath = Path.joinpath(outdir, str(Path(vdpath).stem) + "_" + str(outvdfile))
shutil.copyfile(outvdfile, outpath)