基于opencv的人脸检测与识别(python语言)(1)

人脸检测和识别技术就目前而言,已经相对成熟,各类算法层出不穷,这都归功于各位奋斗在一线的大佬的努力(站在巨人的肩膀上的感觉就是爽)。本文是参考博客 https://www.cnblogs.com/neo-T/p/6477378.html 针对自己实际应用改写程序实现人脸检测与识别,并给出在实际操作过程中的一些问题说明,所以在一些程序注释上略显精简,读者可以参考这篇博客(注释详尽)对比学习。

另外为了让读者能够更快的上手程序,本文末尾也将整个项目百度云分享给大家(我这样的好人不多了!!),同时为了让初涉人脸识别的同学能够对这个方向有着一个整体了解,文末也提供了一篇文章综述的百度云(有英文注释哦!英语差的有福了!!)。

前期准备

环境

原文是在ubuntu环境下,本文则是在windows10环境下(主要差别在路径设置上),选择anaconda+python3.6+tensorflow1.9编写,读者可以根据自己平时喜好选择具体的IDE,jupyter Notebook,PyCharm也不错(虽然我更喜欢spyder)。至于tensorflow安装相关教程不是本文重点就不详说了(想要详说的网上搜哈有很多教程,唉,太多了!还有各种问题!算了看文末百度云链接吧)

原文用的是keras这个深度学习库,keras是纯python语言编写,继承了tensorflow和theano这样的深度学习框架。想学习的可以打开这个链接 https://keras-cn.readthedocs.io/en/latest/ (捡重要的看就行)。
具体安装跟一般python库安装一样的。

opencv作为最受欢迎的开源计算机视觉库,提供Python、Ruby、Matlab等语言的接口,实现图像处理和计算机视觉方面的很多通用算法,是初学者入门的一个重要且高效的工具。安装跟前keras安装流程相同具体见博客。opencvGithub链接:https://github.com/opencv/opencv 本文选择的级联分类器是haarcascade_frontalface_alt2.xml,大家可以在Github中下载下来在路径.\opencv-master\data\haarcascades中选择合适自己的分类器。

数据库

ORL人脸数据库是由英国剑桥大写AT&T实验室创建,包含40人工400张面部图像,每人有10幅经过归一化图像,图像尺寸为92*112,图像格式为pgm格式,是opencv例程中使用的数据集。下载链接:https://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html 也可以从文末百度云下载。数据集下载如下(文件s41是我添加的自己的图像数据,百度云的我删了的哈,大家根据自己需要添加数据):

项目详解

项目列表

  • face_rec_project

    • pycache
    • data
      • s1

        • 1.pgm
        • 2.pgm
        • 10.pgm
      • s2
      • s41
      • data.txt
    • haarcascades
    • model
    • testdata
      • 1
    • catch_pic.py
    • face_predict_test.py
    • load_dataset.py
    • train_with_keras.py

文件夹data存放数据集;haarcascades文件夹存放级联分类器;model文件夹存放训练好的模型;.\testdata\1文件夹存放摄像头获得的人脸作为加入的训练样本。

获取人脸

本文在ORL人脸数据集的基础上,通过摄像头直接获取人脸添加进ORL数据集中扩充该数据集。下面是具体程序介绍:

def catch_pict(classfier, path_name, catch_pic_num):"""Recognizing and storing 1000 face pictures form camera"""cv.namedWindow("face detect", cv.WINDOW_AUTOSIZE)color = (0, 255, 0)  # box color cam = cv.VideoCapture(0)num = 0while cam.isOpened():ret, img = cam.read()  if not ret:breakimg = cv.flip(img, 1) # reverse picturegray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)gray = cv.equalizeHist(gray)faceRects = classfier.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30), flags=cv.CASCADE_SCALE_IMAGE)if len(faceRects) > 0:for faceRect in faceRects:y, x, h, w = faceRectimg_name = '%s/%d.jpg' % (path_name, num)image = img[x-10:x+h+10, y-10:y+h+10]cv.rectangle(img, (y-10, x-10), (y+h+10, x+h+10), color, 4)cv.putText(img, 'num:%d' % num, (x+1, y+1), cv.FONT_HERSHEY_PLAIN, 1.0,(0, 0, 0), thickness=2, lineType=cv.LINE_AA)if num < catch_pic_num:cv.imwrite(img_name, image)num += 1print('picture %d was saved' % num)cv.imshow("face detect", img)if cv.waitKey(5) == 27:breakcam.release()cv.destroyAllWindows()if __name__ == '__main__':classfier = cv.CascadeClassifier(".\\haarcascades\\haarcascade_frontalface_alt2.xml")path_name = '.\\testdata\\1\\'catch_pict(classfier, path_name, 1000)

