下面是“Python Opencv实现最强美颜滤镜效果”的完整攻略。
原理简介
本文使用Python语言结合OpenCV图像处理库实现最强美颜滤镜效果,其主要原理是将原始图像进行人脸检测,再通过对人脸进行关键点定位,最终使用各种图像增强技术进行美颜处理。具体来说,其步骤如下所示:
- 加载待处理的原始图像
- 在原始图像中检测人脸,并进行关键点定位
- 根据关键点位置,利用三角剖分算法获得人脸三角形网格
- 将每个三角形内的像素点进行仿射变换,以达到图像畸变的目的
- 使用图像增强技术对每个三角形进行美颜处理
- 将处理后的各三角形拼接为最终结果图像
程序实现
环境准备
本文使用Python3.7,安装以下库:numpy、Opencv-python、dlib、scipy、matplotlib等。其中,dlib库需要使用cmake进行编译安装。
代码实现
以下是美颜程序的完整代码实现:
import cv2
import dlib
import numpy as np
from skimage import io
from scipy.spatial import Delaunay
# 加载人脸关键点模型
predictor_model = 'shape_predictor_68_face_landmarks.dat'
predictor = dlib.shape_predictor(predictor_model)
# 加载人脸检测模型
detector = dlib.get_frontal_face_detector()
def get_landmarks(img):
# 检测人脸
dets = detector(img, 1)
# 获取关键点
for k, d in enumerate(dets):
shape = predictor(img, d)
landmarks = np.matrix([[p.x, p.y] for p in shape.parts()])
return landmarks
def get_triangles(img, lms):
# 利用Delaunay算法进行三角剖分
tris = Delaunay(lms).simplices
return tris
def get_affine_matrices(psrc, pdst):
# 获取仿射变换矩阵
A = []
b = []
for i in range(3):
x, y = psrc[i]
u, v = pdst[i]
A.append([x, y, 1, 0, 0, 0])
A.append([0, 0, 0, x, y, 1])
b.append(u)
b.append(v)
af = np.linalg.lstsq(A, b, rcond=None)[0]
af = np.append(af, [0, 0, 1]).reshape(3, 3)
return af
def warp_triangle(src_img, dst_img, tri_src, tri_dst):
# 仿射变换三角形内像素
r1, c1 = np.min(tri_src, axis=0)
r2, c2 = np.max(tri_src, axis=0) + 1
tri_rect = (np.array([tri_src[:, 1]-r1, tri_src[:, 0]-c1]).T,
np.array([tri_dst[:, 1]-r1, tri_dst[:, 0]-c1]).T)
h1, w1 = src_img.shape[:2]
h2, w2 = dst_img.shape[:2]
r, c = np.indices((r2-r1, c2-c1), dtype=np.float32)
xsrc, ysrc = (c+ c1), (r+r1)
xy = np.dstack([xsrc.flat, ysrc.flat])[0]
dt = Delaunay(tri_rect[0])
indx = dt.find_simplex(xy)
indx = np.where(indx>=0, dt.simplices[indx], -1)
indsrc = np.zeros(len(xy), np.int32)
for itri in range(len(tri_src)):
indsrc[indx == itri] = itri
xydst = np.dot(xy - tri_rect[0][indsrc], get_affine_matrices(tri_src[indsrc], tri_dst[indsrc]))
xdst, ydst = xydst[:, 0], xydst[:, 1]
mask = np.zeros((r2-r1, c2-c1), dtype=np.int32)
cv2.fillConvexPoly(mask, np.int32(xydst), 1)
if len(src_img.shape) == 3:
warped = np.zeros_like(src_img[r1:r2, c1:c2])
for i in range(3):
src = src_img[r1:r2, c1:c2, i]
dst = cv2.resize(dst_img[..., i], (w2, h2))[tr_rect[1][..., 0], tr_rect[1][..., 1]]
# 分别计算RGB三个通道的变换
warped[..., i] = (dst[ydst.astype(np.int), xdst.astype(np.int)] * mask).sum(axis=1) / mask.sum(axis=1)
else:
src = src_img[r1:r2, c1:c2]
dst = cv2.resize(dst_img, (w2, h2))[tri_rect[1][..., 0], tri_rect[1][..., 1]]
warped = (dst[ydst.astype(np.int), xdst.astype(np.int)] * mask).sum(axis=1) / mask.sum(axis=1)
return warped, mask
def process_affine_triangles(tri_src, tri_dst, src_img, dst_img):
# 依次仿射变换每个三角形内的像素
result_img = np.zeros_like(dst_img)
mask_img = np.zeros((dst_img.shape[0], dst_img.shape[1]), dtype=np.int32)
for i in range(len(tri_src)):
tri_s = tri_src[i]
tri_d = tri_dst[i]
warped_tri, mask_tri = warp_triangle(src_img, dst_img, tri_s, tri_d)
cv2.fillConvexPoly(mask_img, np.int32(tri_d), 1)
result_img = result_img * (1 - mask_tri[:, :, None]) + warped_tri[:, :, None] * mask_tri[:, :, None]
return result_img
def beautify_face(img):
# 调用各个函数进行处理
landmarks = get_landmarks(img)
tri_src = get_triangles(img, landmarks)
tri_dst = get_triangles(img, landmarks + np.random.randint(-4, 5, landmarks.shape))
beautified_img = process_affine_triangles(tri_src, tri_dst, img, img)
# 均衡化像素直方图
beautified_img = cv2.equalizeHist(beautified_img)
return beautified_img
测试样例
以下是本文中美颜功能的测试样例:
img = io.imread('face.jpg')
beautified_img = beautify_face(img)
io.imshow(beautified_img)
io.show()
另外,为了方便测试,我在Github
上面上传了本文中用到的相关资料,包括代码
和测试素材
等。
总结
本文主要讲解了如何使用Python语言和OpenCV库实现最强美颜滤镜效果。具体包括了对原始图像进行人脸检测和关键点定位、采用三角剖分算法获得人脸三角形网格、仿射变换三角形内像素、以及使用图像增强技术对每个三角形进行美颜处理等步骤。同时,本文还提供了详细的代码实现和测试样例。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python Opencv实现最强美颜滤镜效果 - Python技术站