CascadeClassifier
CascadeClassifier
是 OpenCV 提供的一个用于对象检测的类,它基于Haar特征和AdaBoost算法。它能够识别图像中的特定对象,比如人脸、眼睛、微笑等。CascadeClassifier
需要一个预训练的XML分类器文件,该文件包含了用于检测对象的特征。
CascadeClassifier 的工作流程
- 特征选择:从大量的 Haar 特征中选择最有区分力的特征。这些特征能够最好地区分对象和背景。
- 训练 AdaBoost 分类器:使用选定的 Haar 特征训练 AdaBoost 分类器。这个过程会生成一系列弱分类器,每个弱分类器都基于一个 Haar 特征。
- 构建级联分类器:将训练好的 AdaBoost 分类器组织成一个级联结构。级联分类器由多个阶段组成,每个阶段包含多个弱分类器。图像首先通过第一阶段的所有弱分类器,如果通过,则进入第二阶段,以此类推。
- 检测对象:在新的图像中检测对象时,图像会依次通过级联分类器的每个阶段。如果图像在某个阶段被拒绝,则检测过程结束。如果图像通过了所有阶段,则认为图像中存在目标对象。
detectMultiScale
detectMultiScale
是 CascadeClassifier
类的一个方法,用于在给定的图像中检测对象。这个方法会返回一个对象列表,每个对象由其在图像中的矩形框坐标表示。这个方法能够处理不同大小的对象,因为它可以在多个尺度上进行检测
1. 滑动窗口(Sliding Window)机制
detectMultiScale
方法使用滑动窗口机制来扫描整个图像。窗口在图像上从左到右、从上到下移动,每次移动一定的步长(不是像素步长,而是窗口步长)。在每个窗口位置,分类器都会被用来评估该区域是否包含目标对象。
2. 多尺度检测
为了检测不同大小的对象,detectMultiScale
方法会对图像进行多次扫描,每次扫描使用不同的窗口尺寸。这是通过调整图像的尺度来实现的,即图像被多次缩放,每次缩放后都进行滑动窗口检测。scaleFactor
参数控制每次缩放时图像尺寸的减小比例。
3. Haar 特征和分类器评估
在每个窗口位置,分类器会评估该窗口内是否包含目标对象。分类器是基于 Haar 特征的,这些特征是从图像的小块区域计算出来的。分类器使用这些特征来评估窗口内的目标对象。
4. 级联分类器
detectMultiScale
方法使用的分类器是一个级联分类器,它由多个阶段组成。每个阶段包含多个基于 Haar 特征的弱分类器。级联分类器的工作方式如下:
- 第一阶段:快速排除大部分背景区域。如果一个窗口通过了第一阶段的所有弱分类器,它被认为是一个候选区域,进入第二阶段。
- 后续阶段:更详细地评估候选区域。每个阶段都试图更准确地评估窗口是否包含目标对象。
- 最终阶段:如果一个窗口通过了所有阶段的分类器,它被认为是一个真正的目标对象。
5. 非极大值抑制(Non-Maximum Suppression)
在检测过程中,可能会在同一个对象上得到多个重叠的候选区域。为了解决这个问题,detectMultiScale
方法使用非极大值抑制。这个步骤会保留最佳的候选区域,并去除那些与最佳区域重叠且置信度较低的区域。
6. 输出结果
detectMultiScale
方法的输出是一个候选区域列表,每个候选区域由其在图像中的矩形框坐标(x, y, width, height)表示。这些坐标定义了检测到的对象的位置和大小。
代码流程
读取图像
import cv2
img=cv2.imread('renlian1.jpg')
图像尺寸调整
def resize(image,width=None,height=None ,inter=cv2.INTER_AREA):
dim=None
(h,w) = image.shape[:2]#获取输入图像的高度和宽度。
if width is None and height is None:#如果宽度和高度都没有指定,则直接返回原始图像。
return image
if width is None:#如果只指定了高度,计算新的宽度以保持图像的宽高比。
r=height/float(h)
dim=(int(w*r),height)
else:#如果只指定了宽度,计算新的高度以保持图像的宽高比。
r=width/float(w)
dim=(width,int(h*r))
#根据计算出的尺寸 dim 调整图像大小。
resized=cv2.resize(image,dim,interpolation=inter) # 默认为cV2.INTER_AREA,即面积插值,适用于缩放图像。
return resized
img=resize(img,1000)
转换图像为灰度图
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
加载Haar特征分类器
加载OpenCV提供的Haar特征分类器XML文件,该文件用于检测图像中的脸部。
faceCase=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
检测图像中的脸部
使用加载的分类器和灰度图像,调用detectMultiScale
函数来检测图像中的脸部。
faces=faceCase.detectMultiScale(gray,scaleFactor=1.05,minNeighbors=9,minSize=(8,8))
绘制矩形框
遍历检测到的脸部,使用cv2.rectangle
函数在每个脸部周围绘制绿色的矩形框。
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('result',img)
cv2.waitKey(0)
运行结果
完整代码
import cv2
img=cv2.imread('renlian1.jpg')
def resize(image,width=None,height=None ,inter=cv2.INTER_AREA):
dim=None
(h,w) = image.shape[:2]#获取输入图像的高度和宽度。
if width is None and height is None:#如果宽度和高度都没有指定,则直接返回原始图像。
return image
if width is None:#如果只指定了高度,计算新的宽度以保持图像的宽高比。
r=height/float(h)
dim=(int(w*r),height)
else:#如果只指定了宽度,计算新的高度以保持图像的宽高比。
r=width/float(w)
dim=(width,int(h*r))
#根据计算出的尺寸 dim 调整图像大小。
resized=cv2.resize(image,dim,interpolation=inter) # 默认为cV2.INTER_AREA,即面积插值,适用于缩放图像。
return resized
img=resize(img,1000)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faceCase=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
faces=faceCase.detectMultiScale(gray,scaleFactor=1.05,minNeighbors=9,minSize=(8,8))
print('数目{}'.format(len(faces)))
print('坐标',faces)
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('result',img)
cv2.waitKey(0)