opencv 的光流。 CPU 和 GPU 给出的结果截然不同

问题描述 投票:0回答:2

我正在使用 OpenCV 来计算两个图像之间的光流。我之前是用

cv2.optflow.createOptFlow_DualTVL1()
来计算的。现在我正在尝试使用 cuda 复制结果。我在 CUDA 上尝试了几种光流算法,它们都给出了截然不同的结果。有些甚至按数量级计算。

我用错了吗?或者如果是这样的(我强烈怀疑),哪两种算法(CPU,GPU)将始终给出相同的结果?

下面的一些代码:

optical_flow = cv2.optflow.createOptFlow_DualTVL1()
optical_flow_gpu_0 = cv2.cuda.FarnebackOpticalFlow_create()

H,W = prev.shape[:2]
params = {'perfPreset':cv2.cuda.NvidiaOpticalFlow_2_0_NV_OF_PERF_LEVEL_SLOW,
          'outputGridSize':cv2.cuda.NvidiaOpticalFlow_2_0_NV_OF_OUTPUT_VECTOR_GRID_SIZE_1} # Changing this param produces different results but they are still too large flow-vectors.
optical_flow_gpu_1 = cv2.cuda.NvidiaOpticalFlow_2_0_create((W,H),**params)



prev = imgs_gray_batch[0]
curr = imgs_gray_batch[1]

prev_gpu = cv2.cuda_GpuMat(prev)
curr_gpu = cv2.cuda_GpuMat(curr)

flow_cpu = optical_flow.calc(prev,curr,None)

flow_gpu_cuda = optical_flow_gpu_0.calc(prev_gpu, curr_gpu, None)
flow_gpu0 = flow_gpu_cuda.download().astype(np.float32)
flow_gpu_cuda = optical_flow_gpu_1.calc(prev_gpu, curr_gpu, None)
flow_gpu1 = flow_gpu_cuda[0].download().astype(np.float32)
def max_rho(flow):
    #flow = flow.download().astype(np.float32)
    fx,fy = np.split(flow,2,axis=2)
    f_rho = np.sqrt(fx*fx + fy*fy)
    max_rho = f_rho.max()
    print(max_rho)

max_rho(flow_cpu)
max_rho(flow_gpu0)
max_rho(flow_gpu1)
-------------------------------
# The max value of flows are of different magnitude... 
2.4124358
3.2447324
64.0

还有一些图片

plt.figure(figsize = (20,20))
plt.subplot(1,6,1)
plt.imshow(flow_cpu[:,:,0], cmap = 'hot', interpolation = 'nearest')
plt.colorbar()

plt.subplot(1,6,2)
plt.imshow(flow_cpu[:,:,1], cmap = 'hot', interpolation = 'nearest')
plt.colorbar()

plt.subplot(1,6,3)
plt.imshow(flow_gpu0[:,:,0], cmap = 'hot', interpolation = 'nearest')
plt.colorbar()

plt.subplot(1,6,4)
plt.imshow(flow_gpu0[:,:,1], cmap = 'hot', interpolation = 'nearest')
plt.colorbar()

plt.subplot(1,6,5)
plt.imshow(flow_gpu1[:,:,0], cmap = 'hot', interpolation = 'nearest')
plt.colorbar()

plt.subplot(1,6,6)
plt.imshow(flow_gpu1[:,:,1], cmap = 'hot', interpolation = 'nearest')
plt.colorbar()
print('Max')

OpenCV 的这一部分的文档非常少,所以不知道该怎么做。

python opencv opticalflow
2个回答
0
投票

您使用的光流算法不同,opencv中的某些光流算法确实从相同的输入数据返回不同的结果。我认为这可能是CPU和GPU给出不同结果的问题。如果你想检查cpu和gpu结果,你至少应该使用相同的输入数据和相同类型的算法(如cpu和gpu版本的Farneback算法)。


0
投票

您可能正在寻找

convertToFloat()
功能。像这样使用:

sz = 1024
nvof = cv.cuda_NvidiaOpticalFlow_2_0.create((sz,sz), outputGridSize = 4, perfPreset = 5)
im1 = cv.cuda_GpuMat(np.random.rand(sz,sz))
im2 = cv.cuda_GpuMat(np.random.rand(sz,sz))
output = nvof.calc(im1, im2, None, None)
output_cpu = cv.cuda_GpuMat.download(nvof.convertToFloat(output[0], None))
© www.soinside.com 2019 - 2024. All rights reserved.