当前位置:   article > 正文

基于OpenCV的人脸识别(1)_opencv是一个人脸识别模块吗

opencv是一个人脸识别模块吗

OpenCV简介

OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起的并参与开发的,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可以用于开发实时的图像处理、计算机视觉以及模式识别程序。该程序库也可以还有英特尔公司的IPP进行加速。

OpenCV用C++编写,它的主要接口也是C++语言,但依然保留了大量C语言接口。该库也有大量的Python、Java和MATLAB/OCTAVE的接口。

cv2.imread()

用于读取各种图片文件的函数,如jpg、png、bmp等,并将图像数据加载到一个numpy.ndarray中,以便进一步的图像处理操作。

参数:
    ●    filename:要读取的图像文件的路径,路径中不能有中文,否则数据读取不出来。
    ●    flags:可选参数,用于指定读取图像的方式。常用的标志有:
          cv2.IMREAD_COLOR:以彩色模式加载图像,默认使用该标志。
          cv2.IMREAD_GRAYSCALE:以灰度模式加载图像。
          cv2.IMREAD_UNCHANGED:以原始模式加载图像,不进行任何转换。

cv2.imwrite()

用于将图像数据写入图片文件的函数。它可以用于保存各种图像格式,将图像存到一个新的python文件中如 jpg、png、bmp等。
以下是 cv2.imwrite() 函数的语法:
cv2.imwrite(filename, image, params={})
其中:
    ●    filename:要写入的图像文件的路径。
    ●    image:要写入的图像数据,可以是一个 numpy.ndarray 或 cv2.Mat 对象。
    ●    params:可选参数,用于指定图像的一些属性,如质量、编码格式等。

图片灰度转化

OpenCV中有数百中关于在不同色彩空间之间的转换方法,当然,在计算机视觉中有三种常用的色彩空间:灰度、BGR、以及HSV(Hve、Saturation、Value)。

(1)灰度色彩空间是通过去除色彩信息来将其转换成灰阶,灰度色彩空间对中间处理特别有效,比如人脸识别。

(2)BGR即蓝、绿、红色彩空间,每一个像素点都是由一个三元数组来表示,分别代表蓝、绿、红三种颜色,还有RGB(颜色顺序的不同)。

(3)HSV(Hve色调、Saturation饱和度、Value黑暗的程度)

灰度转换的作用:转换为灰度的图片的计算强度得以降低,便于计算机计算和识别。

修改图片尺寸

cv2.resize()

OpenCV 库中用于对图像进行缩放的函数。它可以对图像进行任意比例的缩放,包括放大和缩小。
以下是 cv2.resize() 函数的语法:

cv2.resize(src, dsize[x, y]/(x, y), fx=None, fy=None, interpolation=cv2.INTER_LINEAR])

其中:
    ●    src:要进行缩放的图像,可以是一个 numpy.ndarray 或 cv2.Mat 对象。
    ●    dsize:目标图像的大小,可以是一个元组或列表,表示图像的宽度和高度。
    ●    fx和fy:可选参数,表示在水平和垂直方向上的缩放因子。如果设置了这两个参数,则图像将按照指定的比例进行缩放。
    ●    interpolation:可选参数,表示图像的插值方法。常用的插值方法有:
          cv2.INTER_NEAREST:最近邻插值,图像的像素值直接取缩放后对应位置的像素值。
          cv2.INTER_LINEAR:线性插值,通过计算周围像素的加权平均值来确定缩放后的像素值。
          cv2.INTER_CUBIC:三次样条插值,通过三次函数来平滑地插值。
          cv2.INTER_AREA:面积插值,通过计算缩放后图像的面积与原始图像的面积之比来确定像素值。
          cv2.INTER_LANCZOS4:Lanczos 插值,通过对周围像素进行加权平均,并使用 Lanczos 滤波器来平滑插值。

画图

OpenCV的强大之处的一个体现就是其可以对图片进行任意编辑、处理。

功能函数如:cv2.circle()、cv2.rectangle()   (函数的详细介绍在其他博文中,这里不多赘述)

人脸检测

提取出图像的细节对产生稳定分析结果和追踪结果很有用。这些提取的结果被称为特征,专业表述为:从图像数据中提取特征。虽然任意像素都可能影响多个特征,但特征应该比像素少得多。两个图像的相似程度可以通过它们对应特征的欧氏距离来度量。

Haar特征是一种用于实现实时人脸跟踪的特征。每一个Haar特征都描述了相邻图像区域的对比模式。例如:边、顶点和细线都能生成具有判别行的特征。

需前往 http:/opencv.org 下载opencv

