单纯的变大再覆盖上去,头部检测信息不够全,效果实在是太差,就不多说了,只是按照自己的思路玩一玩,没有达到抖音上那么好的效果
import cv2 as cv
import numpy as np
import dlib detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('../dlib/shape_predictor_68_face_landmarks.dat') def big_head(camera_idx):
cap = cv.VideoCapture(camera_idx)
while cap.isOpened():
cv.namedWindow('big_head', cv.WINDOW_AUTOSIZE)
ok, frame = cap.read()
# 镜像反转
if camera_idx == 0 or camera_idx == 1:
frame = cv.flip(frame, 1, dst=None)
if not ok:
break
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
rects = detector(gray, 0)
for i in range(len(rects)):
landmarks = np.matrix([[p.x, p.y] for p in predictor(frame, rects[i]).parts()])
# 脸部中心点face_center,下巴down
face_center = (landmarks[29][0, 0], landmarks[29][0, 1])
down = (landmarks[8][0, 0], landmarks[8][0, 1])
left = (landmarks[0][0, 0], landmarks[0][0, 1])
right = (landmarks[16][0, 0], landmarks[0][0, 1])
# 上下偏移量y_offset,为了框出尽可能全的头部信息,边框扩大
y_offset = int(1.2*abs(face_center[1]-down[1]))
rect_start = (int(0.8*left[0]), face_center[1]-y_offset)
rect_end = (int(1.2*right[0]), face_center[1]+y_offset)
print(rect_start, rect_end)
face = frame[rect_start[1]: rect_end[1], rect_start[0]: rect_end[0]]
# 放大比例k_size
k_size = 1.1
size = (int(k_size*(rect_end[0]-rect_start[0])), int(k_size*(rect_end[1]-rect_start[1])))
face = cv.resize(face, size, interpolation=cv.INTER_CUBIC)
face_mask = 255 * np.ones(face.shape, face.dtype)
output = cv.seamlessClone(face, frame, face_mask, face_center, cv.NORMAL_CLONE)
cv.imshow('face', face) cv.rectangle(frame, rect_start, rect_end, (0, 0, 255), -1)
# cv.circle(frame, face_center, 1, (0, 0, 255), -1) cv.imshow('big_head', output)
c = cv.waitKey(10)
if c & 0xFF == ord('q'):
break
cap.release()
cv.destroyAllWindows() if __name__ == '__main__':
video = '../video/face.mp4'
big_head(video)
# test()
效果