def align(self, imgDim, rgbImg, bb=None,
landmarks=None, landmarkIndices=INNER_EYES_AND_BOTTOM_LIP,
skipMulti=False, scale=1.0):
r"""align(imgDim, rgbImg, bb=None, landmarks=None, landmarkIndices=INNER_EYES_AND_BOTTOM_LIP)
Transform and align a face in an image.
:param imgDim: The edge length in pixels of the square the image is resized to.
:type imgDim: int
:param rgbImg: RGB image to process. Shape: (height, width, 3)
:type rgbImg: numpy.ndarray
:param bb: Bounding box around the face to align. \
Defaults to the largest face.
:type bb: dlib.rectangle
:param landmarks: Detected landmark locations. \
Landmarks found on `bb` if not provided.
:type landmarks: list of (x,y) tuples
:param landmarkIndices: The indices to transform to.
:type landmarkIndices: list of ints
:param skipMulti: Skip image if more than one face detected.
:type skipMulti: bool
:param scale: Scale image before cropping to the size given by imgDim.
:type scale: float
:return: The aligned RGB image. Shape: (imgDim, imgDim, 3)
:rtype: numpy.ndarray
"""
assert imgDim is not None
assert rgbImg is not None
assert landmarkIndices is not None
if bb is None:
bb = self.getLargestFaceBoundingBox(rgbImg, skipMulti)
if bb is None:
return
if landmarks is None:
landmarks = self.findLandmarks(rgbImg, bb)
npLandmarks = np.float32(landmarks)
npLandmarkIndices = np.array(landmarkIndices)
#pylint: disable=maybe-no-member
H = cv2.getAffineTransform(npLandmarks[npLandmarkIndices],
imgDim * MINMAX_TEMPLATE[npLandmarkIndices]*scale + imgDim*(1-scale)/2)
thumbnail = cv2.warpAffine(rgbImg, H, (imgDim, imgDim))
return thumbnail
python类getAffineTransform()的实例源码
def align(self, imgDim, rgbImg, bb=None,landmarks=None, landmarkIndices=INNER_EYES_AND_BOTTOM_LIP):
"""align(imgDim, rgbImg, bb=None, landmarks=None, landmarkIndices=INNER_EYES_AND_BOTTOM_LIP)
Transform and align a face in an image.
:param imgDim: The edge length in pixels of the square the image is resized to.
:type imgDim: int
:param rgbImg: RGB image to process. Shape: (height, width, 3)
:type rgbImg: numpy.ndarray
:param bb: Bounding box around the face to align. \
Defaults to the largest face.
:type bb: dlib.rectangle
:param landmarks: Detected landmark locations. \
Landmarks found on `bb` if not provided.
:type landmarks: list of (x,y) tuples
:param landmarkIndices: The indices to transform to.
:type landmarkIndices: list of ints
:param skipMulti: Skip image if more than one face detected.
:type skipMulti: bool
:return: The aligned RGB image. Shape: (imgDim, imgDim, 3)
:rtype: numpy.ndarray
"""
#rasie assertion error if one of the following variables is
#not passed to the function
assert imgDim is not None
assert rgbImg is not None
assert landmarkIndices is not None
if bb is None:
bb = self.getLargestFaceBoundingBox(rgbImg)
if bb is None:
return
if landmarks is None:
landmarks = self.findLandmarks(rgbImg, bb)
npLandmarks = np.float32(landmarks)
npLandmarkIndices = np.array(landmarkIndices)
H = cv2.getAffineTransform(npLandmarks[npLandmarkIndices],
imgDim * MINMAX_TEMPLATE[npLandmarkIndices])
thumbnail = cv2.warpAffine(rgbImg, H, (imgDim, imgDim))
return thumbnail
def augment_image(image):
# move channel to the last axis
image = np.rollaxis(image, 0, 3)
h, w, ch = image.shape[:3]
# brightness
brightness = random.uniform(-0.1, 0.1)
# rotation and scaling
rot = 1
scale = 0.01
Mrot = cv2.getRotationMatrix2D((h / 2, w / 2), random.uniform(-rot, rot), random.uniform(1.0 - scale, 1.0 + scale))
# affine transform and shifts
pts1 = np.float32([[0, 0], [w, 0], [w, h]])
a = 1
shift = 1
shiftx = random.randint(-shift, shift)
shifty = random.randint(-shift, shift)
pts2 = np.float32([[
0 + random.randint(-a, a) + shiftx,
0 + random.randint(-a, a) + shifty
], [
w + random.randint(-a, a) + shiftx,
0 + random.randint(-a, a) + shifty
], [
w + random.randint(-a, a) + shiftx,
h + random.randint(-a, a) + shifty
]])
M = cv2.getAffineTransform(pts1, pts2)
def _augment(image):
image = np.add(image, brightness)
augmented = cv2.warpAffine(
cv2.warpAffine(
image
, Mrot, (w, h)
)
, M, (w, h)
)
if augmented.ndim < 3:
augmented = np.expand_dims(augmented, 2)
return augmented
# make same transform for each channel, splitting image by four channels
image_lst = [image[..., i:i+4] for i in xrange(0, ch, 4)]
augmented_lst = map(_augment, image_lst)
augmented = np.concatenate(augmented_lst, axis=-1)
# roll channel axis back when returning
augmented = np.rollaxis(augmented, 2, 0)
return augmented
def align(self, imgDim, rgbImg, bb=None,
landmarks=None, landmarkIndices=INNER_EYES_AND_BOTTOM_LIP,
skipMulti=False, scale=1.0):
r"""align(imgDim, rgbImg, bb=None, landmarks=None, landmarkIndices=INNER_EYES_AND_BOTTOM_LIP)
Transform and align a face in an image.
:param imgDim: The edge length in pixels of the square the image is resized to.
:type imgDim: int
:param rgbImg: RGB image to process. Shape: (height, width, 3)
:type rgbImg: numpy.ndarray
:param bb: Bounding box around the face to align. \
Defaults to the largest face.
:type bb: dlib.rectangle
:param landmarks: Detected landmark locations. \
Landmarks found on `bb` if not provided.
:type landmarks: list of (x,y) tuples
:param landmarkIndices: The indices to transform to.
:type landmarkIndices: list of ints
:param skipMulti: Skip image if more than one face detected.
:type skipMulti: bool
:param scale: Scale image before cropping to the size given by imgDim.
:type scale: float
:return: The aligned RGB image. Shape: (imgDim, imgDim, 3)
:rtype: numpy.ndarray
"""
assert imgDim is not None
assert rgbImg is not None
assert landmarkIndices is not None
if bb is None:
bb = self.getLargestFaceBoundingBox(rgbImg, skipMulti)
if bb is None:
return
if landmarks is None:
landmarks = self.findLandmarks(rgbImg, bb)
npLandmarks = np.float32(landmarks)
npLandmarkIndices = np.array(landmarkIndices)
#pylint: disable=maybe-no-member
H = cv2.getAffineTransform(npLandmarks[npLandmarkIndices],
imgDim * MINMAX_TEMPLATE[npLandmarkIndices]*scale + imgDim*(1-scale)/2)
thumbnail = cv2.warpAffine(rgbImg, H, (imgDim, imgDim))
return thumbnail
def warp_image(img, triangulation, base_points, coord):
"""
Realize the mesh warping phase
triangulation is the Delaunay triangulation of the base points
base_points are the coordinates of the landmark poitns of the reference image
code inspired from http://www.learnopencv.com/warp-one-triangle-to-another-using-opencv-c-python/
"""
all_points, coordinates = preprocess_image_before_triangulation(img)
img_out = 255 * np.ones(img.shape, dtype=img.dtype)
for t in triangulation:
# triangles to map one another
src_tri = np.array([[all_points[x][0], all_points[x][1]] for x in t]).astype(np.float32)
dest_tri = np.array([[base_points[x][0], base_points[x][1]] for x in t]).astype(np.float32)
# bounding boxes
src_rect = cv2.boundingRect(np.array([src_tri]))
dest_rect = cv2.boundingRect(np.array([dest_tri]))
# crop images
src_crop_tri = np.zeros((3, 2), dtype=np.float32)
dest_crop_tri = np.zeros((3, 2))
for k in range(0, 3):
for dim in range(0, 2):
src_crop_tri[k][dim] = src_tri[k][dim] - src_rect[dim]
dest_crop_tri[k][dim] = dest_tri[k][dim] - dest_rect[dim]
src_crop_img = img[src_rect[1]:src_rect[1] + src_rect[3], src_rect[0]:src_rect[0] + src_rect[2]]
# affine transformation estimation
mat = cv2.getAffineTransform(
np.float32(src_crop_tri),
np.float32(dest_crop_tri)
)
dest_crop_img = cv2.warpAffine(
src_crop_img,
mat,
(dest_rect[2], dest_rect[3]),
None,
flags=cv2.INTER_LINEAR,
borderMode=cv2.BORDER_REFLECT_101
)
# Use a mask to keep only the triangle pixels
# Get mask by filling triangle
mask = np.zeros((dest_rect[3], dest_rect[2], 3), dtype=np.float32)
cv2.fillConvexPoly(mask, np.int32(dest_crop_tri), (1.0, 1.0, 1.0), 16, 0)
# Apply mask to cropped region
dest_crop_img = dest_crop_img * mask
# Copy triangular region of the rectangular patch to the output image
img_out[dest_rect[1]:dest_rect[1] + dest_rect[3], dest_rect[0]:dest_rect[0] + dest_rect[2]] = \
img_out[dest_rect[1]:dest_rect[1] + dest_rect[3], dest_rect[0]:dest_rect[0] + dest_rect[2]] * (
(1.0, 1.0, 1.0) - mask)
img_out[dest_rect[1]:dest_rect[1] + dest_rect[3], dest_rect[0]:dest_rect[0] + dest_rect[2]] = \
img_out[dest_rect[1]:dest_rect[1] + dest_rect[3], dest_rect[0]:dest_rect[0] + dest_rect[2]] + dest_crop_img
return img_out[coord[2]:coord[3], coord[0]:coord[1]]