+xlib.facemeta and refactoring

This commit is contained in:
iperov 2021-10-18 16:56:04 +04:00
commit 63adc2995e
28 changed files with 962 additions and 613 deletions

View file

@ -5,10 +5,32 @@ from typing import List, Union, Tuple
import numpy as np
from xlib import mp as lib_mp
from xlib import time as lib_time
from xlib.facemeta import FaceMark
from xlib.mp import csw as lib_csw
from xlib.python.EventListener import EventListener
from xlib.facemeta import FRect, FLandmarks2D, FPose
class BackendFaceSwapInfo:
def __init__(self):
self.image_name = None
self.face_urect : FRect = None
self.face_pose : FPose = None
self.face_ulmrks : FLandmarks2D = None
self.face_align_image_name : str = None
self.face_align_mask_name : str = None
self.face_swap_image_name : str = None
self.face_swap_mask_name : str = None
self.image_to_align_uni_mat = None
self.face_align_ulmrks : FLandmarks2D = None
def __getstate__(self):
return self.__dict__.copy()
def __setstate__(self, d):
self.__init__()
self.__dict__.update(d)
class BackendConnectionData:
"""
@ -27,13 +49,14 @@ class BackendConnectionData:
self._uid = uid
self._is_frame_reemitted = None
self._frame_name = None
self._frame_image_name = None
self._frame_count = None
self._frame_num = None
self._frame_fps = None
self._frame_timestamp = None
self._merged_frame_name = None
self._face_mark_list = []
self._merged_image_name = None
self._face_swap_info_list = []
def __getstate__(self, ):
d = self.__dict__.copy()
@ -43,43 +66,43 @@ class BackendConnectionData:
def assign_weak_heap(self, weak_heap : lib_mp.MPWeakHeap):
self._weak_heap = weak_heap
def set_file(self, name : str, data : Union[bytes, bytearray, memoryview]):
self._weak_heap_refs[name] = self._weak_heap.add_data(data)
def set_file(self, key, data : Union[bytes, bytearray, memoryview]):
self._weak_heap_refs[key] = self._weak_heap.add_data(data)
def get_file(self, name : str) -> Union[bytes, None]:
ref = self._weak_heap_refs.get(name, None)
def get_file(self, key) -> Union[bytes, None]:
ref = self._weak_heap_refs.get(key, None)
if ref is not None:
return self._weak_heap.get_data(ref)
return None
def set_image(self, name : str, image : np.ndarray):
def set_image(self, key, image : np.ndarray):
"""
store image to weak heap
name str
key
image np.ndarray
"""
self.set_file(name, image.data)
self._weak_heap_image_infos[name] = (image.shape, image.dtype)
def get_image_shape_dtype(self, name:str) -> Union[None, Tuple[List, np.dtype]]:
self.set_file(key, image.data)
self._weak_heap_image_infos[key] = (image.shape, image.dtype)
def get_image_shape_dtype(self, key) -> Union[None, Tuple[List, np.dtype]]:
"""
returns (image shape, dtype) or (None, None) if file does not exist
"""
if name is None:
return None
image_info = self._weak_heap_image_infos.get(name, None)
if key is None:
return (None, None)
image_info = self._weak_heap_image_infos.get(key, None)
if image_info is not None:
shape, dtype = image_info
return shape, dtype
return (None, None)
def get_image(self, name : str) -> Union[np.ndarray, None]:
if name is None:
def get_image(self, key) -> Union[np.ndarray, None]:
if key is None:
return None
image_info = self._weak_heap_image_infos.get(name, None)
buffer = self.get_file(name)
image_info = self._weak_heap_image_infos.get(key, None)
buffer = self.get_file(key)
if image_info is not None and buffer is not None:
shape, dtype = image_info
@ -90,10 +113,6 @@ class BackendConnectionData:
def get_is_frame_reemitted(self) -> Union[bool, None]: return self._is_frame_reemitted
def set_is_frame_reemitted(self, is_frame_reemitted : bool): self._is_frame_reemitted = is_frame_reemitted
def get_frame_name(self) -> Union[str, None]: return self._frame_name
def set_frame_name(self, frame_name : str): self._frame_name = frame_name
def get_frame_count(self) -> Union[int, None]: return self._frame_count
def set_frame_count(self, frame_count : int): self._frame_count = frame_count
def get_frame_num(self) -> Union[int, None]: return self._frame_num
@ -103,14 +122,17 @@ class BackendConnectionData:
def get_frame_timestamp(self) -> Union[float, None]: return self._frame_timestamp
def set_frame_timestamp(self, frame_timestamp : float): self._frame_timestamp = frame_timestamp
def get_merged_frame_name(self) -> Union[str, None]: return self._merged_frame_name
def set_merged_frame_name(self, merged_frame_name : str): self._merged_frame_name = merged_frame_name
def get_frame_image_name(self) -> Union[str, None]: return self._frame_image_name
def set_frame_image_name(self, frame_image_name : str): self._frame_image_name = frame_image_name
def get_merged_image_name(self) -> Union[str, None]: return self._merged_image_name
def set_merged_image_name(self, merged_frame_name : str): self._merged_image_name = merged_frame_name
def get_face_swap_info_list(self) -> List[BackendFaceSwapInfo]: return self._face_swap_info_list
def add_face_swap_info(self, fsi : BackendFaceSwapInfo):
if not isinstance(fsi, BackendFaceSwapInfo):
raise ValueError(f'fsi must be an instance of BackendFaceSwapInfo')
self._face_swap_info_list.append(fsi)
def get_face_mark_list(self) -> List[FaceMark]: return self._face_mark_list
def add_face_mark(self, face_mark : FaceMark):
if not isinstance(face_mark, FaceMark):
raise ValueError(f'face_mark must be an instance of FaceMark')
self._face_mark_list.append(face_mark)
class BackendConnection:
@ -144,7 +166,7 @@ class BackendConnection:
def is_full_read(self, buffer_size=0) -> bool:
"""
if fully readed by receiver side minus buffer_size
"""
"""
return self._rd.get_read_id() >= (self._rd.get_write_id() - buffer_size)
@ -205,3 +227,4 @@ class BackendWorker(lib_csw.Worker):
def stop_profile_timing(self):
self.send_msg('_profile_timing', self._profile_timing_measurer.stop() )

