Python基于Opencv来快速实现人脸识别过程详解(完整版)

前言

随着人工智能的日益火热,计算机视觉领域发展迅速,尤其在人脸识别或物体检测方向更为广泛,今天就为大家带来最基础的人脸识别基础,从一个个函数开始走进这个奥妙的世界。

首先看一下本实验需要的数据集,为了简便我们只进行两个人的识别,选取了beyond乐队的主唱黄家驹和贝斯手黄家强,这哥俩长得有几分神似,这也是对人脸识别的一个考验:

两个文件夹,一个为训练数据集,一个为测试数据集,训练数据集中有两个文件夹0和1,之前看一些资料有说这里要遵循“slabel”命名规则,但后面处理起来比较麻烦,因为目前opencv接受的人脸识别标签为整数,那我们就直接用整数命名吧:

为了方便,我们每个人用20张照片来训练,0代表黄家驹,1代表黄家强:

开始啦:

1.检测人脸

这应该是最基本的,给我们一张图片,我们要先检测出人脸的区域,然后才能
进行操作,opencv已经内置了很多分类检测器,我们这次用haar:

def detect_face(img):
 #将测试图像转换为灰度图像,因为opencv人脸检测器需要灰度图像
 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 #加载OpenCV人脸检测分类器Haar
 face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
 #检测多尺度图像,返回值是一张脸部区域信息的列表(x,y,宽,高)
 faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
 # 如果未检测到面部,则返回原始图像
 if (len(faces) == 0):
 return None, None
 #目前假设只有一张脸,xy为左上角坐标,wh为矩形的宽高
 (x, y, w, h) = faces[0]
 #返回图像的正面部分
 return gray[y:y + w, x:x + h], faces[0]

2.有了数据集和检测人脸的功能后,我们就可以进行预训练了

最后返回所有训练图片的人脸检测信息和标签:

# 该函数将读取所有的训练图像,从每个图像检测人脸并将返回两个相同大小的列表,分别为脸部信息和标签
def prepare_training_data(data_folder_path):
 # 获取数据文件夹中的目录(每个主题的一个目录)
 dirs = os.listdir(data_folder_path)
 # 两个列表分别保存所有的脸部和标签
 faces = []
 labels = []
 # 浏览每个目录并访问其中的图像
 for dir_name in dirs:
 # dir_name(str类型)即标签
 label = int(dir_name)
 # 建立包含当前主题主题图像的目录路径
 subject_dir_path = data_folder_path + "/" + dir_name
 # 获取给定主题目录内的图像名称
 subject_images_names = os.listdir(subject_dir_path)
 # 浏览每张图片并检测脸部,然后将脸部信息添加到脸部列表faces[]
 for image_name in subject_images_names:
 # 建立图像路径
 image_path = subject_dir_path + "/" + image_name
 # 读取图像
 image = cv2.imread(image_path)
 # 显示图像0.1s
 cv2.imshow("Training on image...", image)
 cv2.waitKey(100)
 # 检测脸部
 face, rect = detect_face(image)
 # 我们忽略未检测到的脸部
 if face is not None:
 #将脸添加到脸部列表并添加相应的标签
 faces.append(face)
 labels.append(label)
 cv2.waitKey(1)
 cv2.destroyAllWindows()
 #最终返回值为人脸和标签列表
 return faces, labels

3.有了脸部信息和对应标签后,我们就可以使用opencv自带的识别器来进行训练了

#调用prepare_training_data()函数
faces, labels = prepare_training_data("training_data")
#创建LBPH识别器并开始训练,当然也可以选择Eigen或者Fisher识别器
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
face_recognizer.train(faces, np.array(labels))

4.训练完毕后就可以进行预测了

在这之前我们可以设定一下预测的格式,包括用矩形框框出人脸并标出其名字,当然最后别忘了建立标签与真实姓名直接的映射表:

#根据给定的(x,y)坐标和宽度高度在图像上绘制矩形
def draw_rectangle(img, rect):
 (x, y, w, h) = rect
 cv2.rectangle(img, (x, y), (x + w, y + h), (128, 128, 0), 2)
# 根据给定的(x,y)坐标标识出人名
def draw_text(img, text, x, y):
 cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
#建立标签与人名的映射列表(标签只能为整数)
subjects = ["jiaju", "jiaqiang"]

5.现在就可以定义我们的预测函数了:

# 此函数识别传递的图像中的人物并在检测到的脸部周围绘制一个矩形及其名称
def predict(test_img):
 #生成图像的副本,这样就能保留原始图像
 img = test_img.copy()
 #检测人脸
 face, rect = detect_face(img)
 #预测人脸
 label = face_recognizer.predict(face)
 # 获取由人脸识别器返回的相应标签的名称
 label_text = subjects[label[0]]
 # 在检测到的脸部周围画一个矩形
 draw_rectangle(img, rect)
 # 标出预测的名字
 draw_text(img, label_text, rect[0], rect[1] - 5)
 #返回预测的图像
 return img