检测一张人脸、检查多张人脸:

  1. import cv2
  2. def face_detect_demo():
  3. # 将图片转换为灰度
  4. img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  5. #opencv中的功能函数,可识别出图片中的人脸
  6. face_detector = cv2.CascadeClassifier('C:/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
  7. # 获取检测到的人脸对应的坐标、宽度和高度
  8. faces = face_detector.detectMultiScale(img1)
  9. for x, y, w, h in faces:
  10. cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), thickness=2)
  11. cv2.imshow('Video', img)
  12. img = cv2.imread('D:/project1/shuaige.jpg')
  13. face_detect_demo()
  14. cv2.imshow('Video', img)
  15. # 释放内存
  16. cv2.destroyAllWindows()

视频中的人脸检测:

视频是由一张一张图片组成,通过不断重复检测过程就能完成视频中人脸检测。

  1. import cv2
  2. def face_detect_dome(img):
  3. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  4. face_detector = cv2.CascadeClassifier('C:/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
  5. # 获取检测到的人脸对应的坐标、宽度和高度
  6. faces = face_detector.detectMultiScale(gray)
  7. for x, y, w, h in faces:
  8. cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), thickness=2)
  9. cv2.imshow('Video', img)
  10. cap = cv2.VideoCapture(0)
  11. while True:
  12. flag, frame = cap.read()
  13. cap1 = cv2.flip(frame, 1)
  14. if not flag:
  15. break
  16. face_detect_dome(cap1)
  17. if ord('q') == cv2.waitKey(10):
  18. break
  19. cap.release()
  20. # 释放内存
  21. cv2.destroyAllWindows()

人脸识别

人脸检测是人脸识别的基础,所谓人脸识别,其实就是一个程序能识别给定图像或视频中的人脸。实现这一目标的方法之一是用一系列分好类的图像来“训练”程序,并基于这些图像来识别。

人脸识别模块的另外一个重要特征是:每个识别都具有转置信(confidence)评分,因此可在实际应用中通过对其设置的阈值来进行筛选。

首先需安装opencv-contrib-python包

训练数据

有了数据,需要将这些样本图像加载到人脸识别算法中。所有人脸识别算法在它们的train()函数中都有两个参数:图像数组和标签数组。这些标签标识进行识别时某人人脸的ID,因此根据ID就可以知道被识别的人是谁。

  1. import cv2
  2. import os
  3. from PIL import Image
  4. import numpy as np
  5. def getImageAndLabels(path):
  6. # 保存人脸数据,二维列表
  7. facesSamples = []
  8. # 储存姓名
  9. ids = []
  10. # os.path.join(path, f)把图片的路径和名称放到一起
  11. # os.listdir获得的是path路径下的文件
  12. imagePaths = [os.path.join(path, f)for f in os.listdir(path)]
  13. # 加载分分类器
  14. face_detector = cv2.CascadeClassifier('C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')
  15. # 遍历列表中的图像
  16. for imagePath in imagePaths:
  17. # 打开图片
  18. PIL_img = Image.open(imagePath).convert('L')
  19. # 将图像转化成列表,将图片向量化,将图片的每个像素点变成一个数值,让计算机能看懂
  20. img_numpy = np.array(PIL_img, 'uint8')
  21. # 获取人脸特征——检测到的人脸对应的坐标、宽度和高度
  22. faces = face_detector.detectMultiScale(img_numpy)
  23. # 获取每张图片的ID
  24. # 它使用os.path.split(imagePath)[1]获取不含目录的文件路径
  25. # 使用split('.')[0]来分割文件名和扩展名,并获取文件名
  26. # 将字符串转换为int
  27. id = int(os.path.split(imagePath)[1].split('.')[0])
  28. # 遍历列表中的图片
  29. for x, y, w, h in faces:
  30. facesSamples.append(img_numpy[y:y+h, x:x+w])
  31. ids.append(id)
  32. print('id:', ids)
  33. print('fs:', facesSamples)
  34. return facesSamples, ids
  35. # 图片路径
  36. path = '../jm/'
  37. # 获取图像、数组和ID
  38. faces, ids = getImageAndLabels(path)
  39. # 加载识别器
  40. recognizer = cv2.face.LBPHFaceRecognizer_create()
  41. # 训练
  42. recognizer.train(faces, np.array(ids))
  43. # 保存文件
  44. recognizer.write('D:/xierushuju/trainer.yml')

做训练数据时,要先在网站或其他地方找到一些人脸图片,把它们放到同一文件中,再用path方法接收该文件路径;写入数据时,也要先再文件中创建一个文件夹,在把文件的地址写入write()函数中

数据训练中涉及函数的功能和库

os库

Python的一个标准库,提供了许多与操作系统交互的功能

使用这个库,你可以进行文件和目录的管理,比如创建、删除、移动等;也可以启动和管理系统中的其他程序;还可以获取关于系统的环境参数,比如环境变量的值、用户信息等。总之,os库让Python程序员能够更方便地与操作系统进行交互,完成各种任务。

PIL库

(Python Imaging Library,也被称为Pillow)是一个用于图像处理的Python库。

它支持多种图像格式,并提供了许多图像处理功能,如缩放、裁剪、旋转、颜色转换等。PIL库被广泛应用于图像处理和计算机视觉领域。

[os.path.join(path, f)for f in os.listdir(path)]

这段代码是 Python 中使用 os.path.join() 和 os.listdir() 函数的循环结构。它的目的是将指定路径 path 下的所有文件名 f 与路径进行拼接,并生成新的路径。
下面分别解释这两个函数的作用:
1.  os.path.join(path, f) : 这是一个 Python 标准库中的函数,用于将路径 path 和文件名 f 进行拼接,生成完整的文件路径。它会根据操作系统的类型(如 Windows 或 Unix/Linux 系统)自动插入适当的路径分隔符。

2.  os.listdir(path) : 这是一个 Python 标准库中的函数,用于返回指定路径 path 下的文件和文件夹列表。它返回一个包含所有文件名和文件夹名的列表。
 
因此,整个循环的作用是将 path 路径下的每个文件名与 path 进行拼接,生成完整的文件路径。

 cv2.CascadeClassifier() 

OpenCV库中用于使用级联分类器进行目标检测的类,通常用于检测人脸、眼睛、车辆等对象。它使用Haar特征分类器LBP特征分类器进行对象检测。
使用cv2.CascadeClassifier()函数时,需要将对象检测器训练好的xml文件加载到程序中,可以使用以下代码进行加载:
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
其中,xml文件是已经训练好的分类器模型,可以在OpenCV的官方文档中找到并下载。然后,使用cv2.CascadeClassifier对象的detectMultiScale函数进行对象检测。这个函数的参数包括输入图像、缩放因子、最小邻域、最大邻域等。
 
函数的参数如下:
 
- xml_file:表示级联分类器的 XML 文件路径。

- scaleFactor:表示图像缩放比例的因数。

- minNeighbors:表示每个候选区域所需的最小邻近数。
 
函数的返回值是一个  cv2.CascadeClassifier  对象,该对象可以用于对图像进行目标检测。

 Image.open().convert()

 Image.open()用于打开图像文件的函数,convert() 函数是 Image 模块的一部分,用于将图像从一种格式转换为另一种格式。它的参数取决于要转换的图像的颜色模式。以下是一些常见的参数和用法:
-  '1' :将图像转换为二值图像,其中每个像素用8位表示,0表示黑,255表示白。

-  'L' :将图像转换为灰度图像,其中每个像素用8位表示,0表示黑,255表示白,其他数字表示不同的灰度。

-  'P' :将图像转换为8位彩色图像,其中每个像素用8位表示,其对应的彩色值是按照调色板查询出来的。

img_numpy = np.array(PIL_img, 'uint8') 

用于将一个  PIL  图像对象转换为  numpy  数组的操作。
具体解释如下:
-  PIL_img  是一个  PIL (Pillow)图像对象,它是 Python 中常用的图像处理库  PIL  中的一种图像表示形式。

-  np.array()  是  numpy  库中的一个函数,用于将输入转换为  numpy  数组。

-  'uint8'  是一个数据类型参数,指定了转换后的数组的元素类型为无符号 8 位整数( uint8 )
 
通过执行这个操作,将  PIL_img  转换为了一个  numpy  数组  img_numpy ,并且指定了数组的元素类型为  uint8 。这样做的目的是为了在后续的图像处理中利用  numpy  的数组操作和计算功能。

cv2.CascadeClassifier.detectMultiScale()

OpenCV 库中用于使用级联分类器进行多尺度对象检测的函数。
它的主要作用是在图像中寻找符合特定特征的对象,并返回它们的位置和尺寸信息。这个函数可以用于多种对象检测任务,如人脸检测、眼睛检测、车辆检测等。
以下是 cv2.CascadeClassifier.detectMultiScale() 函数的一般语法:
cv2.CascadeClassifier.detectMultiScale(image, scaleFactor, minNeighbors)
该函数的参数如下:
 -  image : 待检测的图像,通常为灰度图像。

-  scaleFactor : 表示在前后两次相继的扫描中,搜索窗口的缩放比例。

-  minNeighbors : 表示构成检测目标的相邻矩形的最小个数。默认值为3,表示有3个以上的检测标记存在时,才认为人脸的存在。如果希望提高检测的准确率,可以将该值设置得更大,但同时可能会让一些人脸无法被检测到。

这个函数会在输入图像上进行多尺度的搜索,尝试找到与分类器模型匹配的对象。它会返回一个列表,其中包含每个检测到的对象的坐标、尺寸和置信度。
需要注意的是,在使用 cv2.CascadeClassifier.detectMultiScale() 函数之前,你需要先使用 cv2.CascadeClassifier() 函数加载训练好的级联分类器模型。

