Tonic.utils.plot.grid()

Tonic.utils.plot.grid()

イベントを視覚化し、フレームに描画します

機能リンク

1.関数プロトタイプ

機能: 目視検査のために、軸の積に等しいフレームにイベントを蓄積します。

import numpy as np

import tonic.transforms as transforms


def plot_event_grid(events, axis_array=(1, 3), plot_frame_number=False):
    """Plot events accumulated as frames equal to the product of axes for visual inspection.

    Parameters:
        events: Structured numpy array of shape [num_events, num_event_channels].
            	事件流,numpy数组
            
        axis_array: dimensions of plotting grid. The larger the grid,
                    the more fine-grained the events will be sliced in time.
                    将事件流,绘制成帧,并用网格形式表示出来,此处可设定帧的数量,以axis_array=(2,3)为例,则帧的数量为2*3=6,以23列的网格显示出                     来
                        
        plot_frame_number: optional index of frame when plotting
            绘图时帧的可选索引

    Example:
        >>> import tonic
        >>> dataset = tonic.datasets.NMNIST(save_to='./data')
        >>> events, target = dataset[100]
        >>> tonic.utils.plot_event_grid(events)

    Returns:
        None
    """
    try:
        import matplotlib.pyplot as plt
    except ImportError:
        raise ImportError(
            "Please install the matplotlib package to plot events. This is an optional"
            " dependency."
        )

        # 事件流events是一个numpy列表,其中dtype为 [('x', '<i8'), ('y', '<i8'), ('t', '<i8'), ('p', '<i8')]
        # events.dtype.names 为 ('x', 'y', 't', 'p') 表示一个事件的坐标x,y(像素坐标系) 时间辍,极性
            
    if "y" in events.dtype.names:
		# 得到了 events 事件流中事件在像素坐标系中横坐标与纵坐标的最大值,用于绘制帧的尺寸
        sensor_size_x = int(events["x"].max() + 1)
        sensor_size_y = int(events["y"].max() + 1)
        # np.unique(events["p"]) 对于一个以为列表或者数组,去除重复元素,并按照元素从小到大返回一个新的列表或者元组
        	# 此处得到了,事件有机种极性,也代表着之后的事件帧有几个通道
        sensor_size_p = len(np.unique(events["p"]))
        # 此处为帧的尺寸,长、宽、通道数
        sensor_size = (sensor_size_x, sensor_size_y, sensor_size_p)

        # 将事件转化为事件帧,sensor_size为事件帧的尺寸,n_time_bins为按照时间箱得到固定的帧数
            # np.product(axis_array) 返回数组或者元组 axis_array中元素的乘积。即时间流通过切片方式得到的事件帧的数量
        transform = transforms.ToFrame(
            sensor_size=sensor_size, n_time_bins=np.product(axis_array)
        )

        # 将事件流转化为事件帧
        frames = transform(events)
        # *axis_array在python中表示 将数组或者元组解开成几个独立的参数,传入函数,如axis_array=(2,3),*axis_array = 2 3
        	# plt.subplots(m,n) 绘制 m*n个子图,字图在一个大图中以m行n列的方式显示
        # 函数的返回值是一个元组,包括一个图形对象和所有的 axes_array 对象。
        	# 其中 axes_array 对象(含所有子图的一个数组)的数量等于 nrows * ncols,且每个 axes_array 对象均可通过索引值访问
            # fig 的类型就是一个大的画布,所有子图均显示在上面(<class 'matplotlib.figure.Figure'>
        fig, axes_array = plt.subplots(*axis_array)

        if 1 in axis_array:
            axes_array = axes_array.reshape(1, -1)

        for i in range(axis_array[0]):
            for j in range(axis_array[1]):
				# 按照索引得到一帧图像
                frame = frames[i * axis_array[1] + j]
                # 将事件帧的两个通道的像素值进行作差---并在子图中显示出来,可以简单的看出事件相机在录制数据时的移动方向
                axes_array[i, j].imshow(frame[1] - frame[0])
                # 关闭子图中所有坐标轴线、刻度标记和标签
                axes_array[i, j].axis("off")
                # 是否给每张子图设置一个标题 title
                if plot_frame_number:
                    axes_array[i, j].title.set_text(str(i * axis_array[1] + j))
        # 自动调整子图参数,使之填充整个图像区域
        plt.tight_layout()
        # 显示所有的figure,这是必要的,若没有则会出现,只出现一张子图的情况
        plt.show()

    else:
        sensor_size_x = int(events["x"].max() + 1)
        frame_transform = transforms.ToFrame(
            sensor_size=(sensor_size_x, 1, 1), n_time_bins=sensor_size_x * 2
        )

        frames = frame_transform(events)
        plt.imshow(frames.squeeze().T)
        plt.xlabel("Time")
        plt.ylabel("Channels")

