Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之八 简单进行鼻子检测并添加特效的功能实现

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之八 简单进行鼻子检测并添加特效的功能实现

目录

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之八 简单进行鼻子检测并添加特效的功能实现

一、简单介绍

二、简单进行鼻子检测并添加特效的功能实现原理方法

三、简单进行鼻子检测并添加特效的功能实现案例实现简单步骤

四、注意事项

五、源码下载地址


一、简单介绍

Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。

这里使用 Python  基于 OpenCV 进行视觉图像处理,......

OpenCV 提供了一些已经训练好的级联分类器,这些级联分类器以XML文件的方式保存在以下路径中:

...\Python\Lib\site-packages\cv2\data\

OpenCV提供了一些经过预训练的人脸检测器模型文件,这些文件通常包含在OpenCV的安装包中。你也可以在OpenCV的官方GitHub页面或者OpenCV官方网站的下载页面找到这些模型文件的下载链接。

一般来说,你可以从以下位置获取OpenCV的预训练模型文件:

  •                 OpenCV GitHub Release 页面:在 Releases · opencv/opencv · GitHub 找到你需要的版本,然后在下载的压缩包中找到位于 opencv\data 目录下的人脸检测器模型文件。
  •                 OpenCV 官方网站下载页面:访问 OpenCV 官方网站 Releases - OpenCV ,下载你需要的版本,并在相应的压缩包中查找人脸检测器模型文件。

请确保下载与你使用的OpenCV版本兼容的模型文件。

该案例效果

二、简单进行鼻子检测并添加特效的功能实现原理方法

通过检测人脸、眼睛和鼻子,在视频中给人脸添加鼻子特效是一种计算机视觉技术,旨在识别视频中的人脸,并在检测到的人脸区域上叠加鼻子特效,以实现一种有趣或增强现实的效果。这一过程可以分为以下步骤:

  1. 人脸检测:首先,使用人脸检测算法(如Haar级联分类器)在视频帧中检测人脸的位置和大小。

  2. 眼睛检测:在检测到的人脸区域内,使用眼睛检测算法(也可以使用Haar级联分类器)来检测眼睛的位置和大小。这可以帮助确定人脸的方向和角度。

  3. 鼻子检测:在人脸区域内,使用鼻子检测算法(如Haar级联分类器)来检测鼻子的位置和大小。

  4. 特效叠加:在检测到的鼻子区域上,将预先准备好的鼻子特效图片叠加。为了使鼻子特效与人脸的方向和角度保持一致,可能需要对特效图片进行旋转。

  5. 显示结果:将叠加了鼻子特效的视频帧显示在屏幕上,以实时展示给用户。

通过这些步骤,可以实现在视频中检测人脸、眼睛和鼻子,并在检测到的人脸区域上添加鼻子特效的功能。这种技术常用于实现视频特效、增强现实应用、娱乐软件等领域。

实现原理

  • 使用OpenCV的级联分类器来检测人脸、眼睛和鼻子。
  • 通过检测到的眼睛位置计算眼睛中心线的斜率,然后将其作为鼻子特效旋转的角度。
  • 使用OpenCV的图像处理功能来旋转鼻子特效图片,并将旋转后的鼻子特效叠加在原始视频帧上。

实现方法

  • 加载人脸、眼睛和鼻子检测器以及鼻子特效图片。
  • 打开视频文件,并循环读取视频的每一帧。
  • 将每一帧转换为灰度图像。
  • 在灰度图像上检测人脸,并遍历每个检测到的人脸。
  • 对于每个人脸,通过检测眼睛并计算眼睛中心线的斜率来确定鼻子特效的旋转角度。
  • 在检测到的人脸区域内检测鼻子,并对每个检测到的鼻子进行处理。
  • 将旋转后的鼻子特效叠加在原始视频帧上。
  • 显示处理后的视频帧,并等待用户按下键盘上的“q”键退出。

