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官方网站的下载页面找到这些模型文件的下载链接。

该案例效果

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

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

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

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

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

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

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

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

1、编写代码

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

2、运行效果

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

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

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

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

五、源码下载地址

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

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

04-30 07:51