我的第二程Python之路-week2 初探人脸识别

目录


  1. class 2 的实操
    • 初级人脸识别
    • 中极人脸识别
    • 究极人脸识别
    • 进阶:人脸定位和人脸核验
  2. 遇到的问题
    • 安装 Face-recognition 库
    • 图片灰度的问题
    • plt显示图片的问题
  3. 拓展一下
    • plt 图像处理基本操作
    • Haar 算法的技术逻辑和 Adaboost 级联分类器原理

写在前面

老师上课说讲人脸识别,着实把我吓了一跳。这是我第二节课就可以学到的东西么?

直到开始实操,我才发现我们站在巨人的肩膀上。程序员朋友总是调侃“瞎造轮子”,对于我们这些非专业手,不会瞎造轮子,也不需要瞎造轮子(主要是不会)。学会从错误中学习,善用百度,能够结合现有的方式实现自己的需求,就很满足了。

Eg:要学会看技术文档。


一、Class 2 实操


第二节课的上机实操,通过 OpenCV 和 Face-recognition 进行人脸识别,对卷积神经网络有一个初步的体会。

老师介绍了三种实现人脸识别的方法,分别是 OpenCV 的 CascadeClassifier 级联分类器、Face-recognition 的 HOG 算法、Face-recognition 的 CNN 算法。

三种算法就能能力相差几何?各有什么优势?三组试验,拉出来溜溜。

环境Python3.7 Jupyter Notebook 用到的库 OpenCV dlib face_recognition matplotlib.pyplot

1. 初级人脸识别


在这一组比赛中,我们先使用难度较低的一张图进行识别。这幅图的难点在于遮挡(比如墨镜和脸不全):


夕阳红舞蹈艺术团

首先使用 OpenCV,开干!

import cv2 as cv
import matplotlib.pyplot as plt

def detectFaces(image_name):
    img = cv.imread(image_name)
    face_cascade = cv.CascadeClassifier("data/haarcascade_frontalface_default.xml")    #这里可以更换模型以满足不同的需求。

    if img.ndim == 3:
        gray = cv.cvtColor(img,cv2.COLOR_BGR2GRAY)
    else:
        gray = img
        
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    for (x, y, w, h) in faces:
            img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

    plt.imshow(img)
    plt.axis("off")
    plt.show()
    cv.imwrite('图片输出.jpg',img)

detectFaces("图片导入.jpg")

查看输出的图片,识别率 4 / 6 ,算他及格。墨镜和遮挡都没有很好的识别出来:


使用 OpenCV

继续使用 Face-recognition 的 HOG 算法和 Face-recognition 的 CNN 算法。代码如下:

# 使用 HOG 算法
import face_recognition
import cv2 as cv
import matplotlib.pyplot as plt
%matplotlib inline        #在 jupyter Notebook 中正确输出图片
image = face_recognition.load_image_file("输入.jpg")
face_locations=face_recognition.face_locations(image)

face_num2=len(face_locations)
org = cv.imread("输入.jpg")

for i in range(0,face_num2):
    top = face_locations[i][0]
    right = face_locations[i][1]
    bottom = face_locations[i][2]
    left = face_locations[i][3]

    start = (left, top)
    end = (right, bottom)

    color = (0,255,255)
    thickness = 2
    img=cv.rectangle(org, start, end, color, thickness)


    plt.axis('off')  
    plt.show()
plt.imshow(img)
cv.imwrite('输出.jpg',img)
# 使用 CNN 算法
import face_recognition
import cv2 as cv
import matplotlib.pyplot as plt

image = face_recognition.load_image_file("输入.jpg")
face_locations_useCNN = face_recognition.face_locations(image,model='cnn')  #同理可以更换不同模型

face_num1=len(face_locations_useCNN)
org = cv.imread("输入.jpg")

for i in range(0,face_num1):
    top = face_locations_useCNN[i][0]
    right = face_locations_useCNN[i][1]
    bottom = face_locations_useCNN[i][2]
    left = face_locations_useCNN[i][3]

    start = (left, top)
    end = (right, bottom)

    color = (0,255,255)
    thickness = 2
    img=cv2.rectangle(org, start, end, color, thickness)    # opencv 里面画矩形的函数
    plt.imshow(img)
    plt.axis('off')  #去掉坐标轴
plt.show()
cv.imwrite('输出.jpg',img)

对比三次的识别结果,答案显而易见:深度学习就是牛!


