In [ ]:
##########
###20200121 Nejc Nate Dolensek, Nadine Gogolla - Gogolla Lab, Max-Planck-Institute of Neurobiology - Mouse Facial Expression Analysis v1
##########
In [1]:
import pandas as pd
import seaborn as sns
import numpy as np  
import matplotlib.pyplot as plt 
from skimage import io
from skimage.feature import hog
from joblib import Parallel, delayed
import cv2
import glob
In [2]:
###example image - full frame

import matplotlib.image as mpimg
plt.imshow(mpimg.imread("E:/20200121_mouseFacialExpr_v1/protoFaces_1/neutral/neutral (27).jpg"), cmap="gray")
Out[2]:
<matplotlib.image.AxesImage at 0x21b0f32eeb8>
In [3]:
###Importing example data


#folder paths - adjust after saving
neutralFolder = "E:/20200121_mouseFacialExpr_v1/protoFaces_1/neutral/*.jpg"
painFolder = "E:/20200121_mouseFacialExpr_v1/protoFaces_1/pain/*.jpg"


#import crop coordinates 
import pickle 
with open("E:/20200121_mouseFacialExpr_v1/proto_cropCoords/proto_cropCoords.pkl", 'rb') as f:
     proto_cropCoords = pickle.load(f)    
     

#import prototypical faces
pickleDirPath = "E:/20200121_mouseFacialExpr_v1/protoFaces/"
from os import listdir
for i in listdir(pickleDirPath):
    vars()[i[:-4]] = pd.read_pickle(pickleDirPath + i)
    
#import tSNE data
pickleDirPath = "E:/20200121_mouseFacialExpr_v1/tSNE_faces/"
from os import listdir
for i in listdir(pickleDirPath):
    vars()[i[:-4]] = pd.read_pickle(pickleDirPath + i)    
In [4]:
###example image - cropped

r = proto_cropCoords
plt.imshow(mpimg.imread("E:/20200121_mouseFacialExpr_v1/protoFaces_1/neutral/neutral (27).jpg")[int(r[1]):int(r[1]+r[3]), int(r[0]):int(r[0]+r[2])], cmap="gray")
Out[4]:
<matplotlib.image.AxesImage at 0x21b0fc70400>
In [5]:
###Preprocessing


#manually select the area containing the head of the mouse, 
#which will save the coordinates into a variable, to be used later.

def findCropCoords(imgFolderAndFileType):
    ###accepts folder containing image files in format "D:/folder1/folder2/folder3/*.jpg"
    ###waits for user to draw a rectangular selection
    ###outputs coordinates of a rectangular selection drawn over an image
    ###by default, the image displayed is the second image in the input folder
    import cv2
    from skimage import io
    
    coll = io.ImageCollection(imgFolderAndFileType)
    coords1 = cv2.selectROI("Image", coll[1]) 
    
    #cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    return coords1

#replace the filepath below and uncomment for own use. In all following examples a set of preselected coordinated will be used 
#(imported in the cell above as proto_cropCoords)
#coords_1 = findCropCoords("D:/folder1/folder2/folder3/*.jpg")
In [6]:
###Data loading and preprocessing
#the imagesToHogsCellCrop() function will take all image files in a given folder, 
#crop the area as given in the cropCoords (use findCropCoords()) 
#and convert them into their HOG (histogram of oriented gradients) descriptors.
#pixels_per_cell argument defines the sliding window size for HOG creation.
# n_jobs argument defines number of threads used

def imagesToHogsCellCrop(imgFolderAndFileType, pixelsPerCell, cropCoords = []):
    from skimage import io
    from skimage.feature import hog
    from joblib import Parallel, delayed
    
    coll = io.ImageCollection(imgFolderAndFileType)
    
    if cropCoords == []:
        cropCoords = findCropCoords(imgFolderAndFileType)
    
    r = cropCoords
    
    kwargs = dict(orientations=8, pixels_per_cell=(pixelsPerCell, pixelsPerCell), cells_per_block=(1, 1), transform_sqrt=True)
    return Parallel(n_jobs=32)(delayed(hog)(image[int(r[1]):int(r[1]+r[3]), int(r[0]):int(r[0]+r[2])], **kwargs) for image in coll)


#replace the filepath below for own use
sh_200uA_32 = imagesToHogsCellCrop("E:/20200121_mouseFacialExpr_v1/sh200_32/*.jpg", 32, cropCoords = proto_cropCoords)
sh_200uA_32 = pd.DataFrame(data = sh_200uA_32)
In [8]:
###Paiwrise similarity

#calculate similarities (correlation coefficients) between all possible pairs of frames
#stimuli are presented starting at frames #: 3600, 7260, 10920 for 60 frames each (2 seconds)
#here, 3 chunks containing 4s before each stimulus and 2s during each stimulus are selected
corr_pain = sh_200uA_32.iloc[np.r_[3480:3660, 7140:7320, 10800:10980]].T.corr()
In [9]:
#clear repetitive pattern in the pairwise correlation matrix can be observed (follow the diagonal)
sns.heatmap(corr_pain, robust = True, rasterized = True)
Out[9]:
<matplotlib.axes._subplots.AxesSubplot at 0x21bf62d6940>
In [10]:
###Paiwrise similarity - hiearachical clustering

#hierarchically clustered pairwise correlation matrix
g = sns.clustermap(corr_pain, robust=True, rasterized = True)