级联分类器(Cascade Classifier)

一种用于目标检测的机器学习算法。它由一系列分类器组成,每个分类器都对输入数据进行分类,并将分类结果传递给下一个分类器。级联分类器是一种用来检测目标的机器学习算法。它就像是一个由很多小分类器组成的大部队,每个小分类器负责判断目标的一部分特征,然后把结果传给下一个分类器。这样,一个接一个,就像接力赛一样,最后就能确定目标是不是我们要找的。
这种方法在处理大量数据时特别有效,因为每个分类器只需要关注一小部分数据,所以速度很快。而且,通过多个分类器的合作,可以提高判断的准确性。
但是,级联分类器也有一些缺点。比如,它需要训练很多分类器,所以训练时间可能会比较长。而且,如果数据有噪声或偏差,也可能会影响判断结果的准确性。

 (os.path.split(imagePath)[1].split('.')[0])


1.  os.path.split(imagePath)[1] :使用 os.path.split() 函数将文件路径 imagePath 拆分成目录和文件名两部分。这个函数会返回一个包含这两部分的元组。在这个代码中,通过索引 1 来获取文件名部分。

2.  split('.')[0] :对上一步获取的文件名部分进行进一步的处理。使用 split('.') 函数将文件名按照点号( . )进行拆分,得到一个文件名的各个部分的列表。然后通过索引 0 来获取第一个部分,即文件的主名。
 
综上所述,这段代码的目的是从文件路径中提取出文件的主名。它通过使用 os.path.split() 函数和 split('.') 函数进行路径和文件名的拆分,最终得到文件的主名。

 cv2.face.LBPHFaceRecognizer_create()

OpenCV中的一个函数,用于创建基于局部二值模式直方图(LBPH)的人脸识别器对象。
该函数返回一个 cv2.face_LBPHFaceRecognizer 对象,可以使用该对象的 train() 方法对算法进行训练,使用 predict() 方法进行预测。
LBPH算法的基本原理是:先将人脸图像分为许多小的局部区域,对于每个局部区域将其中像素点A的值与其最邻近的8个像素点的值逐一比较,然后将像素点A与其周围8个像素点比较所得到的0、1值连接起来,得到一个8位的二进制序列,将该二进制序列转换为十进制数作为点A的LBP值,将所有局部区域的特征值组合成一个直方图作为该人脸图像的向量特征,最终完成相似度的计算。该算法通过比较不同的人脸图像LBP编码直方图来实现人脸识别。

由于这种方法的灵活性,LBPH是唯一允许模型本人脸和检测到的人脸在形状、大小上可以不同的人脸识别算法。

cv2.face.LBPHFaceRecognizer_create.train()

OpenCV库中用于训练LBPH(Local Binary Pattern Histogram)人脸识别器的函数。
该函数的作用是基于已有的人脸图像数据,优化LBPH人脸识别器的参数,以提高模型的识别能力。在训练过程中,函数会根据输入的人脸图像数据,计算出每个图像的特征值,并根据这些特征值对模型进行调整和优化。
调用该函数时,需要提供训练数据的图像文件路径列表,以及用于标识训练数据的标签列表。函数返回训练完成的模型,可以用于后续的人脸识别。

人脸识别

  1. import cv2
  2. # 加载训练数据及文件
  3. recognizer = cv2.face.LBPHFaceRecognizer_create()
  4. recognizer.read('D:/xierushuju/trainer.yml')
  5. # 准备识别的图片
  6. img = cv2.imread('D:/project1/14.png')
  7. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  8. face_detector = cv2.CascadeClassifier('C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')
  9. faces = face_detector.detectMultiScale(gray)
  10. for x, y, w, h in faces:
  11. cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
  12. # 人脸识别
  13. id, confidence = recognizer.predict(gray[y:y+h, x:x+w])
  14. print("标签id:",id,'置信评分',confidence)
  15. cv2.imshow('Video',img)
  16. cv2.waitKey(0)
  17. cv2.destroyAllWindows()

predict()

通常在机器学习和深度学习的人脸识别中用于对输入数据进行预测或推断。
其作用是根据已经训练好的模型,对输入的人脸数据进行分类、识别或其他预测任务。

函数返回两个元素的数组:第一个元素是所识别个体的标签,第二个是置信度评分。所有的算法都有一个置信度评分,置信度评分用来衡量所识别的人脸与模型的差距,0表示完全匹配

可能有时不想保留所有的识别结果,则需要进一步处理,因此可以用自己的算法来估计识别的置信度评分。LBPH一个好的识别参考值要低于50,任何高于80的参考值都会被认为是低的置信度评分

根据B站上的人脸识别系统所写,B站中有许多相似教程,本篇只是对教程总结一下,并给出对应函数用法的详细用法解释和本人的拙见。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号