mirror of
https://github.com/iperov/DeepFaceLab.git
synced 2025-07-07 21:42:08 -07:00
Merge pull request #8 from ChrisTopherTa54321/improve_manual_selection
Improve manual selection
This commit is contained in:
commit
f11da9acfc
3 changed files with 79 additions and 8 deletions
|
@ -27,6 +27,15 @@ mean_face_y = np.array([
|
|||
|
||||
landmarks_2D = np.stack( [ mean_face_x, mean_face_y ], axis=1 )
|
||||
|
||||
# 68 point landmark definitions
|
||||
landmarks_68_pt = { "mouth": (48,68),
|
||||
"right_eyebrow": (17,22),
|
||||
"left_eyebrow": (22,27),
|
||||
"right_eye": (36,42),
|
||||
"left_eye": (42,48),
|
||||
"nose": (27,35),
|
||||
"jaw": (0,17) }
|
||||
|
||||
def get_transform_mat (image_landmarks, output_size, face_type):
|
||||
if not isinstance(image_landmarks, np.ndarray):
|
||||
image_landmarks = np.array (image_landmarks)
|
||||
|
@ -169,6 +178,13 @@ def draw_landmarks (image, image_landmarks, color):
|
|||
cv2.circle(image, (x, y), 2, color, -1)
|
||||
#text_color = colorsys.hsv_to_rgb ( (i%4) * (0.25), 1.0, 1.0 )
|
||||
#cv2.putText(image, str(i), (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.1,text_color,1)
|
||||
if len(image_landmarks) == 68:
|
||||
for feat,idx_range in landmarks_68_pt.items():
|
||||
for idx in range( idx_range[0], idx_range[1] - 1 ):
|
||||
pt1 = tuple(image_landmarks[idx])
|
||||
pt2 = tuple(image_landmarks[idx + 1])
|
||||
cv2.line( image, pt1, pt2, color )
|
||||
|
||||
|
||||
def draw_rect_landmarks (image, rect, image_landmarks, face_size, face_type):
|
||||
image_utils.draw_rect (image, rect, (255,0,0), 2 )
|
||||
|
|
|
@ -44,13 +44,16 @@ class ExtractSubprocessor(SubprocessorBase):
|
|||
self.param_x = -1
|
||||
self.param_y = -1
|
||||
self.param_rect_size = -1
|
||||
self.param = {'x': 0, 'y': 0, 'rect_size' : 5}
|
||||
self.param = {'x': 0, 'y': 0, 'rect_size' : 5, 'rect_locked' : False, 'redraw_needed' : False }
|
||||
|
||||
def onMouse(event, x, y, flags, param):
|
||||
if event == cv2.EVENT_MOUSEWHEEL:
|
||||
mod = 1 if flags > 0 else -1
|
||||
param['rect_size'] = max (5, param['rect_size'] + 10*mod)
|
||||
else:
|
||||
elif event == cv2.EVENT_LBUTTONDOWN:
|
||||
param['rect_locked'] = not param['rect_locked']
|
||||
param['redraw_needed'] = True
|
||||
elif not param['rect_locked']:
|
||||
param['x'] = x
|
||||
param['y'] = y
|
||||
|
||||
|
@ -108,10 +111,26 @@ class ExtractSubprocessor(SubprocessorBase):
|
|||
if len (self.input_data) > 0:
|
||||
return self.input_data.pop(0)
|
||||
else:
|
||||
skip_remaining = False
|
||||
allow_remark_faces = False
|
||||
while len (self.input_data) > 0:
|
||||
data = self.input_data[0]
|
||||
filename, faces = data
|
||||
is_frame_done = False
|
||||
go_to_prev_frame = False
|
||||
|
||||
# Can we mark an image that already has a marked face?
|
||||
if allow_remark_faces:
|
||||
allow_remark_faces = False
|
||||
# If there was already a face then lock the rectangle to it until the mouse is clicked
|
||||
if len(faces) > 0:
|
||||
prev_rect = faces.pop()[0]
|
||||
self.param['rect_locked'] = True
|
||||
faces.clear()
|
||||
self.param['rect_size'] = ( prev_rect[2] - prev_rect[0] ) / 2
|
||||
self.param['x'] = ( ( prev_rect[0] + prev_rect[2] ) / 2 ) * self.view_scale
|
||||
self.param['y'] = ( ( prev_rect[1] + prev_rect[3] ) / 2 ) * self.view_scale
|
||||
|
||||
if len(faces) == 0:
|
||||
self.original_image = cv2.imread(filename)
|
||||
|
||||
|
@ -122,10 +141,12 @@ class ExtractSubprocessor(SubprocessorBase):
|
|||
(h,w,c) = self.original_image.shape
|
||||
|
||||
self.text_lines_img = (image_utils.get_draw_text_lines ( self.original_image, (0,0, self.original_image.shape[1], min(100, self.original_image.shape[0]) ),
|
||||
[ 'Match landmarks with face exactly.',
|
||||
'[Enter] - confirm frame',
|
||||
'[Space] - skip frame',
|
||||
'[Mouse wheel] - change rect'
|
||||
[ 'Match landmarks with face exactly. Click to confirm/unconfirm selection',
|
||||
'[Enter] - confirm and continue to next unmarked frame',
|
||||
'[Space] - skip to next unmarked frame',
|
||||
'[Mouse wheel] - change rect',
|
||||
'[,] [.]- prev frame, next frame',
|
||||
'[Q] - skip remaining frames'
|
||||
], (1, 1, 1) )*255).astype(np.uint8)
|
||||
|
||||
while True:
|
||||
|
@ -138,6 +159,22 @@ class ExtractSubprocessor(SubprocessorBase):
|
|||
elif key == ord(' '):
|
||||
is_frame_done = True
|
||||
break
|
||||
elif key == ord('.'):
|
||||
allow_remark_faces = True
|
||||
# Only save the face if the rect is still locked
|
||||
if self.param['rect_locked']:
|
||||
faces.append ( [(self.rect), self.landmarks] )
|
||||
is_frame_done = True
|
||||
break
|
||||
elif key == ord(',') and len(self.result) > 0:
|
||||
# Only save the face if the rect is still locked
|
||||
if self.param['rect_locked']:
|
||||
faces.append ( [(self.rect), self.landmarks] )
|
||||
go_to_prev_frame = True
|
||||
break
|
||||
elif key == ord('q'):
|
||||
skip_remaining = True
|
||||
break
|
||||
|
||||
new_param_x = self.param['x'] / self.view_scale
|
||||
new_param_y = self.param['y'] / self.view_scale
|
||||
|
@ -148,7 +185,8 @@ class ExtractSubprocessor(SubprocessorBase):
|
|||
|
||||
if self.param_x != new_param_x or \
|
||||
self.param_y != new_param_y or \
|
||||
self.param_rect_size != new_param_rect_size:
|
||||
self.param_rect_size != new_param_rect_size or \
|
||||
self.param['redraw_needed']:
|
||||
|
||||
self.param_x = new_param_x
|
||||
self.param_y = new_param_y
|
||||
|
@ -164,6 +202,18 @@ class ExtractSubprocessor(SubprocessorBase):
|
|||
self.result.append ( data )
|
||||
self.input_data.pop(0)
|
||||
self.inc_progress_bar(1)
|
||||
self.param['redraw_needed'] = True
|
||||
self.param['rect_locked'] = False
|
||||
elif go_to_prev_frame:
|
||||
self.input_data.insert(0, self.result.pop() )
|
||||
self.inc_progress_bar(-1)
|
||||
allow_remark_faces = True
|
||||
self.param['redraw_needed'] = True
|
||||
self.param['rect_locked'] = False
|
||||
elif skip_remaining:
|
||||
while len(self.input_data) > 0:
|
||||
self.result.append( self.input_data.pop(0) )
|
||||
self.inc_progress_bar(1)
|
||||
|
||||
return None
|
||||
|
||||
|
@ -298,6 +348,10 @@ class ExtractSubprocessor(SubprocessorBase):
|
|||
view_landmarks = (np.array(self.landmarks) * self.view_scale).astype(np.int).tolist()
|
||||
facelib.LandmarksProcessor.draw_rect_landmarks (image, view_rect, view_landmarks, self.image_size, self.face_type)
|
||||
|
||||
if self.param['rect_locked']:
|
||||
facelib.draw_landmarks(image, view_landmarks, (255,255,0) )
|
||||
self.param['redraw_needed'] = False
|
||||
|
||||
cv2.imshow (self.wnd_name, image)
|
||||
return 0
|
||||
else:
|
||||
|
|
|
@ -75,7 +75,8 @@ class SubprocessorBase(object):
|
|||
return None
|
||||
|
||||
def inc_progress_bar(self, c):
|
||||
self.progress_bar.update(c)
|
||||
self.progress_bar.n += c
|
||||
self.progress_bar.refresh()
|
||||
|
||||
def safe_print(self, msg):
|
||||
self.print_lock.acquire()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue