通过对博文:《OpenCv视觉之眼》Python图像处理十八:Opencv图像处理实战三之基于OpenCV训练模型的AI人脸检测内容的复现(链接:https://blog.csdn.net/qq_42451251/article/details/108096629),对实现的过程进行重新梳理、记录。方便大家尝试实现,也方便自己查阅。
目录
2、cv2.CascadeClassifier分类器函数介绍
一、OpenCV人脸检测基础介绍
下面讲解到的函数都是我们通过OpenCV实现人脸检测将要用到的函数,接下来将会对每个函数的作用及功能进行讲解,最终实现对图片人脸的检测!
1、运行环境介绍
- windows7 X64
- Python版本:python-3.8.3(pip更新为21.0.1版本) 提示:尽量用较新的版本,搭建环境的成功率更高。
- opencv-python版本:opencv-python-4.5.1.48
- 辅助图表显示matplotlib版本:matplotlib 3.3.4
- IDE环境:jupyter-notebook
可参考博文:https://blog.csdn.net/qq_42451251/article/details/107706794
2、OpenCV人脸检测模型介绍
1)、OpenCV人脸检测模型即haarcascade_frontalface_default.xml模型文件,该模型是OpenCV官方训练好的人脸正脸检测模型,是OpenCV正面人脸检测级联分类器训练结果,在通过OpenCV对图像中的人脸键检测时,我们必须要用到该模型,至于该模型的训练,本次博客将暂时不做讲解,后面会讲到该模型是如何通过OpenCV分类器进行训练的
2)、本次博客的图像人脸检测利用cv2.CascadeClassifier级联分类器的haarcascade_frontalface_default.xml进行正脸人脸预测,我们可以看到介绍,是专注于正脸检测,因此,该模型的缺点就是只能对人脸正脸进行检测,优点是人脸正脸检测速度快,准确率高
3)、haarcascade_frontalface_default.xml模型位置
haarcascade_frontalface_default.xml模型在下载opencv-python的时候,会自动下载该模型,我们只需要找到python的安装路径,在安装路径下找到pip下载的库存放的位置,就可以找到该模型,如下:
2、cv2.CascadeClassifier分类器函数介绍
1)、函数原型:result=cv2.CascadeClassifier(‘haarcascade_frontalface_default.xml’)
haarcascade_frontalface_default.xml:OpenCV官方正脸人脸检测模型
2)、该函数是OpenCV中人脸检测的一个级联分类器,既可以使用Haar,也可以使用LBP特征。以Haar特征分类器为基础的对象检测技术是一种非常有效的技术。它是基于机器学习且使用大量的正负样本训练得到分类器。
Haar-like矩形特征:是用于物体检测的数字图像特征。这类矩形特征模板由两个或多个全等的黑白矩形相邻组合而成,而矩形特征值是白色矩形的灰度值的和减去黑色矩形的灰度值的和,矩形特征对一些简单的图形结构,如线段、边缘比较敏感。如果把这样的矩形放在一个非人脸区域,那么计算出的特征值应该和人脸特征值不一样,所以这些矩形就是为了把人脸特征量化,以区分人脸和非人脸
LBP:是一种特征提取方式,能提取出图像的局部的纹理特征,最开始的LBP算子是在3X3窗口中,取中心像素的像素值为阀值,与其周围八个像素点的像素值比较,若像素点的像素值大于阀值,则此像素点被标记为1,否则标记为0。这样就能得到一个八位二进制的码,转换为十进制即LBP码,于是得到了这个窗口的LBP值,用这个值来反映这个窗口内的纹理信息
3、detectMultiScale()人脸检测算法介绍
1)、函数原型:result1=result.detectMultiScale(image,scaleFactor,minNeighbors,minSize,minSize)
result:联级分类器得到的结果
image:需要键人脸检测的图像
result1:检测到的人脸目标序列
scaleFactor:图像尺寸减小的比例
minNeighbors:每一个目标至少要被检测的次数,知道检测到这么多次才算是真的目标,因为周围的像素和不同的窗口大小都可以检测到人脸
minSize:目标的最小尺寸(选填)
minSize:目标的最大尺寸(选填)
detectMultiScale()是检测人脸算法,通过该函数实现OpenCV对图像中正人脸的检测
4、cv2.rectangle()绘制矩形人脸框
函数原型: cv2.rectangle(image, start_point, end_point, color, thickness)
image:需要进行矩形框绘制的图像
start_point:矩形的起始坐标。坐标表示为两个值的元组,即(X坐标值,Y坐标值)
end_point:矩形的结束坐标。坐标表示为两个值的元组,即(X坐标值,Y坐标值)。
color:绘制的矩形的边界线的颜色。对于BGR,我们通过一个元组。例如:(255,0,0)为蓝色
thickness:矩形边框线的粗细像素。厚度-1像素将以指定的颜色填充矩形形状
通过该函数对检测出来的人脸进行标注,标注的方式为方框。下面将会讲到另一种标注方式(圆圈)这两种标注方式选择其中一种就OK,有关更多的OpenCV图像绘图函数,请参考如下博客连接:python-opencv绘图函数
5、cv2.circle()绘制圆圈人脸框
函数原型:cv2.circle(img,center,radius,color,thickness)
img:需要进行圆圈绘制的图像
center:圆心,即(X坐标值,Y坐标值)
radius:半径
color:绘制的圆圈的边界线的颜色。对于BGR,我们通过一个元组。例如:(255,0,0)为蓝色
thickness:矩形边框线的粗细像素。厚度-1像素将以指定的颜色填充矩形形状
该函数为圆圈标注函数,在图像中通过圆圈的方式在原图像上绘制出检测出来的人脸,同样的,按照自己的需求与方框绘制函数进行选择
二、OpenCV人脸检测
在进行人脸检测的开始,我们需要注意的是,人脸检测与人脸识别是有区别的,人间检测只是将图像中的人检测出来,然后将人脸进行标注;而人脸识别除了需要将图像中的人脸检测出来,还需要识别出该图像中对应的人脸是谁,同时也标注出来,这是区别,本次博客主要讲解人脸检测,对于人脸识别将在后面博客章节进行讲解,记得关注订阅哦!
1、OpenCV实现人脸检测步骤
1)、导入OpenCV函数库并读取人脸图像及显示查看
#导入函数库
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
# 读取原始图像
img = cv2.imread("D:/test1.jpg",1)
#显示图像方法1
cv2.imshow("test",img)
#显示图像方法2
#BGR转换为RGB显示格式
img1= cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img1)
#等待键值关闭
#cv2.waitKey(0)
2)、构建联级分类器
#构建联级分类器
face_detect = cv2.CascadeClassifier("C:/Programs/Python/Python3/CPython/x64/Python38/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml")
注意联级分类器中模型的在python路径中的位置
3)、通过联级分类器的结果进行人脸检测,设置至少检测5次才算检测人脸成功
# 检查人脸 按照1.1倍放到 周围最小像素为5
face = face_detect.detectMultiScale(img, scaleFactor=1.1, minNeighbors=5)
检测到的结果face包括检测到人脸的宽和高,人脸的起始位置,以图像左上角为起点,向右为x,向左为y
4)、将检测到的人脸绘制到原图,方框或者圆圈二选一
OpenCV的图像格式都是[B、G、R]格式的,也就是[蓝、绿、红],在进行矩形或者圆框设置的时候请注意
for x, y, w, h in face:
# 绘制绿色矩形人脸区域 thickness表示线的粗细
cv2.rectangle(img, pt1=(x, y), pt2=(x+w, y+h),color=[0,255,0], thickness=2)
# 绘制红色圆形人脸区域 radius表示半径
#cv2.circle(img, center=(x+w//2, y+h//2), radius=w//2, color=[0,255,0], thickness=2)
5)、显示检测出来的人脸
# 显示图片
cv2.imshow("faceDetection", img)
# 等待显示 设置任意键退出程序
cv2.waitKey(0)
2、图像人脸检测完整代码
1)、OpenCV图像人脸检测完整代码
###################################
##### OpenCV图像人脸检测 #####
###################################
#导入函数库
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
# 读取原始图像
img = cv2.imread("D:/test1.jpg",1)
#显示图像
cv2.imshow("test",img)
#BGR转换为RGB显示格式
#img1= cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
#plt.imshow(img1)
#构建联级分类器
face_detect = cv2.CascadeClassifier("C:/Programs/Python/Python3/CPython/x64/Python38/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml")
# 检查人脸 按照1.1倍放到 周围最小像素为5
face = face_detect.detectMultiScale(img, scaleFactor=1.1, minNeighbors=5)
for x, y, w, h in face:
# 绘制绿色矩形人脸区域 thickness表示线的粗细
cv2.rectangle(img, pt1=(x, y), pt2=(x+w, y+h),color=[0,255,0], thickness=2)
# 绘制红色圆形人脸区域 radius表示半径
#cv2.circle(img, center=(x+w//2, y+h//2), radius=w//2, color=[0,255,0], thickness=2)
# 显示图片
cv2.imshow("faceDetection", img)
# 等待显示 设置任意键退出程序
cv2.waitKey(0)
2)、检测结果
- 单人检测结果
- 多人检测结果
3)、在博客开始的时候说到,haarcascade_frontalface_default.xml模型针对的是正脸的检测,对侧脸测试效果较差,感兴趣的可以自己测试一下。
3、视频人脸检测完整代码
1)、视频人脸检测完整代码
###################################
##### OpenCV视频人脸检测 #####
###################################
#导入函数库
import cv2
import numpy as np
# 加载视频
video_path ="D:/video2.mp4"
cap = cv2.VideoCapture(video_path)
#构建联级分类器
face_detect = cv2.CascadeClassifier("C:/Programs/Python/Python3/CPython/x64/Python38/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml")
while True:
# 读取视频片段
flag, frame = cap.read()
#判断视频是否读取完
if flag == False:
break
# 对每一帧图像进行灰度处理
gray = cv2.cvtColor(frame, code=cv2.COLOR_BGR2GRAY)
# 检查人脸 按照1.1倍放到 周围最小像素为5
face = face_detect.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=9)
# 绘制矩形和圆形检测人脸
for x, y, w, h in face:
# 绘制绿色矩形人脸区域 thickness表示线的粗细
cv2.rectangle(frame, pt1=(x, y), pt2=(x+w, y+h),color=[0,255,0], thickness=2)
# 绘制红色圆形人脸区域 radius表示半径
#cv2.circle(img, center=(x+w//2, y+h//2), radius=w//2, color=[0,255,0], thickness=2)
# 显示图片
cv2.imshow('video-faceDetection',frame)
# 设置q退出键和展示频率
if ord('q') == cv2.waitKey(2):
break
# 释放窗口和摄像头
cv2.destroyAllWindows()
cap.release()
2)、视频人脸检测结果
4、摄像头人脸检测完整代码
摄像头人脸检测和视频人脸检测的代码基本一致,唯一区别就是将读取的视频改为读取笔记本默认摄像头,如下
1)、摄像头人脸检测完整代码
#######################################
##### OpenCV摄像头视频人脸检测 #####
#######################################
#导入函数库
import cv2
import numpy as np
# 参数0为加载默认摄像头
cap = cv2.VideoCapture(0)
#构建联级分类器
face_detect = cv2.CascadeClassifier("C:/Programs/Python/Python3/CPython/x64/Python38/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml")
while True:
# 读取视频片段
flag, frame = cap.read()
#判断视频是否读取完
if flag == False:
break
# 对每一帧图像进行灰度处理
gray = cv2.cvtColor(frame, code=cv2.COLOR_BGR2GRAY)
# 检查人脸 按照1.1倍放到 周围最小像素为5
face = face_detect.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
# 绘制矩形和圆形检测人脸
for x, y, w, h in face:
# 绘制绿色矩形人脸区域 thickness表示线的粗细
cv2.rectangle(frame, pt1=(x, y), pt2=(x+w, y+h),color=[0,255,0], thickness=2)
# 绘制红色圆形人脸区域 radius表示半径
#cv2.circle(img, center=(x+w//2, y+h//2), radius=w//2, color=[0,255,0], thickness=2)
# 显示图片
cv2.imshow('video-faceDetection',frame)
# 设置q退出键和展示频率
if ord('q') == cv2.waitKey(2):
break
# 释放窗口和摄像头
cv2.destroyAllWindows()
cap.release()