Skip to content

Commit 841efa6

Browse files
Copilotalexarje
andauthored
Address code review: improve docstrings and GPU memory management
Agent-Logs-Url: https://github.com/fourMs/MGT-python/sessions/37e34660-f746-453a-b428-74fc3f53285f Co-authored-by: alexarje <114316+alexarje@users.noreply.github.com>
1 parent 698aaef commit 841efa6

1 file changed

Lines changed: 9 additions & 7 deletions

File tree

musicalgestures/_flow.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def dense(
6969
angle_of_view (int, optional): angle of view of camera, for reporting flow in meters per second. Defaults to 0.
7070
scaledown (int, optional): factor to scaledown frame size of the video. Defaults to 1.
7171
skip_empty (bool, optional): If True, repeats previous frame in the output when encounters an empty frame. Defaults to False.
72-
use_gpu (bool, optional): Whether to attempt GPU (CUDA) acceleration using `cv2.cuda.FarnebackOpticalFlow`. Falls back to CPU automatically if CUDA is unavailable or the required OpenCV CUDA modules are not installed. Defaults to True.
72+
use_gpu (bool, optional): Whether to attempt GPU (CUDA) acceleration using `cv2.cuda.FarnebackOpticalFlow`. When `True`, falls back to CPU automatically if CUDA is unavailable or the required OpenCV CUDA modules are not installed. When `False`, CPU processing is used unconditionally. Defaults to True.
7373
target_name (str, optional): Target output name for the video. Defaults to None (which assumes that the input filename with the suffix "_flow_dense" should be used).
7474
overwrite (bool, optional): Whether to allow overwriting existing files or to automatically increment target filenames to avoid overwriting. Defaults to False.
7575
@@ -145,6 +145,7 @@ def dense(
145145

146146
if _use_gpu:
147147
gpu_prev_frame = cv2.cuda_GpuMat()
148+
gpu_next_frame = cv2.cuda_GpuMat()
148149
gpu_prev_frame.upload(prev_frame)
149150

150151
prev_rgb = None
@@ -163,11 +164,12 @@ def dense(
163164
next_frame = cv2.cvtColor(cv2.resize(frame2, size), cv2.COLOR_BGR2GRAY)
164165

165166
if _use_gpu:
166-
gpu_next_frame = cv2.cuda_GpuMat()
167167
gpu_next_frame.upload(next_frame)
168168
gpu_flow_result = farneback_gpu.calc(gpu_prev_frame, gpu_next_frame, None)
169169
flow = gpu_flow_result.download()
170-
gpu_prev_frame = gpu_next_frame
170+
# Swap references so gpu_next_frame becomes the next prev without
171+
# allocating a new GpuMat object each frame
172+
gpu_prev_frame, gpu_next_frame = gpu_next_frame, gpu_prev_frame
171173
else:
172174
flow = cv2.calcOpticalFlowFarneback(prev_frame, next_frame, None, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags)
173175

@@ -335,7 +337,7 @@ def sparse(
335337
of_win_size (tuple, optional): Size of the search window at each pyramid level. Defaults to (15, 15).
336338
of_max_level (int, optional): 0-based maximal pyramid level number. If set to 0, pyramids are not used (single level), if set to 1, two levels are used, and so on. If pyramids are passed to input then the algorithm will use as many levels as pyramids have but no more than `maxLevel`. Defaults to 2.
337339
of_criteria (tuple, optional): Specifies the termination criteria of the iterative search algorithm (after the specified maximum number of iterations criteria.maxCount or when the search window moves by less than criteria.epsilon). Defaults to (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03).
338-
use_gpu (bool, optional): Whether to attempt GPU (CUDA) acceleration using `cv2.cuda.SparsePyrLKOpticalFlow`. Falls back to CPU automatically if CUDA is unavailable or the required OpenCV CUDA modules are not installed. Defaults to True.
340+
use_gpu (bool, optional): Whether to attempt GPU (CUDA) acceleration using `cv2.cuda.SparsePyrLKOpticalFlow`. When `True`, falls back to CPU automatically if CUDA is unavailable or the required OpenCV CUDA modules are not installed. When `False`, CPU processing is used unconditionally. Defaults to True.
339341
target_name (str, optional): Target output name for the video. Defaults to None (which assumes that the input filename with the suffix "_flow_sparse" should be used).
340342
overwrite (bool, optional): Whether to allow overwriting existing files or to automatically increment target filenames to avoid overwriting. Defaults to False.
341343
@@ -419,6 +421,7 @@ def sparse(
419421

420422
if _use_gpu:
421423
gpu_old_gray = cv2.cuda_GpuMat()
424+
gpu_frame_gray = cv2.cuda_GpuMat()
422425
gpu_old_gray.upload(old_gray)
423426
gpu_p0 = cv2.cuda_GpuMat()
424427
gpu_p0.upload(p0)
@@ -435,12 +438,12 @@ def sparse(
435438

436439
# calculate optical flow
437440
if _use_gpu:
438-
gpu_frame_gray = cv2.cuda_GpuMat()
439441
gpu_frame_gray.upload(frame_gray)
440442
gpu_p1, gpu_st = lk_gpu.calc(gpu_old_gray, gpu_frame_gray, gpu_p0, None, None)
441443
p1 = gpu_p1.download()
442444
st = gpu_st.download()
443-
gpu_old_gray = gpu_frame_gray
445+
# Swap references to avoid allocating a new GpuMat each frame
446+
gpu_old_gray, gpu_frame_gray = gpu_frame_gray, gpu_old_gray
444447
else:
445448
p1, st, err = cv2.calcOpticalFlowPyrLK(
446449
old_gray, frame_gray, p0, None, **lk_params)
@@ -470,7 +473,6 @@ def sparse(
470473
old_gray = frame_gray.copy()
471474
p0 = good_new.reshape(-1, 1, 2)
472475
if _use_gpu:
473-
gpu_p0 = cv2.cuda_GpuMat()
474476
gpu_p0.upload(p0)
475477

476478
else:

0 commit comments

Comments
 (0)