2.1.  项目简介

  人脸识别是基于人的脸部特征信息进行身份识别的一种图像识别技术。使用0PenCV 进行人脸识别的过程如下。

  (1)  针对每个识别对象收集大量的人脸图傣作为样本。

  (2)  将样本送给识别器进行学习,在训练完成之后得到一个人脸数据模型。

  (3)  利用这个模型对新的人脸图像进行身份识别,预测人脸的所有者。

  简单地说就是收集训练数据、训练识别器、识别目标对象3个步骤,其工作过程如原书图33_1所示。

  使用OpenCV提供的人脸检测分类器,能够做到检测图像中的人脸并定位目标区域。如果想识别图像中的人脸是谁的,还需要训练专门的人脸识别器。这也不难,功能强大的0penCV提供简单易用的人脸识别接口,编程者不需要深人了解人脸识别理论知识,就可以轻松编写出人脸识别程序。

本节将介绍对“钢铁侠”和“蜘蛛侠“进行人脸识别。

  2.2.  准备工作

  1. 安装依赖模块 opencv-contrib

  opencv-contrib是OpenCV的扩展模块,在进行人脸识别时要用到 OpenCv 的识别器,有他提供。在python中,需要安装opencv-contrib-python库。

在julia中,用Conda安装opencv-contrib时会提示该包不存在,其实在julia中用Conda安装OpenCV库时,已经包含了这个扩展包。

  2.准备项目目录和数据

  在本地磁盘上建立一个名为“face-recogniz”的文件夹作为项目目录,用于存放本项目的数据、源程序、图像等文件,然后从原书“资源包/第 33 课”文件夹中把两个文件夹(testing和training) 以及一个人脸特征文件 (lbpcascade_frontalface_improved.xml) 复制到 “face-recogniz”文件夹中。

training 文件夹中提供了用于训练识别器使用的图像文件,testing文件夹中提供了进行人脸识别测试时使用的图像文件。

  2.3.  收集训练数据

  在这个项目中,巳经准备好了用于训练人脸识别器的人脸图像文件。也可以通过互联网搜索一些自己感兴趣的人脸图像作为训练数据,然后将其存放在 testing 文件夹中的一个子文件夹内即可。每一个人的人脸图像文件放在一个单独的文件夹中。

此外,在使用摄像头的人脸识别项目中,可 以通过摄像头采集人脸图作为训练数据。

  2.4.  训练识别器

  在收集人脸图像的工作完成后,就可以开始编写程序训练人脸识别器。如原书图 33-2 所示,这是使用0PEnCV 的 FaceRecognizer 进行人脸识别器的训练并生成数据模型的过程。

  • 编程实现:

  新建一个空白源文件,以face_training.jl作为文件名保存到“face-recogniz”项目文件夹中 ,然后编写程序进行人脸识别器的训练,具体过程如下。

  (1) 导人cv2、numpy和os模块。

using PyCall
cv2=pyimport("cv2")
numpy=pyimport("numpy")
os=pyimport("os")

  说明:在这个程序中需要使用python的os模块读取磁盘目录和文件列表。事实上julia中内置函数readdir()读取磁盘目录和文件也极为方便,这里只是偷懒,直接采用原来python的代码。

  (2) 创建训练识别器时使用的标签(整数 id 值)列表和人脸图像列表,及创建人脸检测器和人脸识别器的实。  

#创建人脸检测器和识别器
labels, faces = [], []
file = "lbpcascade_frontalface_improved.xml"
face_cascade = cv2.CascadeClassifier(file)
recognizer = cv2.face.LBPHFaceRecognizer_create()

  (3) 编写detect_face()函数, 用于从图像中检测人脸并返回人脸区域。

function detect_face(image)
#'''检测人脸区域'''
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.2, 5, minSize=(20, 20))
if (length(faces) == 0)
return nothing
end
(x, y, w, h) = faces[1,:]
return gray[y:y+w, x:x+h]
end

  说明: 调用 detectMultiScale()方法能够检测并返回图像的多个人脸区域,这里只使用其中的一个作为detect_face() 函数的返回值。原书python代码是这样的。

  (x, y, w, h) = faces[0]

  但是julia的数组是列主数组,如果用faces[1]只能返回数组的第一个元素,因此这里改为这样:

  (x, y, w, h) = faces[1,:]

  (4) 编写 read_face()函数于读取训练识别器使用的图像文件,并将检测出的人脸图像数据和id加人到faces列表和labels列表中 。

 1 function read_face(label, images_path)
2 #'''读取人脸图像'''
3 println("trainning:", label, images_path)
4 files = os.listdir(images_path)
5 for file in files
6 if startswith(file,'.')
7 continue
8 end
9 #从文件中读取图像
10 image = cv2.imread(images_path * "/" * file)
11 #检测图像中的人脸区域
12 face = detect_face(image)
13
14 if face !==nothing
15 ce = cv2.resize(face, (256, 256))
16 #faces.append(face)
17 #labels.append(label)
18 push!(faces,face)
19 push!(labels,label)
20 end
21 end
22 end

  说明: 在 faces 和 labels 这两个列表中的元素一一对应 ,即人脸图像和 id要匹配。

  (5) 训练人脸识别器,生成人脸特 征模型数据文件。这里使用蜘蛛侠和钢铁侠的图像进行训练。