catch_pic.py程序主要是通过摄像头获取原始图像,采用opencv人脸识别的分类器将获得的图像中的人脸部分识别并框出来,再保存到.\testdata\1\文件夹中,图片按1-1000的命名方式保存。

参照opencv获取人脸图像的一些例程就可以理解上述程序大部分代码含义,所以具体每行代码就不一一说明了,说一些大家可能困惑的地方就行。

img = cv.flip(img, 1) # reverse picture

因为opencv在使用摄像头时是没有翻转的,所以要进行翻转(具体效果读者可以注释掉该行实际测试看一下效果)。

gray = cv.equalizeHist(gray)

对获得的灰度图像进行直方图均衡化增强图像对比度。

faceRects = classfier.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30), flags=cv.CASCADE_SCALE_IMAGE)

opencv关于级联分类器的使用函数(具体参数含义就不细说了,网上查一查很多)

   y, x, h, w = faceRect

返回的参数是识别人脸框左上角坐标和该框的长宽。

cv.rectangle(img, (y-10, x-10), (y+h+10, x+h+10), color, 4)
cv.putText(img, 'num:%d' % num, (x+1, y+1), cv.FONT_HERSHEY_PLAIN, 1.0,(0, 0, 0), thickness=2, lineType=cv.LINE_AA)

把人脸用框标示出来,并在窗口上显示此时保存第几张人脸。(具体参数也不细说了)

      if cv.waitKey(5) == 27:break

27是Esc的ASCII码,读者可以根据自己喜好选择退出按键。

写到这里也对windows和linux两种环境下的路径设置做一下说明:

路径设置在windows和linux的区别

首先说一下绝对路径跟相对路径:
绝对路径顾名思义即完整的路径名例如:

E:\PyCharm2019.1.1\PycharmProjects\PythonCode\face_rec_project

相对路径即相对而言的路径,对于python从程序所在的目录下开始的路径名就是相对路径:

.\testdata\1\

设成相对路径可以让项目文件在其它PC上可以不需要更改路径直接运行,很方便。

说完绝对路径跟相对路径,再谈谈windows跟linux环境下的路径设置差别。
linux下路径设置:

./testdata/1/

在linux下路径设置用斜杠来表示。

windows下路径设置:

.\\testdata\\1\\

windows环境下路径表示用反斜杠,但是不管是linux还是windows环境下python的转义字符都是用反斜杠表示,这就造成一个问题,在windows下编写路径如果用单反斜杠,系统可能会将其认为是转义字符而报错。

所以为了稳妥起见,本文都是使用的双杆斜杆路径表示,这样就不会出现上面所说的错误,此时的双反斜杠等同于单反斜杠。

加载数据

load_dataset.py主要有两个函数,函数resize_image将数据集中的图片先通过填充变成一个长宽相同图片,再按照需要的图片size进行缩放成指定大小图片用以训练。本文进行训练的图片数据大小为64*64。具体程序入下,比较简单就不做仔细说明。

def resize_image(img, height, width):"""Fill the input picture with black pixels into a square and,zoom to a given length and width of the picture"""row, col = (0, 0)h, w, _ = img.shapemax_dege = max(h, w)if h < max_dege:dh = max_dege-hcol = dh//2 elif w < max_dege:dw = max_dege-wrow = dw//2else:passconstant = cv.copyMakeBorder(img, col, col, row, row, cv.BORDER_CONSTANT, value=[0, 0, 0]) # black pixelsreturn cv.resize(constant, (height, width))

对于第二个函数load_data如下:

def load_data(path_name):"""Read training data and generate labels"""images = []faces = []labels = []face_num = 0ext = ['.pgm', 'jpg'] # data categoriesfor root, dirs, files in os.walk(path_name):for sub_dir in dirs:subject_path = os.path.join(root, sub_dir)face_num += 1for file in os.listdir(subject_path):abs_path = os.path.abspath(os.path.join(subject_path, file))if file.endswith(tuple(ext)):img = cv.imread(abs_path)img = resize_image(img, 64, 64)images.append(img)faces.append(subject_path)# Generate labels by file name number for picture labels in each filefor face in faces:for j in range(0, face_num):if face.endswith('s'+str(j+1)):labels.append(np.array(j))return images, labels, face_num

函数load_data将.\data\中每个文件夹的图片保存在images的list中,并按照每个文件夹名称的类别名将每张图片对应的label保存在labels的list中,这样我们就获得所有的图片及对应的标签(注意本文标签s1文件夹对应标签0,以此类推)。

ext = ['.pgm', 'jpg'] # data categories

ORL数据集给的图片是pgm格式,而本文通过摄像头获取图片格式别jpg格式,所以做一下扩展
(读者可以根据自己想要训练的图片类型自行添加格式)。

for root, dirs, files in os.walk(path_name):

模块os中函数walk返回根目录、给定路径下的所有子路径、给定路径下的所有文件。本文中root即指\face_rec_project\data\,dirs指.\s1~.\s41\,files指所有图片。

这样就好理解后面程序含义:

遍历所有子路径;
将每个子路径变为绝对路径(加上根目录);
对每个子路径就是一个人的人脸,所以每遍历一个子路径face_num就加1,最终得到总共多少个人的人脸;
对于每张图片获取其绝对路径;
若绝对路径格式为.pmg跟.jpg则读取并赋给img;
将img大小改为64*64;
保存到iamges中;
faces保存每张图片所在子路径。
    for face in faces:for j in range(0, face_num):if face.endswith('s'+str(j+1)):labels.append(np.array(j))

对于每张图片所在子路径根据其名称保存为对应的标签(再说明一下s1文件夹对应标签0)

在这个模块中注释掉的部分给出的是另一种保存数据的方法,通过将图片及对应标签保存在名为data的txt文本中。具体程序跟前面差不多,只是使用方法不一样,有兴趣的读者可以自行尝试这种加载数据方式。给出这种方法得到的数据样式:

前面为图片路径,后面为标签。

百度云

ORL数据集:链接:https://pan.baidu.com/s/1ANHklLXCwDtekVSBDm0Lpg
提取码:jdws
face_rec_project项目:链接:https://pan.baidu.com/s/1Vh3ZMZJljwep4oC2vqPg5A
提取码:wak0
tensorflow安装:链接:https://pan.baidu.com/s/18cJ1CF13ToLlCndoJqlKTA
提取码:rp87
人脸识别综述:链接:https://pan.baidu.com/s/1NmJgQy0QPMa_jGUWLkjGeg
提取码:0v7q

待续

