  from lib.aligner import get_align_mat
  
  class Extract(object):
      def extract(self, image, face, size):
          if face.landmarks == None:
              print("Warning! landmarks not found. Switching to crop!")
              return cv2.resize(face.image, (size, size))
  
          alignment = get_align_mat( face )
          return self.transform( image, alignment, size, 48 )
      
      def transform( self, image, mat, size, padding=0 ):
          mat = mat * (size - 2 * padding)
 
</s> remove     face_locations = face_recognition.face_locations(frame, model=model)
    landmarks = _raw_face_landmarks(frame, face_locations)

    for ((y, right, bottom, x), landmarks) in zip(face_locations, landmarks):
        yield DetectedFace(frame[y: bottom, x: right], x, right - x, y, bottom - y, landmarks)

# Copy/Paste (mostly) from private method in face_recognition
predictor_68_point_model = face_recognition_models.pose_predictor_model_location()
pose_predictor = dlib.shape_predictor(predictor_68_point_model)

def _raw_face_landmarks(face_image, face_locations):
    face_locations = [_css_to_rect(face_location) for face_location in face_locations]
    return [pose_predictor(face_image, face_location) for face_location in face_locations]

def _css_to_rect(css):
    return dlib.rectangle(css[3], css[0], css[1], css[2])
# end of Copy/Paste
 </s> add     fd = FaceLandmarksExtractor.extract (frame, True if model == "cnn" else False )
    for face in fd:
        x, y, right, bottom, landmarks = face[0][0], face[0][1], face[0][2], face[0][3], face[1]
        yield DetectedFace(frame[y: bottom, x: right], x, right - x, y, bottom - y, landmarksXY=landmarks) </s> remove         if self.landmarksXY:
            return self.landmarksXY
        self.landmarksXY = [(p.x, p.y) for p in self.landmarks.parts()]
        return self.landmarksXY
 </s> add         return self.landmarksXY </s> remove         self.landmarks = landmarks
 </s> add  </s> remove     def __init__(self, image=None, x=None, w=None, y=None, h=None, landmarks=None, landmarksXY=None):
 </s> add     def __init__(self, image=None, x=None, w=None, y=None, h=None, landmarksXY=None): </s> remove import dlib
import face_recognition
import face_recognition_models
 </s> add from lib import FaceLandmarksExtractor
  from lib.aligner import get_align_mat
  
  class Extract(object):
      def extract(self, image, face, size):




          alignment = get_align_mat( face )
          return self.transform( image, alignment, size, 48 )
      
      def transform( self, image, mat, size, padding=0 ):
          mat = mat * (size - 2 * padding)
keep keep keep keep replace replace replace replace keep keep keep keep keep
 port 'face_alignment' from PyTorch to Keras. (#228)

* port 'face_alignment' from PyTorch to Keras. It works x2 faster, but initialization takes 20secs.

2DFAN-4.h5 and mmod_human_face_detector.dat included in lib\FaceLandmarksExtractor

fixed dlib vs tensorflow conflict: dlib must do op first, then load keras model, otherwise CUDA OOM error

if face location not found by CNN, its try to find by HOG.

removed this:
-        if face.landmarks == None:
-            print("Warning! landmarks not found. Switching to crop!")
-            return cv2.resize(face.image, (size, size))
because DetectedFace always has landmarks

* removing DetectedFace.landmarks 
plugins/Extract_Align.py