changes
This commit is contained in:
parent
0b6dd6c8b1
commit
37239f06f6
@ -5,7 +5,7 @@ import cv2
|
|||||||
import numpy
|
import numpy
|
||||||
from cv2.typing import Size
|
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 =\
|
WARP_TEMPLATES : WarpTemplateSet =\
|
||||||
{
|
{
|
||||||
@ -33,6 +33,14 @@ WARP_TEMPLATES : WarpTemplateSet =\
|
|||||||
[ 0.38710391, 0.72160547 ],
|
[ 0.38710391, 0.72160547 ],
|
||||||
[ 0.61507734, 0.72034453 ]
|
[ 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(
|
'ffhq_512': numpy.array(
|
||||||
[
|
[
|
||||||
[ 0.37691676, 0.46864664 ],
|
[ 0.37691676, 0.46864664 ],
|
||||||
@ -56,17 +64,9 @@ WARP_TEMPLATES : WarpTemplateSet =\
|
|||||||
[ 0.50123859, 0.61331904 ],
|
[ 0.50123859, 0.61331904 ],
|
||||||
[ 0.43364461, 0.68337652 ],
|
[ 0.43364461, 0.68337652 ],
|
||||||
[ 0.57015325, 0.68306005 ]
|
[ 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(
|
'square': numpy.array(
|
||||||
[
|
[
|
||||||
@ -74,19 +74,19 @@ POLYGON_TEMPLATES : PolygonTemplateSet =\
|
|||||||
[ 1, 0 ],
|
[ 1, 0 ],
|
||||||
[ 1, 1 ],
|
[ 1, 1 ],
|
||||||
[ 0, 1 ]
|
[ 0, 1 ]
|
||||||
]),
|
]).astype(numpy.float32),
|
||||||
'triangle_orthogonal': numpy.array(
|
'triangle_orthogonal': numpy.array(
|
||||||
[
|
[
|
||||||
[ 0, 0 ],
|
[ 0, 0 ],
|
||||||
[ 1, 0 ],
|
[ 1, 0 ],
|
||||||
[ 0, 1 ]
|
[ 0, 1 ]
|
||||||
]),
|
]).astype(numpy.float32),
|
||||||
'triangle_skew': numpy.array(
|
'triangle_skew': numpy.array(
|
||||||
[
|
[
|
||||||
[ 0, 0 ],
|
[ 0, 0 ],
|
||||||
[ 1, 0 ],
|
[ 1, 0 ],
|
||||||
[ 1, 1 ]
|
[ 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
|
return affine_matrix
|
||||||
|
|
||||||
|
|
||||||
def estimate_matrix_by_points(source_points : Points, polygon_template : PolygonTemplate, crop_size : Size) -> Matrix:
|
def estimate_matrix_by_points(source_points : Points, polygon_template : PointsTemplate, crop_size : Size) -> Matrix:
|
||||||
target_points = POLYGON_TEMPLATES.get(polygon_template) * crop_size
|
target_points = POINTS_TEMPLATES.get(polygon_template) * crop_size
|
||||||
affine_matrix = cv2.getAffineTransform(source_points, target_points.astype(numpy.float32))
|
affine_matrix = cv2.getAffineTransform(source_points, target_points.astype(numpy.float32))
|
||||||
return affine_matrix
|
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
|
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))
|
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))
|
square_points = transform_points(square_points, cv2.invertAffineTransform(affine_matrix))
|
||||||
center_point = square_points.mean(axis = 0)
|
center_point = square_points.mean(axis = 0)
|
||||||
center_point += x_shift * numpy.subtract(square_points[1], square_points[0])
|
center_point += shift[0] * numpy.subtract(square_points[1], square_points[0])
|
||||||
center_point += y_shift * numpy.subtract(square_points[3], 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
|
scale = numpy.linalg.norm(center_point - square_points[0]) * coverage
|
||||||
top_bottom_direction = calc_points_direction(square_points[0], square_points[2]) * scale
|
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
|
bottom_top_direction = calc_points_direction(square_points[3], square_points[1]) * scale
|
||||||
|
@ -42,10 +42,9 @@ MODEL_SET : ModelSet =\
|
|||||||
'path': resolve_relative_path('../.assets/models/Jackie_Chan.dfm')
|
'path': resolve_relative_path('../.assets/models/Jackie_Chan.dfm')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'x_shift': 0.0,
|
'size': (224, 224),
|
||||||
'y_shift': 0.0,
|
'shift': (0.0, 0.0),
|
||||||
'coverage': 2.2,
|
'coverage': 2.2
|
||||||
'size': (224, 224)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,10 +112,9 @@ def post_process() -> None:
|
|||||||
|
|
||||||
def swap_face(target_face : Face, temp_vision_frame : VisionFrame) -> VisionFrame:
|
def swap_face(target_face : Face, temp_vision_frame : VisionFrame) -> VisionFrame:
|
||||||
model_size = get_model_options().get('size')
|
model_size = get_model_options().get('size')
|
||||||
|
model_shift = get_model_options().get('shift')
|
||||||
model_coverage = get_model_options().get('coverage')
|
model_coverage = get_model_options().get('coverage')
|
||||||
model_x_shift = get_model_options().get('x_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)
|
||||||
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_raw = crop_vision_frame.copy()
|
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'))
|
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 =\
|
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:
|
def prepare_crop_mask(crop_source_mask : Mask, crop_target_mask : Mask) -> Mask:
|
||||||
model_size = get_model_options().get('size')
|
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 = numpy.minimum.reduce([ crop_source_mask, crop_target_mask ])
|
||||||
crop_mask = crop_mask.reshape(model_size).clip(0, 1)
|
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.erode(crop_mask, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (kernel_size, kernel_size)), iterations = 2)
|
||||||
crop_mask = cv2.GaussianBlur(crop_mask, (0, 0), 6.25)
|
crop_mask = cv2.GaussianBlur(crop_mask, (0, 0), blur_size)
|
||||||
return crop_mask
|
return crop_mask
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,10 +86,10 @@ ProcessStep = Callable[[str, int, Args], bool]
|
|||||||
|
|
||||||
Content = Dict[str, Any]
|
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]]
|
WarpTemplateSet = Dict[WarpTemplate, NDArray[Any]]
|
||||||
PolygonTemplate = Literal['square', 'triangle_orthogonal', 'triangle_skew']
|
PointsTemplate = Literal['square', 'triangle_orthogonal', 'triangle_skew']
|
||||||
PolygonTemplateSet = Dict[PolygonTemplate, NDArray[Any]]
|
PointsTemplateSet = Dict[PointsTemplate, NDArray[Any]]
|
||||||
ProcessMode = Literal['output', 'preview', 'stream']
|
ProcessMode = Literal['output', 'preview', 'stream']
|
||||||
|
|
||||||
ErrorCode = Literal[0, 1, 2, 3, 4]
|
ErrorCode = Literal[0, 1, 2, 3, 4]
|
||||||
|
Loading…
Reference in New Issue
Block a user