View file

@ -253,7 +253,7 @@ class CameraSourceWorker(BackendWorker):
bcd.assign_weak_heap(self.weak_heap)
frame_name = f'Camera_{state.device_idx}_{bcd_uid:06}'
bcd.set_frame_name(frame_name)
bcd.set_frame_image_name(frame_name)
bcd.set_frame_num(bcd_uid)
bcd.set_frame_timestamp(timestamp)
bcd.set_image(frame_name, img)

View file

@ -2,7 +2,6 @@ import time
import numpy as np
from xlib import os as lib_os
from xlib.facemeta import FaceAlign, FaceULandmarks
from xlib.mp import csw as lib_csw
from xlib.python import all_is_not_None
@ -51,7 +50,7 @@ class FaceAlignerWorker(BackendWorker):
cs.exclude_moving_parts.enable()
cs.exclude_moving_parts.set_flag(state.exclude_moving_parts if state.exclude_moving_parts is not None else True)
cs.head_mode.enable()
cs.head_mode.set_flag(state.head_mode if state.head_mode is not None else False)
@ -91,7 +90,7 @@ class FaceAlignerWorker(BackendWorker):
state.head_mode = head_mode
self.save_state()
self.reemit_frame_signal.send()
def on_cs_x_offset(self, x_offset):
state, cs = self.get_state(), self.get_control_sheet()
cfg = cs.x_offset.get_config()
@ -118,21 +117,17 @@ class FaceAlignerWorker(BackendWorker):
if bcd is not None:
bcd.assign_weak_heap(self.weak_heap)
frame_name = bcd.get_frame_name()
frame_image = bcd.get_image(frame_name)
frame_image_name = bcd.get_frame_image_name()
frame_image = bcd.get_image(frame_image_name)
if all_is_not_None(state.face_coverage, state.resolution, frame_name, frame_image):
for face_id,face_mark in enumerate( bcd.get_face_mark_list() ):
face_ulmrks = face_mark.get_face_ulandmarks_by_type(FaceULandmarks.Type.LANDMARKS_468)
if face_ulmrks is None:
face_ulmrks = face_mark.get_face_ulandmarks_by_type(FaceULandmarks.Type.LANDMARKS_68)
if all_is_not_None(state.face_coverage, state.resolution, frame_image):
for face_id, fsi in enumerate( bcd.get_face_swap_info_list() ):
head_yaw = None
if state.head_mode:
face_pose = face_mark.get_face_pose()
if face_pose is not None:
head_yaw = face_pose.as_radians()[1]
if fsi.face_pose is not None:
head_yaw = fsi.face_pose.as_radians()[1]
face_ulmrks = fsi.face_ulmrks
if face_ulmrks is not None:
face_image, uni_mat = face_ulmrks.cut(frame_image, state.face_coverage, state.resolution,
exclude_moving_parts=state.exclude_moving_parts,
@ -140,19 +135,11 @@ class FaceAlignerWorker(BackendWorker):
x_offset=state.x_offset,
y_offset=state.y_offset)
face_align_image_name = f'{frame_name}_{face_id}_aligned'
fsi.face_align_image_name = f'{frame_image_name}_{face_id}_aligned'
fsi.image_to_align_uni_mat = uni_mat
fsi.face_align_ulmrks = face_ulmrks.transform(uni_mat)
face_align = FaceAlign()
face_align.set_image_name(face_align_image_name)
face_align.set_coverage(state.face_coverage)
face_align.set_source_face_ulandmarks_type(face_ulmrks.get_type())
face_align.set_source_to_aligned_uni_mat(uni_mat)
for face_ulmrks in face_mark.get_face_ulandmarks_list():
face_align.add_face_ulandmarks( face_ulmrks.transform(uni_mat) )
face_mark.set_face_align(face_align)
bcd.set_image(face_align_image_name, face_image)
bcd.set_image(fsi.face_align_image_name, face_image)
self.stop_profile_timing()
self.pending_bcd = bcd

