分析import h5py
import numpy as np
import os

def compute_indices(event_stamps, frame_stamps):
    """
    Given event timestamps and frame timestamps as arrays,
    find the event indices that correspond to the beginning and
    end period of each frames
    @param event_stamps The event timestamps
    @param frame_stamps The frame timestamps
    @returns The indices as a 2xN numpy array (N=number of frames)
    """
    indices_first = np.searchsorted(event_stamps[:,0], frame_stamps[1:])
    indices_last = np.searchsorted(event_stamps[:,0], frame_stamps[:-1])
    index = np.stack([indices_first, indices_last], -1)
    return index

def read_memmap_events(memmap_path, skip_frames=1, return_events=False, images_file = 'images.npy',
        images_ts_file = 'timestamps.npy', optic_flow_file = 'optic_flow.npy',
        optic_flow_ts_file = 'optic_flow_timestamps.npy', events_xy_file = 'xy.npy',
        events_p_file = 'p.npy', events_t_file = 't.npy'):
    """
    Given a path to an RPG-style memmap, read the events it contains.
    These memmaps break images, timestamps, optic flow, xy, p and t
    components of events into separate files.
    @param memmap_path Path to the root directory of the memmap
    @param skip_frames Skip reading every 'skip_frames'th frame, default=1
    @param return_events If True, return the events as numpy arrays, else return
        a handle to the event data files (which can be indexed, but does not load
        events into RAM)
    @param images_file The file containing images
    @param images_ts_file The file containing image timestamps
    @param optic_flow_file The file containing optic flow frames
    @param optic_flow_ts_file The file containing optic flow frame timestamps
    @param events_xy_file The file containing event coordinate data
    @param events_p_file The file containing the event polarities
    @param events_ts_file The file containing the event timestamps
    @return dict with event data:
        data = {
            "index": index mapping image index to event idx
            "frame_stamps": frame timestamps
            "images": images
            "optic_flow": optic flow
            "optic_flow_stamps": of timestamps
            "t": event timestamps
            "xy": event coords
            "p": event polarities
            "t0": t0
    """
    assert os.path.isdir(memmap_path), '%s is not a valid memmap_pathectory' % memmap_path

    data = {}
    has_flow = False
    for subroot, _, fnames in sorted(os.walk(memmap_path)):
        for fname in sorted(fnames):
            path = os.path.join(subroot, fname)
            if fname.endswith(".npy"):
                if fname=="index.npy":  # index mapping image index to event idx
                    indices = np.load(path)  # N x 2
                    assert len(indices.shape) == 2 and indices.shape[1] == 2
                    indices = indices.astype("int64")  # ignore event indices which are 0 (before first image)
                    data["index"] = indices.T
                elif fname==images_ts_file:
                    data["frame_stamps"] = np.load(path)[::skip_frames,...]
                elif fname==images_file:
                    data["images"] = np.load(path, mmap_mode="r")[::skip_frames,...]
                elif fname==optic_flow_file:
                    data["optic_flow"] = np.load(path, mmap_mode="r")[::skip_frames,...]
                    has_flow = True
                elif fname==optic_flow_ts_file:
                    data["optic_flow_stamps"] = np.load(path)[::skip_frames,...]

                handle = np.load(path, mmap_mode="r")
                if fname==events_t_file:  # timestamps
                    data["t"] = handle[:].squeeze() if return_events else handle
                    data["t0"] = handle[0]
                elif fname==events_xy_file: # coordinates
                    data["xy"] = handle[:].squeeze() if return_events else handle
                elif fname==events_p_file: # polarity
                    data["p"] = handle[:].squeeze() if return_events else handle

        if len(data) > 0:
            data['path'] = subroot
            if "t" not in data:
                raise Exception(f"Ignoring memmap_pathectory {subroot} since no events")
            if not (len(data['p']) == len(data['xy']) and len(data['p']) == len(data['t'])):
                raise Exception(f"Events from {subroot} invalid")
            data["num_events"] = len(data['p'])

            if "index" not in data and "frame_stamps" in data:
                data["index"] = compute_indices(data["t"], data['frame_stamps'])
    return data