1. プログラム例:

"""
    将事件数据转换为帧
"""
import tonic
import tonic.transforms as transforms
import matplotlib.pyplot as plt
import torch

# 下载 NMINST 数据
dataset = tonic.datasets.NMNIST(save_to="/home/zxz/Proj/DP/Do/demo_03/Tonic_dir/tutorials/data",train=False)

print(len(dataset))  # 10000
events,target = dataset[1000]
print(events)  # numpy数组
"""
    每行对应一个事件,由四个参数组成:(x坐标、y坐标、时间戳、极性)
        x和y坐标对应34*34网格中的地址
        事件的时间戳以微秒为单位记录
        极性指的是是否发生了峰上(+1)或峰下(-1);即,亮度的增加或减少
"""

# 将许多事件累积到一个框架中,使其可视化---将事件流划分为3*2个事件帧
tonic.utils.plot_event_grid(events,axis_array=(3,2))

ディスプレイ効果

画像-20230205142409828

2. 同じ効果を持つプログラムを手書きする

"""
    将事件数据转换为帧---对tonic中的一些操作进行合并
"""
import tonic
import tonic.transforms as transforms
import matplotlib.pyplot as plt
import torch
import torchvision


"""
    事件帧的可视化程序,将事件帧可视化
"""
def plot_frames(frames):
    # subplots 生成 1*len(frames) 个子图像
    # 函数的返回值是一个元组,包括一个图形对象和所有的 axes 对象。
        # 其中 axes 对象的数量等于 nrows * ncols,且每个 axes 对象均可通过索引值访问(从1开始)
    fig, axes = plt.subplots(1, len(frames))
    # zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表
    for axis, frame in zip(axes, frames):
        # 让画布上的每一个子图显示一个图像
        axis.imshow((frame[1]-frame[0]))
        # 关闭所有坐标轴线、刻度标记和标签next(iternext(iter
        axis.axis("off")

    # 自动调整子图参数,使之填充整个图像区域
    plt.tight_layout()
    # 显示所有的figure,这是必要的,若没有则会出现,只出现一张子图的情况
    plt.show()

# 设置 CPU 生成随机数的 种子,可见不同的随机种子能够生成不同的随机数,但只要随机种子一样,每次运行代码都会生成该种子下的随机数
torch.manual_seed(1234)

# 手动转化
sensor_size = tonic.datasets.NMNIST.sensor_size
# 帧有尺寸(时间,极性数,高度和宽度)。让我们为N-MNIST样本中的三次扫视绘制一个帧。我们将利用两个相机的极性差来观察运动方向
    # 用时间箱将事件流划分为 数量为n_time_bins的事件帧
frame_transfrom = transforms.ToFrame(sensor_size=sensor_size,n_time_bins=6)
# 对事件进行去噪
denoise_transform = tonic.transforms.Denoise(filter_time=10000)
# 对事件的变化操作
transform = transforms.Compose([denoise_transform,frame_transfrom])


# 下载 NMINST 数据 --- 已经对NMINST中数据进行处理变为帧
dataset = tonic.datasets.NMNIST(
    save_to="/home/zxz/Proj/DP/Do/demo_03/Tonic_dir/tutorials/data", train=False, transform=transform
)

frame,target = dataset[1000]
plot_frames(frame)

ディスプレイ効果

画像-20230205143215481

おすすめ

転載: blog.csdn.net/A2000613/article/details/128924940