This commit is contained in:
harisreedhar 2024-11-13 16:48:12 +05:30
parent 0b6dd6c8b1
commit 37239f06f6
3 changed files with 31 additions and 31 deletions

View File

@ -5,7 +5,7 @@ import cv2
import numpy
from cv2.typing import Size
from facefusion.typing import Anchors, Angle, BoundingBox, Direction, Distance, FaceDetectorModel, FaceLandmark5, FaceLandmark68, Mask, Matrix, Points, PolygonTemplate, PolygonTemplateSet, Scale, Score, Translation, VisionFrame, WarpTemplate, WarpTemplateSet
from facefusion.typing import Anchors, Angle, BoundingBox, Direction, Distance, FaceDetectorModel, FaceLandmark5, FaceLandmark68, Mask, Matrix, Points, PointsTemplate, PointsTemplateSet, Scale, Score, Translation, VisionFrame, WarpTemplate, WarpTemplateSet
WARP_TEMPLATES : WarpTemplateSet =\
{
@ -33,6 +33,14 @@ WARP_TEMPLATES : WarpTemplateSet =\
[ 0.38710391, 0.72160547 ],
[ 0.61507734, 0.72034453 ]
]),
'deep_face_live': numpy.array(
[
[ 0.22549182, 0.21599032 ],
[ 0.75476142, 0.21599032 ],
[ 0.49012712, 0.51562511 ],
[ 0.25414925, 0.78023333 ],
[ 0.72610437, 0.78023333 ]
]),
'ffhq_512': numpy.array(
[
[ 0.37691676, 0.46864664 ],
@ -56,17 +64,9 @@ WARP_TEMPLATES : WarpTemplateSet =\
[ 0.50123859, 0.61331904 ],
[ 0.43364461, 0.68337652 ],
[ 0.57015325, 0.68306005 ]
]),
'deep_face_live': numpy.array(
[
[ 0.22549182, 0.21599032 ],
[ 0.75476142, 0.21599032 ],
[ 0.49012712, 0.51562511 ],
[ 0.25414925, 0.78023333 ],
[ 0.72610437, 0.78023333 ]
])
}
POLYGON_TEMPLATES : PolygonTemplateSet =\
POINTS_TEMPLATES : PointsTemplateSet =\
{
'square': numpy.array(
[
@ -74,19 +74,19 @@ POLYGON_TEMPLATES : PolygonTemplateSet =\
[ 1, 0 ],
[ 1, 1 ],
[ 0, 1 ]
]),
]).astype(numpy.float32),
'triangle_orthogonal': numpy.array(
[
[ 0, 0 ],
[ 1, 0 ],
[ 0, 1 ]
]),
]).astype(numpy.float32),
'triangle_skew': numpy.array(
[
[ 0, 0 ],
[ 1, 0 ],
[ 1, 1 ]
])
]).astype(numpy.float32)
}
@ -96,8 +96,8 @@ def estimate_matrix_by_face_landmark_5(face_landmark_5 : FaceLandmark5, warp_tem
return affine_matrix
def estimate_matrix_by_points(source_points : Points, polygon_template : PolygonTemplate, crop_size : Size) -> Matrix:
target_points = POLYGON_TEMPLATES.get(polygon_template) * crop_size
def estimate_matrix_by_points(source_points : Points, polygon_template : PointsTemplate, crop_size : Size) -> Matrix:
target_points = POINTS_TEMPLATES.get(polygon_template) * crop_size
affine_matrix = cv2.getAffineTransform(source_points, target_points.astype(numpy.float32))
return affine_matrix
@ -108,13 +108,13 @@ def warp_face_by_face_landmark_5(temp_vision_frame : VisionFrame, face_landmark_
return crop_vision_frame, affine_matrix
def warp_face_for_deepfacelive(temp_vision_frame : VisionFrame, face_landmark_5 : FaceLandmark5, crop_size : Size, coverage : float, x_shift : float, y_shift : float) -> Tuple[VisionFrame, Matrix]:
def warp_face_for_deepfacelive(temp_vision_frame : VisionFrame, face_landmark_5 : FaceLandmark5, crop_size : Size, shift : Tuple[float, float], coverage : float) -> Tuple[VisionFrame, Matrix]:
affine_matrix = estimate_matrix_by_face_landmark_5(face_landmark_5, 'deep_face_live', (1, 1))
square_points = POLYGON_TEMPLATES.get('square').astype(numpy.float32)
square_points = POINTS_TEMPLATES.get('square')
square_points = transform_points(square_points, cv2.invertAffineTransform(affine_matrix))
center_point = square_points.mean(axis = 0)
center_point += x_shift * numpy.subtract(square_points[1], square_points[0])
center_point += y_shift * numpy.subtract(square_points[3], square_points[0])
center_point += shift[0] * numpy.subtract(square_points[1], square_points[0])
center_point += shift[1] * numpy.subtract(square_points[3], square_points[0])
scale = numpy.linalg.norm(center_point - square_points[0]) * coverage
top_bottom_direction = calc_points_direction(square_points[0], square_points[2]) * scale
bottom_top_direction = calc_points_direction(square_points[3], square_points[1]) * scale

View File

@ -42,10 +42,9 @@ MODEL_SET : ModelSet =\
'path': resolve_relative_path('../.assets/models/Jackie_Chan.dfm')
}
},
'x_shift': 0.0,
'y_shift': 0.0,
'coverage': 2.2,
'size': (224, 224)
'size': (224, 224),
'shift': (0.0, 0.0),
'coverage': 2.2
}
}
@ -113,10 +112,9 @@ def post_process() -> None:
def swap_face(target_face : Face, temp_vision_frame : VisionFrame) -> VisionFrame:
model_size = get_model_options().get('size')
model_shift = get_model_options().get('shift')
model_coverage = get_model_options().get('coverage')
model_x_shift = get_model_options().get('x_shift')
model_y_shift = get_model_options().get('y_shift')
crop_vision_frame, affine_matrix = warp_face_for_deepfacelive(temp_vision_frame, target_face.landmark_set.get('5/68'), model_size, model_coverage, model_x_shift, model_y_shift)
crop_vision_frame, affine_matrix = warp_face_for_deepfacelive(temp_vision_frame, target_face.landmark_set.get('5/68'), model_size, model_shift, model_coverage)
crop_vision_frame_raw = crop_vision_frame.copy()
box_mask = create_static_box_mask(crop_vision_frame.shape[:2][::-1], state_manager.get_item('face_mask_blur'), state_manager.get_item('face_mask_padding'))
crop_masks =\
@ -170,10 +168,12 @@ def normalize_crop_frame(crop_vision_frame : VisionFrame) -> VisionFrame:
def prepare_crop_mask(crop_source_mask : Mask, crop_target_mask : Mask) -> Mask:
model_size = get_model_options().get('size')
blur_size = 6.25
kernel_size = 3
crop_mask = numpy.minimum.reduce([ crop_source_mask, crop_target_mask ])
crop_mask = crop_mask.reshape(model_size).clip(0, 1)
crop_mask = cv2.erode(crop_mask, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)), iterations = 2)
crop_mask = cv2.GaussianBlur(crop_mask, (0, 0), 6.25)
crop_mask = cv2.erode(crop_mask, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (kernel_size, kernel_size)), iterations = 2)
crop_mask = cv2.GaussianBlur(crop_mask, (0, 0), blur_size)
return crop_mask

View File

@ -86,10 +86,10 @@ ProcessStep = Callable[[str, int, Args], bool]
Content = Dict[str, Any]
WarpTemplate = Literal['arcface_112_v1', 'arcface_112_v2', 'arcface_128_v2', 'ffhq_512', 'mtcnn_512', 'styleganex_384', 'deep_face_live']
WarpTemplate = Literal['arcface_112_v1', 'arcface_112_v2', 'arcface_128_v2', 'deep_face_live', 'ffhq_512', 'mtcnn_512', 'styleganex_384']
WarpTemplateSet = Dict[WarpTemplate, NDArray[Any]]
PolygonTemplate = Literal['square', 'triangle_orthogonal', 'triangle_skew']
PolygonTemplateSet = Dict[PolygonTemplate, NDArray[Any]]
PointsTemplate = Literal['square', 'triangle_orthogonal', 'triangle_skew']
PointsTemplateSet = Dict[PointsTemplate, NDArray[Any]]
ProcessMode = Literal['output', 'preview', 'stream']
ErrorCode = Literal[0, 1, 2, 3, 4]