前言
在计算机视觉领域,人脸检测 和微笑检测是最基础、最经典的入门实战项目。OpenCV 提供了训练好的 Haar 级联分类器,无需复杂算法,几行代码就能快速实现人脸、微笑的识别与标注。
本文将手把手带你实现:
- 静态图片人脸识别:检测图片中的人脸并框选标注
- 视频人脸 + 微笑检测:逐帧识别视频中的人脸,并精准检测微笑区域
一、环境准备
Haar 级联分类器文件.xml在安装 OpenCV 时会自动下载,路径根据自己 Python 安装位置修改**,**可以通过以下代码查找到分类器.xml文件。
python
import cv2
print(cv2.__file__)


二、实战一:静态图片人脸识别
功能说明
读取本地图片,自动检测图片中的所有人脸,用矩形框标注,并输出人脸数量和位置坐标。
完整代码
python
import cv2
image = cv2.imread('hezhao.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 路径替换为你本地的xml文件路径
faceCascade = cv2.CascadeClassifier(r'C:\Users\86152\AppData\Local\Programs\Python\Python311\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3, minSize=(80, 80))
# 输出检测结果
print("发现{0}张人脸!".format(len(faces)))
print("人脸位置坐标(x,y,w,h):", faces)
for (x, y, w, h) in faces:
# 绘制绿色矩形框,thickness为边框粗细
cv2.rectangle(image, pt1=(x, y), pt2=(x + w, y + h), color=(0, 255, 0), thickness=2)
# 显示结果图
cv2.imshow("result", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果展示

三、实战二:视频文件人脸 + 微笑检测
功能说明
读取本地视频文件,逐帧处理 :先检测人脸,再在人脸区域内检测微笑,用不同颜色框标注,并显示 smile 文字提示,按 ESC 键退出。
完整代码
python
import cv2
# 加载人脸+微笑检测分类器
faceCascade = cv2.CascadeClassifier(r'C:\Users\86152\AppData\Local\Programs\Python\Python311\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
smileCascade = cv2.CascadeClassifier(r'C:\Users\86152\AppData\Local\Programs\Python\Python311\Lib\site-packages\cv2\data\haarcascade_smile.xml')
# 读取视频文件(替换为你的视频路径)
cap = cv2.VideoCapture('人脸.mp4')
while True:
# 逐帧读取视频
ret, image = cap.read()
# 视频读取完毕/失败,退出循环
if not ret:
break
# 水平镜像翻转(可选,适配摄像头视角)
image = cv2.flip(image, flipCode=1)
# 转灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 第一步:检测人脸
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=15, minSize=(5, 5))
# 遍历检测到的每一张人脸
for (x, y, w, h) in faces:
# 绘制绿色人脸框
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 截取人脸区域(仅在人脸上检测微笑,提升准确率)
roi_gray = gray[y:y + h, x:x + w]
# 第二步:人脸区域内检测微笑
smiles = smileCascade.detectMultiScale(roi_gray, scaleFactor=1.5, minNeighbors=33, minSize=(25, 25))
# 遍历检测到的微笑区域
for (sx, sy, sw, sh) in smiles:
# 绘制蓝色微笑框
cv2.rectangle(image, (x+sx, y+sy), (x+sx+sw, y+sy+sh), (255, 0, 0), 2)
# 标注微笑文字
cv2.putText(image, "smile", (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)
# 显示实时检测画面
cv2.imshow("result", image)
# 按ESC键退出(ASCII码27)
if cv2.waitKey(25) & 0xFF == 27:
break
# 释放视频资源,关闭窗口
cap.release()
cv2.destroyAllWindows()
代码详解
python
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=15, minSize=(5, 5))
在整幅灰度图中检测所有人脸。
返回值 faces 是一个列表,包含所有人脸的坐标:[[x,y,w,h], ...]
scaleFactor:扫描窗口缩放比例
minNeighbors:值越大,检测越准(减少误检)
minSize:最小人脸尺寸
python
smiles = smileCascade.detectMultiScale(roi_gray, scaleFactor=1.5, minNeighbors=33, minSize=(25, 25))
在人脸区域内检测微笑。
返回微笑区域坐标 (sx,sy,sw,sh)。
python
for (sx, sy, sw, sh) in smiles:
cv2.rectangle(image, (x+sx, y+sy), (x+sx+sw, y+sy+sh), (255, 0, 0), 2)
cv2.putText(image, "smile", (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255,255), 2)
用蓝色框标出嘴巴微笑区域。
显示黄色文字 smile,位置在人脸框上方,不遮挡画面。
坐标必须加上人脸的 x、y,否则位置会错乱。
结果展示
