def test_plot_face(): # test plotting method fx = Fex( filename=join(get_test_data_path(), "iMotions_Test_v6.txt"), sampling_freq=30, detector="FACET", ) fx = fx.read_file() ax = fx.plot_aus(row_n=0) assert_plot_shape(ax) plt.close() fx = Fex( filename=join(get_test_data_path(), "OpenFace_Test.csv"), sampling_freq=30, detector="OpenFace", ) fx = fx.read_file() ax = fx.plot_aus(row_n=0) assert_plot_shape(ax) plt.close() fx = Fex( filename=join(get_test_data_path(), "sample_affectiva-api-app_output.json"), sampling_freq=30, detector="Affectiva", ) fx = fx.read_file(orig_cols=False) ax = fx.plot_aus(row_n=0) assert_plot_shape(ax) plt.close() # test plot in util plot_face() assert_plot_shape(plt.gca()) plt.close() plot_face(au=au, vectorfield={"reference": predict(au2)}, feature_range=(0, 1)) assert_plot_shape(plt.gca()) plt.close() with pytest.raises(ValueError): plot_face(model=au, au=au, vectorfield={"reference": predict(au2)}) with pytest.raises(ValueError): plot_face(model=au, au=au, vectorfield=[]) with pytest.raises(ValueError): plot_face(model=au, au=au, vectorfield={"noreference": predict(au2)})
def plot(self, row_n, model=None, vectorfield=None, muscles=None, ax=None, color='k', linewidth=1, linestyle='-', gaze=None, *args, **kwargs): """ Plot facial representation of data Args: row_n: the row of data to use model: sklearn PLSRegression instance vectorfield: (dict) {'target':target_array,'reference':reference_array} muscles: (dict) {'muscle': color} ax: matplotlib axis handle color: matplotlib color linewidth: matplotlib linewidth linestyle: matplotlib linestyle gaze: array of gaze vectors (len(5)) """ feats = [ 'AU1', 'AU2', 'AU4', 'AU5', 'AU6', 'AU7', 'AU9', 'AU10', 'AU12', 'AU14', 'AU15', 'AU17', 'AU18', 'AU20', 'AU23', 'AU24', 'AU25', 'AU26', 'AU28', 'AU43', 'Pitch', 'Roll', 'Yaw' ] if (row_n > len(self)): raise ValueError("Row number out of range.") try: au = [] for feat in feats: aun = self[feat] au.append(aun.copy()[row_n]) au = np.array(au) if model is None: model = load_h5('facet.h5') if muscles is not None: muscles['facet'] = 1 ax = plot_face(model=model, au=au, vectorfield=vectorfield, muscles=muscles, ax=ax, color=color, linewidth=linewidth, linestyle=linestyle, gaze=gaze, *args, **kwargs) return ax except Exception as e: print('Unable to plot data:', e)
def test_plot_face(): # test plotting method fx = Fex(filename=join(get_test_data_path(), 'iMotions_Test_v6.txt'), sampling_freq=30, detector='FACET') fx = fx.read_file() ax = fx.plot_aus(row_n=0) assert_plot_shape(ax) plt.close() fx = Fex(filename=join(get_test_data_path(), 'OpenFace_Test.csv'), sampling_freq=30, detector='OpenFace') fx = fx.read_file() ax = fx.plot_aus(row_n=0) assert_plot_shape(ax) plt.close() fx = Fex(filename=join(get_test_data_path(), 'sample_affectiva-api-app_output.json'), sampling_freq=30, detector='Affectiva') fx = fx.read_file(orig_cols=False) ax = fx.plot_aus(row_n=0) assert_plot_shape(ax) plt.close() # test plot in util plot_face() assert_plot_shape(plt.gca()) plt.close() plot_face(au=au, vectorfield={'reference': predict(au2)}) assert_plot_shape(plt.gca()) plt.close() with pytest.raises(ValueError): plot_face(model=au, au=au, vectorfield={'reference': predict(au2)}) with pytest.raises(ValueError): plot_face(model=au, au=au, vectorfield=[]) with pytest.raises(ValueError): plot_face(model=au, au=au, vectorfield={'noreference': predict(au2)})
# Plotting examples *written by Jin Hyun Cheong* Included in the toolbox are two models for Action Units to landmark visualization. The 'pyfeat_aus_to_landmarks.h5' model was created by using landmarks extracted using Py-FEAT to align each face in the dataset to a neutral face with numpy's least squares function. Then the PLS model was trained using Action Unit labels to predict transformed landmark data. Draw a standard neutral face. Figsize can be altered but a ratio of 4:5 is recommended. # Load modules %matplotlib inline from feat.plotting import plot_face import numpy as np import matplotlib.pyplot as plt plot_face(au=np.zeros(20)) ## Draw lineface using input vector Affectiva vectors should be divided by twenty for use with our 'blue' model. from feat.plotting import plot_face import numpy as np import matplotlib.pyplot as plt # Add data, AU is ordered as such: # AU1, 2, 4, 5, 6, 7, 9, 10, 12, 14, 15, 17, 18, 20, 23, 24, 25, 26, 28, 43 # Activate AU1: Inner brow raiser au = [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # Plot face fig, axes = plt.subplots(1,2)
f, axes = plt.subplots(5, 4, figsize=(12, 18)) axes = axes.flatten() # Exaggerate the intensity of the expression for clearer visualization. # We do not recommend exceeding 2. intensity = 2 for aui, auname in enumerate(axes): try: auname = au_cols[aui] au = np.zeros(clf.n_components) au[aui] = intensity predicted = clf.predict([au]).reshape(2, 68) plot_face(au=au, model=clf, vectorfield={ "reference": neutral.T, 'target': predicted, 'color': 'r', 'alpha': .6 }, ax=axes[aui]) axes[aui].set(title=auname) except: pass finally: ax = axes[aui] ax.axes.get_xaxis().set_visible(False) ax.axes.get_yaxis().set_visible(False) # Here is how we would export our model into an h5 format which can be loaded using our load_h5 function. # In[ ]:
Draw a standard neutral face. Figsize can be altered but a ratio of 4:5 is recommended. %load_ext autoreload %autoreload 2 %config InlineBackend.figure_format = 'retina' intensity = 2 # Load modules %matplotlib inline from feat.plotting import plot_face, predict import numpy as np import pandas as pd import matplotlib.pyplot as plt plot_face(au=np.zeros(20)) ## Draw lineface using input vector Affectiva vectors should be divided by twenty for use with our 'blue' model. from feat.plotting import plot_face, predict import numpy as np import matplotlib.pyplot as plt # Add data, AU is ordered as such: # AU1, 2, 4, 5, 6, 7, 9, 10, 12, 14, 15, 17, 18, 20, 23, 24, 25, 26, 28, 43 # Activate AU1: Inner brow raiser
def plot(self, row_n, model=None, vectorfield=None, muscles=None, ax=None, color='k', linewidth=1, linestyle='-', gaze=False, gaze_vecs=False, *args, **kwargs): """ Plot facial representation of data Args: row_n: the row of data to use model: sklearn PLSRegression instance vectorfield: (dict) {'target':target_array,'reference':reference_array} muscles: (dict) {'muscle': color} ax: matplotlib axis handle color: matplotlib color linewidth: matplotlib linewidth linestyle: matplotlib linestyle gaze: (bool) whether to draw gaze based on data """ feats = [ 'AU01_r', 'AU02_r', 'AU04_r', 'AU05_r', 'AU06_r', 'AU07_r', 'AU09_r', 'AU10_r', 'AU12_r', 'AU14_r', 'AU15_r', 'AU17_r', 'AU20_r', 'AU23_r', 'AU25_r', 'AU26_r', 'AU45_r' ] if (row_n > len(self)): raise ValueError("Row number out of range.") try: au = [] for feat in feats: aun = self[feat] au.append(aun.copy()[row_n]) au = np.array(au + [0, 0, 0]) if gaze: gaze_dat = ['gaze_0_x', 'gaze_0_y', 'gaze_1_x', 'gaze_1_y'] gaze = [] for i in range(4): gaze.append(self[gaze_dat[i]][row_n]) if gaze_vecs: gaze.append(1) else: gaze.append(0) else: gaze = None ax = plot_face(model=model, au=au, vectorfield=vectorfield, muscles=muscles, ax=ax, color=color, linewidth=linewidth, linestyle=linestyle, gaze=gaze, *args, **kwargs) return ax except Exception as e: print('Unable to plot data:', e)
def plot(self, row_n, model=None, vectorfield=None, muscles=None, ax=None, color='k', linewidth=1, linestyle='-', gaze=None, *args, **kwargs): """ Plot facial representation of data Args: row_n: the row of data to use model: sklearn PLSRegression instance vectorfield: (dict) {'target':target_array,'reference':reference_array} muscles: (dict) {'muscle': color} ax: matplotlib axis handle color: matplotlib color linewidth: matplotlib linewidth linestyle: matplotlib linestyle gaze: array of gaze vectors (len(5)) """ if "AU01" not in self: feats = [ "innerBrowRaise", "browRaise", "browFurrow", "eyeWiden", "cheekRaise", "lidTighten", "noseWrinkle", "upperLipRaise", "smile", "dimpler", "lipCornerDepressor", "chinRaise", "lipStretch", "lipPress", "mouthOpen", "jawDrop", "eyeClosure" ] else: feats = [ "AU01", "AU02", "AU04", "AU05", "AU06", "AU07", "AU9", "AU10", "AU12", "AU14", "AU15", "AU17", "AU20", "AU24", "AU25", "AU26", "AU43" ] if (row_n > len(self)): raise ValueError("Row number out of range.") try: au = [] for feat in feats: aun = self[feat] au.append(aun.copy()[row_n] / 20) au = np.array(au + [0, 0, 0]) ax = plot_face(model=model, au=au, vectorfield=vectorfield, muscles=muscles, ax=ax, color=color, linewidth=linewidth, linestyle=linestyle, gaze=gaze, *args, **kwargs) return ax except Exception as e: print('Unable to plot data:', e)