View file

@ -4,14 +4,14 @@ from enum import IntEnum
import numpy as np
from modelhub import onnx as onnx_models
from xlib import os as lib_os
from xlib.facemeta import FaceMark, FaceURect
from xlib.facemeta import FRect
from xlib.image import ImageProcessor
from xlib.mp import csw as lib_csw
from xlib.python import all_is_not_None
from .BackendBase import (BackendConnection, BackendDB, BackendHost,
BackendSignal, BackendWeakHeap, BackendWorker,
BackendWorkerState)
BackendWorkerState, BackendFaceSwapInfo)
class DetectorType(IntEnum):
@ -213,10 +213,10 @@ class FaceDetectorWorker(BackendWorker):
detector_state = state.get_detector_state()
frame_name = bcd.get_frame_name()
frame_image = bcd.get_image(frame_name)
frame_image_name = bcd.get_frame_image_name()
frame_image = bcd.get_image(frame_image_name)
if all_is_not_None(frame_image, frame_name):
if frame_image is not None:
_,H,W,_ = ImageProcessor(frame_image).get_dims()
rects = []
@ -228,13 +228,13 @@ class FaceDetectorWorker(BackendWorker):
rects = self.YoloV5Face.extract (frame_image, threshold=detector_state.threshold, fixed_window=detector_state.fixed_window_size)[0]
# to list of FaceURect
rects = [ FaceURect.from_ltrb( (l/W, t/H, r/W, b/H) ) for l,t,r,b in rects ]
rects = [ FRect.from_ltrb( (l/W, t/H, r/W, b/H) ) for l,t,r,b in rects ]
# sort
if detector_state.sort_by == FaceSortBy.LARGEST:
rects = FaceURect.sort_by_area_size(rects)
rects = FRect.sort_by_area_size(rects)
elif detector_state.sort_by == FaceSortBy.DIST_FROM_CENTER:
rects = FaceURect.sort_by_dist_from_center(rects)
rects = FRect.sort_by_dist_from_center(rects)
if len(rects) != 0:
max_faces = detector_state.max_faces
@ -245,20 +245,20 @@ class FaceDetectorWorker(BackendWorker):
if len(self.temporal_rects) != len(rects):
self.temporal_rects = [ [] for _ in range(len(rects)) ]
for face_id, face_rect in enumerate(rects):
for face_id, face_urect in enumerate(rects):
if detector_state.temporal_smoothing != 1:
if not is_frame_reemitted or len(self.temporal_rects[face_id]) == 0:
self.temporal_rects[face_id].append( face_rect.as_4pts() )
self.temporal_rects[face_id].append( face_urect.as_4pts() )
self.temporal_rects[face_id] = self.temporal_rects[face_id][-detector_state.temporal_smoothing:]
face_rect = FaceURect.from_4pts ( np.mean(self.temporal_rects[face_id],0 ) )
face_urect = FRect.from_4pts ( np.mean(self.temporal_rects[face_id],0 ) )
if face_rect.get_area() != 0:
face_mark = FaceMark()
face_mark.set_image_name(frame_name)
face_mark.set_face_urect ( face_rect )
bcd.add_face_mark(face_mark)
if face_urect.get_area() != 0:
fsi = BackendFaceSwapInfo()
fsi.image_name = frame_image_name
fsi.face_urect = face_urect
bcd.add_face_swap_info(fsi)
self.stop_profile_timing()
self.pending_bcd = bcd

