【光流】——《GMFlow: Learning Optical Flow via Global Matching》基于全局匹配的光流估计算法可视化

本文介绍gmflow中采用矩阵乘法实现全局匹配的方法,并通过可视化技术展现匹配效果。文中详细解释了全局匹配的过程,包括使用matmul计算相关性,以及通过ClassActivationMap (CAM) 图形展示局部匹配的相关性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

gmflow

简介

gmflow中采用矩阵乘法求两个图像的全局匹配,而以前的光流算法多采用一定半径的局部求相关性,而两个超多元素的矩阵乘法会严重增加计算量,所以这里对全局匹配的结果进行可视化,进行直观感受。

1. 全局匹配

gmflow中全局匹配的code

# global correlation
b, c, h, w= feature0.shape
feature0 = feature0.view(b, c, -1).permute(0, 2, 1)  # [B, H*W, C]
feature1 = feature1.view(b, c, -1)  # [B, C, H*W]

correlation = torch.matmul(feature0, feature1).view(b, h, w, h, w) / (c ** 0.5)  # [B, H, W, H, W]
correlation = correlation.view(b, h * w, h * w)  # [B, H*W, H*W]
prob = F.softmax(correlation, dim=-1)  # [B, H*W, H*W]

就是对两个特征用matmul求相关性。后面可视化就是对prob的可视化。

2. 可视化

整体流程:

  • 在feature0的尺度上,高度,宽度方向分别均匀采样N=20个点,整幅图就有N**2个点
  • 画出每个点的Class Activation Map(CAM)图,我参考的代码为:CAM
  • 最后对所有点的CAM图求和,再和原图相加得到最后的可视化图像。

code:
在这里插入图片描述

在这里插入图片描述
第一张图是前向光流可视化图,第二张图分别是400个点对应的ativation map图。
可以看到:

  • 相关性上还是呈现一个局部相关性,所有用matmul理论上应该是非必须的。可以以当前点为基点,在一定范围内做局部匹配
  • 核心的光流部分点的匹配,相较于静止点,其AM还是有不一样的。

总结

  • 找一种高效的局部匹配方式进行替换。
### SPyNet 可视化的实现方法 SPyNet 是一种基于深度学习的估计框架,其核心在于通过空间金字塔结构来高效地捕捉不同尺度下的像素运动[^3]。为了实现 SPyNet 的可视化,通常需要以下几个方面的技术支持: #### 1. **数据准备** 需要一组连续的视频帧作为输入。这些帧可以通过摄像头采集或者从现有的视频文件中提取。对于每一对相邻帧 \(I_1\) 和 \(I_2\),SPyNet 能够预测它们之间的场。 #### 2. **加载预训练模型** 使用 PyTorch 或其他深度学习框架加载 SPyNet 的预训练权重。这一步骤非常重要,因为 SPyNet 的性能依赖于经过充分训练的参数集合[^2]。 ```python import torch from models.spynet import SpyNet # 假设这是 SPyNet 的定义模块 model = SpyNet() pretrained_weights_path = 'path_to_pretrained_spynet.pth' state_dict = torch.load(pretrained_weights_path, map_location=torch.device('cpu')) model.load_state_dict(state_dict) model.eval() # 设置为评估模式 ``` #### 3. **前向传播获取** 输入两个连续帧到 SPyNet 中,得到对应的张量。该张量表示了每一像素在两帧之间移动的方向和大小。 ```python def estimate_optical_flow(frame1, frame2): with torch.no_grad(): flow_tensor = model(frame1.unsqueeze(0), frame2.unsqueeze(0)) return flow_tensor.squeeze().numpy() frame1_tensor = preprocess_frame(frame1) # 自定义预处理函数 frame2_tensor = preprocess_frame(frame2) optical_flow = estimate_optical_flow(frame1_tensor, frame2_tensor) ``` #### 4. **可视化** 获取到的是一个二维矢量场,其中每个位置对应一个 (u,v) 向量,分别代表水平方向和垂直方向上的位移。常见的可视化方式包括颜色编码法(Color Coding)以及箭头图(Quiver Plot)。以下是两种主要的实现方法: ##### (1)**颜色编码法** 利用 HSV 色彩空间将向量映射成彩色图像。这种方法能够直观展示的方向和强度[^1]。 ```python import cv2 import numpy as np def visualize_color_coding(flow_uv): h, w = flow_uv.shape[:2] hsv_image = np.zeros((h, w, 3), dtype=np.uint8) mag, ang = cv2.cartToPolar(flow_uv[..., 0], flow_uv[..., 1]) hsv_image[..., 0] = ang * 180 / np.pi / 2 # 方向 -> 色相 hsv_image[..., 1] = 255 # 饱和度固定为最大值 hsv_image[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX) # 大小 -> 明亮度 bgr_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR) return bgr_image color_coded_flow = visualize_color_coding(optical_flow) cv2.imshow('Optical Flow Visualization', color_coded_flow) cv2.waitKey(0) ``` ##### (2)**箭头图** 对部分采样点绘制带有方向的箭头线段,适合观察局部区域内的运动趋势。 ```python import matplotlib.pyplot as plt def plot_quiver(flow_uv, step=10): u = flow_uv[::step, ::step, 0] v = flow_uv[::step, ::step, 1] y_coords, x_coords = np.mgrid[0:flow_uv.shape[0]:step, 0:flow_uv.shape[1]:step] fig, ax = plt.subplots(figsize=(7, 7)) q = ax.quiver(x_coords, y_coords, u, v, angles='xy', scale_units='xy', scale=1) ax.set_aspect('equal') plt.show() plot_quiver(optical_flow) ``` --- ### 总结 上述过程展示了如何利用 SPyNet 进行估计并将其结果转换为可理解的形式。无论是采用颜色编码还是箭头图的方式,都可以帮助研究者更好地分析视频序列中的动态变化特性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值