Визуализируйте оптический поток с помощью цветовой модели

Я реализовал алгоритм плотного оптического потока и хочу визуализировать его с помощью следующей цветовой модели.

введите здесь описание изображения

(цвет обозначает направление потока в некоторой точке, интенсивность обозначает длину вектора смещения)

Я реализовал грязную версию визуализации

def visualizeFlow(u, v):
    colorModel = cv2.imread('../colormodel.png')
    colorModelCenter = (colorModel.shape[0]/2, colorModel.shape[1]/2)
    res = np.zeros((u.shape[0], u.shape[1], 3), dtype=np.uint8)
    mag = np.max(np.sqrt(u**2 + v**2)) 
    if mag == 0:
        return res, colorModel
    for i in xrange(res.shape[0]):
        for j in xrange(res.shape[1]):
            res[i, j] = colorModel[
                        colorModelCenter[0] + (v[i, j]/mag*colorModelCenter[0]),
                        colorModelCenter[1] + (u[i, j]/mag*colorModelCenter[1])
                    ]
    return res, colorModel

Он производит хорошие в общем случае изображения, но он очень медленный

введите здесь описание изображения

Итак, мой вопрос: может ли кто-нибудь помочь мне сделать эту визуализацию быстрее? Если кто-то знает лучший способ визуализировать плотный поток, это может быть круто.


person Dark_Daiver    schedule 06.03.2015    source источник
comment
что значит очень медленно?   -  person Micka    schedule 06.03.2015
comment
@Micka визуализация потока размером 2637 x 1300 занимает несколько минут. Это очень важно для меня, потому что я хочу использовать его внутри итерации деформации, чтобы отслеживать, как поток изменяется в процессе оптимизации. И хотя бы уровень визуализации пирамиды может занять очень много времени.   -  person Dark_Daiver    schedule 06.03.2015
comment
Если вы суммируете высоту и ширину, это то, сколько раз выполняется ваш цикл for. Вы видите причину его медленной работы?   -  person GPPK    schedule 06.03.2015
comment
@GPPK Только что я удалил /mag*colorModelCenter из цикла (и заменил его одинарным умножением), и кажется, что функция стала быстрее. Я предполагаю, что еще одна проблема - это множественный вызов элементов матрицы в коде Python.   -  person Dark_Daiver    schedule 06.03.2015
comment
если вы часто вызываете это, вам, вероятно, не следует читать модель при каждом вызове, а загружать один раз и проходить. но я не в питоне, так что не уверен.   -  person Micka    schedule 06.03.2015
comment
@Micka, это хороший совет, но вложенные циклы занимают гораздо больше времени, чем чтение изображений.   -  person Dark_Daiver    schedule 06.03.2015
comment
конечно, это не было решением, а подсказкой для дополнительного важного ускорения.   -  person Micka    schedule 06.03.2015
comment
Это выглядит очень круто. Есть ли у вас какие-либо видеоролики, демонстрирующие видеопоток в сравнении с цветным оптическим потоком? Я пытаюсь найти хорошее видео сравнения.   -  person rolls    schedule 18.01.2018
comment
@rolls, к сожалению, нет =( Но я уверен, что это легко сделать   -  person Dark_Daiver    schedule 18.01.2018


Ответы (3)


Код из учебника OpenCV:

import cv2
import numpy as np

# Use Hue, Saturation, Value colour model 
hsv = np.zeros(im1.shape, dtype=np.uint8)
hsv[..., 1] = 255

mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])
hsv[..., 0] = ang * 180 / np.pi / 2
hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
cv2.imshow("colored flow", bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

введите здесь описание изображения

person Mastergalen    schedule 03.04.2018
comment
какова размерность потока? Я передал свои вычисленные u и v в качестве аргументов (dim 480 x 640). В результате он выдал ошибку, так как hsv[...,0].shape =480 и присвоение неверно. - person creative; 14.09.2019

Если вы используете функцию, предоставляемую opencv, ваш код будет работать быстрее. Визуализация оптического потока работает следующим образом:

  • Преобразуйте матрицы компонентов движения u и v в полярные координаты. Применение функции cartToPolar (массив x = массив u, массив y = массив v) даст вам матрицы углов и величин ваших векторов движения.

Окончательную визуализацию цвета можно получить с помощью обратного преобразования HSV в RGB, где матрица углов соответствует каналу оттенка (H), а величина насыщенности (S), значение (V) установлено на максимум. (В вашем примере каналы значения и насыщенности поменяны местами).

  • Объедините величину, угол и матрицу, заполненную 1, с матрицей канала CV_32FC3, используя merge или mixChannels.

  • Применить cvtColor с флагом CV_HSV2BGR. Обратите внимание, что матрица углов выражается в градусах, а величина должна быть масштабирована, чтобы соответствовать i [0,1], что можно сделать, разделив ее на максимальную величину, используя, например, MinMaxLoc

person Tobias Senst    schedule 16.11.2015

Возможно, вы захотите проверить потрясающий пакет flow_vis. Цитата с их страницы:

  1. pip install flow_vis

  2. Затем в вашем коде:

import flow_vis
flow_color = flow_vis.flow_to_color(flow_uv, convert_to_bgr=False)
person nivniv    schedule 01.12.2020