案例中涉及了一些关键函数,这些函数用于实现人脸、眼睛和鼻子的检测,以及对鼻子特效图片进行旋转和叠加。下面是这些关键函数的说明:

  1. cv2.CascadeClassifier()

    • 这个函数用于加载级联分类器,用于对象检测,如人脸、眼睛和鼻子等。
    • 参数是级联分类器文件的路径。
    • 示例中使用了三个级联分类器:人脸(haarcascade_frontalface_default.xml)、眼睛(haarcascade_eye.xml)和鼻子(haarcascade_mcs_nose.xml)。
  2. cv2.imread()

    • 这个函数用于读取图像文件。
    • 参数包括图像文件路径和读取模式,示例中使用了cv2.IMREAD_UNCHANGED模式读取鼻子特效图片。
  3. cv2.VideoCapture()

    • 这个函数用于打开视频文件或捕获设备的视频流。
    • 参数是视频文件路径或设备索引。
  4. cv2.cvtColor()

    • 这个函数用于将图像从一个颜色空间转换为另一个颜色空间,通常用于灰度化。
    • 参数是要转换的图像和目标颜色空间。
  5. cv2.warpAffine()

    • 这个函数用于对图像进行仿射变换,如平移、旋转、缩放等。
    • 参数包括原始图像、变换矩阵和目标图像的大小。
  6. cv2.getRotationMatrix2D()

    • 这个函数用于计算仿射变换的旋转矩阵。
    • 参数包括旋转中心点、旋转角度和缩放因子。
  7. np.clip()

    • 这个NumPy函数用于将数组中的元素限制在指定范围内。
    • 参数包括待限制的数组、最小值和最大值。
  8. np.arctan()

    • 这个NumPy函数用于计算数组元素的反正切值。
    • 参数是待计算的数组。
  9. cv2.imshow()cv2.waitKey()

    • 这两个函数一起使用来显示图像并等待用户按下键盘上的键。
    • imshow()函数用于显示图像窗口,参数包括窗口名称和要显示的图像。
    • waitKey()函数用于等待用户按键输入,并返回按下的键的ASCII码,参数是等待时间(毫秒)。
  10. cap.release()cv2.destroyAllWindows()

    • 这两个函数用于释放视频捕获对象和关闭所有图像窗口。
    • release()函数释放视频捕获对象的资源。
    • destroyAllWindows()函数关闭所有通过OpenCV创建的图像窗口。

如果通过眼睛计算的偏转角度不够准确,可以尝试以下方法进行处理:

  1. 使用更准确的角度计算方法:眼睛中心的斜率可能不是最准确的角度计算方法。考虑使用更精确的方法来计算角度,例如通过计算两个眼睛中心的连线与水平线的夹角来确定偏转角度。

  2. 使用更多的特征点:除了眼睛的中心点,还可以考虑使用更多的特征点来计算偏转角度,例如眼睛的角点或眉毛的位置。通过综合考虑多个特征点的位置和方向,可以更准确地估计人脸的偏转角度。

  3. 引入平滑处理:考虑对计算出的角度进行平滑处理,例如使用滑动窗口或滤波器来平均多个帧的角度值,以减少突变和不稳定性。

  4. 调整参数:尝试调整眼睛检测算法的参数,例如缩放因子、邻近点数量和最小尺寸,以获取更准确的眼睛检测结果。

  5. 使用机器学习方法:考虑使用机器学习方法,例如深度学习模型,通过大量数据训练来学习人脸的姿态和偏转角度,以提高预测准确性。

通过以上方法的组合或单独应用,可以更准确地计算人脸的偏转角度,从而改善通过眼睛计算的偏转角度的准确性。

三、简单进行鼻子检测并添加特效的功能实现案例实现简单步骤

1、编写代码

2、运行效果

3、具体代码

"""
简单进行鼻子检测并添加特效的功能实现
    1、加载人脸、眼睛和鼻子检测器以及鼻子特效图片。
    2、打开视频文件,并循环读取视频的每一帧。
    3、将每一帧转换为灰度图像。
    4、在灰度图像上检测人脸,并遍历每个检测到的人脸。
    5、对于每个人脸,通过检测眼睛并计算眼睛中心线的斜率来确定鼻子特效的旋转角度。
    6、在检测到的人脸区域内检测鼻子,并对每个检测到的鼻子进行处理。
    7、将旋转后的鼻子特效叠加在原始视频帧上。
    8、显示处理后的视频帧,并等待用户按下键盘上的“q”键退出。
"""

import cv2
import numpy as np
import os