def read_memmap_events_dict(memmap_path, skip_frames=1, return_events=False, images_file = 'images.npy',
        images_ts_file = 'timestamps.npy', optic_flow_file = 'optic_flow.npy',
        optic_flow_ts_file = 'optic_flow_timestamps.npy', events_xy_file = 'xy.npy',
        events_p_file = 'p.npy', events_t_file = 't.npy'):
    """
    Read memmap file events and return them in a dict
    """
    data = read_memmap_events(memmap_path, skip_frames, return_events, images_file, images_ts_file,
            optic_flow_file, optic_flow_ts_file, events_xy_file, events_p_file, events_t_file)
    events = {
            'xs':data['xy'][:,0].squeeze(),
            'ys':data['xy'][:,1].squeeze(),
            'ts':events['t'][:].squeeze(),
            'ps':events['p'][:].squeeze()}
    return events

def read_h5_events(hdf_path):
    """
    Read events from HDF5 file (Monash style).
    @param hdf_path Path to HDF5 file
    @returns Events as 4xN numpy array (N=num events)
    """
    f = h5py.File(hdf_path, 'r')
    if 'events/x' in f:
        #legacy
        events = np.stack((f['events/x'][:], f['events/y'][:], f['events/ts'][:], np.where(f['events/p'][:], 1, -1)), axis=1)
    else:
        events = np.stack((f['events/xs'][:], f['events/ys'][:], f['events/ts'][:], np.where(f['events/ps'][:], 1, -1)), axis=1)
    return events

def read_h5_event_components(hdf_path):
    """
    Read events from HDF5 file (Monash style).
    @param hdf_path Path to HDF5 file
    @returns Events as four np arrays with the event components
    """
    f = h5py.File(hdf_path, 'r')
    if 'events/x' in f:
        #legacy
        return (f['events/x'][:], f['events/y'][:], f['events/ts'][:], np.where(f['events/p'][:], 1, -1))
    else:
        return (f['events/xs'][:], f['events/ys'][:], f['events/ts'][:], np.where(f['events/ps'][:], 1, -1))

def read_h5_events_dict(hdf_path, read_frames=True):
    """
    Read events from HDF5 file (Monash style).
    @param hdf_path Path to HDF5 file
    @returns Events as a dict with entries 'xs', 'ys', 'ts', 'ps' containing the event components,
        'frames' containing the frames, 'frame_timestamps' containing frame timestamps and
        'frame_event_indices' containing the indices of the corresponding event for each frame
    """
    f = h5py.File(hdf_path, 'r')
    if 'events/x' in f:
        #legacy
        events = {
                'xs':f['events/x'][:],
                'ys':f['events/y'][:],
                'ts':f['events/ts'][:],
                'ps':np.where(f['events/p'][:], 1, -1)
        }
        return events
    else:
        events = {
                'xs':f['events/xs'][:],
                'ys':f['events/ys'][:],
                'ts':f['events/ts'][:],
                'ps':np.where(f['events/ps'][:], 1, -1)
                }
        if read_frames:
            images = []
            image_stamps = []
            image_event_indices = []
            for key in f['images']:
                frame = f['images/{}'.format(key)][:]
                images.append(frame)
                image_stamps.append(f['images/{}'.format(key)].attrs['timestamp'])
                image_event_indices.append(f['images/{}'.format(key)].attrs['event_idx'])
            events['frames'] = images
            #np.concatenate(images, axis=2).swapaxes(0,2) if len(frame.shape)==3 else np.stack(images, axis=0)
            events['frame_timestamps'] = np.array(image_stamps)
            events['frame_event_indices'] = np.array(image_event_indices)
        return events和import argparse
import os
import numpy as np
from lib.data_formats.read_events import read_memmap_events, read_h5_events_dict

