There is no Python documentation available for the CUDA optical flow modules. I have been trying to obtain the Brox optical flow and used some workarounds for bugs I encountered.
However, the output doesn’t make any sense.
If someone could point out any mistakes in my code, I’d be very grateful.
import cv2
import numpy as np
#fresh start
print(cv2.cuda.getCudaEnabledDeviceCount())
vidPath = 'C:/Users/Aditya/Downloads/JESTER DATASET/20bn-jester-v1/1/%5d.jpg'
lr = 0.05
check_res = False
frame_device = cv2.cuda_GpuMat()
#taking input, pass 0 to use webcam data
cap = cv2.VideoCapture(vidPath)
bgmog2_device = cv2.cuda.createBackgroundSubtractorMOG2()
brox_of = cv2.cuda_BroxOpticalFlow.create(0.197, 50.0, 0.8, 10, 77, 10)
#(alpha ,gamma ,scale ,inner_iterations ,outer_iterations ,solver_iterations)
def bgmogCuda(frame,lr,store_res=False):
frame_device.upload(frame)
fg_device = bgmog2_device.apply(frame_device,lr,cv2.cuda.Stream_Null())
fg_host = fg_device.download()
if(store_res):
gpu_res.append(np.copy(fg_host))
return fg_host
gpu_res = []
gpu_prev = cv2.cuda_GpuMat()
gpu_frame = cv2.cuda_GpuMat()
ret, frame = cap.read()
frame = np.float32(frame)/255.0
gpu_prev.upload(frame)
gpu_prev = cv2.cuda.cvtColor(gpu_prev, cv2.COLOR_BGR2GRAY)
print("Type prev = ",gpu_prev.type())
h, w = frame.shape[:2]
temp = np.zeros((h, w), np.float32)
temp = gpu_prev.download()
cv2.imshow('temp', temp)
gpu_v = cv2.cuda_GpuMat(gpu_prev.size(), cv2.CV_32FC1)
#loop frames
while(1):
ret, frame = cap.read()
if not ret:
cap.release()
break
#bgsgm
fgmask = bgmogCuda(frame, lr, store_res=check_res)
kernel = np.ones((3, 3), np.uint8)
erode = cv2.erode(fgmask, kernel, iterations = 1)
cv2.imshow('bgmog', erode)
#brox optical flow opencv cuda
frame = np.float32(frame)/255.0
gpu_frame.upload(frame)
if(gpu_prev.type() != 5):
gpu_prev = cv2.cuda.cvtColor(gpu_prev, cv2.COLOR_BGR2GRAY)
gpu_frame = cv2.cuda.cvtColor(gpu_frame, cv2.COLOR_BGR2GRAY)
gpu_flow = brox_of.calc(gpu_prev, gpu_frame, None)
gpu_flow_x = cv2.cuda_GpuMat(gpu_flow.size(), cv2.CV_32FC1)
gpu_flow_y = cv2.cuda_GpuMat(gpu_flow.size(), cv2.CV_32FC1)
cv2.cuda.split(gpu_flow, [gpu_flow_x, gpu_flow_y], cv2.cuda.Stream_Null())
gpu_magnitude, gpu_angle = cv2.cuda.cartToPolar(gpu_flow_x, gpu_flow_y, angleInDegrees=False)
# set value to normalized magnitude from 0 to 1
gpu_v = cv2.cuda.normalize(gpu_magnitude, 0.0, 255.0, cv2.NORM_MINMAX, -1)
res = gpu_v.download()
cv2.imshow("result", res)
gpu_prev = gpu_frame
if 0xFF & cv2.waitKey(50) == 27:
break
cv2.waitKey(0)
cv2.destroyAllWindows()