OpenCV自带的HAAR级联分类器对脸部(人脸、猫脸等)的检测识别

2023-10-13 16:40

本文主要是介绍OpenCV自带的HAAR级联分类器对脸部(人脸、猫脸等)的检测识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在计算机视觉领域,检测人脸等是一种很常见且非常重要的应用,我们可以先通过开放计算机视觉库OpenCV来熟悉这个人脸识别领域。另外OpenCV关于颜色的识别,可以查阅:OpenCV的HSV颜色空间在无人车中颜色识别的应用HSV颜色识别的跟踪实践https://blog.csdn.net/weixin_41896770/article/details/131746841

1、多尺度检测人脸

我们先直接对一张图片中的多个人脸进行检测,看下OpenCV自带的这个级联分类器HAAR对于人脸识别的效果怎么样:

import cv2
import numpy as npimg = cv2.imread('c.png') # (H,W,C)
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# 使用预训练模型创建 Cascade 分类器
getCascade = lambda model_name: cv2.CascadeClassifier(cv2.data.haarcascades + model_name)# 人脸
Cascade = getCascade("haarcascade_profileface.xml")
#Cascade = getCascade("haarcascade_frontalface_alt2.xml")# 多尺度识别人脸
faces = Cascade.detectMultiScale(imgGray,1.2,3)
# 矩形标注(左上角与右下角坐标)
for (x,y,w,h) in faces:cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255) , 2)cv2.imshow("face", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

如图:

虽然位置有偏差,往右移动了一些,边界框没有在中心位置,但是对目标的大概位置还是能够检测到,也就是对于脸部这个对象还是可以正确的被识别到。
其中这个haarcascade_profileface.xml文件是OpenCV自带的人脸分类器,在Windows中的位置如下(我这里是在虚拟环境pygpu中安装的OpenCV视觉库):
envs\pygpu\Lib\site-packages\cv2\data
我们将会在这个目录里面看到,还包含有其他很多的预训练模型,如图:

2、haarcascade分类器

我们知道OpenCV自带的haarcascade分类器还是挺多的,这里的cascade翻译为级联,什么意思呢?
我个人的理解是,这里的提取特征方法还是用到卷积,因为卷积可以检测到边缘,质地纹理等,而一张图里面有很多很多的特征,这个时候我们可以将它们各种尺度缩放来分别提取不同特征并分组,这样一层一层的过滤,当需要检测需要的对象时,只需将不符合的直接丢弃,减少计算,这样就可以加速得到特征。不清楚这种表达是否正确,欢迎指正。
这里的haarcascade分两部分理解,haar先提取特征,然后使用cascade来对特征进行分类。所以haarcascade_profileface.xml这个文件的意思就是提取特征之后,加载人脸分类的一个预训练模型。下划线后面跟随的profileface名称也可以知道,需要进行的分类是人脸。
接下来我们换一个对象,检测猫脸和猫的眼睛,只需要更换对应的模型即可:

2.1、猫脸

我更换为一张包含多只猫的图片,然后加载这个猫脸的预训练模型:

Cascade = getCascade("haarcascade_frontalcatface.xml")

如图:

从检测的图片中,我们可以看到第一只猫没有检测到,其余4只都很好的检测到并做了标注。

2.2、检测眼睛

除了检测脸部之外,还可以检测眼睛,同样的我们更换为眼睛分类模型:

Cascade = getCascade("haarcascade_eye.xml")

如图:

从检测图片中可以看到,除了中间的那只猫,其余的都很好的检测到了眼睛。

3、detectMultiScale

分类器创建好了之后,我们还可以做多尺度检测,先来认识下这个detectMultiScale函数:

help(detectMultiScale)

detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]) -> objects

参数说明:

image:CV_8U类型的矩阵,也就是8位无符号整数[0,255],其余还有16位、32位等有符号整数与浮点数,其中的字母S表示有符号整型,U表示无符号整型,F表示浮点型
scaleFactor:搜索窗口前后大小的比例系数,默认为1.1,也就是每次搜索窗口扩大10%
minNeighbors:指定每个候选矩形应该有多少个邻居的参数
minSize:检测的最小尺寸,小于该值的对象将被忽略
maxSize:检测的最大尺寸,大于该值的对象将被忽略。如果maxSize == minSize模型在单个尺度上进行评估。

对于这种多尺度的检测,还可以在一张图中检测出不同对象并标注,也就是说可以做嵌套: 

faces1 = Cascade1.detectMultiScale(imgGray,1.3,2)
faces2 = Cascade2.detectMultiScale(imgGray,1.5,3)for (x,y,w,h) in faces1:cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255) , 2)for (x,y,w,h) in faces2:cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,255) , 2)

 如下图,就将猫脸和眼睛都检测出来了:

4、摄像头检测

既然对于图片能够识别其中想要检测的对象,那在视频中应该也是没有问题的,我们来看下摄像头检测的效果,由于本人电脑没有摄像头,还是使用无人车上的CSI摄像头来测试下:
测试环境:JupyterLab

from jetbotmini import Camera
from jetbotmini import bgr8_to_jpeg
import traitlets
import ipywidgets.widgets as widgets
from IPython.display import display
import cv2camera = Camera.instance(width=720, height=720)
face_image = widgets.Image(format='jpeg', width=300, height=300)
face = widgets.Image(format='jpeg', width=300, height=300)
display(face_image)
display(face)face_cascade = cv2.CascadeClassifier('haarcascade_profileface.xml')

初始化摄像头与图片显示组件之后,紧接着就是实时地将摄像头接收的数据反馈到Image组件,并检测人脸以及将人脸特写,给显示出来。

while 1:frame = camera.valueframe = cv2.resize(frame, (300, 300))frame_face =frame.copy()gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)faces = face_cascade.detectMultiScale(gray)if len(faces)>0:(face_x, face_y, face_w, face_h) = faces[0]# 将检测到的人脸标记出来cv2.rectangle(frame,(face_x,face_y),(face_x+face_h,face_y+face_w),(0,255,0),2)#cv2.rectangle(frame,(face_x+10,face_y),(face_x+face_w-10,face_y+face_h+20),(0,255,0),2)frame_face = frame_face[face_y:face_y+face_h,face_x:face_x+face_w]frame_face = cv2.resize(frame_face,(300,300))face.value = bgr8_to_jpeg(frame_face)# 实时传回图像数据进行显示face_image.value = bgr8_to_jpeg(frame)

如图:

这里还多出一个显示脸部特写的组件,这里没有截图了,比较简单,用法是一样的,将识别到的脸部显示出来即可。

5、错误处理

如果在前面不使用匿名函数:

getCascade = lambda model_name: cv2.CascadeClassifier(cv2.data.haarcascades + model_name)
Cascade = getCascade("haarcascade_profileface.xml")

处理的话,而使用类似后面摄像头中的写法:

cv2.CascadeClassifier('haarcascade_profileface.xml')

如果报下面的错误:

error: OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\objdetect\src\cascadedetect.cpp:1689: error: (-215:Assertion failed) !empty() in function 'cv::CascadeClassifier::detectMultiScale'

就是缺少这个文件,需要将haarcascade_profileface.xml模型文件拷贝到当前目录即可。

6、小结

在做图片显示的时候,有两种方式,可以是OpenCV自带的imshow方法:

cv2.imshow("face", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

这种显示很简单直观,直接显示cv2.imread读取到的数据即可,另外需要注意的时,显示方法的后面需要waitkey,不然会出现程序不响应。

另外一种方法是在JupyterLab里面显示的情况,比如后面介绍的在摄像头里面的显示,这里需要注意图片的转换: 

face_image = widgets.Image(format='jpeg', width=300, height=300)
display(face_image)
face_image.value = bytes(cv2.imencode('.jpg', img)[1])

这里的widgets.Image组件格式是jpeg格式,所以需要进行编码成jpeg格式之后,再转换成二进制的字节序列赋值给这个图片组件即可。

其中的字节函数bytes里面的取值范围是[0,255],比如

bytes([0,97,98,99,255]) # b'\x00abc\xff'

如果不在这个范围就会报错:

bytes([0,97,98,99,255,256])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: bytes must be in range(0, 256) 

这篇关于OpenCV自带的HAAR级联分类器对脸部(人脸、猫脸等)的检测识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/204539

相关文章

OpenCV在Java中的完整集成指南分享

《OpenCV在Java中的完整集成指南分享》本文详解了在Java中集成OpenCV的方法,涵盖jar包导入、dll配置、JNI路径设置及跨平台兼容性处理,提供了图像处理、特征检测、实时视频分析等应用... 目录1. OpenCV简介与应用领域1.1 OpenCV的诞生与发展1.2 OpenCV的应用领域2

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

Python如何将OpenCV摄像头视频流通过浏览器播放

《Python如何将OpenCV摄像头视频流通过浏览器播放》:本文主要介绍Python如何将OpenCV摄像头视频流通过浏览器播放的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完... 目录方法1:使用Flask + MJPEG流实现代码使用方法优点缺点方法2:使用WebSocket传输视

Python中图片与PDF识别文本(OCR)的全面指南

《Python中图片与PDF识别文本(OCR)的全面指南》在数据爆炸时代,80%的企业数据以非结构化形式存在,其中PDF和图像是最主要的载体,本文将深入探索Python中OCR技术如何将这些数字纸张转... 目录一、OCR技术核心原理二、python图像识别四大工具库1. Pytesseract - 经典O

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.