热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python+opencv实现简单的人脸识别

前言最近自己尝试了python+opencv实现简单的人脸识别,接下来我将一步步讲解我实现其功能的详细步骤,有不对的地方请指正具体的功能是:识别图片或者视频片段中的人脸,打印出识别

前言

最近自己尝试了python+opencv实现简单的人脸识别,接下来我将一步步讲解我实现其功能的详细步骤,有不对的地方请指正

具体的功能是:识别图片或者视频片段中的人脸,打印出识别的信息



模块

这里我将罗列我们需要使用的模块


  1. opencv(cv2) : 这是我们实现人脸识别的主要模块

  2. os :文件操作

  3. xlrd :操作excel(我将一部分信息放在excel中)

  4. pillow :图像处理标准库

  5. numpy :数组运算 (通常我们可以将彩色图片看作三维数组,黑白图片看作二维数组)


功能实现


        1.目录介绍

这是我创建的文件目录,下面我将依次介绍相应信息(该文件夹是按照自己习惯建立,大家只需要了解具体用处即可)


  1. image:  存放照片的总文件夹

  2. imge/colours:  存放用来训练模型的照片

  3. image/need_recognize:  存放需要识别的照片

  4. image/video:  存放需要识别的视频

  5. info/faceInfo.xls:  存放照片训练模型照片的相应信息

  6. train/train.yml:  训练好的模型文件

  7. haarcascade_frontalface_default.xml:  opencv人脸识别文件,需自行下载

  8. recognize.py:  实现人脸识别功能的文件

  9. train.py:  实现模型训练的文件


        2.训练模块

模型训练最终会生成train.yml文件,在train.py中,我定义了两个函数来完成改功能,我将会在代码注释部分详细讲解其作用。

#train.py =>  getImageAndLabels(images_path)

def getImageAndLabels(images_path): # 传入模型训练的照片路径
faces = []
ids = []
face_detector = cv.CascadeClassifier('haarcascade_frontalface_default.xml')
# 引用人脸识别模块 (这个模块来自opencv开源人脸模块)
images = [os.path.join(images_path, title) for title in os.listdir(images_path)]
# 将路径下照片依次放入images列表
for image in images:
gray_image = Image.open(image).convert('L') # 灰度照片
image_numpy = np.array(gray_image, 'uint8') # 将照片转化为数组
face_site = face_detector.detectMultiScale(image_numpy) # 检测人脸并存入
id = os.path.split(image)[1].split('.')[0]
# 将每张照片的id记录
if not len(face_site):
print(image, '无法识别')
else:
for x, y, w, h in face_site:
faces.append(image_numpy[y:y + h, x:x + w])
ids.append(int(id))
return faces, ids # 返回所有照片的人脸数据和id

#train.py =>  train_data(face_image_path)

def train_data(face_image_path): # 传入模型训练的照片路径
faces, ids = getImageAndLabels(face_image_path) # 获取所有照片人脸数据和id
recognizer = face.LBPHFaceRecognizer_create() # 引入训练模型的函数
recognizer.train(faces, np.array(ids)) # 训练模型
recognizer.write('trainer/trainer.yml') # 创建训练模型的文件或重新写入


  


        3.识别模块

在识别模块中,对于照片的人脸识别和视频的人脸识别,其实现方式是相同的,故我将视频的每一帧作为照片传入函数进行识别,达到复用函数的目的,该模块共定义了四个函数。

#recognize.py =>  read_info(id_info)

def read_info(id_info): # 传入需要识别出的人脸id
excel = xlrd.open_workbook(excel_path)
sheet = excel.sheet_by_index(0)
name = sheet.row_values(id_info + 1)[1] # 查找传入id照片的信息
return name

#recognize.py =>  face_recognize(image, isVideo)

def face_recognize(image, isVideo): # 传入需要识别的照片以及该照片是否属于视频的一帧
recognizer.read('trainer/trainer.yml') # 读取训练模型
gray_img = cv.cvtColor(image, cv.COLOR_BGR2GRAY) # 将图片灰度转换
faces = face_detector.detectMultiScale(gray_img) # 检测图片中人脸部分
for x, y, w, h in faces:
cv.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 在原图中圈出人脸
id, cOnfidence= recognizer.predict(gray_img[y:y + h, x:x + w])
# 返回id、置信度
name = read_info(id)
if confidence <100:
print(id, name)
else:
print('识别度较低')
name = '识别度较低'
image = cv.resize(image, (300, 400)) # 限定展示照片的大小
cv.imshow('result', image)
if not isVideo:
cv.waitKey(0)

#recognize.py =>  image_face_recognize(recognize_image_path)

def image_face_recognize(recognize_image_path): # 传入需要识别的照片都总路径
lists = [os.path.join(recognize_image_path, title) for title in os.listdir(recognize_image_path)]
# 将路径下所有照片的具体路径存入lists列表
for item in lists:
image = cv.imread(item) # 读取图片
face_recognize(image, False) # 调用识别函数
cv.destroyAllWindows()

#recognize.py =>  video_face_recognize(video_path)

def video_face_recognize(video_path): # 传入视频路径
lists = [os.path.join(video_path, title) for title in os.listdir(video_path)]
print(lists)
for item in lists:
print(item)
capture = cv.VideoCapture(item) # 打开视频
while True:
flag, frame = capture.read() # 读取视频每一帧
if not flag:
break
face_recognize(frame, True) # 传入该帧图片
if ord('q') == cv.waitKey(10):
break


总结

目前人脸识别我只采用 'haarcascade_frontalface_default.xml' 模块,如果需要更高的精度可以结合更多的模块一起进行处理和识别。同时,增加模型训练中一组照片的数量也能在一定程度上提高人脸识别精度。


推荐阅读
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 这篇文章主要介绍了Python拼接字符串的七种方式,包括使用%、format()、join()、f-string等方法。每种方法都有其特点和限制,通过本文的介绍可以帮助读者更好地理解和运用字符串拼接的技巧。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • Python的参数解析argparse模块的学习
    本文介绍了Python中参数解析的重要模块argparse的学习内容。包括位置参数和可选参数的定义和使用方式,以及add_argument()函数的详细参数关键字解释。同时还介绍了命令行参数的操作和可接受数量的设置,其中包括整数类型的参数。通过学习本文内容,可以更好地理解和使用argparse模块进行参数解析。 ... [详细]
  • 本文整理了Java中org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc.getTypeInfo()方法的一些代码示例,展 ... [详细]
  • mapreduce源码分析总结
    这篇文章总结的非常到位,故而转之一MapReduce概述MapReduce是一个用于大规模数据处理的分布式计算模型,它最初是由Google工程师设计并实现的ÿ ... [详细]
author-avatar
兜兜岁月真伟大
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有