View file

@ -5,7 +5,7 @@ from modelhub import onnx as onnx_models
from modelhub import cv as cv_models
from xlib import os as lib_os
from xlib.facemeta import FaceULandmarks, FacePose
from xlib.facemeta import ELandmarks2D, FLandmarks2D, FPose
from xlib.image import ImageProcessor
from xlib.mp import csw as lib_csw
from xlib.python import all_is_not_None
@ -153,20 +153,18 @@ class FaceMarkerWorker(BackendWorker):
is_google_facemesh = marker_type == MarkerType.GOOGLE_FACEMESH and self.google_facemesh is not None
if marker_type is not None:
frame_name = bcd.get_frame_name()
frame_image = bcd.get_image(frame_name)
frame_image = bcd.get_image(bcd.get_frame_image_name())
if all_is_not_None(frame_image) and (is_opencv_lbf or is_google_facemesh):
face_mark_list = bcd.get_face_mark_list()
if frame_image is not None and (is_opencv_lbf or is_google_facemesh):
fsi_list = bcd.get_face_swap_info_list()
if marker_state.temporal_smoothing != 1 and \
len(self.temporal_lmrks) != len(face_mark_list):
self.temporal_lmrks = [ [] for _ in range(len(face_mark_list)) ]
len(self.temporal_lmrks) != len(fsi_list):
self.temporal_lmrks = [ [] for _ in range(len(fsi_list)) ]
for face_id, face_mark in enumerate(face_mark_list):
face_mark_rect = face_mark.get_face_urect()
if face_mark_rect is not None:
for face_id, fsi in enumerate(fsi_list):
if fsi.face_urect is not None:
# Cut the face to feed to the face marker
face_image, face_uni_mat = face_mark_rect.cut(frame_image, marker_state.marker_coverage, 256 if is_opencv_lbf else \
face_image, face_uni_mat = fsi.face_urect.cut(frame_image, marker_state.marker_coverage, 256 if is_opencv_lbf else \
192 if is_google_facemesh else 0 )
_,H,W,_ = ImageProcessor(face_image).get_dims()
@ -183,20 +181,17 @@ class FaceMarkerWorker(BackendWorker):
lmrks = np.mean(self.temporal_lmrks[face_id],0 )
if is_google_facemesh:
face_mark.set_face_pose(FacePose.from_3D_468_landmarks(lmrks))
fsi.face_pose = FPose.from_3D_468_landmarks(lmrks)
if is_opencv_lbf:
lmrks /= (W,H)
elif is_google_facemesh:
lmrks = lmrks[...,0:2] / (W,H)
face_ulmrks = FaceULandmarks.create (FaceULandmarks.Type.LANDMARKS_68 if is_opencv_lbf else \
FaceULandmarks.Type.LANDMARKS_468 if is_google_facemesh else None, lmrks)
face_ulmrks = FLandmarks2D.create (ELandmarks2D.L68 if is_opencv_lbf else \
ELandmarks2D.L468 if is_google_facemesh else None, lmrks)
face_ulmrks = face_ulmrks.transform(face_uni_mat, invert=True)
face_mark.add_face_ulandmarks (face_ulmrks)
fsi.face_ulmrks = face_ulmrks
self.stop_profile_timing()
self.pending_bcd = bcd

View file

@ -255,44 +255,35 @@ class FaceMergerWorker(BackendWorker):
if bcd is not None:
bcd.assign_weak_heap(self.weak_heap)
frame_name = bcd.get_frame_name()
frame_image = bcd.get_image(frame_name)
frame_image_name = bcd.get_frame_image_name()
frame_image = bcd.get_image(frame_image_name)
if frame_image is not None:
for face_mark in bcd.get_face_mark_list():
face_align = face_mark.get_face_align()
if face_align is not None:
face_swap = face_align.get_face_swap()
face_align_mask = face_align.get_face_mask()
for fsi in bcd.get_face_swap_info_list():
face_align_img_shape, _ = bcd.get_image_shape_dtype(fsi.face_align_image_name)
face_align_mask_img = bcd.get_image(fsi.face_align_mask_name)
face_swap_img = bcd.get_image(fsi.face_swap_image_name)
face_swap_mask_img = bcd.get_image(fsi.face_swap_mask_name)
image_to_align_uni_mat = fsi.image_to_align_uni_mat
if face_swap is not None:
face_swap_mask = face_swap.get_face_mask()
if face_swap_mask is not None:
if all_is_not_None(face_align_img_shape, face_align_mask_img, face_swap_img, face_swap_mask_img, image_to_align_uni_mat):
face_height, face_width = face_align_img_shape[:2]
frame_height, frame_width = frame_image.shape[:2]
aligned_to_source_uni_mat = image_to_align_uni_mat.invert()
aligned_to_source_uni_mat = aligned_to_source_uni_mat.source_translated(-state.face_x_offset, -state.face_y_offset)
aligned_to_source_uni_mat = aligned_to_source_uni_mat.source_scaled_around_center(state.face_scale,state.face_scale)
aligned_to_source_uni_mat = aligned_to_source_uni_mat.to_exact_mat (face_width, face_height, frame_width, frame_height)
face_align_img_shape, _ = bcd.get_image_shape_dtype(face_align.get_image_name())
face_align_mask_img = bcd.get_image(face_align_mask.get_image_name())
face_swap_img = bcd.get_image(face_swap.get_image_name())
face_swap_mask_img = bcd.get_image(face_swap_mask.get_image_name())
source_to_aligned_uni_mat = face_align.get_source_to_aligned_uni_mat()
if state.device == 'CPU':
merged_frame = self._merge_on_cpu(frame_image, face_align_mask_img, face_swap_img, face_swap_mask_img, aligned_to_source_uni_mat, frame_width, frame_height )
else:
merged_frame = self._merge_on_gpu(frame_image, face_align_mask_img, face_swap_img, face_swap_mask_img, aligned_to_source_uni_mat, frame_width, frame_height )
# keep image in float32 in order not to extra load FaceMerger
if all_is_not_None(face_align_img_shape, face_align_mask_img, face_swap_img, face_swap_mask_img):
face_height, face_width = face_align_img_shape[:2]
frame_height, frame_width = frame_image.shape[:2]
aligned_to_source_uni_mat = source_to_aligned_uni_mat.invert()
aligned_to_source_uni_mat = aligned_to_source_uni_mat.source_translated(-state.face_x_offset, -state.face_y_offset)
aligned_to_source_uni_mat = aligned_to_source_uni_mat.source_scaled_around_center(state.face_scale,state.face_scale)
aligned_to_source_uni_mat = aligned_to_source_uni_mat.to_exact_mat (face_width, face_height, frame_width, frame_height)
if state.device == 'CPU':
merged_frame = self._merge_on_cpu(frame_image, face_align_mask_img, face_swap_img, face_swap_mask_img, aligned_to_source_uni_mat, frame_width, frame_height )
else:
merged_frame = self._merge_on_gpu(frame_image, face_align_mask_img, face_swap_img, face_swap_mask_img, aligned_to_source_uni_mat, frame_width, frame_height )
# keep image in float32 in order not to extra load FaceMerger
merged_frame_name = f'{frame_name}_merged'
bcd.set_merged_frame_name(merged_frame_name)
bcd.set_image(merged_frame_name, merged_frame)
break
merged_image_name = f'{frame_image_name}_merged'
bcd.set_merged_image_name(merged_image_name)
bcd.set_image(merged_image_name, merged_frame)
break
self.stop_profile_timing()
self.pending_bcd = bcd

View file

@ -4,7 +4,6 @@ from pathlib import Path
import numpy as np
from modelhub import DFLive
from xlib import os as lib_os
from xlib.facemeta import FaceMask, FaceSwap
from xlib.image.ImageProcessor import ImageProcessor
from xlib.mp import csw as lib_csw
from xlib.python import all_is_not_None
@ -171,7 +170,7 @@ class FaceSwapperWorker(BackendWorker):
cs.model_dl_progress.enable()
cs.model_dl_progress.set_config( lib_csw.Progress.Config(title='@FaceSwapper.downloading_model') )
cs.model_dl_progress.set_progress(0)
elif events.new_status_initialized:
self.dfm_model = events.dfm_model
self.dfm_model_initializer = None
@ -239,47 +238,39 @@ class FaceSwapperWorker(BackendWorker):
if all_is_not_None(dfm_model, model_state):
face_id = model_state.face_id
if face_id is not None:
for i, face_mark in enumerate(bcd.get_face_mark_list()):
if face_id == i:
face_align = face_mark.get_face_align()
if face_align is not None:
face_align_image_name = face_align.get_image_name()
face_align_image = bcd.get_image(face_align_image_name)
if face_align_image is not None:
for i, fsi in enumerate(bcd.get_face_swap_info_list()):
if face_id != i:
continue
pre_gamma_red = model_state.pre_gamma_red
pre_gamma_green = model_state.pre_gamma_green
pre_gamma_blue = model_state.pre_gamma_blue
face_align_image = bcd.get_image(fsi.face_align_image_name)
if face_align_image is not None:
fai_ip = ImageProcessor(face_align_image)
if model_state.presharpen_amount != 0:
fai_ip.sharpen(factor=model_state.presharpen_amount)
pre_gamma_red = model_state.pre_gamma_red
pre_gamma_green = model_state.pre_gamma_green
pre_gamma_blue = model_state.pre_gamma_blue
if pre_gamma_red != 1.0 or pre_gamma_green != 1.0 or pre_gamma_blue != 1.0:
fai_ip.adjust_gamma(pre_gamma_red, pre_gamma_green, pre_gamma_blue)
face_align_image = fai_ip.get_image('HWC')
fai_ip = ImageProcessor(face_align_image)
if model_state.presharpen_amount != 0:
fai_ip.sharpen(factor=model_state.presharpen_amount)
celeb_face, celeb_face_mask_img, face_align_mask_img = dfm_model.convert(face_align_image, morph_factor=model_state.morph_factor)
celeb_face, celeb_face_mask_img, face_align_mask_img = celeb_face[0], celeb_face_mask_img[0], face_align_mask_img[0]
if pre_gamma_red != 1.0 or pre_gamma_green != 1.0 or pre_gamma_blue != 1.0:
fai_ip.adjust_gamma(pre_gamma_red, pre_gamma_green, pre_gamma_blue)
face_align_image = fai_ip.get_image('HWC')
if model_state.two_pass:
celeb_face, celeb_face_mask_img, _ = dfm_model.convert(celeb_face, morph_factor=model_state.morph_factor)
celeb_face, celeb_face_mask_img = celeb_face[0], celeb_face_mask_img[0]
celeb_face, celeb_face_mask_img, face_align_mask_img = dfm_model.convert(face_align_image, morph_factor=model_state.morph_factor)
celeb_face, celeb_face_mask_img, face_align_mask_img = celeb_face[0], celeb_face_mask_img[0], face_align_mask_img[0]
face_align_mask = FaceMask()
face_align_mask.set_image_name(f'{face_align_image_name}_mask')
face_align.set_face_mask(face_align_mask)
bcd.set_image(face_align_mask.get_image_name(), face_align_mask_img)
if model_state.two_pass:
celeb_face, celeb_face_mask_img, _ = dfm_model.convert(celeb_face, morph_factor=model_state.morph_factor)
celeb_face, celeb_face_mask_img = celeb_face[0], celeb_face_mask_img[0]
face_swap = FaceSwap()
face_swap.set_image_name (f"{face_align_image_name}_swapped")
face_align.set_face_swap(face_swap)
bcd.set_image(face_swap.get_image_name(), celeb_face)
fsi.face_align_mask_name = f'{fsi.face_align_image_name}_mask'
fsi.face_swap_image_name = f'{fsi.face_align_image_name}_swapped'
fsi.face_swap_mask_name = f'{fsi.face_swap_image_name}_mask'
face_swap_mask = FaceMask()
face_swap_mask.set_image_name(f'{face_swap.get_image_name()}_mask')
face_swap.set_face_mask(face_swap_mask)
bcd.set_image(face_swap_mask.get_image_name(), celeb_face_mask_img)
bcd.set_image(fsi.face_align_mask_name, face_align_mask_img)
bcd.set_image(fsi.face_swap_image_name, celeb_face)
bcd.set_image(fsi.face_swap_mask_name, celeb_face_mask_img)
self.stop_profile_timing()
self.pending_bcd = bcd

View file

@ -287,7 +287,7 @@ class FileSourceWorker(BackendWorker):
bcd.set_frame_num(p_frame.frame_num)
bcd.set_frame_fps(p_frame.fps)
bcd.set_frame_timestamp(p_frame.timestamp)
bcd.set_frame_name(p_frame.name)
bcd.set_frame_image_name(p_frame.name)
image = ImageProcessor(p_frame.image).to_uint8().get_image('HWC')
bcd.set_image(p_frame.name, image)

View file

@ -72,8 +72,8 @@ class FrameAdjusterWorker(BackendWorker):
if bcd is not None:
bcd.assign_weak_heap(self.weak_heap)
frame_name = bcd.get_frame_name()
frame_image = bcd.get_image(frame_name)
frame_image_name = bcd.get_frame_image_name()
frame_image = bcd.get_image(frame_image_name)
if frame_image is not None:
frame_image_ip = ImageProcessor(frame_image)
@ -81,7 +81,7 @@ class FrameAdjusterWorker(BackendWorker):
frame_image_ip.degrade_resize( state.degrade_bicubic_per / 100.0, interpolation=ImageProcessor.Interpolation.CUBIC)
frame_image = frame_image_ip.get_image('HWC')
bcd.set_image(frame_name, frame_image)
bcd.set_image(frame_image_name, frame_image)
self.stop_profile_timing()
self.pending_bcd = bcd

View file

@ -202,31 +202,26 @@ class StreamOutputWorker(BackendWorker):
view_image = None
if source_type == SourceType.SOURCE_FRAME:
view_image = bcd.get_image(bcd.get_frame_name())
view_image = bcd.get_image(bcd.get_frame_image_name())
elif source_type == SourceType.MERGED_FRAME:
view_image = bcd.get_image(bcd.get_merged_frame_name())
view_image = bcd.get_image(bcd.get_merged_image_name())
elif source_type == SourceType.ALIGNED_FACE:
aligned_face_id = state.aligned_face_id
for i, face_mark in enumerate(bcd.get_face_mark_list()):
for i, fsi in enumerate(bcd.get_face_swap_info_list()):
if aligned_face_id == i:
face_align = face_mark.get_face_align()
if face_align is not None:
view_image = bcd.get_image(face_align.get_image_name())
view_image = bcd.get_image(fsi.face_align_image_name)
break
elif source_type == SourceType.SWAPPED_FACE:
for face_mark in bcd.get_face_mark_list():
face_align = face_mark.get_face_align()
if face_align is not None:
face_swap = face_align.get_face_swap()
if face_swap is not None:
view_image = bcd.get_image(face_swap.get_image_name())
break
for fsi in bcd.get_face_swap_info_list():
view_image = bcd.get_image(fsi.face_swap_image_name)
if view_image is not None:
break
elif source_type == SourceType.SOURCE_N_MERGED_FRAME:
source_frame = bcd.get_image(bcd.get_frame_name())
merged_frame = bcd.get_image(bcd.get_merged_frame_name())
source_frame = bcd.get_image(bcd.get_frame_image_name())
merged_frame = bcd.get_image(bcd.get_merged_image_name())
if source_frame is not None and merged_frame is not None:
source_frame = ImageProcessor(source_frame).to_ufloat32().get_image('HWC')
view_image = np.concatenate( (source_frame, merged_frame), 1 )

View file

@ -92,20 +92,18 @@ class QFaceDetector(QBackendPanel):
if bcd is not None:
bcd.assign_weak_heap(self._weak_heap)
frame_name = bcd.get_frame_name()
frame_image = bcd.get_image(frame_name)
frame_image = bcd.get_image(bcd.get_frame_image_name())
frame_image_w_h = None
if frame_image is not None:
h,w = frame_image.shape[0:2]
frame_image_w_h = (w,h)
info = []
for face_num,face_mark in enumerate(bcd.get_face_mark_list()):
info_str = f'{face_num}: '
rect = face_mark.get_face_urect()
if rect is not None:
l,t,r,b = rect.as_ltrb_bbox(frame_image_w_h).astype(np.int)
for face_id, fsi in enumerate(bcd.get_face_swap_info_list()):
info_str = f'{face_id}: '
if fsi.face_urect is not None:
l,t,r,b = fsi.face_urect.as_ltrb_bbox(frame_image_w_h).astype(np.int)
info_str += f'[{l},{t},{r},{b}]'
info.append(info_str)

View file

@ -5,8 +5,6 @@ from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from resources.fonts import QXFontDB
from xlib import qt as lib_qt
from xlib.facemeta import FaceULandmarks
from xlib.python import all_is_not_None
from ... import backend
@ -47,36 +45,25 @@ class QBCFaceAlignViewer(lib_qt.QXCollapsibleSection):
self._layered_images.clear_images()
for face_mark in bcd.get_face_mark_list():
face_align = face_mark.get_face_align()
if face_align is not None:
face_image = bcd.get_image (face_align.get_image_name())
if face_image is not None:
source_to_aligned_uni_mat = face_align.get_source_to_aligned_uni_mat()
for fsi in bcd.get_face_swap_info_list():
face_image = bcd.get_image (fsi.face_align_image_name)
if face_image is not None:
h,w = face_image.shape[:2]
self._layered_images.add_image(face_image)
h,w = face_image.shape[:2]
self._layered_images.add_image(face_image)
if fsi.face_align_ulmrks is not None:
lmrks_layer = np.zeros( (self._preview_width, self._preview_width, 4), dtype=np.uint8)
face_ulmrks = face_align.get_face_ulandmarks_by_type(FaceULandmarks.Type.LANDMARKS_468)
if face_ulmrks is None:
face_ulmrks = face_align.get_face_ulandmarks_by_type(FaceULandmarks.Type.LANDMARKS_68)
fsi.face_align_ulmrks.draw(lmrks_layer, (0,255,0,255))
if face_ulmrks is not None:
lmrks_layer = np.zeros( (self._preview_width, self._preview_width, 4), dtype=np.uint8)
if fsi.face_urect is not None and fsi.image_to_align_uni_mat is not None:
aligned_uni_rect = fsi.face_urect.transform(fsi.image_to_align_uni_mat)
aligned_uni_rect.draw(lmrks_layer, (0,0,255,255) )
face_ulmrks.draw(lmrks_layer, (0,255,0,255))
self._layered_images.add_image(lmrks_layer)
face_mark_rect = face_mark.get_face_urect()
if face_mark_rect is not None:
aligned_uni_rect = face_mark_rect.transform(source_to_aligned_uni_mat)
aligned_uni_rect.draw(lmrks_layer, (0,0,255,255) )
self._layered_images.add_image(lmrks_layer)
self._info_label.setText(f'{w}x{h}')
return
self._info_label.setText(f'{w}x{h}')
return
def clear(self):

View file

@ -45,17 +45,13 @@ class QBCFaceSwapViewer(lib_qt.QXCollapsibleSection):
self._layered_images.clear_images()
for face_mark in bcd.get_face_mark_list():
face_align = face_mark.get_face_align()
if face_align is not None:
face_swap = face_align.get_face_swap()
if face_swap is not None:
face_swap_image = bcd.get_image(face_swap.get_image_name())
if face_swap_image is not None:
self._layered_images.add_image(face_swap_image)
h,w = face_swap_image.shape[0:2]
self._info_label.setText(f'{w}x{h}')
return
for fsi in bcd.get_face_swap_info_list():
face_swap_image = bcd.get_image(fsi.face_swap_image_name)
if face_swap_image is not None:
self._layered_images.add_image(face_swap_image)
h,w = face_swap_image.shape[0:2]
self._info_label.setText(f'{w}x{h}')
return
def clear(self):
self._layered_images.clear_images()

View file

@ -43,16 +43,16 @@ class QBCFinalFrameViewer(lib_qt.QXCollapsibleSection):
self._layered_images.clear_images()
merged_frame_name = bcd.get_merged_frame_name()
merged_frame_image = bcd.get_image(merged_frame_name)
merged_image_name = bcd.get_merged_image_name()
merged_image = bcd.get_image(merged_image_name)
if merged_frame_image is not None:
if merged_frame_image.dtype != np.uint8:
merged_frame_image = lib_image.ImageProcessor(merged_frame_image).to_uint8().get_image('HWC')
if merged_image is not None:
if merged_image.dtype != np.uint8:
merged_image = lib_image.ImageProcessor(merged_image).to_uint8().get_image('HWC')
self._layered_images.add_image(merged_frame_image)
h,w = merged_frame_image.shape[0:2]
self._info_label.setText(f'{merged_frame_name} {w}x{h}')
self._layered_images.add_image(merged_image)
h,w = merged_image.shape[0:2]
self._info_label.setText(f'{merged_image_name} {w}x{h}')
def clear(self):

View file

@ -42,16 +42,13 @@ class QBCFrameViewer(lib_qt.QXCollapsibleSection):
self._layered_images.clear_images()
frame_name = bcd.get_frame_name()
frame_image = bcd.get_image(frame_name)
frame_image_name = bcd.get_frame_image_name()
frame_image = bcd.get_image(frame_image_name)
if frame_image is not None:
self._layered_images.add_image (frame_image)
h,w = frame_image.shape[:2]
if frame_name is not None:
self._info_label.setText(f'{frame_name} {w}x{h}')
else:
self._info_label.setText(f'{w}x{h}')
self._info_label.setText(f'{frame_image_name} {w}x{h}')
def clear(self):