OpenCv人脸与笑容检测
·
一、OpenCv人脸与笑容检测
import cv2 as cv
import matplotlib.pyplot as plt
import os
print("=== 开始人脸和笑容检测 ===")
# 1. 读取图片
img = cv.imread("zrn.jpg")
if img is None:
print("错误:无法读取 zrn.jpg 文件")
print("当前目录文件:", os.listdir('.'))
exit()
# 转换为灰度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
print("图片读取成功")
# 2. 加载分类器
face_cas = cv.CascadeClassifier(cv.data.haarcascades + 'haarcascade_frontalface_default.xml')
smile_cas = cv.CascadeClassifier(cv.data.haarcascades + 'haarcascade_smile.xml')
# 检查分类器是否加载成功
if face_cas.empty():
print("错误:人脸分类器加载失败")
exit()
if smile_cas.empty():
print("错误:笑容分类器加载失败")
exit()
print("分类器加载成功")
# 3. 检测人脸
faceRects = face_cas.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30)
)
print(f"检测到 {len(faceRects)} 张人脸")
for (x, y, w, h) in faceRects:
# 框出人脸 - 绿色矩形
cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 3)
cv.putText(img, 'Face', (x, y - 10), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
# 在人脸区域检测笑容
roi_gray = gray[y:y + h, x:x + w]
roi_color = img[y:y + h, x:x + w]
# 笑容检测参数需要更宽松一些
smiles = smile_cas.detectMultiScale(
roi_gray,
scaleFactor=1.8, # 笑容检测需要更大的缩放因子
minNeighbors=20, # 需要更多的邻居确认
minSize=(25, 25) # 笑容的最小尺寸
)
# 绘制笑容区域 - 红色矩形
for (sx, sy, sw, sh) in smiles:
cv.rectangle(roi_color, (sx, sy), (sx + sw, sy + sh), (0, 0, 255), 2)
cv.putText(roi_color, 'Smile', (sx, sy - 5), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
print(f"检测到笑容在位置: ({sx}, {sy})")
# 4. 显示结果
plt.figure(figsize=(10, 8))
plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
plt.title(f'人脸和笑容检测 - 找到 {len(faceRects)} 张人脸')
plt.axis('off')
plt.tight_layout()
plt.show()
# 保存结果
cv.imwrite('face_smile_result.jpg', img)
print("结果已保存为 'face_smile_result.jpg'")

这里的问题还是会误判人脸。下面是设计的知识点:
1.1图像读取与显示
import cv2 as cv
import matplotlib.pyplot as plt
# 图像读取
img = cv.imread("zrn.jpg")
# 图像显示(使用matplotlib)
plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
plt.show()
cv.imread(): 读取图像文件,返回numpy数组支持多种格式:JPG、PNG、BMP等
OpenCV使用BGR色彩空间,matplotlib使用RGB,需要转换
1.2色彩空间转换
# BGR转灰度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# BGR转RGB(用于matplotlib显示)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
cv.cvtColor(): 色彩空间转换函数常用转换:BGR2GRAY、BGR2RGB、BGR2HSV
灰度图减少计算复杂度,提高检测速度
二、Haar级联分类器
Haar级联分类器是一种基于机器学习的目标检测方法。
2.1分类器加载与初始化
# 加载预训练的分类器
face_cas = cv.CascadeClassifier(cv.data.haarcascades + 'haarcascade_frontalface_default.xml')
smile_cas = cv.CascadeClassifier(cv.data.haarcascades + 'haarcascade_smile.xml')
# 检查分类器是否加载成功
if face_cas.empty():
print("分类器加载失败")
CascadeClassifier: Haar特征级联分类器OpenCV提供多种预训练模型:人脸、眼睛、笑容、身体等
cv.data.haarcascades: OpenCV内置分类器路径
2.2目标检测详解
faces = face_cas.detectMultiScale(
gray, # 输入灰度图像
scaleFactor=1.1, # 图像缩放比例
minNeighbors=5, # 检测框最小邻居数
minSize=(30, 30) # 目标最小尺寸
)
scaleFactor=1.1: 每次图像缩放10%,值越小检测越精确但速度越慢
minNeighbors=5: 候选框需要5个邻居才能确认,值越大检测越严格
minSize=(30,30): 忽略小于30x30像素的检测
三.图像处理与标注
3.1绘制几何图形
# 绘制矩形框
cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 3)
# 添加文本标注
cv.putText(img, 'Face', (x, y-10), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
(x, y): 矩形左上角坐标
(x+w, y+h): 矩形右下角坐标
(0, 255, 0): BGR颜色值(绿色)
3: 线条粗细
cv.FONT_HERSHEY_SIMPLEX: 字体类型
3.2 ROI(Region of Interest)区域处理
# 提取人脸区域
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
# 在ROI区域内进行笑容检测
smiles = smile_cas.detectMultiScale(roi_gray, 1.8, 20, minSize=(25, 25))
ROI操作提高检测效率和准确性
numpy数组切片语法提取特定区域
分层检测:先检测大人脸,再在脸内检测小特征
下周开始学习yolo的原理以及初步搭建项目结构。
更多推荐


所有评论(0)