基于opencv的人脸检测与识别(python)(1)相关推荐

  1. 基于opencv实现人脸检测

    基于opencv实现人脸检测 opencv简述 opencv是一个开源的计算机视觉库,它有着C++,Python,Java等接口,支持Windows,Linux,Mac OS,IOS 和 Androi ...

  2. python识别人脸多种属性_人脸检测及识别python实现系列(4)——卷积神经网络(CNN)入门...

    人脸检测及识别python实现系列(4)--卷积神经网络(CNN)入门 上篇博文我们准备好了2000张训练数据,接下来的几节我们将详细讲述如何利用这些数据训练我们的识别模型.前面说过,原博文给出的训练 ...

  3. 【零基础跑项目】20代码教你基于opencv的人脸检测

    20代码教你基于opencv的人脸检测

  4. 【OpenCV】人脸检测和识别

    文章目录 前言 一.人脸检测 1.基于Haar的人脸检测 2.基于深度学习的人脸检测 二.人脸识别 1.特征脸EigenFaces 2.人鱼脸FisherFaces 3.局部二进制编码直方图LBPH ...

  5. opencv(人脸检测和识别)

    Opencv的人脸检测函数,定义了具体可跟踪对象类型的数据文件. Haar级联分类器,通过对比分析相邻图像区域来判断给定图像或子图像与已知对象是否匹配. 两个图像的相似程度可以通过它们对应特征的欧式距 ...

  6. 基于opencv的人脸检测

    这里写目录标题 一.基本信息 1.导言 2.应用 3.环境搭建 二.逻辑以及关键代码 1.逻辑分析 关键代码 三.结果分析 四.总结 一.基本信息 1.导言 输入:图片,视频,可以使用本地,网络,监控 ...

  7. 基于opencv的人脸检测(图片、视频、摄像头)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.检测图片中的人脸 二.检测视频与摄像头中的人脸 总结 前言 人脸检测识别一直是个热门的研究问题,同时也是opencv中 ...

  8. python基于opencv的人脸检测(有最详细的注释)摄像头实时检测人脸

    主要实现功能: 通过opencv的模块的内置的方法打开电脑摄像头,读取每一帧数据进行分析.通过界面的方式在界面里实时更新摄像头视频并且标记出人脸. 效果图: 代码: 这部分代码可以用来检测opencv ...

  9. 人工智能之基于face_recognition的人脸检测与识别

    不久乘高铁出行,看见高铁火车站已经实现了"刷脸进站",而且效率很高,很感兴趣,今天抽时间研究一下,其实没那么复杂. 我基本上是基于https://github.com/ageitg ...

最新文章

  1. (转载)Hadoop2.7.1配置
  2. 【有三说图像】图像简史与基础
  3. 注释数据库介绍之GO、KEGG数据库
  4. Redis(三)、支持数据类型及常用操作命令
  5. C/C++指针 引用
  6. 运算符重载——算术运算符重载
  7. KeyMob手机聚合平台已集成多家移动广告平台
  8. sqoop连接hive和mysql_【数据平台】sqoop支持hive和mysql互导的基本语句格式
  9. 3.Entity Framework Core 5.0 设置字段属性
  10. 天勤2022数据结构(一)线性表
  11. 大数据之spark_spark SQL的建表语句
  12. QT cmd强制删除文件
  13. 鲍斯科机器人_芜湖鲍斯柯机器人有限公司、上海富治机械科技有限公司服务合同纠纷二审民事判决书...
  14. java 跳跃表_你真的了解跳跃表吗
  15. 微信扫一扫中的js安全接口域名的配置
  16. 转:深网 | 中国手机往事:因为雷军、罗永浩们,中国才告别山寨机
  17. 做科研的几点体会:如何多发 SCI
  18. STM32之蜂鸣器实验
  19. 【XSS漏洞03】XSS漏洞验证、语句构造与绕过方法
  20. 基于mpvue的微信小程序全栈保姆式教程一

热门文章

  1. 第三章 关系数据库标准语言SQL
  2. 计算机主板上的电池作用,主板电池在哪_主板电池的作用_电脑主板电池能用多久...
  3. 浅析计算机在医学方面的应用,医学计算机论文,关于医学领域中计算机技术的应用相关参考文献资料-免费论文范文...
  4. (各大虚拟化产品掐架)浅解VMware加入OpenStack的原因
  5. 微信小程序 view的文本不能自动换行问题
  6. 苹果cmsV10-Dplayer播放器插件整合前置广告、暂停广告
  7. 2022年R1快开门式压力容器操作考试技巧及R1快开门式压力容器操作模拟考试题
  8. 华为鸿蒙上手,原生鸿蒙系统,华为WATCH 3真机上手视频曝光
  9. 范冰冰着大仁哥新装出街 款款皆真爱
  10. 认识系统函数$test$plusargs与$value$plusargs