带有光流的箭袋图?

Posted

技术标签:

【中文标题】带有光流的箭袋图?【英文标题】:Quiver plot with optical flow? 【发布时间】:2020-05-21 20:24:13 【问题描述】:

最近我正在使用图像进行云运动跟踪,但在许多示例中,当在视频实现中使用时会显示根据跟踪对象移动的颤动图。

Quiver 文档主要采用四个参数 ([X, Y], U, V),其中 XY 是起点,UV 是方向。另一方面,基于this example 的光流返回p1(位移),形状为(m,n,l)的图像的形状为(200,200)。我的困惑在于如何对参数进行排序,因为goodFeaturesToTrack 的返回值与p1 相同

¿如何连接两个组件来绘制云运动的颤动?

【问题讨论】:

【参考方案1】:

我找到了一个很好的解决方案。我在这里使用汉堡出租车序列解释我的所有示例:

    下载出租车序列。
$ curl -O ftp://ftp.ira.uka.de/pub/vid-text/image_sequences/taxi/taxi.zip
$ unzip -q taxi.zip
    获取所有图像并随机选取两个帧
from pathlib import Path
import numpy as np
import cv2 as cv
from PIL import Image
import matplotlib.pyplot as plt

taxis_fnames = list(Path('taxi').iterdir())
taxi1 = Image.open(taxis_fnames[rand_idx])
taxi2 = Image.open(taxis_fnames[rand_idx + 4])
    计算光流
flow = cv.calcOpticalFlowFarneback(np.array(taxi1), 
                                   np.array(taxi2), 
                                   None, 0.5, 3, 15, 3, 5, 1.2, 0)
    绘制箭袋
step = 3
plt.quiver(np.arange(0, flow.shape[1], step), np.arange(flow.shape[0], -1, -step), 
           flow[::step, ::step, 0], flow[::step, ::step, 1])

该步骤是对选取的光流向量的数量进行下采样。 x 位置从 0 变为图像宽度,而 y 位置从图像高度反转(否则光流将上下颠倒)从图像高度变为 0。在某些情况下,您必须更改步长,以便高度和宽度为能被它整除。

    生成的图像:

【讨论】:

【参考方案2】:

这是一种简单而准确地绘制箭袋场的通用方法。

def plot_quiver(ax, flow, spacing, margin=0, **kwargs):
    """Plots less dense quiver field.

    Args:
        ax: Matplotlib axis
        flow: motion vectors
        spacing: space (px) between each arrow in grid
        margin: width (px) of enclosing region without arrows
        kwargs: quiver kwargs (default: angles="xy", scale_units="xy")
    """
    h, w, *_ = flow.shape

    nx = int((w - 2 * margin) / spacing)
    ny = int((h - 2 * margin) / spacing)

    x = np.linspace(margin, w - margin - 1, nx, dtype=np.int64)
    y = np.linspace(margin, h - margin - 1, ny, dtype=np.int64)

    flow = flow[np.ix_(y, x)]
    u = flow[:, :, 0]
    v = flow[:, :, 1]

    kwargs = **dict(angles="xy", scale_units="xy"), **kwargs
    ax.quiver(x, y, u, v, **kwargs)

    ax.set_ylim(sorted(ax.get_ylim(), reverse=True))
    ax.set_aspect("equal")

示例用法:

flow = cv2.calcOpticalFlowFarneback(
    frame_1, frame_2, None, 0.5, 3, 15, 3, 5, 1.2, 0
)

fig, ax = plt.subplots()
plot_quiver(ax, flow, spacing=10, scale=1, color="#ff44ff")

【讨论】:

以上是关于带有光流的箭袋图?的主要内容,如果未能解决你的问题,请参考以下文章

在光流路径场周围创建一个边界框

如何使用光流图像将后一帧扭曲到前一帧

如何使用光流和 grid_sample 扭曲图像?

光流法详解之二(HS光流)

光流法详解之一(LK光流)

光流介绍以及FlowNet学习笔记