Tiling Motion Clouds

Script done in collaboration with Jean Spezia.

In [1]:
import os
In [2]:
import numpy as np
import MotionClouds as mc
size = 8
mc.N_X, mc.N_Y, mc.N_frame = 2**size, 2**size, 2**size
fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame)
name = 'MotionPlaid'
mc.figpath = '../files/2015-02-19_MotionPlaid'
mc.seed = 42
os.makedirs(mc.figpath, exist_ok=True)
!ls -lR
In [3]:
!mkdir -p results
In [4]:
#mask = 1 - np.abs(2*fx) - np.abs(2*fy)
#mask = 1.*(mask>0.)
#mask *= mask>0.
mask = 1 - np.max((np.abs(2*fx), np.abs(2*fy)), axis=0)
#mask = np.sqrt((2*fx)**2 + (2*fy)**2)
#mask = np.ones_like(fx)
print (mask.min(), mask.max(), mask.shape)
mc.anim_save(mask, os.path.join(mc.figpath, 'mask2'), verbose=False)
# mc.figures(mask, 'mask2', figpath=mc.figpath, seed=mc.seed, do_figs=False)
mc.in_show_video('mask2', figpath=mc.figpath)
0.0 1.0 (256, 256, 256)
In [5]:
N_orient, N_overlap = 8, 2
B_theta = 1.
In [6]:
mov = mc.np.zeros(((N_orient*mc.N_X), (N_orient*mc.N_X), mc.N_frame))
mov_mask = mc.np.zeros(((N_orient*mc.N_X), (N_orient*mc.N_X), mc.N_frame))
for i, theta1 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)[::-1]):
    diag1 = mc.envelope_gabor(fx, fy, ft, theta=theta1, V_X=np.cos(theta1), V_Y=np.sin(theta1), B_theta=B_theta)
    for j, theta2 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)):
        mov_ = np.zeros_like(mov)
        mov_mask_ = np.zeros_like(mov)
        diag2 = mc.envelope_gabor(fx, fy, ft, theta=theta2, V_X=np.cos(theta2), V_Y=np.sin(theta2), B_theta=B_theta)
        #mov[(i)*mc.N_X:(i+1)*mc.N_X, (j)*mc.N_Y : (j+1)*mc.N_Y, :] = mc.random_cloud(diag1 + diag2, seed=1234)
        mov_[:mc.N_X, :mc.N_Y, :] = mc.random_cloud(diag1 + diag2, seed=1234)*mask
        mov_mask_[:mc.N_X, :mc.N_Y, :] = mask
        #mov_[:mc.N_X, :mc.N_Y, :] = mask
        mov_ = np.roll(mov_, i*mc.N_X//N_overlap, axis=0)
        mov_ = np.roll(mov_, j*mc.N_Y//N_overlap, axis=1)
        mov += mov_
        mov_mask_ = np.roll(mov_mask_, i*mc.N_X//N_overlap, axis=0)
        mov_mask_ = np.roll(mov_mask_, j*mc.N_Y//N_overlap, axis=1)
        #print mov_mask_.max(), mov_mask_.min()
        mov_mask += mov_mask_
In [7]:
print (mov.max(), mov.min())
0.0014431233612189815 -0.001493586661014011
In [8]:
mc.anim_save(mc.rectif(mov, contrast=.99), os.path.join(mc.figpath, name), verbose=False)
mc.in_show_video(name, figpath=mc.figpath)
In [9]:
mov_=mc.anim_save(mc.rectif(mov_mask, contrast=.99), os.path.join(mc.figpath, name + '_mask'), verbose=False)
mc.in_show_video(name, figpath=mc.figpath)
In [10]:
mov_=mc.anim_save(mc.rectif(mov/mov_mask, contrast=.99), os.path.join(mc.figpath, name + '_div-mask'), verbose=False)
mc.in_show_video(name, figpath=mc.figpath)
In [11]:
print (mov_mask.max(), mov_mask.min())
2.0 1.0
In [12]:
A = np.random.rand(5, 5)
In [13]:
mc.rectif(A, contrast=1, verbose=False)
Out[13]:
array([[0.43064154, 0.685696  , 0.83759052, 0.57948009, 0.62478965],
       [0.12521843, 0.86895494, 0.21959545, 0.20643294, 0.41805521],
       [0.13307147, 0.53089714, 0.6082179 , 0.59117388, 0.21733599],
       [0.42241094, 0.31889594, 0.70038546, 0.7034166 , 0.85961836],
       [0.7500114 , 0.38186557, 0.        , 0.87463093, 0.41161366]])
In [14]:
A
Out[14]:
array([[0.47445221, 0.75463556, 0.9214953 , 0.63795487, 0.68772849],
       [0.13893768, 0.95594985, 0.24261308, 0.22815375, 0.46062583],
       [0.14756443, 0.58458535, 0.66952404, 0.65080079, 0.240131  ],
       [0.4654107 , 0.35169701, 0.77077229, 0.77410206, 0.9456934 ],
       [0.82528755, 0.42087064, 0.00138227, 0.96218506, 0.45354962]])
In [17]:
size = 6
mc.N_X, mc.N_Y, mc.N_frame = 2**size, 2**size, 2**size
fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame)

N_orient, N_overlap = 8, 3
B_theta = 1.
In [18]:
%%timeit -n1

mov = mc.np.zeros(((N_orient*mc.N_X), (N_orient*mc.N_X), mc.N_frame))

for i, theta1 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)[::-1]):
    diag1 = mc.envelope_gabor(fx, fy, ft, theta=theta1, V_X=np.cos(theta1), V_Y=np.sin(theta1), B_theta=B_theta)
    for j, theta2 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)):
        mov_ = np.zeros_like(mov)
        diag2 = mc.envelope_gabor(fx, fy, ft, theta=theta2, V_X=np.cos(theta2), V_Y=np.sin(theta2), B_theta=B_theta)
        #mov[(i)*mc.N_X:(i+1)*mc.N_X, (j)*mc.N_Y : (j+1)*mc.N_Y, :] = mc.random_cloud(diag1 + diag2, seed=1234)
        mov_[:mc.N_X, :mc.N_Y, :] = mc.random_cloud(diag1 + diag2, seed=1234)
        #mov_[:mc.N_X, :mc.N_Y, :] = mask
        mov_ = np.roll(mov_, i*mc.N_X//N_overlap, axis=0)
        mov_ = np.roll(mov_, j*mc.N_Y//N_overlap, axis=1)
        mov += mov_
1min 37s ± 2.34 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [19]:
%%timeit -n1

mov = mc.np.zeros(((N_orient*mc.N_X), (N_orient*mc.N_X), mc.N_frame))

for i, theta1 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)[::-1]):
    diag1 = mc.envelope_gabor(fx, fy, ft, theta=theta1, V_X=np.cos(theta1), V_Y=np.sin(theta1), B_theta=B_theta)
    mov_ = np.zeros_like(mov)
    mov_[:mc.N_X, :mc.N_Y, :] = mc.random_cloud(diag1, seed=1234)
    for j, theta2 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)):
        mov += np.roll(mov_, j*mc.N_Y//N_overlap, axis=1)
for j, theta2 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)):
    diag2 = mc.envelope_gabor(fx, fy, ft, theta=theta2, V_X=np.cos(theta2), V_Y=np.sin(theta2), B_theta=B_theta)
    mov_ = np.zeros_like(mov)
    mov_[:mc.N_X, :mc.N_Y, :] = mc.random_cloud(diag2, seed=1234)
    for i, theta1 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)[::-1]):
        mov += np.roll(mov_, i*mc.N_X//N_overlap, axis=0)
1min 4s ± 1.11 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [20]:
%%timeit -n1

mov = mc.np.zeros(((N_orient*mc.N_X), (N_orient*mc.N_X), mc.N_frame))
mov1 = mc.np.zeros(((N_orient*mc.N_X), (N_orient*mc.N_X), mc.N_frame))
mov2 = mc.np.zeros(((N_orient*mc.N_X), (N_orient*mc.N_X), mc.N_frame))

for i, theta1 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)[::-1]):
    diag1 = mc.envelope_gabor(fx, fy, ft, theta=theta1, V_X=np.cos(theta1), V_Y=np.sin(theta1), B_theta=B_theta)
    mov_ = np.zeros_like(mov)
    mov_[:mc.N_X, :mc.N_Y, :] = mc.random_cloud(diag1, seed=1234)
    mov1 += np.roll(mov_, i*mc.N_X//N_overlap, axis=0)
    mov2 += np.roll(mov_, i*mc.N_Y//N_overlap, axis=1)
    for j, theta2 in enumerate(np.linspace(0, 2*np.pi, N_orient*N_overlap, endpoint=False)):
        mov1 += np.roll(mov1, j*mc.N_Y//N_overlap, axis=1)
        mov2 += np.roll(mov2, j*mc.N_Y//N_overlap, axis=0)

mov = mov1 + mov2
1min 1s ± 1.19 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [21]:
%%timeit -n1

diag1 = mc.envelope_gabor(fx, fy, ft)
22.4 ms ± 2.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

some book keeping for the notebook

In [22]:
%load_ext watermark
%watermark -i -h -m -v -p numpy,matplotlib,scipy,pillow,imageio  -r -g -b
Python implementation: CPython
Python version       : 3.9.22
IPython version      : 8.18.1

numpy     : 1.26.4
matplotlib: 3.9.4
scipy     : 1.13.1
pillow    : not installed
imageio   : 2.37.0

Compiler    : Clang 16.0.0 (clang-1600.0.26.6)
OS          : Darwin
Release     : 24.5.0
Machine     : x86_64
Processor   : i386
CPU cores   : 36
Architecture: 64bit

Hostname: Ahsoka

Git hash: deee42141be8a69b1ce6e6c24fbc1f5b89ab26e8

Git repo: https://github.com/laurentperrinet/sciblog

Git branch: master