PyTorch绘制光流flow

本文介绍了两种在PyTorch中绘制光流flow的方法,重点是利用HSV色彩空间来表示flow的角度和长度。通过对比两种方法的输出结果,验证了第一种方法的正确性。

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

flow
这里给出两种方法的code,第一种是用hsv来转化,第二种是直接绘制。

比较tricky的地方可能是思路上先生成hsv图,因为hsv图中第一个h维度,刚好用各种不同的颜色来表达角度,这个和flow中的角度是一致的。而flow的绝对值长度刚好又能被s和v维度表达(其实h和v只有一个自由度)

def arctan(x, y):
    y_x = abs(y/x)
    angle = (x >= 0) * (y > 0) * torch.atan(y_x) # first quadrant
    angle += (x < 0) * (y >= 0) * (torch.atan(y_x) + np.pi/2) # second quadrant
    angle += (x <= 0) * (y < 0) * (torch.atan(y_x) + np.pi) # third quadrant
    angle += (x > 0) * (y <= 0) * (torch.atan(y_x) + np.pi*3/2) # forth quadrant
    return angle


def flow_to_color(flow):

    mag = torch.sqrt(torch.pow(flow, 2).sum(dim=1)) # get abs flow
    max_mag_each_batch = torch.max(mag.reshape([mag.shape[0],-1]),1)[0]

    
    flow_u, flow_v = flow[:,0,:,:], flow[:,1,:,:]
    for i in range(len(max_mag_each_batch)):
        flow_u[i] /= max_mag_each_batch[i]
        flow_v[i] /= max_mag_each_batch[i]

    angle = arctan(flow_u, flow_v)

    im_h = angle / (2*np.pi)
    im_s = torch.clamp(mag / mag.max(), min=0, max=1) 
    im_v = torch.clamp(mag.max() - im_s, min=0
### 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 进行估计并将其结果转换为可理解的形式。无论是采用颜色编码还是箭头图的方式,都可以帮助研究者更好地分析视频序列中的动态变化特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值