云计算百科
云计算领域专业知识百科平台

基于OpenCV的人脸微笑检测实现

文章目录

    • 引言
    • 一、技术原理
    • 二、代码实现
      • 2.1 关键代码解析
        • 2.1.1 模型加载
        • 2.1.2 图像翻转
        • 2.1.3 人脸检测 + 微笑检测
      • 2.2 显示效果
    • 三、参数调优建议
    • 四、总结

引言

在计算机视觉领域,人脸检测和表情识别一直是热门的研究方向。今天我将分享一个使用Python和OpenCV实现的实时人脸微笑检测系统。这个系统能够通过摄像头捕捉视频流,实时检测人脸并识别微笑表情,非常适合初学者学习计算机视觉的基础应用。

一、技术原理

本实现主要基于OpenCV提供的Haar级联分类器,使用了两个预训练模型:

  • haarcascade_frontalface_default.xml – 用于人脸检测
  • haarcascade_smile.xml – 用于微笑检测
  • Haar级联分类器是一种基于机器学习的物体检测方法,由Paul Viola和Michael Jones在2001年提出。它通过训练大量正负样本,学习物体的特征模式,从而实现快速检测。

    二、代码实现

    import cv2

    # 加载预训练模型
    faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    smile = cv2.CascadeClassifier("haarcascade_smile.xml")
    cap = cv2.VideoCapture('smile.mp4') #初始化摄像头

    while True: #处理每一帧
    ret,image = cap.read() #读取一帧
    image = cv2.flip(image,1) #图片翻转,水平翻转(镜像)

    # 没有读到,直接退出
    if ret is None:
    break

    # 转换为灰度图像
    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区域(灰度)
    roi_gray_face = gray[y:y+h,x:x+w]
    cv2.imshow('Face ROI',roi_gray_face)

    # 微笑检测,仅在人脸区域内检测
    smiles = smile.detectMultiScale(roi_gray_face,
    scaleFactor=1.5,
    minNeighbors=2,
    minSize=(50,50))

    for (sx,sy,sw,sh) in smiles:
    # 绘制微笑区域
    a = x + sx
    b = y + sy
    cv2.rectangle(image,(a,b),(a+sw,b+sh),(255,0,0),2)
    # 显示"smile"文字
    cv2.putText(image,"smile",(x,y),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,
    (0,255,255),thickness=2)

    # 显示结果
    cv2.imshow("Smile Detection",image)
    key = cv2.waitKey(25)
    if key ==27: # ESC键退出
    break

    # 释放资源
    cap.release()
    cv2.destroyAllWindows()

    2.1 关键代码解析

    2.1.1 模型加载

    faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    smile = cv2.CascadeClassifier("haarcascade_smile.xml")

    这两行代码加载了OpenCV提供的预训练Haar级联分类器模型。


    2.1.2 图像翻转

    image = cv2.flip(image, 1)

  • cv2.flip()函数

    • 作用:翻转输入图像(水平、垂直或同时翻转)。
    • 参数:
      • 第1个参数 image:输入的图像(NumPy数组)。
      • 第2个参数 1:翻转模式的标志。
        • 0:垂直翻转(沿x轴翻转)。
        • 1:水平翻转(沿y轴翻转,即镜像效果)。
        • -1:同时水平和垂直翻转。
  • flipCode=1 的效果 假设原图为:

  • 原图: [A B C] → 翻转后: [C B A]
    [D E F] [F E D]

    • 每一行的元素顺序被反转,但行的顺序不变。

    2.1.3 人脸检测 + 微笑检测

    for (x,y,w,h) in faces:
    cv2.rectangle(image,(x,y),(x + w,y + h),(0,255,0),2)
    # 提取人脸所在区域,多通道形式
    # roiColorFace = image(y:y+h,x:x+w)
    # 提取人脸所在区域,单通道形式
    roi_gray_face = gray[y:y+h,x:x+w]
    cv2.imshow('lian',roi_gray_face)
    # 微笑检测,仅在人脸区域内检测
    smiles = smile.detectMultiScale(roi_gray_face,
    scaleFactor=1.5,
    minNeighbors=2,
    minSize=(50,50))
    for (sx,sy,sw,sh) in smiles:
    # 绘制微笑区域
    a = x + sx
    b = y + sy
    cv2.rectangle(image,(a,b),(a+sw,b+sh),(255,0,0),2)
    # 显示文字“smile” 表示微笑了
    cv2.putText(image,"smile",(x,y),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,
    (0,255,255),thickness=2)

    这段代码是一个 人脸检测 + 微笑检测 的程序,主要使用了 OpenCV 的 Haar 级联分类器(detectMultiScale)来检测人脸和微笑。以下是详细解析:


    代码功能概述

  • 检测人脸(在 faces 中存储的人脸矩形框)。
  • 提取人脸区域(灰度图 roi_gray_face)。
  • 在人脸区域内检测微笑(smiles)。
  • 绘制人脸框和微笑框,并标注文字“smile”。

  • 代码逐行解析

    1. 遍历检测到的人脸

    for (x, y, w, h) in faces:

    • faces 是一个包含人脸矩形框的列表,每个框由 (x, y, w, h) 表示:
      • (x, y):人脸左上角坐标。
      • (w, h):人脸的宽度和高度。

    2. 绘制人脸矩形框

    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

    • 在原始图像 image 上绘制绿色矩形框(RGB (0,255,0)),线宽为 2。

    3. 提取人脸区域(灰度图)

    roi_gray_face = gray[y:y+h, x:x+w]
    cv2.imshow('lian', roi_gray_face)

    • gray 是灰度图像(单通道)。
    • roi_gray_face 是从 gray 中截取的人脸区域。
    • cv2.imshow('lian', roi_gray_face) 显示人脸区域的灰度图(窗口名 'lian')。

    4. 在人脸区域内检测微笑

    smiles = smile.detectMultiScale(
    roi_gray_face,
    scaleFactor=1.5,
    minNeighbors=2,
    minSize=(50, 50)
    )

    • smile 是一个训练好的 Haar 级联分类器(用于微笑检测)。
    • 参数说明:
      • scaleFactor=1.5:每次图像缩放的比例(越大检测越快,但可能漏检)。
      • minNeighbors=2:候选框至少需要多少个邻近检测才被确认(越小误检越多)。
      • minSize=(50, 50):微笑区域的最小尺寸(小于该尺寸的忽略)。

    5. 遍历检测到的微笑区域

    for (sx, sy, sw, sh) in smiles:

    • smiles 包含微笑矩形框 (sx, sy, sw, sh),坐标是相对于 roi_gray_face(人脸区域)的。

    6. 绘制微笑框(蓝色)

    a = x + sx # 转换到原始图像的坐标
    b = y + sy
    cv2.rectangle(image, (a, b), (a + sw, b + sh), (255, 0, 0), 2)

    • (a, b) 是微笑框在原始图像 image 中的左上角坐标。
    • 绘制蓝色矩形框(RGB (255,0,0)),线宽 2。

    7. 标注文字“smile”

    cv2.putText(image, "smile", (x, y), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 255, 255), 2)

    • 在人脸框左上角 (x, y) 处显示黄色文字“smile”:
      • 字体:cv2.FONT_HERSHEY_COMPLEX_SMALL。
      • 字号:1。
      • 颜色:(0, 255, 255)(黄色)。
      • 线宽:2。

    代码执行流程

  • 输入图像 → 检测人脸 → 绘制绿色人脸框。
  • 提取人脸区域 → 检测微笑 → 绘制蓝色微笑框。
  • 标注“smile”文字 → 显示结果。

  • 注意事项

  • 依赖 Haar 级联分类器:
    • faces 和 smiles 是由 cv2.CascadeClassifier 检测得到的。
    • 通常需要加载预训练模型:face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
      smile_cascade = cv2.CascadeClassifier('haarcascade_smile.xml')
  • 参数调优:
    • scaleFactor 和 minNeighbors 影响检测精度和速度,需根据实际场景调整。
  • 坐标转换:
    • 微笑检测是在人脸区域 (roi_gray_face) 内进行的,绘制时需要转换回原始图像坐标。

  • 2.2 显示效果

    # 显示结果
    cv2.imshow("dect",image)
    key = cv2.waitKey(25)
    if key ==27:
    break
    cap.release()
    cv2.destroyAllWindows()

    • 显示效果如下,我们插入一段视频,在视频中对人物进行微笑检测,并画出检测框:

    在这里插入图片描述

    三、参数调优建议

  • 人脸检测参数:

    • minNeighbors值越大,检测越严格,但可能漏检
    • scaleFactor通常在1.01-1.5之间
  • 微笑检测参数:

    • 由于微笑区域相对较小,minSize不宜设置过大
    • minNeighbors可以适当调小以避免漏检
  • 四、总结

    本文介绍了一个基于OpenCV Haar级联分类器的实时微笑检测系统。虽然Haar级联分类器在复杂场景下可能表现不佳,但它的计算效率高,非常适合初学者学习和快速原型开发。通过调整参数和优化流程,可以在实际应用中获得不错的效果。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 基于OpenCV的人脸微笑检测实现
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!