写一个使用OpenCV库读取图片并进行人脸检测。 使用Dlib库定位出人脸关键点,比如眼睛、嘴巴、眉毛等。 将检测到的关键点用于生成一个人脸网格,以便于后面进行形变处理。 使用形变算法将人物的面部特征卡通化,如加大眼睛、改变眉毛形状、加大嘴巴等。 通过卡通处理后的面部特征与原始图片进行融合,生成卡通化后的图片。的程序
时间: 2023-05-21 19:07:36 浏览: 93
下面是 OpenCV 和 Dlib 库实现人脸卡通化的 Python 代码:
```python
import cv2
import dlib
import numpy as np
# 使用OpenCV库读取图片
original_image = cv2.imread('image.jpg')
# 使用Dlib库定位出人脸关键点
predictor_path = 'shape_predictor_68_face_landmarks.dat'
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
gray_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
faces = detector(gray_image, 1)
landmarks = []
for face in faces:
landmark = predictor(gray_image, face)
landmarks.append(np.array([[p.x, p.y] for p in landmark.parts()]))
# 将检测到的关键点用于生成一个人脸网格
mask = np.zeros(original_image.shape[:2], dtype=np.uint8)
for landmark in landmarks:
cv2.fillConvexPoly(mask, landmark[[0, 1, 3, 4], :], 255, 8, 0)
cv2.fillConvexPoly(mask, landmark[[2, 5, 6], :], 192, 8, 0)
cv2.fillConvexPoly(mask, landmark[[7, 8, 9, 10], :], 128, 8, 0)
cv2.fillConvexPoly(mask, landmark[[11, 12, 13, 14], :], 64, 8, 0)
cv2.fillConvexPoly(mask, landmark[[15, 16, 17], :], 32, 8, 0)
cv2.fillConvexPoly(mask, landmark[[18, 19, 20], :], 16, 8, 0)
cv2.fillConvexPoly(mask, landmark[[21, 22, 23], :], 8, 8, 0)
cv2.fillConvexPoly(mask, landmark[[24, 25, 26], :], 4, 8, 0)
cv2.fillConvexPoly(mask, landmark[[27, 28, 29], :], 2, 8, 0)
cv2.fillConvexPoly(mask, landmark[[30, 31], :], 1, 8, 0)
# 使用形变算法将人物的面部特征卡通化
cartoon_landmarks = []
for landmark in landmarks:
cartoon_landmark = landmark.copy()
cartoon_landmark[:, 1] = landmark[:, 1] + (landmark[:, 1] - np.mean(landmark[[51, 57]], axis=0))[1] / 10
cartoon_landmark[17:19, 1] = landmark[39:41, 1] - 5
cartoon_landmark[21:23, 1] = landmark[42:44, 1] - 5
cartoon_landmark[18, 0] = landmark[36, 0] + 10
cartoon_landmark[25, 0] = landmark[45, 0] - 10
cartoon_landmark[11, :] = (landmark[18, :] + landmark[22, :]) / 2
cartoon_landmark[12, :] = (landmark[23, :] + landmark[27, :]) / 2
cartoon_landmark[13, :] = (landmark[28, :] + landmark[32, :]) / 2
cartoon_landmark[14, :] = (landmark[33, :] + landmark[36, :]) / 2
cartoon_landmark[15, :] = (landmark[37, :] + landmark[42, :]) / 2
cartoon_landmark[16, :] = (landmark[43, :] + landmark[46, :]) / 2
cartoon_landmark[[1, 2, 6, 7], :] = cartoon_landmark[[1, 2, 6, 7], :] + np.array([-5, 5])
cartoon_landmark[[17, 18], 1] = cartoon_landmark[[17, 18], 1] + 5
cartoon_landmark[[21, 22], 1] = cartoon_landmark[[21, 22], 1] + 5
cartoon_landmark[[19, 23], 1] = landmark[[19, 23], 1] + 10
cartoon_landmark[[24, 28], 1] = landmark[[24, 28], 1] + 10
cartoon_landmark[[20, 25], 1] = cartoon_landmark[[20, 25], 1] + 15
cartoon_landmark[[27, 29], 1] = cartoon_landmark[[27, 29], 1] - 5
cartoon_landmark[[31, 32], :] = landmark[[31, 32], :] + np.array([-10, 0])
cartoon_landmark[[33, 34, 35], :] = landmark[[33, 34, 35], :] + np.array([10, 0])
cartoon_landmarks.append(cartoon_landmark)
# 通过卡通处理后的面部特征与原始图片进行融合,生成卡通化后的图片
cartoon_image = np.zeros(original_image.shape, dtype=np.uint8)
for num, landmark in enumerate(landmarks):
cartoon_landmark = cartoon_landmarks[num]
hull = cv2.convexHull(cartoon_landmark)
warped_mask = cv2.warpAffine(mask, cv2.getAffineTransform(landmark[[17, 21, 22], :], cartoon_landmark[[17, 21, 22], :]), (original_image.shape[1], original_image.shape[0]), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REPLICATE)
warped_image = cv2.warpAffine(original_image, cv2.getAffineTransform(landmark[[17, 21, 22], :], cartoon_landmark[[17, 21, 22], :]), (original_image.shape[1], original_image.shape[0]), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REPLICATE)
seamless_mask = cv2.seamlessClone(warped_image, cartoon_image, warped_mask, (cartoon_landmark[33] + cartoon_landmark[34]) // 2, cv2.NORMAL_CLONE)
cartoon_image = cv2.bitwise_or(cartoon_image, seamless_mask)
# 显示原始图片和卡通化后的图片
cv2.imshow('Original Image', original_image)
cv2.imshow('Cartoon Image', cartoon_image)
cv2.waitKey()
cv2.destroyAllWindows()
```
其中,使用的 Dlib 面部关键点定位器(shape_predictor_68_face_landmarks.dat)可以在 Dlib 的官方网站上下载,或者使用 pip 命令安装:
```
pip install dlib
```
阅读全文