if __name__ == "__main__":
    """
    Quick demo
    """
    parser = argparse.ArgumentParser()
    parser.add_argument("path", help="memmap events path")
    parser.add_argument("--output_path", type=str, default="/tmp/visualization", help="Where to save image outputs")

    parser.add_argument('--plot_method', default='between_frames', type=str,
                        help='which method should be used to visualize',
                        choices=['between_frames', 'k_events', 't_seconds'])
    parser.add_argument('--w_width', type=float, default=0.01,
                        help='new plot is formed every t seconds (required if voxel_method is t_seconds)')
    parser.add_argument('--sw_width', type=float,
                        help='sliding_window size in seconds (required if voxel_method is t_seconds)')

    parser.add_argument("--num_bins", type=int, default=6, help="How many bins voxels should have.")

    parser.add_argument('--show_plot', action='store_true', help='If true, will also display the plot in an interactive window.\
            Useful for selecting the desired orientation.')

    parser.add_argument("--num_show", type=int, default=-1, help="How many events to show per plot. If -1, show all events.")
    parser.add_argument("--event_size", type=float, default=2, help="Marker size of the plotted events")
    parser.add_argument("--ts_scale", type=int, default=10000, help="Scales the time axis. Only applicable for mayavi rendering.")
    parser.add_argument("--elev", type=float, default=20, help="Elevation of plot")
    parser.add_argument("--azim", type=float, default=45, help="Azimuth of plot")
    parser.add_argument("--stride", type=int, default=1, help="Downsample stride for plotted images.")
    parser.add_argument("--skip_frames", type=int, default=1, help="Amount of frames to place per plot.")
    parser.add_argument("--start_frame", type=int, default=0, help="On which frame to start.")
    parser.add_argument('--hide_skipped', action='store_true', help='Do not draw skipped frames into plot.')
    parser.add_argument('--hide_events', action='store_true', help='Do not draw events')
    parser.add_argument('--hide_frames', action='store_true', help='Do not draw frames')
    parser.add_argument('--show_axes', action='store_true', help='Draw axes')
    parser.add_argument("--num_compress", type=int, default=0, help="How many events to draw compressed. If 'auto'\
            will automatically determine.", choices=['value', 'auto'])
    parser.add_argument('--compress_front', action='store_true', help='If set, will put the compressed events at the _start_\
            of the event volume, rather than the back.')
    parser.add_argument('--invert', action='store_true', help='If the figure is for a black background, you can invert the \
            colors for better visibility.')
    parser.add_argument("--crop", type=str, default=None, help="Set a crop of both images and events. Uses 'imagemagick' \
            syntax, eg for a crop of 10x20 starting from point 30,40 use: 10x20+30+40.")
    parser.add_argument("--renderer", type=str, default="matplotlib", help="Which renderer to use (mayavi is faster)", choices=["matplotlib", "mayavi"])
    args = parser.parse_args()

    if os.path.isdir(args.path):
        events = read_memmap_events(args.path)

        ts = events['t'][:].squeeze()
        t0 = ts[0]
        ts = ts-t0
        frames = (events['images'][args.start_frame+1::])/255
        frame_idx = events['index'][args.start_frame::]
        frame_ts = events['frame_stamps'][args.start_frame+1::]-t0

        start_idx = np.searchsorted(ts, frame_ts[0])
        print("Starting from frame {}, event {}".format(args.start_frame, start_idx))

        xs = events['xy'][:,0]
        ys = events['xy'][:,1]
        ts = ts[:]
        ps = events['p'][:]

        print("Have {} frames".format(frames.shape))
    else:
        events = read_h5_events_dict(args.path)
        xs = events['xs']
        ys = events['ys']
        ts = events['ts']
        ps = events['ps']
        t0 = ts[0]
        ts = ts-t0
        frames = [np.flip(np.flip(x/255., axis=0), axis=1) for x in events['frames']]
        frame_ts = events['frame_timestamps'][1:]-t0
        frame_end = events['frame_event_indices'][1:]
        frame_start = np.concatenate((np.array([0]), frame_end))
        frame_idx = np.stack((frame_end, frame_start[0:-1]), axis=1)
        ys = frames[0].shape[0]-ys
        xs = frames[0].shape[1]-xs

    if args.plot_method == 'between_frames':
        if args.renderer == "mayavi":
            from lib.visualization.draw_event_stream_mayavi import plot_between_frames
            plot_between_frames(xs, ys, ts, ps, frames, frame_idx, args, plttype='events')
        elif args.renderer == "matplotlib":
            from lib.visualization.draw_event_stream import plot_between_frames
            plot_between_frames(xs, ys, ts, ps, frames, frame_idx, args, plttype='events')
    elif args.plot_method == 'k_events':
        print(args.renderer)
        pass
    elif args.plot_method == 't_seconds':
        if args.renderer == "mayavi":
            from lib.visualization.draw_event_stream_mayavi import plot_events_sliding
            plot_events_sliding(xs, ys, ts, ps, args, dt=args.w_width, sdt=args.sw_width, frames=frames, frame_ts=frame_ts)
        elif args.renderer == "matplotlib":
            from lib.visualization.draw_event_stream import plot_events_sliding
            plot_events_sliding(xs, ys, ts, ps, args, frames=frames, frame_ts=frame_ts)，分析作用