예제 #1
0
def wavelets_test():
    dt = 0.01  # sampling frequency
    dj = 0.125  # scale distribution parameter

    t = np.linspace(0, 250.0, int(250.0 / dt))

    # Signal
    batch = np.sin(np.exp((800 - t) / 150))

    wavelet = Morlet()

    # Initialize wavelet filter banks (scipy and torch implementation)
    wa_scipy = WaveletTransform(dt, dj, wavelet)

    # Performing wavelet transform (and compute scalogram)
    cwt_scipy = wa_scipy.power(batch)

    fig, ax = plt.subplots(1, 2, figsize=(12, 3))
    ax = ax.flatten()
    ax[0].plot(t, batch)
    ax[0].set_title(
        r"$f(t) = \sin(2\pi \cdot f t) + \mathcal{N}(\mu,\,\sigma^{2})$")
    ax[0].set_xlabel("Time (s)")
    plot_scalogram(cwt_scipy[0],
                   wa_scipy.fourier_periods,
                   t,
                   ax=ax[1],
                   scale_legend=False)
    ax[1].axhline(1.0 / frequencies[0], lw=1, color="k")
    ax[1].set_title("Scalogram (SciPy)".format(1.0 / frequencies[0]))
    plt.tight_layout()
    fig.savefig("wavelets.jpg", dpi=200)
    plt.show()
예제 #2
0
def test_cwt_scipy_multi_channel():
    # create random data
    n_samples = 100
    n_channels = 12
    signal_length = 42
    X = np.random.rand(n_samples, n_channels, signal_length)

    # execute wavelet transformation
    wa = WaveletTransform(dt=1.0, dj=0.125)
    wt = wa.cwt(X)
예제 #3
0
def test_cwt_scipy_vs_torch_single_channel():
    # create random data
    n_samples = 100
    signal_length = 42
    X = np.random.rand(n_samples, signal_length)

    # SciPy and PyTorch based wavelet transformation
    wa_scipy = WaveletTransform(dt=1.0, dj=0.125)
    wa_torch = WaveletTransformTorch(dt=1.0, dj=0.125, cuda=False)
    cwt_scipy = wa_scipy.cwt(X)
    cwt_torch = wa_torch.cwt(X)

    # ensure that the exact same scales were used
    assert np.array_equal(wa_scipy.scales, wa_torch.scales)
    assert np.allclose(cwt_torch, cwt_scipy, rtol=1e-5, atol=1e-6)

    # test correct sizes
    assert cwt_torch.shape == (n_samples, len(wa_scipy.scales), signal_length)
    assert cwt_scipy.shape == (n_samples, len(wa_torch.scales), signal_length)
