Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hackassin
GitHub Repository: hackassin/learnopencv
Path: blob/master/Getting-Started-OpenCV-CUDA-Module/demo.py
3119 views
1
import argparse
2
import time
3
4
import cv2
5
import numpy as np
6
7
8
def main(video, device):
9
10
# init dict to track time for every stage at each iteration
11
timers = {
12
"full pipeline": [],
13
"reading": [],
14
"pre-process": [],
15
"optical flow": [],
16
"post-process": [],
17
}
18
19
# init video capture with video
20
cap = cv2.VideoCapture(video)
21
22
# get default video FPS
23
fps = cap.get(cv2.CAP_PROP_FPS)
24
25
# get total number of video frames
26
num_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
27
28
# read the first frame
29
ret, previous_frame = cap.read()
30
31
if device == "cpu":
32
33
# proceed if frame reading was successful
34
if ret:
35
# resize frame
36
frame = cv2.resize(previous_frame, (960, 540))
37
38
# convert to gray
39
previous_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
40
41
# create hsv output for optical flow
42
hsv = np.zeros_like(frame, np.float32)
43
44
# set saturation to 1
45
hsv[..., 1] = 1.0
46
47
while True:
48
# start full pipeline timer
49
start_full_time = time.time()
50
51
# start reading timer
52
start_read_time = time.time()
53
54
# capture frame-by-frame
55
ret, frame = cap.read()
56
57
# end reading timer
58
end_read_time = time.time()
59
60
# add elapsed iteration time
61
timers["reading"].append(end_read_time - start_read_time)
62
63
# if frame reading was not successful, break
64
if not ret:
65
break
66
67
# start pre-process timer
68
start_pre_time = time.time()
69
# resize frame
70
frame = cv2.resize(frame, (960, 540))
71
72
# convert to gray
73
current_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
74
75
# end pre-process timer
76
end_pre_time = time.time()
77
78
# add elapsed iteration time
79
timers["pre-process"].append(end_pre_time - start_pre_time)
80
81
# start optical flow timer
82
start_of = time.time()
83
84
# calculate optical flow
85
flow = cv2.calcOpticalFlowFarneback(
86
previous_frame, current_frame, None, 0.5, 5, 15, 3, 5, 1.2, 0,
87
)
88
# end of timer
89
end_of = time.time()
90
91
# add elapsed iteration time
92
timers["optical flow"].append(end_of - start_of)
93
94
# start post-process timer
95
start_post_time = time.time()
96
97
# convert from cartesian to polar coordinates to get magnitude and angle
98
magnitude, angle = cv2.cartToPolar(
99
flow[..., 0], flow[..., 1], angleInDegrees=True,
100
)
101
102
# set hue according to the angle of optical flow
103
hsv[..., 0] = angle * ((1 / 360.0) * (180 / 255.0))
104
105
# set value according to the normalized magnitude of optical flow
106
hsv[..., 2] = cv2.normalize(
107
magnitude, None, 0.0, 1.0, cv2.NORM_MINMAX, -1,
108
)
109
110
# multiply each pixel value to 255
111
hsv_8u = np.uint8(hsv * 255.0)
112
113
# convert hsv to bgr
114
bgr = cv2.cvtColor(hsv_8u, cv2.COLOR_HSV2BGR)
115
116
# update previous_frame value
117
previous_frame = current_frame
118
119
# end post-process timer
120
end_post_time = time.time()
121
122
# add elapsed iteration time
123
timers["post-process"].append(end_post_time - start_post_time)
124
125
# end full pipeline timer
126
end_full_time = time.time()
127
128
# add elapsed iteration time
129
timers["full pipeline"].append(end_full_time - start_full_time)
130
131
# visualization
132
cv2.imshow("original", frame)
133
cv2.imshow("result", bgr)
134
k = cv2.waitKey(1)
135
if k == 27:
136
break
137
138
else:
139
140
# proceed if frame reading was successful
141
if ret:
142
# resize frame
143
frame = cv2.resize(previous_frame, (960, 540))
144
145
# upload resized frame to GPU
146
gpu_frame = cv2.cuda_GpuMat()
147
gpu_frame.upload(frame)
148
149
# convert to gray
150
previous_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
151
152
# upload pre-processed frame to GPU
153
gpu_previous = cv2.cuda_GpuMat()
154
gpu_previous.upload(previous_frame)
155
156
# create gpu_hsv output for optical flow
157
gpu_hsv = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_32FC3)
158
gpu_hsv_8u = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_8UC3)
159
160
gpu_h = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_32FC1)
161
gpu_s = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_32FC1)
162
gpu_v = cv2.cuda_GpuMat(gpu_frame.size(), cv2.CV_32FC1)
163
164
# set saturation to 1
165
gpu_s.upload(np.ones_like(previous_frame, np.float32))
166
167
while True:
168
# start full pipeline timer
169
start_full_time = time.time()
170
171
# start reading timer
172
start_read_time = time.time()
173
174
# capture frame-by-frame
175
ret, frame = cap.read()
176
177
# upload frame to GPU
178
gpu_frame.upload(frame)
179
180
# end reading timer
181
end_read_time = time.time()
182
183
# add elapsed iteration time
184
timers["reading"].append(end_read_time - start_read_time)
185
186
# if frame reading was not successful, break
187
if not ret:
188
break
189
190
# start pre-process timer
191
start_pre_time = time.time()
192
193
# resize frame
194
gpu_frame = cv2.cuda.resize(gpu_frame, (960, 540))
195
196
# convert to gray
197
gpu_current = cv2.cuda.cvtColor(gpu_frame, cv2.COLOR_BGR2GRAY)
198
199
# end pre-process timer
200
end_pre_time = time.time()
201
202
# add elapsed iteration time
203
timers["pre-process"].append(end_pre_time - start_pre_time)
204
205
# start optical flow timer
206
start_of = time.time()
207
208
# create optical flow instance
209
gpu_flow = cv2.cuda_FarnebackOpticalFlow.create(
210
5, 0.5, False, 15, 3, 5, 1.2, 0,
211
)
212
# calculate optical flow
213
gpu_flow = cv2.cuda_FarnebackOpticalFlow.calc(
214
gpu_flow, gpu_previous, gpu_current, None,
215
)
216
217
# end of timer
218
end_of = time.time()
219
220
# add elapsed iteration time
221
timers["optical flow"].append(end_of - start_of)
222
223
# start post-process timer
224
start_post_time = time.time()
225
226
gpu_flow_x = cv2.cuda_GpuMat(gpu_flow.size(), cv2.CV_32FC1)
227
gpu_flow_y = cv2.cuda_GpuMat(gpu_flow.size(), cv2.CV_32FC1)
228
cv2.cuda.split(gpu_flow, [gpu_flow_x, gpu_flow_y])
229
230
# convert from cartesian to polar coordinates to get magnitude and angle
231
gpu_magnitude, gpu_angle = cv2.cuda.cartToPolar(
232
gpu_flow_x, gpu_flow_y, angleInDegrees=True,
233
)
234
235
# set value to normalized magnitude from 0 to 1
236
gpu_v = cv2.cuda.normalize(gpu_magnitude, 0.0, 1.0, cv2.NORM_MINMAX, -1)
237
238
# get angle of optical flow
239
angle = gpu_angle.download()
240
angle *= (1 / 360.0) * (180 / 255.0)
241
242
# set hue according to the angle of optical flow
243
gpu_h.upload(angle)
244
245
# merge h,s,v channels
246
cv2.cuda.merge([gpu_h, gpu_s, gpu_v], gpu_hsv)
247
248
# multiply each pixel value to 255
249
gpu_hsv.convertTo(cv2.CV_8U, 255.0, gpu_hsv_8u, 0.0)
250
251
# convert hsv to bgr
252
gpu_bgr = cv2.cuda.cvtColor(gpu_hsv_8u, cv2.COLOR_HSV2BGR)
253
254
# send original frame from GPU back to CPU
255
frame = gpu_frame.download()
256
257
# send result from GPU back to CPU
258
bgr = gpu_bgr.download()
259
260
# update previous_frame value
261
gpu_previous = gpu_current
262
263
# end post-process timer
264
end_post_time = time.time()
265
266
# add elapsed iteration time
267
timers["post-process"].append(end_post_time - start_post_time)
268
269
# end full pipeline timer
270
end_full_time = time.time()
271
272
# add elapsed iteration time
273
timers["full pipeline"].append(end_full_time - start_full_time)
274
275
# visualization
276
cv2.imshow("original", frame)
277
cv2.imshow("result", bgr)
278
k = cv2.waitKey(1)
279
if k == 27:
280
break
281
282
# release the capture
283
cap.release()
284
285
# destroy all windows
286
cv2.destroyAllWindows()
287
288
# print results
289
print("Number of frames : ", num_frames)
290
291
# elapsed time at each stage
292
print("Elapsed time")
293
for stage, seconds in timers.items():
294
print("-", stage, ": {:0.3f} seconds".format(sum(seconds)))
295
296
# calculate frames per second
297
print("Default video FPS : {:0.3f}".format(fps))
298
299
of_fps = (num_frames - 1) / sum(timers["optical flow"])
300
print("Optical flow FPS : {:0.3f}".format(of_fps))
301
302
full_fps = (num_frames - 1) / sum(timers["full pipeline"])
303
print("Full pipeline FPS : {:0.3f}".format(full_fps))
304
305
306
if __name__ == "__main__":
307
308
# init argument parser
309
parser = argparse.ArgumentParser(description="OpenCV CPU/GPU Comparison")
310
311
parser.add_argument(
312
"--video", help="path to .mp4 video file", required=True, type=str,
313
)
314
315
parser.add_argument(
316
"--device",
317
default="cpu",
318
choices=["cpu", "gpu"],
319
help="device to inference on",
320
)
321
322
# parsing script arguments
323
args = parser.parse_args()
324
video = args.video
325
device = args.device
326
327
# output passed arguments
328
print("Configuration")
329
print("- device : ", device)
330
print("- video file : ", video)
331
332
# run pipeline
333
main(video, device)
334
335