cv2 Farneback Optical FLow значения слишком низкие - PullRequest
3 голосов
/ 07 мая 2020

Я пытаюсь вычислить оптический поток между двумя кадрами, а затем деформировать предыдущий кадр, используя вычисленный оптический поток. Я обнаружил, что cv2 имеет оптический поток Farneback, поэтому я использую его для вычисления потока. Я взял параметры по умолчанию из учебника cv2 и искажаю фрейм, используя код, указанный в этом ответе . Но когда я вижу деформированный кадр, он точно такой же, как и предыдущий, и без изменений (массивы равны).

При дальнейшей отладке я обнаружил, что вычисленные значения расхода слишком малы. Почему это происходит? Я что-то делаю не так?

Код :

def get_optical_flow(prev_frame: numpy.ndarray, next_frame: numpy.ndarray) -> numpy.ndarray:
    prev_gray = skimage.color.rgb2gray(prev_frame)
    next_gray = skimage.color.rgb2gray(next_frame)
    flow = cv2.calcOpticalFlowFarneback(prev_gray, next_gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
    return flow


def warp_frame(prev_frame: numpy.ndarray, flow: numpy.ndarray):
    h, w = flow.shape[:2]
    flow = -flow
    flow[:,:,0] += numpy.arange(w)
    flow[:,:,1] += numpy.arange(h)[:,numpy.newaxis]
    # res = cv2.remap(img, flow, None, cv2.INTER_LINEAR)
    next_frame = cv2.remap(prev_frame, flow, None, cv2.INTER_LINEAR)
    return next_frame


def demo1():
    prev_frame_path = Path('./frame025.png')
    next_frame_path = Path('./frame027.png')
    prev_frame = skimage.io.imread(prev_frame_path.as_posix())
    next_frame = skimage.io.imread(next_frame_path.as_posix())
    flow = get_optical_flow(prev_frame, next_frame)
    print(f'Flow: max:{flow.max()}, min:{flow.min()}, mean:{flow.__abs__().mean()}')
    warped_frame = warp_frame(prev_frame, flow)

    print(numpy.array_equal(prev_frame, warped_frame))

    pyplot.subplot(1,3,1)
    pyplot.imshow(prev_frame)
    pyplot.subplot(1,3,2)
    pyplot.imshow(next_frame)
    pyplot.subplot(1,3,3)
    pyplot.imshow(warped_frame)
    pyplot.show()
    return

Входные изображения : Image1 Image2

Вывод :
Деформированное изображение точно такое же, как предыдущее изображение, но должно выглядеть как следующее изображение.
enter image description here

Любая помощь приветствуется!

1 Ответ

1 голос
/ 07 мая 2020

Проблема с преобразованием рамок rgb в серые. skimage.color.rgb2gray() изменяет диапазон интенсивности с [0,255] на [0,1]. Изменение его обратно на [0,255] сработало!

def get_optical_flow(prev_frame: numpy.ndarray, next_frame: numpy.ndarray) -> numpy.ndarray:
    prev_gray = (skimage.color.rgb2gray(prev_frame) * 255).astype('uint8')
    next_gray = (skimage.color.rgb2gray(next_frame) * 255).astype('uint8')
    flow = cv2.calcOpticalFlowFarneback(prev_gray, next_gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
    return flow
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...