Skip to content

Commit

Permalink
improve some speed, but there is a fatal BUG to fix
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangshaocheng committed Feb 18, 2019
1 parent bb81931 commit 09fcd64
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 27 deletions.
17 changes: 5 additions & 12 deletions face_detect_and_track.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Detector(object):
def __init__(self):
self.detector = cv2.CascadeClassifier(CASCADE_PATH)

def face_detection(self,frame):
def face_detection(self,frame)->np.ndarray:
face_rects = self.__get_face_rects(frame)
if not isinstance(face_rects, np.ndarray):
logging.info("No face")
Expand All @@ -37,17 +37,17 @@ def __get_face_rects(self,img):


class DlibDetector(object):
def __init__(self):
def __init__(self)->dlib.rectangle:
self.detector = dlib.get_frontal_face_detector()

def __get_face_rects(self,img,upsample_num_times=0):
# To get faster speed, I recommend the param upsample_num_times == 0
# For faster speed, I recommend the param upsample_num_times == 0
face_rects = self.detector(img, upsample_num_times)
if not face_rects:
return None # face_rects=None
return face_rects

def rect_to_bb(self,rect: dlib.rectangle):
def rect_to_bb(self,rect: dlib.rectangle)->tuple:
x = rect.left()
y = rect.top()
w = rect.right() - x
Expand Down Expand Up @@ -95,17 +95,10 @@ def __init__(self, tracker_type="mosse"):
# def start_track(self,frame,starX,startY,endX,endY):
# self.tracker.init(frame,(starX,startY,endX,endY))

def start_track(self,frame,bbox):
def start_track(self,frame,bbox:np.ndarray):
self.tracker.init(frame,bbox)

def update_track(self,frame):
# success,bbox=self.tracker.update(frame)
# if not success:
# logging.info("failed")
# return False
# (x, y, w, h) = [int(v) for v in bbox]
# cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# return bbox
return self.tracker.update(frame)

def clear(self):
Expand Down
49 changes: 34 additions & 15 deletions video_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,28 @@ def process_src_img(self):
self.src_only_face=apply_mask(self.src_img,src_mask)

def run_face_swap(self,dst_img,dst_face_rect:dlib.rectangle):
if True:
return self.fast_face_swap(dst_img,dst_face_rect)
else:
return self.slow_face_swap(dst_img, dst_face_rect)


def fast_face_swap(self,dst_img,dst_face_rect:dlib.rectangle):
h,w=dst_img.shape[:2]
dst_points = face_points_detection(dst_img, dst_face_rect) # 4ms
dst_mask = mask_from_points((h,w), dst_points)
dst_only_face = apply_mask(dst_img, dst_mask)

warped_src_img = warp_image_3d(self.src_img, self.src_points[:48], dst_points[:48],(h,w) )
src_only_face = correct_colours(dst_only_face, warped_src_img, dst_points)

r = cv2.boundingRect(dst_mask)
center = ((r[0] + int(r[2] / 2), r[1] + int(r[3] / 2)))
output = cv2.seamlessClone(warped_src_img, dst_img, dst_mask, center, cv2.NORMAL_CLONE)
return output


def slow_face_swap(self,dst_img,dst_face_rect:dlib.rectangle):
dst_points=face_points_detection(dst_img,dst_face_rect) #4ms
w,h = dst_img.shape[:2]
t0=time.time()
Expand All @@ -54,7 +76,6 @@ def run_face_swap(self,dst_img,dst_face_rect:dlib.rectangle):
center = ((r[0] + int(r[2] / 2), r[1] + int(r[3] / 2)))
output = cv2.seamlessClone(warped_src_img, dst_img, dst_mask, center, cv2.NORMAL_CLONE)
return output

# For TEST
# def run_face_swap(self,dst_img,dst_face_bbox):
# dst_points=face_points_detection(dst_img,dst_face_bbox)
Expand All @@ -77,10 +98,10 @@ def cascade_vh(self):
start_tc = cv2.getTickCount()
grabbed, frame = self.cap.read()
if not face_flag:
face_bbox = self.detector.face_detection(frame)
face_bbox:np.ndarray = self.detector.face_detection(frame)
# No face has been detected
if isinstance(face_bbox, int):
cv2.imshow("frame", frame)
cv2.imshow("output", frame)
continue
# detect successfully
else:
Expand All @@ -89,10 +110,6 @@ def cascade_vh(self):
face_bbox = self.expand_bbox(*face_bbox)
self.tracker.start_track(frame, face_bbox)
target_lose_cnt = 0
(x, y, w, h) = face_bbox

cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)



else:
Expand All @@ -102,38 +119,41 @@ def cascade_vh(self):
if not success:
logging.info("update failed")
target_lose_cnt += 1
cv2.imshow("frame", frame)
cv2.imshow("output", frame)
continue

(old_x, old_y, old_w, old_h) = (int(v) for v in box_predict)

# draw predict rect
cv2.rectangle(frame, (old_x, old_y), (old_x + old_w, old_y + old_h), (0, 0, 255), 2)
# cv2.rectangle(frame, (old_x, old_y), (old_x + old_w, old_y + old_h), (0, 0, 255), 2)

# face_bbox is relative coordinates!!!!
face_bbox = self.detector.face_detection(frame[old_y:old_y + old_h, old_x:old_x + old_w])
if isinstance(face_bbox, int):
target_lose_cnt += 1
cv2.imshow("frame", frame)
cv2.imshow("output", frame)
continue
target_lose_cnt = 0
(x, y, w, h) = self.expand_bbox(*face_bbox)

# Convert it to absolute coordinates
x = int(old_x + x)
y = int(old_y + y)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

face_bbox[0]=x
face_bbox[1]=y

# lose target
else:
logging.info("losing target")
logging.info("target lost")
# reset tracker
self.tracker = Tracker()
face_flag = 0
cv2.imshow("frame", frame)
cv2.imshow("output", frame)
continue

face_rect = self.box_to_dlib_rect(face_bbox)
face_rect:dlib.rectangle = self.box_to_dlib_rect(face_bbox)
frame = self.run_face_swap(frame, face_rect)
# frame_roi=frame[y:y+h,x:x+w]
# face_rect = self.box_to_dlib_rect(face_bbox)
Expand All @@ -142,7 +162,6 @@ def cascade_vh(self):
end_tc = cv2.getTickCount()
fps = cv2.getTickFrequency() / (end_tc - start_tc)
logging.info("fps {}".format(fps))

cv2.imshow("frame", frame)

cv2.destroyAllWindows()
Expand Down

0 comments on commit 09fcd64

Please sign in to comment.