GEOMETRY MIXINS EXAMPLE I

HERE WE DIVIDE THE EXPERIMENTAL ARENA INTO GEOMETRIES, AND COMPUTE AND VISUALIZE THE TIME THAT THE ANIMAL SPENDS IN THE DIFFERENT ARENA GEOMETRIES

[1]:
import numpy as np
import os
import cv2
from simba.mixins.geometry_mixin import GeometryMixin
from simba.mixins.config_reader import ConfigReader
from simba.utils.read_write import read_df, read_frm_of_video
from simba.mixins.plotting_mixin import PlottingMixin
import matplotlib.pyplot as plt
import matplotlib
dpi = matplotlib.rcParams['figure.dpi']
[2]:
# DEFINE PROJECT AND VIDEO NAME
PROJECT_PATH = r'/Users/simon/Desktop/envs/troubleshooting/Rat_NOR/project_folder/project_config.ini'
VIDEO_NAME = '2022-06-20_NOB_DOT_4'
BP = 'Nose' # THE BODY-PART WE WILL USE TO INFER POSITION OF ANIMAL
[3]:
# READ IN THE DATA, VIDEO SIZE, FPS, AND PIXEL CONVERSION FACTOR.
config = ConfigReader(config_path=PROJECT_PATH, create_logger=False)
video_info, px_per_mm, fps = config.read_video_info(video_name=VIDEO_NAME)
width, height = int(video_info['Resolution_width'].values[0]), int(video_info['Resolution_height'].values[0])
bp = [f'{BP}_x', f'{BP}_y']
data_path = os.path.join(config.outlier_corrected_dir, VIDEO_NAME + f'.{config.file_type}')
data = read_df(file_path=data_path, usecols=bp, file_type=config.file_type)
[4]:
# WE CREATE A SQUARE GEOMETRY GRID WHICH IS 5 BY 5 LARGE TO COVER THE EXPERIMENTAL ARENA
GRID_SIZE = (5, 5) # THE SIXE OF THE GRID WE WILL CREATE
grid, aspect_ratio = GeometryMixin().bucket_img_into_grid_square(img_size=(width, height), bucket_grid_size=GRID_SIZE, px_per_mm=px_per_mm)
SIMBA COMPLETE: Bucket image into grid squares complete (elapsed time: 0.0004s)         complete
[5]:
# WE VISUALIZE THE GRID AS A SANITY CHECK
video_path = r'/Users/simon/Desktop/envs/troubleshooting/Rat_NOR/project_folder/videos/2022-06-20_NOB_DOT_4.mp4'
video_frm = read_frm_of_video(video_path=video_path, frame_index=0, opacity=30)
img = GeometryMixin().view_shapes(shapes=list(grid.values()), bg_img=video_frm)
height, width, depth = img.shape
figsize = width / float(dpi), height / float(dpi)

plt.figure(figsize=figsize)
plt.axis('off')
plt.imshow(img)
plt.show()
../_images/nb_geometry_example_1_6_0.png
[6]:
# ALTERNATIVE: IF YOU PREFER HEXAGONAL GRID, USE simba.mixins.geometry_mixins.GeometryMixin.bucket_img_into_grid_hexagon()
hex_grid, aspect_ratio = GeometryMixin().bucket_img_into_grid_hexagon(img_size=(width, height), bucket_size_mm=20, px_per_mm=px_per_mm)
video_frm = read_frm_of_video(video_path=video_path, frame_index=0, opacity=30)
img = GeometryMixin().view_shapes(shapes=list(hex_grid.values()), bg_img=video_frm)

plt.figure(figsize=figsize)
plt.axis('off')
plt.imshow(img)
plt.show()
SIMBA COMPLETE: Bucket image into hexagon grid complete (elapsed time: 0.0059s)         complete
../_images/nb_geometry_example_1_7_1.png
[7]:
# ALTERNATIVE: IF YOU PREFER TRIANGULATES GRID, USE simba.mixins.geometry_mixins.GeometryMixin.delaunay_triangulate_keypoints()
grid_points = GeometryMixin().bucket_img_into_grid_points(point_distance=100, px_per_mm=px_per_mm, img_size=(width, height), border_sites= False)
grid_point_locations = np.full((len(list(grid_points.keys()), ), 2), np.nan)
for cnt, (k, v) in enumerate(grid_points.items()): grid_point_locations[cnt] = np.array(v)
delaunay_grid = GeometryMixin().delaunay_triangulate_keypoints(data=grid_point_locations)

video_frm = read_frm_of_video(video_path=video_path, frame_index=0, opacity=10)
img = GeometryMixin().view_shapes(shapes=delaunay_grid, bg_img=video_frm)

plt.figure(figsize=figsize)
plt.axis('off')
plt.imshow(img)
plt.show()
SIMBA COMPLETE: Bucket image into grid points complete (elapsed time: 0.0089s)  complete
../_images/nb_geometry_example_1_8_1.png
[8]:
# WE CALCULATE THE CUMULATIVE TIME THE ANIMAL SPENDS IN EACH GEOMETRY
time_data = GeometryMixin().cumsum_coord_geometries(data=data.values, geometries=grid, fps=fps, verbose=False)
SIMBA COMPLETE: Cumulative coordinates in geometries complete (elapsed time: 5.0678s)   complete
[9]:
#THIS RETURNS A 3D ARRAY, WHERE THE LAST 2D ARRAY CORRESPONDS WITH THE CUMULATIVE TIME THE ANIMAL HAS SPENT IN
#EACH GEOMETRY AT THE END OF THE VIDEO.

#EACH 2D ARRAY REPRESENTS THE CUMULATIVE TIME THE ANIMAL HAS SPENT IN EACH GEOMETRY UP UNTIL AND INCLUDING THAT FRMAE,
#AND THE ARRAY WILL BE LEN(VIDEO FRAMES) X VERTICAL SHAPES X HORIXONTAL SHAPES.
time_data[-1]
[9]:
array([[11.36666667, 26.93333333, 41.06666667,  7.86666667,  5.46666667],
       [ 7.16666667, 14.53333333, 27.7       ,  6.86666667,  8.86666667],
       [18.96666667, 19.46666667, 25.16666667,  2.06666667, 11.4       ],
       [ 0.76666667,  2.26666667,  1.5       ,  0.        ,  3.26666667],
       [ 7.83333333, 17.83333333, 14.9       ,  9.2       ,  7.53333333]])
[10]:
#TO PLOT A HEATMAP REPRESENTING THE GRID LOCATIONS OF THE ANIMAL IN THE VIDEO, USE
# simba.mixins.plotting_mixin.PlottingMixin.make_location_heatmap_plot()

img = PlottingMixin().make_location_heatmap_plot(frm_data=time_data[-1],
                                                 max_scale=np.max(time_data[-1]),
                                                 palette='jet',
                                                 shading='gouraud',
                                                 img_size=(width, height),
                                                 aspect_ratio=aspect_ratio)

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

height, width, depth = img.shape
figsize = width / float(dpi), height / float(dpi)

plt.figure(figsize=figsize)
plt.axis('off')
plt.imshow(img)
plt.show()
../_images/nb_geometry_example_1_11_0.png
[11]:
# ALTERNATIVE EXAMPLE USING FLAT AND MAGMA SETTINGS
img = PlottingMixin().make_location_heatmap_plot(frm_data=time_data[-1],
                                                 max_scale=np.max(time_data[-1]),
                                                 palette='magma',
                                                 shading='flat',
                                                 img_size=(width, height),
                                                 aspect_ratio=aspect_ratio)

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

height, width, depth = img.shape
figsize = width / float(dpi), height / float(dpi)

plt.figure(figsize=figsize)
plt.axis('off')
plt.imshow(img)
plt.show()
../_images/nb_geometry_example_1_12_0.png