def detect_and_add_nose_effect(video_path, nose_effect_image_path):
    """
    通过检测人脸、眼睛和鼻子,给视频中的人脸添加鼻子特效
    :param video_path: 视频文件路径
    :param nose_effect_image_path: 鼻子特效图片文件路径
    :return:
    """
    # 检查视频文件路径是否存在
    if not os.path.exists(video_path):
        print("Error: 视频文件路径不存在!")
        return

    # 检查鼻子特效图片文件路径是否存在
    if not os.path.exists(nose_effect_image_path):
        print("Error: 鼻子特效图片文件路径不存在!")
        return

    # 加载人脸、眼睛和鼻子检测器
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')
    # nose_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_mcs_nose.xml') # 系统没有该数据,注释使用下面的
    nose_cascade = cv2.CascadeClassifier('haarcascade/haarcascade_mcs_nose.xml')

    # 加载鼻子特效图片
    nose_effect = cv2.imread(nose_effect_image_path, cv2.IMREAD_UNCHANGED)

    # 打开视频文件
    cap = cv2.VideoCapture(video_path)

    while True:
        # 读取一帧视频
        ret, frame = cap.read()
        if not ret:
            break

        # 将视频帧转换为灰度图像
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 人脸检测
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

        # 遍历检测到的人脸
        for (x, y, w, h) in faces:
            # 在人脸区域绘制矩形框
            # cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)

            # 在人脸区域检测眼睛
            roi_gray = gray[y:y + h, x:x + w]
            eyes = eye_cascade.detectMultiScale(roi_gray, scaleFactor=1.35, minNeighbors=15, minSize=(20, 20))
            if len(eyes) >= 2:
                # 计算两个眼睛的中心位置
                eye_centers = np.array([(x + ex + ew // 2, y + ey + eh // 2) for (ex, ey, ew, eh) in eyes])

                # 计算眼睛中心线的斜率
                slope = (eye_centers[1][1] - eye_centers[0][1]) / (eye_centers[1][0] - eye_centers[0][0])

                # 计算角度
                angle = np.arctan(slope) * 180 / np.pi
                angle = np.clip(angle, -45, 45)  # 将角度限制在[-45, 45]范围内
                angle = -angle  # 取反,适应后面鼻子的旋转

                # 在画面上绘制眼睛的位置
                for (ex, ey, ew, eh) in eyes:
                    # cv2.rectangle(frame, (x + ex, y + ey), (x + ex + ew, y + ey + eh), (0, 255, 0), 2)
                    print("cv2.rectangle eye ")

            # 鼻子检测
            noses = nose_cascade.detectMultiScale(roi_gray, scaleFactor=2.5, minNeighbors=15, minSize=(20, 20))
            for (nx, ny, nw, nh) in noses:
                # 在人脸区域绘制鼻子矩形框
                # cv2.rectangle(frame, (x+nx, y+ny), (x+nx+nw, y+ny+nh), (255, 255, 0), 2)

                # 调整鼻子特效图片的大小以适应鼻子区域
                resized_nose_effect = cv2.resize(nose_effect, (nw, nh))

                # 计算鼻子区域的中心点和旋转中心
                nose_center = (int(x + nx + nw // 2), int(y + ny + nh // 2))
                rotation_center = (int((nx + nw) // 2), int((ny + nh) // 2))

                # 旋转鼻子特效图片
                nose_effect_rotated = cv2.warpAffine(resized_nose_effect,
                                                     cv2.getRotationMatrix2D(rotation_center, angle, 1), (nw, nh))

                # 在鼻子位置上添加旋转后的特效图片
                for c in range(0, 3):
                    frame[y + ny:y + ny + nh, x + nx:x + nx + nw, c] = \
                        nose_effect_rotated[:, :, c] * (nose_effect_rotated[:, :, 3] / 255.0) + \
                        frame[y + ny:y + ny + nh, x + nx:x + nx + nw, c] * (1.0 - nose_effect_rotated[:, :, 3] / 255.0)

        # 显示结果
        cv2.imshow('Face and Features Detection', frame)

        # 检测按键输入
        key = cv2.waitKey(1)
        if key == ord('q'):  # 按 'q' 键退出
            break

    # 释放视频捕获对象
    cap.release()
    cv2.destroyAllWindows()


def main():
    # 使用示例
    video_path = 'Videos/GirlFace.mp4'
    nose_effect_image_path = 'Images/pig_nose_flat.png'
    detect_and_add_nose_effect(video_path, nose_effect_image_path)


if __name__ == "__main__":
    main()

四、注意事项

  1. 确保OpenCV的数据文件(如级联分类器文件)和鼻子特效图片文件路径正确。
  2. 对于鼻子检测器,代码使用了一个外部的级联分类器文件(haarcascade_mcs_nose.xml)。如果该文件不存在或路径错误,检测鼻子的功能将无法正常工作。
  3. 对于眼睛检测器,调整minNeighborsminSize参数可以影响检测的准确性和速度。
  4. 旋转角度的计算可能会受到眼睛检测的准确性和偏差的影响,因此可能需要调整参数以获得最佳效果。
  5. 如果报错:cv::FileStorage::Impl::open Can't open file: 'xxxxxxxxx\cv2\data\haarcascade_mcs_nose.xml' in read mode

可以网上下载 haarcascade_mcs_nose.xml,进行本地加载

五、源码下载地址

github:https://github.com/XANkui/PythonOpencvBeginnerPracticalDemo

案例代码:Opencv人脸检测人脸识别/09Cv2FaceNoseDetectToAddGifEffect.py

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-30 06:44:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-30 06:44:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-30 06:44:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-30 06:44:02       20 阅读

热门阅读

  1. arco.design重写message实现只提示一次错误的功能

    2024-04-30 06:44:02       10 阅读
  2. SQL LPAD函数使用

    2024-04-30 06:44:02       13 阅读
  3. RTCRTC

    2024-04-30 06:44:02       8 阅读
  4. golang垃圾回收

    2024-04-30 06:44:02       11 阅读
  5. Linux 系统中如何将网卡设置为桥接模式

    2024-04-30 06:44:02       10 阅读