예제 #4
0
def pipeline():
    phases = (
        "resized",
        "gray",
        "optical-flow",
        "optical-flow-over-resized",
        "Fx",
        "Fy",
        "dxfx",
        "dxfy",
        "dyfy",
        "dyfx",
        "divergence",
        "curl",
        "shear",
    )
    differential_maps = (
        "Fx",
        "Fy",
        "dxfx",
        "dyfy",
        "divergence",
        "curl",
    )
    cfg = VideoConfiguration(
        phases=phases,
        differential_maps=differential_maps,
        save_phase_as_video={phase: True
                             for phase in phases},
        save_phase_as_ndarray={phase: True
                               for phase in phases},
        plot_phase={phase: False
                    for phase in phases},
        input_filepath="resources/input/animation.mp4",
        # input_filepath="resources/input/pushups_6sec.mp4",
        # input_filepath="resources/input/QUVARepetitionDataset/videos/078_ski_waxing.mp4",
        # input_filepath="resources/input/QUVARepetitionDataset/videos/014_weights_floor.mp4",
        # input_filepath="resources/input/QUVARepetitionDataset/videos/097_swimming_freestyle.mp4",
        max_dimension_size=6400,
        gpu=True,
        read_frames=False,
    )

    # TODO: save & read frames
    #  different phases require different pix_fmt

    frames = preprocess_video(cfg=cfg)

    frames = {
        motion: data
        for motion, data in frames.items() if motion in cfg.differential_maps
    }

    power_maps = {}
    for motion in cfg.differential_maps:

        motion_map = frames[motion]  # t x N x M
        power_maps[motion] = np.ndarray(shape=motion_map.shape)

        pixel_coordinates = list(
            itertools.product(range(motion_map.shape[1]),
                              range(motion_map.shape[2])))

        dpi = 100
        dt = 1 / cfg.fps  # sampling frequency
        dj = 1 / 8  # scale distribution parameter
        wavelet = Morlet(w0=6)
        batch_size = 2048
        if cfg.gpu:
            wavelet_transform = WaveletTransformTorch(dt,
                                                      dj,
                                                      wavelet,
                                                      cuda=True)

            signals = np.array(
                [motion_map[:, x, y] for x, y in pixel_coordinates])  # N*M x t

            power_spectrums = []
            for batch in tqdm.tqdm(
                    np.array_split(signals,
                                   len(signals) // batch_size)):
                results = wavelet_transform.power(batch)  # b x J x t
                power_spectrums.extend(results)

            power_spectrums = np.array(power_spectrums)  # N*M x J x t
            power_maps[motion] = np.amax(power_spectrums, axis=1)  # N*M x t
            reshape = (
                motion_map.shape[1],
                motion_map.shape[2],
                power_spectrums.shape[-1],
            )
            power_maps[motion] = power_maps[motion].reshape(
                reshape)  # N x M x t
            power_maps[motion] = np.moveaxis(power_maps[motion], 2,
                                             0)  # t x N x M

        else:
            wavelet_transform = WaveletTransform(dt, dj, wavelet)

            # TODO: meshgrid ?
            for (x, y) in tqdm.tqdm(pixel_coordinates):
                signal = motion_map[:, x, y]
                power_spectrum = wavelet_transform.power(signal)  # J x t
                power_maps[motion][:, x, y] = np.amax(power_spectrum,
                                                      axis=0)  # t x N x M

    # In case to much 0s make mean thresholding useless
    # threshold = power_maps["total_mean_th"].mean()
    # threshold = power_maps["total_mean_th"][power_maps["total_mean_th"] > 0].mean()

    power_maps["total"] = np.sum(np.asarray(list(power_maps.values())), axis=0)
    power_maps["total_mean_th"] = power_maps["total"].copy()
    threshold = np.unique(power_maps["total_mean_th"]).mean()
    mask = power_maps["total_mean_th"] < threshold
    logging.info(
        f"{round(threshold, 2)} -- {np.count_nonzero(mask)} out of {mask.size}, {round(np.count_nonzero(mask) / mask.size, 2) * 100} are below threshold"
    )
    power_maps["total_mean_th"][mask] = 0
    logging.debug(
        f"Min power in power map before thresholding: {sorted(np.unique(power_maps['total']))[:10]} and after {sorted(np.unique(power_maps['total_mean_th']))[:10]}"
    )

    for mmap, arr in power_maps.items():
        logging.debug(
            f"{mmap}, {round(np.min(arr), 2)}, {round(np.mean(arr), 2)}, {round(np.max(arr), 2)}"
        )

    vmax = np.max(power_maps["total"])
    for motion, power_map in power_maps.items():
        pixel_map = []
        xv, yv = np.meshgrid(range(power_map.shape[2]),
                             range(power_map.shape[1]))
        for i in tqdm.tqdm(range(power_map.shape[0])):  # for i in t
            fig, ax = plt.subplots(
                figsize=(
                    power_map.shape[2] / dpi,
                    power_map.shape[1] / dpi,
                ),
                dpi=dpi,
                frameon=False,
                clear=True,
                tight_layout={"pad": 0},
            )
            ax.set_axis_off()
            plt.subplots_adjust(top=1,
                                bottom=0,
                                right=1,
                                left=0,
                                hspace=0,
                                wspace=0)
            plt.margins(0, 0)

            cnt = ax.contourf(
                xv,
                yv,
                power_map[i],
                100,
                cmap=plt.get_cmap("PuBu_r"),
                vmin=0,
                vmax=vmax,
            )

            # Fix for saving as PDF (aliasing)
            for c in cnt.collections:
                c.set_edgecolor("face")

            # Save separate frames as images
            # Path(
            #     f"resources/output/{cfg.input_filename}/{motion}/{i}.png"
            # ).parent.mkdir(parents=True, exist_ok=True)
            # plt.savefig(f"resources/output/{cfg.input_filename}/{motion}/{i}.png")

            fig.canvas.draw()
            buf = fig.canvas.tostring_rgb()
            ncols, nrows = fig.canvas.get_width_height()
            data = np.frombuffer(buf, dtype=np.uint8).reshape(nrows, ncols, 3)
            pixel_map.append(data)
            plt.close("all")

        pixel_map = np.array(pixel_map)
        pixel_map = np.flip(pixel_map, axis=1)

        power_output_fname = (
            f"resources/output/{cfg.input_filename}/_power_{motion}.mp4")
        Path(power_output_fname).parent.mkdir(parents=True, exist_ok=True)
        video_write(
            output_fname=power_output_fname,
            images=pixel_map,
            framerate=cfg.fps,
        )
예제 #5
0
t_min = 0
t_max = 10
t = np.linspace(t_min, t_max, (t_max - t_min) * fps)

######################################
# Generating batch of random sinusoidals

random_frequencies = np.random.uniform(0.5, 4.0, size=batch_size)
batch = np.asarray([np.sin(2 * np.pi * f * t) for f in random_frequencies])
batch += np.random.normal(0, 0.2, batch.shape)  # Gaussian noise

######################################
# Performing wavelet transform

wa = WaveletTransform(dt, dj, wavelet, unbias=unbias)
wa_torch = WaveletTransformTorch(dt, dj, wavelet, unbias=unbias, cuda=cuda)

power = wa.power(batch)
batch_torch = torch.tensor(batch[:, None, :],
                           dtype=torch.float,
                           device='cuda' if cuda else 'cpu')
power_torch = wa_torch.power(batch_torch).cpu()

######################################
# Plotting

fig, ax = plt.subplots(1, 3, figsize=(12, 3))
ax = ax.flatten()
ax[0].plot(t, batch[0])
ax[0].set_title(
예제 #6
0
# Author: Tom Runia
# Date Created: 2018-04-16

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
from wavelets_pytorch.transform import WaveletTransform  # SciPy version
from wavelets_pytorch.transform import WaveletTransformTorch  # PyTorch version

dt = 0.1  # sampling frequency
dj = 0.125  # scale distribution parameter
batch_size = 32  # how many signals to process in parallel

t = np.linspace(0., 10., int(10. / dt))

# Sinusoidals with random frequency
frequencies = np.random.uniform(-0.5, 2.0, size=batch_size)
batch = np.asarray([np.sin(2 * np.pi * f * t) for f in frequencies])

# Initialize wavelet filter banks (scipy and torch implementation)
wa_scipy = WaveletTransform(dt, dj)
wa_torch = WaveletTransformTorch(dt, dj, cuda=True)

# Performing wavelet transform (and compute scalogram)
cwt_scipy = wa_scipy.cwt(batch)
cwt_torch = wa_torch.cwt(batch)

# For plotting, see the examples/plot.py function.
# ...