专栏首页阿黎逸阳的代码Python人脸识别—我的眼里只有你

Python人脸识别—我的眼里只有你

人脸识别总感觉特别高深,但是因为Python中已经有很多前辈写好了一些库,可以直接调用,大大降低了人脸识别的难度。

之前在网上看到陈晓眼里只有陈妍希的照片,特别喜欢,想自己用python中的dlib人脸识别库实现这个功能。

所以到网上找了下资料,成功用python实现了这个功能,现在把实现方法分享给大家。

一、我的眼里只有你效果图

可以把图片放大,看下效果。

1 亲爱的热爱的—佟年眼里的韩商言

2 余生请多指教—顾魏眼里的林之校

二、安装并导入库

首先,要在电脑中安装相关的库。

import cv2
import numpy as np
from PIL import Image
import os
import dlib

这些库除了dlib库,安装都比较顺利。只有安装dlib库时踩了很多坑,折腾了比较久。

建议直接下载whl文件,并用pip install dlib-19.17.99-cp37-cp37m-win_amd64.whl安装dlib库。

注意:要根据你自己的python版本下载对应版本的whl,我的是python3.7,windows64位所以我下载的是cp37,amd64版本的whl。

具体步骤如下:

step1: 下载whl文件

step2:在下载好whl文件的目录下打开cmd,并pip install xxx.whl,这个xxx就是你电脑对应版本的whl文件。

step3:在python中import dlib即可。

三、标记人脸中68个点的位置

我用一张肖战的硬照,标记五官中68个点的位置,方便大家找到眼睛的位置。

根据点的位置和计算好的眼球大小,把一个人的照片填充到另一个人的眼睛中去,营造我的眼里只有你的效果。

os.chdir(r"F:\微信公众号\Python\33.我的眼里只有你\眼里都是你")
bg = '肖战.jpg'                              #背景图片
img = cv2.imdecode(np.fromfile(bg,dtype=np.uint8),-1)
detector = dlib.get_frontal_face_detector()  #用它来检测人脸,返回图中人脸的个数和坐标位置:
faces = detector(img,1)
points = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

if (len(faces) > 0):
    for k,d in enumerate(faces):
        print(k,d)
        cv2.rectangle(img,(d.left(),d.top()),(d.right(),d.bottom()),(255,0,0))
        pts = points(img,d)
        for i in range(68):
            cv2.circle(img, (pts.part(i).x,pts.part(i).y),3,(0,255,0), -1, 3)
            cv2.putText(img,str(i),(pts.part(i).x,pts.part(i).y), cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,255))
            
cv2.imwrite('xiaozhan_68point.png', img)

运行以上程序,可得到如下结果:

从上图知,用68个点标记的五官,左眼球位置对应的数字是:37、38、40、41,右眼球位置对应的数字是43、44、46、47。

只要把另一个人的照片缩小,放到眼球对应的位置里去,就可以营造出本文想要的效果啦。

四、把图片的背景颜色设置成眼球的颜色

有时候图片的背景颜色不一定和眼球颜色的一致,我们可以用如下代码从图像中裁剪出人,并自定义背景颜色。

from removebg import RemoveBg
from PIL import Image

#把图片背景设置成眼球的颜色
def Change_img_bg(old_img, bg_color):
    rmbg = RemoveBg("UQ7x2hmLXxv8XXXXXXXXX###", "error.log") # 引号内是你获取的API
    rmbg.remove_background_from_img_file(old_img)            #图片地址
    old_no_bg = old_img + '_no_bg.png' 
    im = Image.open(old_no_bg)
    x, y = im.size   
    # 填充背景
    p = Image.new('RGBA', im.size, bg_color)
    p.paste(im, (0, 0, x, y), im)
    # 保存填充后的图片
    p.save("new_black_pg_img.png")

如需函数中的API,请参考文末参考文献中的第一篇文章。

五、把放入眼睛的图片处理成圆形

一般我们见到的图片都是方形的,而眼球的形状是圆形的,故要把方形照片处理成眼球的形状。

#把图片裁剪成圆形
def img_deal(ori_img):
    img = cv2.imread(ori_img, cv2.IMREAD_UNCHANGED)
    h, w, channel = img.shape
    img_deal = np.zeros((h, w, 4), np.uint8)
    img_deal[:, :, 0:3] = img[:, :, 0:3]
    img_circle = np.zeros((h, w, 1), np.uint8)
    img_circle[:, :, :] = 0
    center = (int(w / 2), int(h / 2))
    radius = int(min(h, w) / 2)
    img_circle = cv2.circle(img_circle,center ,radius , 255, -1)
    img_deal[:, :, 3] = img_circle[:, :, 0]
    cv2.imwrite('eye_circle.png', img_deal)

六、把处理好的图片贴到眼球中

找到眼球的位置,并把处理好的图片贴到眼球中。

