{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Motion Clouds utilities\n",
"\n",
"Here, we test some of the utilities that are delivered with the MotionClouds package.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import MotionClouds as mc"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"mc.N_X, mc.N_Y, mc.N_frame = 30, 40, 50\n",
"fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## generating figures"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As they are visual stimuli, the main outcome of the scripts are figures. Utilities allow to plot all figures, usually marked by a name:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"name = 'testing_utilities'"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function figures_MC in module MotionClouds:\n",
"\n",
"figures_MC(fx, fy, ft, name, V_X=1.0, V_Y=0.0, do_figs=True, do_movie=True, B_V=0.5, sf_0=0.125, B_sf=0.1, loggabor=True, recompute=False, theta=0.0, B_theta=0.19634954084936207, alpha=0.0, vext='.mp4', seed=None, impulse=False, do_amp=False, verbose=False, figpath='../files/', return_envelope=False, **kwargs)\n",
" Generates the figures corresponding to the Fourier spectra and the stimulus cubes and\n",
" movies directly from the parameters.\n",
" \n",
" The figures names are automatically generated.\n",
"\n"
]
}
],
"source": [
"help(mc.figures_MC)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"mc.figures_MC(fx, fy, ft, name, recompute=True)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function in_show_video in module MotionClouds:\n",
"\n",
"in_show_video(name, vext='.mp4', loop=True, autoplay=True, controls=True, embed=False, figpath='../files/', **kwargs)\n",
" Columns represent isometric projections of a cube. The left column displays\n",
" iso-surfaces of the spectral envelope by displaying enclosing volumes at 5\n",
" different energy values with respect to the peak amplitude of the Fourier spectrum.\n",
" The middle column shows an isometric view of the faces of the movie cube.\n",
" The first frame of the movie lies on the x-y plane, the x-t plane lies on the\n",
" top face and motion direction is seen as diagonal lines on this face (vertical\n",
" motion is similarly see in the y-t face). The third column displays the actual\n",
" movie as an animation.\n",
" \n",
" Given a name, displays the figures corresponding to the Fourier spectra, the\n",
" stimulus cubes and movies within the notebook.\n",
"\n"
]
}
],
"source": [
"help(mc.in_show_video)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"mc.in_show_video(name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This function embeds the images and video *within* the notebook. Sometimes you want to avoid that:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"mc.in_show_video(name, embed=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sometimes, you may have already computed some envelope or just want to distort it, then you can use ``mc.figures``:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"env = mc.envelope_gabor(fx, fy, ft)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function figures in module MotionClouds:\n",
"\n",
"figures(z=None, name='MC', vext='.mp4', do_movie=True, do_figs=True, recompute=False, seed=None, impulse=False, verbose=False, masking=False, do_amp=False, figpath='../files/', **kwargs)\n",
" Given an envelope, generates the figures corresponding to the Fourier spectra\n",
" and the stimulus cubes and movies.\n",
" \n",
" The figures names are automatically generated.\n",
"\n"
]
}
],
"source": [
"help(mc.figures)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"mc.figures(np.sqrt(env), name + '_0')"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
\n",
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"mc.in_show_video(name + '_0')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## low-level figures : 3D visualizations"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function cube in module MotionClouds:\n",
"\n",
"cube(im_in, azimuth=30.0, elevation=45.0, name=None, ext='.png', do_axis=True, show_label=True, cube_label={'x': 'x', 'y': 'y', 't': 't'}, colormap='gray', roll=-180.0, vmin=0.0, vmax=1.0, figsize=(800, 800), figpath='../files/', **kwargs)\n",
" Visualization of the stimulus as a cube\n",
"\n"
]
}
],
"source": [
"help(mc.cube)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function visualize in module MotionClouds:\n",
"\n",
"visualize(z_in, azimuth=25.0, elevation=30.0, thresholds=[0.94, 0.89, 0.75, 0.5, 0.25, 0.1], opacities=[0.9, 0.8, 0.7, 0.5, 0.2, 0.1], fourier_label={'f_x': 'f_x', 'f_y': 'f_y', 'f_t': 'f_t'}, name=None, ext='.png', do_axis=True, do_grids=False, draw_projections=True, colorbar=False, f_N=2.0, f_tN=2.0, figsize=(800, 800), figpath='../files/', **kwargs)\n",
" Visualization of the Fourier spectrum by showing 3D contour plots at different thresholds\n",
" \n",
" parameters\n",
" ----------\n",
" z : envelope of the cloud\n",
"\n"
]
}
],
"source": [
"help (mc.visualize)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Handling filenames"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"By default, the folder for generating figures or data is ``mc.figpath``:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"../files/\n"
]
}
],
"source": [
"print(mc.figpath)"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"print(os.listdir(mc.figpath))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To generate figures, we assign file names, such as:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"filename = os.path.join(mc.figpath, name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is then possible to check if that figures exist:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"filename= ../files/testing_utilities , exists? : False\n"
]
}
],
"source": [
"print('filename=', filename, ', exists? : ', mc.check_if_anim_exist(filename))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the file won't be recomputed if it exists:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"mc.figures(env, name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This behavior can be overriden using the recompute option"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"mc.figures(env, name, recompute=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Warning: be sure that when you display a given file, it corresponds to the parameters you have set for your stimulus."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## low-level figures : exporting to various formats"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is possible to export motion clouds to many different formats. Here are some examples:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"!rm -fr ../files/export"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Exporting to format: .h5\n",
"Exporting to format: .mpg\n",
"Exporting to format: .mp4\n",
"Exporting to format: .gif\n",
"Exporting to format: .webm\n",
"Exporting to format: .zip\n",
"Exporting to format: .mat\n",
"Exporting to format: .png\n"
]
}
],
"source": [
"name = 'export'\n",
"fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame)\n",
"z = mc.rectif(mc.random_cloud(mc.envelope_gabor(fx, fy, ft)))\n",
"mc.PROGRESS = False\n",
"for vext in mc.SUPPORTED_FORMATS:\n",
" print ('Exporting to format: ', vext)\n",
" mc.anim_save(z, os.path.join(mc.figpath, name), display=False, vext=vext, verbose=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## showing a video"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To show a video in a notebook, issue:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"
\n",
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"mc.notebook = True # True by default\n",
"mc.in_show_video('export')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Rectifying the contrast"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The ``mc.rectif`` function allows to rectify the amplitude of luminance values within the whole generated texture between $0$ and $1$:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Min : -2.21666797481 , mean: -1.70234197109e-19 , max: 2.09408478901\n"
]
}
],
"source": [
"fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame)\n",
"envelope = mc.envelope_gabor(fx, fy, ft)\n",
"image = mc.random_cloud(envelope)\n",
"print('Min :', image.min(), ', mean: ', image.mean(), ', max: ', image.max())"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Min : 0.0 , mean: 0.5 , max: 0.972349673655\n"
]
}
],
"source": [
"image = mc.rectif(image)\n",
"print('Min :', image.min(), ', mean: ', image.mean(), ', max: ', image.max())"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"import pylab\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import math\n",
"%matplotlib inline\n",
"#%config InlineBackend.figure_format='retina' # high-def PNGs, quite bad when using file versioning\n",
"%config InlineBackend.figure_format='svg'"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Before Rectification of the frames\n",
"Mean= 1.06581410364e-18 , std= 0.84527878442 , Min= -3.07067785094 , Max= 3.47591337022 Abs(Max)= 3.47591337022\n",
"After Rectification of the frames\n",
"Mean= 0.5 , std= 0.0303977219219 , Min= 0.389572986872 , Max= 0.625\n",
"percentage pixels clipped= 0.0\n",
"Before Rectification of the frames\n",
"Mean= -1.18423789293e-19 , std= 0.817871986507 , Min= -3.42450006883 , Max= 3.40014935729 Abs(Max)= 3.42450006883\n",
"After Rectification of the frames\n",
"Mean= 0.5 , std= 0.125 , Min= -0.0233857078689 , Max= 1.01966405094\n",
"percentage pixels clipped= 0.005\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"name = 'contrast_methods-'\n",
"#initialize\n",
"fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame)\n",
"ext = '.zip'\n",
"contrast = 0.25\n",
"B_sf = 0.3\n",
"\n",
"for method in ['Michelson', 'Energy']:\n",
" z = mc.envelope_gabor(fx, fy, ft, B_sf=B_sf)\n",
" im = np.ravel(mc.random_cloud(z, seed =1234))\n",
" im_norm = mc.rectif(mc.random_cloud(z), contrast, method=method, verbose=True)\n",
" plt.figure()\n",
" plt.subplot(111)\n",
" plt.title(method + ' Histogram Ctr: ' + str(contrast))\n",
" plt.ylabel('pixel counts')\n",
" plt.xlabel('grayscale')\n",
" bins = int((np.max(im_norm[:])-np.min(im_norm[:])) * 256)\n",
" plt.xlim([0, 1])\n",
" plt.hist(np.ravel(im_norm), bins=bins, normed=False, facecolor='blue', alpha=0.75)\n",
" #plt.savefig(name_)\n",
"\n",
"def image_entropy(img):\n",
" \"\"\"calculate the entropy of an image\"\"\"\n",
" histogram = img.histogram()\n",
" histogram_length = np.sum(histogram)\n",
" samples_probability = [float(h) / histogram_length for h in histogram]\n",
" return -np.sum([p * math.log(p, 2) for p in samples_probability if p != 0])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we normalise the histogram then the entropy base on gray levels is going to be the almost the same.\n",
" TODO: Review the idea of entropy between narrowband and broadband stimuli."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 1
}