diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2019-01-05 12:35:01 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2019-01-05 12:35:01 +0100 |
| commit | 374dc54d049766fce225ca84d31fdf51f40f292c (patch) | |
| tree | 915b4bf3ea6645a1a65c30c4aee51870d6f955e3 /megapixels/app/processors/face_landmarks_3d.py | |
| parent | 824c958a7f29ab1fe31d09035c04a150379aecea (diff) | |
| parent | bff4e1c50349b0ba7d8e5fab6ce697c0b856f13f (diff) | |
Merge branch 'master' of github.com:adamhrv/megapixels_dev
Diffstat (limited to 'megapixels/app/processors/face_landmarks_3d.py')
| -rw-r--r-- | megapixels/app/processors/face_landmarks_3d.py | 97 |
1 files changed, 93 insertions, 4 deletions
diff --git a/megapixels/app/processors/face_landmarks_3d.py b/megapixels/app/processors/face_landmarks_3d.py index 84a423b0..3663364c 100644 --- a/megapixels/app/processors/face_landmarks_3d.py +++ b/megapixels/app/processors/face_landmarks_3d.py @@ -13,15 +13,104 @@ from app.settings import app_cfg as cfg from app.settings import types +class FaceLandmarks2D: + + # Estimates 2D facial landmarks + import face_alignment + + def __init__(self, gpu=0): + self.log = logger_utils.Logger.getLogger() + device = f'cuda:{gpu}' if gpu > -1 else 'cpu' + self.fa = face_alignment.FaceAlignment(face_alignment.LandmarksType._2D, device=device, flip_input=True) + + def landmarks(self, im, as_type=str): + '''Calculates the 3D facial landmarks + :param im: (numpy.ndarray) image + :param as_type: (str) or (list) type to return data + ''' + preds = self.fa.get_landmarks(im) + # convert to comma separated ints + # storing data as "[1,2], [3,4]" is larger file size than storing as "1,2,3,4" + # storing a list object in Pandas seems to result in 30% larger CSV files + # TODO optimize this + preds_int = [list(map(int, x)) for x in preds[0]] # list of ints + if as_type is str: + return ','.join([','.join(list(map(str,[x,y]))) for x,y in preds_int]) + else + return preds_int + class FaceLandmarks3D: # Estimates 3D facial landmarks + import face_alignment - def __init__(self): + def __init__(self, gpu=0): self.log = logger_utils.Logger.getLogger() - pass + device = f'cuda:{gpu}' if gpu > -1 else 'cpu' + self.fa = face_alignment.FaceAlignment(face_alignment.LandmarksType._3D, device=device, flip_input=False) + + def landmarks(self, im, as_type=str): + '''Calculates the 3D facial landmarks + :param im: (numpy.ndarray) image + :param as_type: (str) or (list) type to return data + ''' + preds = self.fa.get_landmarks(im) + # convert to comma separated ints + # storing data as "[1,2], [3,4]" is larger file size than storing as "1,2,3,4" + # storing a list object in Pandas seems to result in 30% larger CSV files + # TODO optimize this + preds_int = [list(map(int, x)) for x in preds[0]] # list of ints + if as_type is str: + return ','.join([','.join(list(map(str,[x,y]))) for x,y in preds_int]) + else + return preds_int + + def draw(self, im): + '''draws landmarks in 3d scene''' + + # TODO + ''' + import face_alignment + import numpy as np + from mpl_toolkits.mplot3d import Axes3D + import matplotlib.pyplot as plt + from skimage import io + + # Run the 3D face alignment on a test image, without CUDA. + fa = face_alignment.FaceAlignment(face_alignment.LandmarksType._3D, device='cuda:0', flip_input=True) + + input = io.imread('../test/assets/aflw-test.jpg') + preds = fa.get_landmarks(input)[-1] + + #TODO: Make this nice + fig = plt.figure(figsize=plt.figaspect(.5)) + ax = fig.add_subplot(1, 2, 1) + ax.imshow(input) + ax.plot(preds[0:17,0],preds[0:17,1],marker='o',markersize=6,linestyle='-',color='w',lw=2) + ax.plot(preds[17:22,0],preds[17:22,1],marker='o',markersize=6,linestyle='-',color='w',lw=2) + ax.plot(preds[22:27,0],preds[22:27,1],marker='o',markersize=6,linestyle='-',color='w',lw=2) + ax.plot(preds[27:31,0],preds[27:31,1],marker='o',markersize=6,linestyle='-',color='w',lw=2) + ax.plot(preds[31:36,0],preds[31:36,1],marker='o',markersize=6,linestyle='-',color='w',lw=2) + ax.plot(preds[36:42,0],preds[36:42,1],marker='o',markersize=6,linestyle='-',color='w',lw=2) + ax.plot(preds[42:48,0],preds[42:48,1],marker='o',markersize=6,linestyle='-',color='w',lw=2) + ax.plot(preds[48:60,0],preds[48:60,1],marker='o',markersize=6,linestyle='-',color='w',lw=2) + ax.plot(preds[60:68,0],preds[60:68,1],marker='o',markersize=6,linestyle='-',color='w',lw=2) + ax.axis('off') + ax = fig.add_subplot(1, 2, 2, projection='3d') + surf = ax.scatter(preds[:,0]*1.2,preds[:,1],preds[:,2],c="cyan", alpha=1.0, edgecolor='b') + ax.plot3D(preds[:17,0]*1.2,preds[:17,1], preds[:17,2], color='blue' ) + ax.plot3D(preds[17:22,0]*1.2,preds[17:22,1],preds[17:22,2], color='blue') + ax.plot3D(preds[22:27,0]*1.2,preds[22:27,1],preds[22:27,2], color='blue') + ax.plot3D(preds[27:31,0]*1.2,preds[27:31,1],preds[27:31,2], color='blue') + ax.plot3D(preds[31:36,0]*1.2,preds[31:36,1],preds[31:36,2], color='blue') + ax.plot3D(preds[36:42,0]*1.2,preds[36:42,1],preds[36:42,2], color='blue') + ax.plot3D(preds[42:48,0]*1.2,preds[42:48,1],preds[42:48,2], color='blue') + ax.plot3D(preds[48:,0]*1.2,preds[48:,1],preds[48:,2], color='blue' ) - def landmarks(self): - return [1,2,3,4,100]
\ No newline at end of file + ax.view_init(elev=90., azim=90.) + ax.set_xlim(ax.get_xlim()[::-1]) + plt.show() + ''' + return im
\ No newline at end of file |