for face in faces:
    face_68point = predictor(gray, face)
    #获取左眼球位置信息
    left_eye_x1 = min(face_68point.part(37).x, face_68point.part(41).x)
    left_eye_x2 = min(face_68point.part(38).x, face_68point.part(40).x)
    left_eye_y1 = min(face_68point.part(37).y, face_68point.part(48).y)
    left_eye_y2 = min(face_68point.part(40).y, face_68point.part(41).y)
    left_eye_midx = int((left_eye_x1+left_eye_x2)/2)
    left_eye_midy = int((left_eye_y1+left_eye_y2)/2)
    #获取右眼球位置信息
    right_eye_x1 = min(face_68point.part(43).x, face_68point.part(47).x)
    right_eye_x2 = min(face_68point.part(44).x, face_68point.part(46).x)
    right_eye_y1 = min(face_68point.part(43).y, face_68point.part(44).y)
    right_eye_y2 = min(face_68point.part(47).y, face_68point.part(46).y)
    right_eye_midx = int((right_eye_x1+right_eye_x2)/2)
    right_eye_midy = int((right_eye_y1+right_eye_y2)/2)
    #左眼球大小
    left_eye_r = abs(int(min(left_eye_x1-left_eye_x2,left_eye_y1-left_eye_y2)/2))
    left_eye_d = left_eye_r*2
    #右眼球大小
    right_eye_r = abs(int(min(right_eye_x1-right_eye_x2,right_eye_y1-right_eye_y2)/2))
    right_eye_d = right_eye_r*2
    #设置眼球中图片直径
    eye_img_d = min(int(left_eye_d/1.2),int(right_eye_d/1.2))
    #把图像贴到左眼   
    left_ori = cv2.resize(src_img, (eye_img_d, eye_img_d), interpolation=cv2.INTER_AREA)
    cv2.imwrite("left_eye.png", left_ori)
    img_deal("left_eye.png")
    left_eye = Image.open("eye_circle.png")
    im = Image.open(back_graph)
    im.paste(left_eye,(left_eye_midx-int(eye_img_d/3), left_eye_midy-int(eye_img_d/2)),left_eye)
    #把图像贴到右眼    
    right_ori = cv2.resize(src_img, (eye_img_d, eye_img_d), interpolation=cv2.INTER_AREA)
    cv2.imwrite("right_eye.png", right_ori)
    img_deal("right_eye.png")
    right_eye = Image.open("eye_circle.png")
    im.paste(right_eye,(right_eye_midx-int(eye_img_d/3),right_eye_midy-int(eye_img_d/2)),right_eye)
    #保存最终图形
    im.save("you_in_my_eye.png")

至此,我的眼里只有你代码全部讲解完啦

参考文献:

1. https://blog.csdn.net/qq_42374697/article/details/106202744
2. https://www.cnblogs.com/darkknightzh/p/6117528.html
3. https://blog.csdn.net/weixin_40632944/article/details/81.698508?utm_medium=distributepc_relevant.none-task-blog-baidujs-1

本文分享自微信公众号 - 阿黎逸阳的代码(gh_f3910c467dfe),作者:阿黎逸阳

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 决策树-ID3算法和C4.5算法

    它通过对已有样本的学习生成一颗决策树(可看成if-then规则集合),从而能对新样本作出相应分类。

    阿黎逸阳
  • 用Python中的py2neo库调用neo4j,搭建简单关联图谱

    我第一次建立关联图谱用的是R语言,通过写代码帮公安挖掘团伙犯罪,并用图形展示团伙之间的关联关系。

    阿黎逸阳
  • Python中的集合

    Python中的集合专门用于存储信息,存储的元素无序且不能重复,它用一对花括号{}定义,数据之间用逗号隔开。

    阿黎逸阳
  • 【致敬程序员节】科大讯飞发布1024计划,10.24亿倾注AI开发者

    【新智元导读】 程序员节这一天,科大讯飞在合肥发布打造AI生态,汇聚AI开发者的“1024计划”。科大讯飞将启动10.24亿生态扶持基金,助力AI开发者。此外,...

    新智元
  • Matplotlib数据可视化:图片展示与保存

    除了作图功能,matplotlib也提供本地图片展示以及保存图片的功能,这两个通能通过imshow()方法和savefig()方法实现。

    统计学家
  • 深入浅出FaaS的两种进程模型

    上一篇我们通过一个 Node.js 纯 FaaS 的 Serverless 应用,给你介绍了 Serverless 引擎盖下的运作机制,总结来说,FaaS 依赖...

    码农架构
  • 深入浅出FaaS的两种进程模型

    上一篇我们通过一个 Node.js 纯 FaaS 的 Serverless 应用,给你介绍了 Serverless 引擎盖下的运作机制,总结来说,FaaS 依赖...

    码农架构
  • ASP.NET AJAX(6)__Microsoft AJAX Library中的面向对象类型系统命名空间类类——构造函数类——定义方法类——定义属性类——注册类类——抽象类类——继承类——调用父类方

    如果我们可以合理的使用面向对象编程,我们可以提高代码的复用性和可维护性,这里强调的是合理的使用,有了面向对象类型系统,就可以使用一些成熟的设计方式 命名空间 合...

    小白哥哥
  • 巩固基础从Java集合类开始,最系统全面的集合类笔记

    来源:https://blog.csdn.net/weizhengzhou520/article/details/81806539

    挨踢小子部落阁
  • 对话乔友林教授:我对腾讯觅影在宫颈癌预防上的几点期待

    做科研的时候认真做,我们也能做出好的世界性结果,得到国际社会的认可。世卫组织已提出全球消除宫颈癌的计划,中国作为宫颈癌负担大国,将在实现全球宫颈癌消除目标的进程...

    AI掘金志

扫码关注云+社区

领取腾讯云代金券