6.最后使用我们test_data中的图片进行预测并显示最终效果:

#加载测试图像
test_img1 = cv2.imread("test_data/test1.jpg")
test_img2 = cv2.imread("test_data/test2.jpg")
#执行预测
predicted_img1 = predict(test_img1)
predicted_img2 = predict(test_img2)
#显示两个图像
cv2.imshow(subjects[0], predicted_img1)
cv2.imshow(subjects[1], predicted_img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

来看看识别的结果:

这就是人脸识别最基本的流程,后续还会进一步的研究,下一篇我们将讨论本次实验的一些细节和注意事项,算是对本篇的一次挖掘和总结吧。

最后附上完整代码:

# # -*- coding:utf-8 -*-
import cv2
import os
import numpy as np
# 检测人脸
def detect_face(img):
 #将测试图像转换为灰度图像,因为opencv人脸检测器需要灰度图像
 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 #加载OpenCV人脸检测分类器Haar
 face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
 #检测多尺度图像,返回值是一张脸部区域信息的列表(x,y,宽,高)
 faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
 # 如果未检测到面部,则返回原始图像
 if (len(faces) == 0):
 return None, None
 #目前假设只有一张脸,xy为左上角坐标,wh为矩形的宽高
 (x, y, w, h) = faces[0]
 #返回图像的正面部分
 return gray[y:y + w, x:x + h], faces[0]
# 该函数将读取所有的训练图像,从每个图像检测人脸并将返回两个相同大小的列表,分别为脸部信息和标签
def prepare_training_data(data_folder_path):
 # 获取数据文件夹中的目录(每个主题的一个目录)
 dirs = os.listdir(data_folder_path)
 # 两个列表分别保存所有的脸部和标签
 faces = []
 labels = []
 # 浏览每个目录并访问其中的图像
 for dir_name in dirs:
 # dir_name(str类型)即标签
 label = int(dir_name)
 # 建立包含当前主题主题图像的目录路径
 subject_dir_path = data_folder_path + "/" + dir_name
 # 获取给定主题目录内的图像名称
 subject_images_names = os.listdir(subject_dir_path)
 # 浏览每张图片并检测脸部,然后将脸部信息添加到脸部列表faces[]
 for image_name in subject_images_names:
 # 建立图像路径
 image_path = subject_dir_path + "/" + image_name
 # 读取图像
 image = cv2.imread(image_path)
 # 显示图像0.1s
 cv2.imshow("Training on image...", image)
 cv2.waitKey(100)
 # 检测脸部
 face, rect = detect_face(image)
 # 我们忽略未检测到的脸部
 if face is not None:
 #将脸添加到脸部列表并添加相应的标签
 faces.append(face)
 labels.append(label)
 cv2.waitKey(1)
 cv2.destroyAllWindows()
 #最终返回值为人脸和标签列表
 return faces, labels
#调用prepare_training_data()函数
faces, labels = prepare_training_data("training_data")
#创建LBPH识别器并开始训练,当然也可以选择Eigen或者Fisher识别器
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
face_recognizer.train(faces, np.array(labels))
#根据给定的(x,y)坐标和宽度高度在图像上绘制矩形
def draw_rectangle(img, rect):
 (x, y, w, h) = rect
 cv2.rectangle(img, (x, y), (x + w, y + h), (128, 128, 0), 2)
# 根据给定的(x,y)坐标标识出人名
def draw_text(img, text, x, y):
 cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
#建立标签与人名的映射列表(标签只能为整数)
subjects = ["jiaju", "jiaqiang"]
# 此函数识别传递的图像中的人物并在检测到的脸部周围绘制一个矩形及其名称
def predict(test_img):
 #生成图像的副本,这样就能保留原始图像
 img = test_img.copy()
 #检测人脸
 face, rect = detect_face(img)
 #预测人脸
 label = face_recognizer.predict(face)
 # 获取由人脸识别器返回的相应标签的名称
 label_text = subjects[label[0]]
 # 在检测到的脸部周围画一个矩形
 draw_rectangle(img, rect)
 # 标出预测的名字
 draw_text(img, label_text, rect[0], rect[1] - 5)
 #返回预测的图像
 return img
#加载测试图像
test_img1 = cv2.imread("test_data/test1.jpg")
test_img2 = cv2.imread("test_data/test2.jpg")
#执行预测
predicted_img1 = predict(test_img1)
predicted_img2 = predict(test_img2)
#显示两个图像
cv2.imshow(subjects[0], predicted_img1)
cv2.imshow(subjects[1], predicted_img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Python识别快递条形码及Tesseract-OCR使用详解

    识别快递单号 这次跟老师做项目,这项目大概是流水线上识别快递上的快递单号.首先我尝试了解条形码的基本知识 百度百科:条形码 条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符.常见的条形码是由反射率相差很大的黑条(简称条)和白条(简称空)排成的平行线图案.条形码可以标出物品的生产国.制造厂家.商品名称.生产日期.图书分类号.邮件起止地点.类别.日期等许多信息,因而在商品流通.图书管理.邮政管理.银行系统等许多领域都得到广泛的应用. 条形码有

  • 使用Python的OpenCV模块识别滑动验证码的缺口(推荐)

    最近终于找到一个好的方法,使用Python的OpenCV模块识别滑动验证码的缺口,可以将滑动验证码中的缺口识别出来了. 测试使用如下两张图片: target.jpg template.png 现在想要通过"template.png"在"target.jpg"中找到对应的缺口,代码实现如下: # encoding=utf8 import cv2 import numpy as np def show(name): cv2.imshow('Show', name) cv

  • python批量识别图片指定区域文字内容

    Python批量识别图片指定区域文字内容,供大家参考,具体内容如下 简介 对于一张图片,需求识别指定区域的内容 1.截取原始图上的指定图片当做模板 2.根据模板相似度去再原始图片上识别准确坐标 3.根据坐标剪切出指定位置图片,也就是所需的内容区域 4.对指定位置图片进行ocr识别 环境 Ubuntu18.04 Python2.7 所需Python模块 1.aircv 用于识别模板再原始图的位置坐标 pip install aircv 2.Pillow 用于剪裁图片 pip install Pil

  • Python Opencv实现图像轮廓识别功能

    本文实例为大家分享了python opencv识别图像轮廓的具体代码,供大家参考,具体内容如下 要求:用矩形或者圆形框住图片中的云朵(不要求全部框出) 轮廓检测 Opencv-Python接口中使用cv2.findContours()函数来查找检测物体的轮廓. import cv2 img = cv2.imread('cloud.jpg') # 灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化 ret, binary = cv2.th

  • Python3.6使用tesseract-ocr的正确方法

    Tesseract介绍 tesseract是一个挺不错的OCR引擎,目前的问题是最新的中文资料相对较少,过时.不准确的信息偏多. tesseract是一个google支持的开源ocr项目,其项目地址:https://github.com/tesseract-ocr/tesseract,目前最新的源码可以在这里下载. 实际使用tesseract ocr也有两种方式:1. 动态库方式 libtesseract  2. 执行程序方式 tesseract.exe 环境 Python 3.6.3 pip

  • Perl使用Tesseract-OCR实现验证码识别教程

    一.Tesseract-OCR 是什么 An OCR Engine that was developed at HP Labs between 1985 and 1995- and now at Google 基于Leptonica(http://leptonica.com/)图形处理库开的开源图形识别引擎. 支持Linux.Windows.Mac平台, 支持.NET.C++.Python.Java等开发语言:https://code.google.com/p/tesseract-ocr/wik

  • 用Python识别人脸,人种等各种信息

    最近几天了解了一下人脸识别,应用场景可以是图片标注,商品图和广告图中有没有模特,有几个模特,模特的性别,年龄,颜值,表情等数据的挖掘. 基础的识别用dlib来实现,dlib是一个机器学习的包,主要用C++写的,但是也有Python版本.其中最流行的一个功能是Facial Landmark Detection, 配备已经训练好的轮廓预测模型,叫shape_predictor_68_face_landmarks.dat, 从名字就可以看出,它可以检测出面部的68个关键点,包括五官和外轮廓等. 安装d

  • Python基于Opencv来快速实现人脸识别过程详解(完整版)

    前言 随着人工智能的日益火热,计算机视觉领域发展迅速,尤其在人脸识别或物体检测方向更为广泛,今天就为大家带来最基础的人脸识别基础,从一个个函数开始走进这个奥妙的世界. 首先看一下本实验需要的数据集,为了简便我们只进行两个人的识别,选取了beyond乐队的主唱黄家驹和贝斯手黄家强,这哥俩长得有几分神似,这也是对人脸识别的一个考验: 两个文件夹,一个为训练数据集,一个为测试数据集,训练数据集中有两个文件夹0和1,之前看一些资料有说这里要遵循"slabel"命名规则,但后面处理起来比较麻烦,

  • Python基于OpenCV库Adaboost实现人脸识别功能详解

    本文实例讲述了Python基于OpenCV库Adaboost实现人脸识别功能.分享给大家供大家参考,具体如下: 以前用Matlab写神经网络的面部眼镜识别算法,研究算法逻辑,采集大量训练数据,迭代,计算各感知器的系数...相当之麻烦~而现在运用调用pythonOpenCV库Adaboost算法,无需知道算法逻辑,无需进行模型训练,人脸识别变得相当之简单了. 需要用到的库是opencv(open source computer vision),下载安装方式如下: 使用pip install num

  • 基于Opencv图像识别实现答题卡识别示例详解

    目录 1. 项目分析 2.项目实验 3.项目结果 总结 在观看唐宇迪老师图像处理的课程中,其中有一个答题卡识别的小项目,在此结合自己理解做一个简单的总结. 1. 项目分析 首先在拿到项目时候,分析项目目的是什么,要达到什么样的目标,有哪些需要注意的事项,同时构思实验的大体流程. 图1. 答题卡测试图像 比如在答题卡识别的项目中,针对测试图片如图1 ,首先应当实现的功能是: 能够捕获答题卡中的每个填涂选项. 将获取的填涂选项与正确选项做对比计算其答题正确率. 2.项目实验 在对测试图像进行形态学操

  • Java OpenCV实现人脸识别过程详解

    准备 : 下载openCV安装包 :  https://opencv.org/ 安装包安装之后支持多种语言环境,此处使用Java,在Eclipse中引入 openCV目录下的java/opencv-320.jar,同时配置openCV库路径. Eclipse配置openCV 代码实现 : package test; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfRect;

  • 基于opencv和pillow实现人脸识别系统(附demo)

    目录 一.人脸检测和数据收集 二.训练识别器 三.人脸识别和显示 本文不涉及分类器.训练识别器等算法原理,仅包含对其应用(未来我也会写自己对机器学习算法原理的一些观点和了解) 首先我们需要知道的是利用现有框架做一个人脸识别系统并不难,然后就开始我们的系统开发吧. 我们的系统主要分为三个部分,然后我还会提出对补获图片不能添加中文的解决方案.我们需要完成的任务:1.人脸检测和数据收集2.训练识别器3.人脸识别和显示 在读此篇文章之前我相信你已经做了python环境部署和opencv模块的下载安装工作

  • Python基于纹理背景和聚类算法实现图像分割详解

    目录 一.基于纹理背景的图像分割 二.基于K-Means聚类算法的区域分割 三.总结 一.基于纹理背景的图像分割 该部分主要讲解基于图像纹理信息(颜色).边界信息(反差)和背景信息的图像分割算法.在OpenCV中,GrabCut算法能够有效地利用纹理信息和边界信息分割背景,提取图像目标物体.该算法是微软研究院基于图像分割和抠图的课题,它能有效地将目标图像分割提取,如图1所示[1]. GrabCut算法原型如下所示: mask, bgdModel, fgdModel = grabCut(img,

  • 基于python中pygame模块的Linux下安装过程(详解)

    一.使用pip安装Python包 大多数较新的Python版本都自带pip,因此首先可检查系统是否已经安装了pip.在Python3中,pip有时被称为pip3. 1.在Linux和OS X系统中检查是否安装了pip 打开一个终端窗口,并执行如下命令: Python2.7中: zhuzhu@zhuzhu-K53SJ:~$ pip --version pip 8.1.1 from /usr/lib/python2.7/dist-packages (python 2.7) Python3.X中: z

  • Python 基于FIR实现Hilbert滤波器求信号包络详解

    在通信领域,可以通过希尔伯特变换求解解析信号,进而求解窄带信号的包络. 实现希尔伯特变换有两种方法,一种是对信号做FFT,单后只保留单边频谱,在做IFFT,我们称之为频域方法:另一种是基于FIR根据传递函数设计一个希尔伯特滤波器,我们称之为时域方法. # -*- coding:utf8 -*- # @TIME : 2019/4/11 18:30 # @Author : SuHao # @File : hilberfilter.py import scipy.signal as signal im

  • python使用scapy模块实现ping扫描的过程详解

    关于scapy Scapy 是一个可以让用户发送.侦听和解析并伪装网络报文的Python程序.这些功能可以用于制作侦测.扫描和攻击网络的工具. 换言之, Scapy 是一个强大的操纵报文的交互程序.它可以伪造或者解析多种协议的报文,还具有发送.捕获.匹配请求和响应这些报文以及更多的功能. Scapy 可以轻松地做到像扫描(scanning).路由跟踪(tracerouting).探测(probing).单元测试(unit tests).攻击(attacks)和发现网络(network disco

  • 基于vue cli重构多页面脚手架过程详解

    官方提供的项目生成工具vue-cli没有对多页面webApp的支持,但是在实际的项目中,我们需要这样的脚手架,参考了很多大牛的方法,这里提供了一种我的单页面脚手架转换为多页面脚手架的方案,供大家参考.不好的地方也请大家指正. 准备 使用vue-cli生成一个你需要的单页面项目脚手架,然后我们就要开始我们的改装工程了. 重构过程 步骤一 改变目录结构 step1 在src目录下面新建views文件夹,然后再views文件夹下新建index文件夹 step2 将src目录下的main.js和App.

随机推荐