#读取人脸图像
read_face(1, "training/spider_man/")
read_face(2, "training/iron_man/")
#训练人脸识别器
recognizer.train(faces, numpy.array(labels))
#保存人脸特征数据
recognizer.save("trainner.yml")

  说明:人脸识别器的train()将读取的人脸图像生成特征数据,第1个参数是图像列表,第2个参数是标签(整数的 id 值)数组,需要用 numpy.array()方法将列表(List)类型转换为 numpy 的数纽。 人脸识别器的save()方法将生成的人脸特征模型数据保存到一个文件中。

  至此训练人脸识别器的程序编写完毕。运行程序,将会读取 training 文件夹中的人脸图像,然后调用人脸识别器的 train()方法进行训练,最终在项 目目录下生成一个人脸特征模型的数据文件trainner.yml。

  2.5.  人脸检测与识别

  在训练好识别器之后,使用生成的人脸特征模型文件trainner.yml 就可以对testing目录下的人脸图像进行测试,看看是否能够识别出图像中的人脸是谁的。如原书图33-3所示,这是使用训练好的人脸识别器对图像中的人脸进行身份识别的过程。

  • 编程实现

  新建一个空白源文件,以face_detection.jl作为文件名保存到“face-recogniz”项目文件夹中 ,然后编写程序对测试图像进行人脸识别,具体过程如下。

  (1) 导人CV2 库。

cv2=pyimport("cv2")

  (2) 创建一个元组,存放人脸所有者的名字。 其中,第一个元素不使用。

names = ("None", "Spider Man", "Iron Man")

  (3) 创建人脸检测器和识别。

file = "lbpcascade_frontalface_improved.xml"
face_cascade = cv2.CascadeClassifier(file)
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("trainner.yml")

  说明:通过人脸识别器的read()方法,读取人脸特征模型数据文件 trainner. yml。

  (4) 从文件中读取用于测试的人脸图像

#读取测试的人脸图像
test_img = cv2.imread("testing/test1.jpg")
gray_img = cv2.cvtColor(test_img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray_img, 1.2, 5)

  (5) 在循环结构中对检测出的一组人脸图像进行预测。取出人脸图像改变大小。

#Julia数组是列主数组,而cv需要行主数组。
#反转维度,然后使用PyReverseDims数组
rimg = permutedims(test_img, ndims(test_img):-1:1)
pyimg = PyReverseDims(rimg) #对检测出的每一个人脸图像进行测试
for i in 1:size(faces,1)
(x,y,w,h)=faces[i,:]
face = gray_img[y:y+w, x:x+h]
face = cv2.resize(face, (256, 256))
……
end

  (6) 使用前面训练的人脸识别器预测图像中的人脸所有者。

#使用人脸识别器预测图像
label, confidence = recognizer.predict(face)
confidence = 100 - confidence
……

  说明:LBPHFaceRecognizer 预测产生0~100 的评分,低于50是可靠的,高于80是不可靠的。这里把评分转换一下,以符合正常的阅读习惯。

  (7) 当信任度大于50时,标注出图像中的人脸所有者

#取最大值
if label > 0 && confidence > 50
cv2.rectangle(pyimg, (x, y), (x+w, y+h), (255, 0, 0), 2)
text =@sprintf("%s:%d", names[label], confidence)
print(text)
font = cv2.FONT_HERSHEY_PLAIN
cv2.putText(pyimg, text, (x, y), font, 2.5, (0, 255, 0), 2)
end

  (8) 所有人脸处理完毕,显示到窗口。

#显示图像并等待
cv2.namedWindow("Image", cv2.WINDOW_NORMAL)
cv2.imshow("Image", pyimg)
cv2.waitKey(0)
cv2.destroyAllWindows()

  至此,人脸识别程序编写完毕。运行程序,对同时含有蜘蛛侠和钢铁侠的图像进行预测。从结果来看,能够正确识别出蜘蛛侠和钢铁侠,如下图所示:

源码下载:https://files.cnblogs.com/files/zjzkiss/face-recogniz.zip

