-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added __version__ ; Moved
GFTT
class to feature
; Created dedicate…
…d `face_utils` sub-module ; Added `FaceAligner` class
- Loading branch information
Showing
7 changed files
with
89 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# import the necessary packages | ||
from .helpers import FACIAL_LANDMARKS_IDXS | ||
from .helpers import rect_to_bb | ||
from .helpers import shape_to_np | ||
from .helpers import visualize_facial_landmarks | ||
from .facealigner import FaceAligner |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# import the necessary packages | ||
from .helpers import FACIAL_LANDMARKS_IDXS | ||
from .helpers import shape_to_np | ||
import numpy as np | ||
import cv2 | ||
|
||
class FaceAligner: | ||
def __init__(self, predictor, desiredLeftEye=(0.35, 0.35), | ||
desiredFaceWidth=256, desiredFaceHeight=None): | ||
# store the facial landmark predictor, desired output left | ||
# eye position, and desired output face width + height | ||
self.predictor = predictor | ||
self.desiredLeftEye = desiredLeftEye | ||
self.desiredFaceWidth = desiredFaceWidth | ||
self.desiredFaceHeight = desiredFaceHeight | ||
|
||
# if the desired face height is None, set it to be the | ||
# desired face width (normal behavior) | ||
if self.desiredFaceHeight is None: | ||
self.desiredFaceHeight = self.desiredFaceWidth | ||
|
||
def align(self, image, gray, rect): | ||
# convert the landmark (x, y)-coordinates to a NumPy array | ||
shape = self.predictor(gray, rect) | ||
shape = shape_to_np(shape) | ||
|
||
# extract the left and right eye (x, y)-coordinates | ||
(lStart, lEnd) = FACIAL_LANDMARKS_IDXS["left_eye"] | ||
(rStart, rEnd) = FACIAL_LANDMARKS_IDXS["right_eye"] | ||
leftEyePts = shape[lStart:lEnd] | ||
rightEyePts = shape[rStart:rEnd] | ||
|
||
# compute the center of mass for each eye | ||
leftEyeCenter = leftEyePts.mean(axis=0).astype("int") | ||
rightEyeCenter = rightEyePts.mean(axis=0).astype("int") | ||
|
||
# compute the angle between the eye centroids | ||
dY = rightEyeCenter[1] - leftEyeCenter[1] | ||
dX = rightEyeCenter[0] - leftEyeCenter[0] | ||
angle = np.degrees(np.arctan2(dY, dX)) - 180 | ||
|
||
# compute the desired right eye x-coordinate based on the | ||
# desired x-coordinate of the left eye | ||
desiredRightEyeX = 1.0 - self.desiredLeftEye[0] | ||
|
||
# determine the scale of the new resulting image by taking | ||
# the ratio of the distance between eyes in the *current* | ||
# image to the ratio of distance between eyes in the | ||
# *desired* image | ||
dist = np.sqrt((dX ** 2) + (dY ** 2)) | ||
desiredDist = (desiredRightEyeX - self.desiredLeftEye[0]) | ||
desiredDist *= self.desiredFaceWidth | ||
scale = desiredDist / dist | ||
|
||
# compute center (x, y)-coordinates (i.e., the median point) | ||
# between the two eyes in the input image | ||
eyesCenter = ((leftEyeCenter[0] + rightEyeCenter[0]) // 2, | ||
(leftEyeCenter[1] + rightEyeCenter[1]) // 2) | ||
|
||
# grab the rotation matrix for rotating and scaling the face | ||
M = cv2.getRotationMatrix2D(eyesCenter, angle, scale) | ||
|
||
# update the translation component of the matrix | ||
tX = self.desiredFaceWidth * 0.5 | ||
tY = self.desiredFaceHeight * self.desiredLeftEye[1] | ||
M[0, 2] += (tX - eyesCenter[0]) | ||
M[1, 2] += (tY - eyesCenter[1]) | ||
|
||
# apply the affine transformation | ||
(w, h) = (self.desiredFaceWidth, self.desiredFaceHeight) | ||
output = cv2.warpAffine(image, M, (w, h), | ||
flags=cv2.INTER_CUBIC) | ||
|
||
# return the aligned face | ||
return output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from .helpers import corners_to_keypoints | ||
from .factories import FeatureDetector_create | ||
from .factories import DescriptorExtractor_create | ||
from .gftt import GFTT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import cv2 | ||
from .convenience import corners_to_keypoints | ||
from .helpers import corners_to_keypoints | ||
|
||
|
||
class GFTT: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,8 @@ | |
|
||
setup( | ||
name='imutils', | ||
packages=['imutils', 'imutils.video', 'imutils.io', 'imutils.feature'], | ||
version='0.4.2', | ||
packages=['imutils', 'imutils.video', 'imutils.io', 'imutils.feature', 'imutils.face_utils'], | ||
version='0.4.3', | ||
description='A series of convenience functions to make basic image processing functions such as translation, rotation, resizing, skeletonization, displaying Matplotlib images, sorting contours, detecting edges, and much more easier with OpenCV and both Python 2.7 and Python 3.', | ||
author='Adrian Rosebrock', | ||
author_email='[email protected]', | ||
|