深度学习就是牛

2. 中级人脸识别


中级人脸识别难度上了一层楼。开始对 30 多人的大合影开始识别了!
由于代码基本没有调整,所以就直接上结果了。通过对比发现,结果差距不大。


深度学习就是牛

3. 究极人脸识别


就前两轮的竞争来说,CNN 算法均是略胜一筹,但是 OpenCV 和 另外两种的差距还不算明显。但是我相信下面这一组的识别绝对超出你的想象。

这一组合影照片,不光人数众多,而且分辨率有限,遮挡也比较复杂。三种方法究竟谁能更胜一筹呢?上才艺!

大吃一惊

从结果来看,表现优秀的 CNN 算法在这一轮翻车了,甚至还不如另外两种算法。相比较而言,OpenCV 对于低分辨率的人脸(比如后排同学)有着更好的识别能力;CNN 可以识别出更多的遮挡,反而 HOG 算法识别出了最多数量的人脸。

另外,CNN 算法的最大问题是运算时间比另外两种要久数倍,在一些需要快速响应的场景下就有很大的局限性了。

并不存在一劳永逸的万能算法和万能代码,各种方法实际上都各有利弊。没有最好,只有最合适。如何选择出最合适的代码,不仅要求对代码的运行原理有所了解,更重要的是对需求应用场景有一个准确的判断。

4. 进阶:人脸定位和人脸核验


人脸定位是人脸检测的前置条件。这一功能可以实现对面部器官的形状、位置等等进行识别。我们经常使用的美颜、脸部贴纸、表情等等,都是基于人脸定位开始的。
下面的代码可以对图片上的人脸进行5点或是64点定位。

import cv2 as cv
import dlib
import matplotlib.pyplot as plt

img = cv.imread("图片.png")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

#人脸分类器
detector = dlib.get_frontal_face_detector()
# 获取人脸检测器
#predictor = dlib.shape_predictor(r"C:\Python36\Lib\site-packages\face_recognition_models\models\shape_predictor_68_face_landmarks.dat")
predictor = dlib.shape_predictor(r"data\shape_predictor_68_face_landmarks.dat")

dets = detector(gray, 1)
for face in dets:
    shape = predictor(img, face)  # 寻找人脸的68个标定点
    # 遍历所有点,打印出其坐标,并圈出来
    for pt in shape.parts():
        pt_pos = (pt.x, pt.y)
        img=cv2.circle(img, pt_pos, 2, (0, 255, 0), 1)
        
plt.imshow(img)
plt.axis('off')  #去掉坐标轴
plt.show()

而人脸检测则可以对比不同图片中出现的脸部是否是同一人,并给出反馈。代码如下:

import cv2 as cv
import face_recognition
import matplotlib.pyplot as plt

known_image=cv.imread("ycy.jpg")
known_image = face_recognition.load_image_file("ycy.jpg")

unknown_image=cv.imread("ycy2.png")
unknown_image = face_recognition.load_image_file("ycy2.png")

known_encoding = face_recognition.face_encodings(known_image)[0]
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]

results = face_recognition.compare_faces([known_encoding],unknown_encoding,tolerance=0.6)
if results[0] == True:
    print("匹配成功,该未知图片与已有图片人脸可匹配!")
else:
    print("匹配失败!")
    
#print(known_encoding) 
#print(unknown_encoding)

plt.imshow(known_image)
plt.axis('off')  #去掉坐标轴
plt.show()

plt.imshow(unknown_image)
plt.axis('off')  #去掉坐标轴


二、遇到的问题


  • 安装 Face-recognition 库

    • 安装 Face-recognition 库需要先安装 dlib 库。而dlib 库又需要电脑有 VS C++ 的环境。所以应该先安装 VS (不是 VS Code,它只是一个编译器。)
  • plt 显示图片的问题

    • 在 jupyter 中,因为对图片进行了去色处理,所以plt.show()显示的是去色后的图片。只需要使用 OpenCV 的.imwrite命令将图片存为本地即可。

    • plt.show()默认的图片输出分辨率其实很低。在进行图片编码时,一些行列的像素会被丢弃,所以有的图片上人脸的红框会消失。可以通过下面的代码调整图片分辨率和像素:

      plt.rcParams["savefig.dpi"] = 100 # 图片像素
      plt.rcParams["figure.dpi"] = 100 # 分辨率
      

三、拓展一下



See you next time!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容