对比python学julia(第四章:人工智能)--(第二节)人脸识别的更多相关文章

  1. python学习心得第四章

     python 学习心得第四章 1.lambda表达式 1:什么是lambda表达式 为了简化简单函数的代码,选择使用lambda表达式 上面两个函数的表达式虽然不一样,但是本质是一样的,并且lamb ...

  2. 进击的Python【第十四章】:Web前端基础之Javascript

    进击的Python[第十四章]:Web前端基础之Javascript 一.javascript是什么 JavaScript 是一种轻量级的编程语言. JavaScript 是可插入 HTML 页面的编 ...

  3. 《Python CookBook2》 第四章 Python技巧 对象拷贝 && 通过列表推导构建列表

    (先学第四章) 对象拷贝 任务: Python通常只是使用指向原对象的引用,并不是真正的拷贝. 解决方案: >>> a = [1,2,3] >>> import c ...

  4. [Python学习笔记][第四章Python字符串]

    2016/1/28学习内容 第四章 Python字符串与正则表达式之字符串 编码规则 UTF-8 以1个字节表示英语字符(兼容ASCII),以3个字节表示中文及其他语言,UTF-8对全世界所有国家需要 ...

  5. 《零压力学Python》 之 第四章知识点归纳

    第四章(决策和循环)知识点归纳 if condition: indented_statements [ elif condition: Indented_statements] [else: Inde ...

  6. python 教程 第十四章、 地址薄作业

    第十四章. 地址薄作业 #A Byte of Python #!/usr/bin/env python import cPickle import os #define the contacts fi ...

  7. 2018-06-20 中文代码示例视频演示Python入门教程第四章 控制流

    知乎原链 续前作: 中文代码示例视频演示Python入门教程第三章 简介Python 对应在线文档: 4. More Control Flow Tools 录制中出了不少岔子. 另外, 输入法确实是一 ...

  8. 【Learning Python】【第四章】Python代码结构(一)

    这一章的主旨在于介绍python的代码结构 缩进 在很多的编程语言中,一般{}用于控制代码块,比如以下的一段C代码 if(var <= 10) { printf("....." ...

  9. Python开发【第四章】:Python函数剖析

    一.Python函数剖析 1.函数的调用顺序 #!/usr/bin/env python # -*- coding:utf-8 -*- #-Author-Lian #函数错误的调用方式 def fun ...

  10. 【2】python核心编程 第四章-python对象

    1.python对象 所有的Python 对像都拥有三个特性:身份,类型和值. 身份: 每一个对象都有一个唯一的身份标识自己,任何对象的身份可以使用内建函数id()来得到. 这个值可以被认为是该对象的 ...

随机推荐

  1. 8.19考试总结(NOIP模拟44)[Emotional Flutter·Medium Counting·Huge Counting·字符消除2 ]

    在自称善意的之时,即存恶意. 前言 几乎是大暑假的最后一次考试了. 我也迎来了我的第一次报零(雾 T1 Emotional Flutter 解题思路 比较考验思维能力,其实就是区间覆盖问题. 我考场上 ...

  2. 【论文笔记】AlexNet

    [深度学习]总目录 由于受到计算机性能的影响,虽然LeNet在图像分类中取得了较好的成绩,但是并没有引起很多的关注. 直到2012年,Alex等人提出的AlexNet网络在ImageNet大赛上以远超 ...

  3. js 实现仿百度换肤效果

    图片自行换掉即可查看效果,原理就是基于tab切换的效果实现的 效果图 1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <met ...

  4. epoll使用与原理

    使用要点 边缘模式(ET)与水平模式(LT)区别 下面内容来自linux man page The epoll event distribution interface is able to beha ...

  5. AlertManager解析:构建高效告警系统

    本文深入探讨了AlertManager的技术细节和实际应用,从基本概念.核心组件.工作流程,到与Prometheus的集成和实战案例,旨在为专业人士提供一个全面的AlertManager技术和应用指南 ...

  6. 可以把 FolkMQ 内嵌到 SpringBoot3 项目里(可内嵌的消息中间件,纯血国产)

    之前发了<把 FolkMQ 内嵌到 SpringBoot2 项目里(比如 "诺依" 啊)>.有人说都淘态了,有什么好内嵌的...所以再发个 SpringBoot3 Fo ...

  7. [iOS]Size Class不同尺寸适配的是什么样的机型(实验向)

    Size Class的定义可以翻阅网友的博客,本文不再赘述http://blog.csdn.net/yongyinmg/article/details/39315829 http://blog.csd ...

  8. 大模型重塑软件开发,华为云AI原生应用架构设计与实践分享

    在ArchSummit全球架构师峰会2024上,华为云aPaaS平台首席架构师马会彬受邀出席,和技术爱好者分享AI原生应用引擎的架构与实践. AI大模型与AI重塑软件的大趋势下,软件会发生哪些本质的变 ...

  9. Cython编译报错“numpy/arrayobject.h: No such file or directory”解决方案

    问题背景 Cython是用来加速Python程序性能的一个工具,其基本使用逻辑就是将类Python代码(*.pyx扩展格式)编译成\(*.c,*.so\)动态链接库文件,然后就可以在正常的Python ...

  10. 处理 3d 视频的简单理论基础

    背景 公司产品需要满足一些带有3d功能的应用场景,需要需要懂得如何处理3d信号.之前在调试以前产品的时候,发现处理3d信号的时候,是由2个画面叠加起来的. 导言 3D视频(或3D信号)为什么是两个画面 ...