opencv+dlib实现给蒙娜丽莎“配”眼镜

opencv+dlib实现给蒙娜丽莎“配”眼镜

本案例利用opencv+dlib实现了给蒙娜丽莎佩戴眼镜。

主要原理就是利用dlib人脸识别的特征点提取效果,并利用特征点给人脸加上一个眼镜。

给蒙诺丽莎配眼镜

导入工具包

import cv2
import numpy as np
import dlib
from PIL import Image, ImageDraw, ImageFont
from imutils import face_utils, translate, rotate, resize
#导入python绘图matplotlib
import matplotlib.pyplot as plt
#使用ipython的魔法方法,将绘制出的图像直接嵌入在notebook单元格中
%matplotlib inline
#定义可视化图像函数
def look_img(img):
    '''opencv读入图像格式为BGR,matplotlib可视化格式为RGB,因此需将BGR转RGB'''
    img_RGB = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    plt.imshow(img_RGB)
    plt.show()

导入模型

# 创建人脸检测器
det_face = dlib.get_frontal_face_detector()
# 加载标志点检测器
det_landmarks = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")  # 68点

单张图片处理

max_width = 500
img=cv2.imread('mnls.jpg')
img=resize(img,width=max_width)
deal = Image.open("0.png")      #眼镜图片
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rects = det_face(img_gray, 0)
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

for rect in rects:
    face = {}
    shades_width = rect.right() - rect.left()
    
    # 用于检测当前人脸所在位置方向的预测器
    shape = det_landmarks(img_gray, rect)
    shape = face_utils.shape_to_np(shape)
    
    # 从输入图像中抓取每只眼睛的轮廓
    leftEye = shape[36:42]
    rightEye = shape[42:48]
    
    # 计算每只眼睛的中心
    leftEyeCenter = leftEye.mean(axis=0).astype("int")
    rightEyeCenter = rightEye.mean(axis=0).astype("int")
    
    # 计算眼心之间的夹角
    dY = leftEyeCenter[1] - rightEyeCenter[1]
    dX = leftEyeCenter[0] - rightEyeCenter[0]
    angle = np.rad2deg(np.arctan2(dY, dX)) 
    
    # 图片重写
    current_deal = deal.resize((shades_width, int(shades_width * deal.size[1] / deal.size[0])),
                           resample=Image.Resampling.LANCZOS)
    current_deal = current_deal.rotate(angle, expand=True)
    current_deal = current_deal.transpose(Image.Transpose.FLIP_TOP_BOTTOM)
    face['glasses_image'] = current_deal
    left_eye_x = leftEye[0,0] - shades_width // 4
    left_eye_y = leftEye[0,1] - shades_width // 6
    face['final_pos'] = (left_eye_x, left_eye_y)
    current_animation=1   #参数调节
    glasses_on=1         #参数调节
    current_y = int(current_animation / glasses_on * left_eye_y)
    img.paste(current_deal, (left_eye_x, current_y-20), current_deal)   #调节眼镜位置
    
display(img)

在这里插入图片描述

完整代码

# 完整代码:
import cv2
import numpy as np
import dlib
from PIL import Image, ImageDraw, ImageFont
from imutils import face_utils, translate, rotate, resize
#导入python绘图matplotlib
import matplotlib.pyplot as plt
#使用ipython的魔法方法,将绘制出的图像直接嵌入在notebook单元格中
%matplotlib inline

#定义可视化图像函数
def look_img(img):
    '''opencv读入图像格式为BGR,matplotlib可视化格式为RGB,因此需将BGR转RGB'''
    img_RGB = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    plt.imshow(img_RGB)
    plt.show()

# 创建人脸检测器
det_face = dlib.get_frontal_face_detector()
# 加载标志点检测器
det_landmarks = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")  # 68点

max_width = 500
img=cv2.imread('mnls.jpg')     #人脸照片
img=resize(img,width=max_width)
deal = Image.open("./Glasses/1.png")      #眼镜图片
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rects = det_face(img_gray, 0)
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

for rect in rects:
    face = {}
    shades_width = rect.right() - rect.left()
    
    # 用于检测当前人脸所在位置方向的预测器
    shape = det_landmarks(img_gray, rect)
    shape = face_utils.shape_to_np(shape)
    
    # 从输入图像中抓取每只眼睛的轮廓
    leftEye = shape[36:42]
    rightEye = shape[42:48]
    
    # 计算每只眼睛的中心
    leftEyeCenter = leftEye.mean(axis=0).astype("int")
    rightEyeCenter = rightEye.mean(axis=0).astype("int")
    
    # 计算眼心之间的夹角
    dY = leftEyeCenter[1] - rightEyeCenter[1]
    dX = leftEyeCenter[0] - rightEyeCenter[0]
    angle = np.rad2deg(np.arctan2(dY, dX)) 
    
    # 图片重写
    current_deal = deal.resize((shades_width, int(shades_width * deal.size[1] / deal.size[0])),
                           resample=Image.Resampling.LANCZOS)
    current_deal = current_deal.rotate(angle, expand=True)
    current_deal = current_deal.transpose(Image.Transpose.FLIP_TOP_BOTTOM)
    face['glasses_image'] = current_deal
    left_eye_x = leftEye[0,0] - shades_width // 4
    left_eye_y = leftEye[0,1] - shades_width // 6
    face['final_pos'] = (left_eye_x, left_eye_y)
    current_animation=1   #参数调节
    glasses_on=0.8          #参数调节
    current_y = int(current_animation / glasses_on * left_eye_y)
    img.paste(current_deal, (left_eye_x, current_y-20), current_deal)   #调节眼镜位置

#PIL图像转CV2图像
cv2_img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
look_img(cv2_img)

在这里插入图片描述

图片合成gif

import imageio

def compose_gif():
    gif_images = []
    for path in img_paths:
        gif_images.append(imageio.imread(path))
    imageio.mimsave("test.gif",gif_images,fps=1)

data_path='./output'   #数据文件夹
images=os.listdir(data_path)
img_paths=[]
for i in images:
    img_paths+=[os.path.join(data_path,i)]  
compose_gif()

效果展示:
在这里插入图片描述

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值