python 光流计算(更新中)

TVL1算法:
https://blog.csdn.net/weixin_41558411/article/details/89855290
核心函数:

    TVL1 = cv2.DualTVL1OpticalFlow_create()
    flow = TVL1.calc(prev, curr, None)

速度较慢,两张之间的光流图计算耗时大概6-11s左右

Farneback算法
https://github.com/jiangzhubo/extract_optical_flow/blob/master/extractallopt.py
核心函数:

cv2.calcOpticalFlowFarneback(prev, curr, None, 0.5, 3, 15, 3, 5, 1.2, 0)

速度较快,两张之间的光流图计算耗时大概0.1s左右

上面两种方法均只使用CPU运算,未使用GPU加速!所以第一种算法较慢,照理来说可以编译gpu版opencv,不过编译opencv实在是各种报错。不过TVL1算法得到的光流图片与论文中的更加相似,均为灰色的,Farneback就不太像。

通常网络所需要的光流输入如i3d的光流输入的通道数为二通道,而一般网上所使用Farneback算法提取光流后并保存光流的方法如下(先使用Farneback算法提取二通道的光流,然后转换为hsv格式,最后转为bgr格式使用cv2保存下来;但这个过程由于np.minimum是一个不可逆的过程,即保存后的光流bgr图片后续不能转换为我网络所需要的二通道数组;还有由于通过Farneback提取的二通道光流数组为浮点型且还存在负数,这使得无法把二通道的数组直接多加一个通道变为数据类型为uint8的图片数组,浮点型数据将会取整,且负数均为0;再一个直接使用npy保存二通道光流数组,由于视频数据较多,占用空间可能是图片的几百倍;所以最后二通道的光流数组还是边训练的时候边提取,虽然这样训练会慢不少,我这是慢了5倍)

def draw_hsv(flow):
    h, w = flow.shape[:2]
    fx, fy = flow[:,:,0], flow[:,:,1]
    ang = np.arctan2(fy, fx) + np.pi
    v = np.sqrt(fx*fx+fy*fy)
    hsv = np.zeros((h, w, 3), np.uint8)
    hsv[...,0] = ang*(180/np.pi/2)
    hsv[...,1] = 255
    hsv[...,2] = np.minimum(v*4, 255)
    bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    return bgr
    
case_dir = ...
files = os.listdir(case_dir)
files.sort()

prev = cv2.cvtColor(cv2.imread(case_dir + files[0]), cv2.COLOR_BGR2GRAY)

for file in files:
    t1 = time.time()
    file_dir = case_dir + file
    curr = cv2.cvtColor(cv2.imread(file_dir), cv2.COLOR_BGR2GRAY)
    flow = cv2.calcOpticalFlowFarneback(prev, curr, None, 0.5, 3, 15, 3, 5, 1.2, 0)
    prev = curr
    bgr = draw_hsv(flow)
    cv2.imwrite(optical_flow_dir + folder + '/' + disease_type + '/' + patient + '/' + case + '/' + file, bgr,
                [cv2.IMWRITE_JPEG_QUALITY, 12])
    t2 = time.time()
    print(str(t2 - t1), 'seconds')

可能的其他方法(待测):
https://github.com/feichtenhofer/gpu_flow
https://github.com/yjxiong/dense_flow

你可能感兴趣的:(python 光流计算(更新中))