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

二、简单人脸检测添加戴眼镜效果实现原理

人脸检测添加带眼镜效果是指利用计算机视觉技术中的人脸检测算法,识别图像或视频中的人脸,并在识别到的人脸位置上叠加眼镜图像,以实现给人脸添加眼镜的效果。

案例中涉及的两个关键函数说明

这些函数负责在人脸图像上添加眼镜效果,其中over_img函数用于将眼镜图像覆盖到人脸图像的指定位置上,而apply_glasses函数则是整个眼镜效果添加的入口函数,调用了人脸识别、图像处理等功能。

三、简单人脸检测添加戴眼镜效果案例实现简单步骤

1、编写代码

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之二 简单人脸检测添加戴眼镜效果-LMLPHP

2、运行效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之二 简单人脸检测添加戴眼镜效果-LMLPHP

3、具体代码

"""
简单人脸检测添加戴眼镜效果
    1、使用 OpenCV 加载人脸识别分类器。
    2、读取人脸图像和眼镜图像。
    3、对人脸图像进行人脸检测,获取人脸的位置信息。
    4、遍历检测到的每张人脸,根据人脸宽度调整眼镜大小。
    5、将调整后的眼镜图像覆盖到对应人脸位置上。
    6、返回带有眼镜效果的图像数据。
"""

import cv2


def over_img(img, img_over, over_x, over_y):
    """
    将一张图像覆盖到另一张图像上
    :param img: (numpy.ndarray) 目标图像数据
    :param img_over: (numpy.ndarray) 待覆盖图像数据,包含 alpha 通道
    :param over_x: (int) 待覆盖图像左上角的 x 坐标
    :param over_y: (int) 待覆盖图像左上角的 y 坐标
    :return: numpy.ndarray 覆盖后的图像数据
    """
    img_h, img_w, c = img.shape
    img_over_h, img_over_w, over_c = img_over.shape
    # 将待覆盖图像转换为带 alpha 通道的 BGRA 格式
    if over_c == 3:
        img_over = cv2.cvtColor(img_over, cv2.COLOR_BGR2BGRA)
    # 遍历待覆盖图像的每个像素
    for w in range(0, img_over_w):
        for h in range(0, img_over_h):
            # 透明像素不能覆盖目标图像
            if img_over[h, w, 3] != 0:
                # 遍历 RGB 通道
                for c in range(0, 3):
                    x = over_x + w
                    y = over_y + h
                    # 如果超出目标图像范围,则跳出循环
                    if x >= img_w or y >= img_h:
                        break
                    # 将待覆盖图像像素覆盖到目标图像上
                    img[y, x, c] = img_over[h, w, c]
    return img


def apply_glasses(input_image_path, glasses_image_path, vertical_offset=0.35):
    """
    在人脸图像上添加眼镜效果
    :param input_image_path: (str) 输入的人脸图像路径
    :param glasses_image_path: (str) 眼镜图像的路径
    :param vertical_offset: (float) 眼镜垂直位置的调整参数,范围为0到1,默认值为0.35
    :return: numpy.ndarray 带眼镜效果的图像数据
    """
    # 参数安全性校验
    if not isinstance(input_image_path, str) or not input_image_path.strip():
        raise ValueError("Invalid input image path.")

    if not isinstance(glasses_image_path, str) or not glasses_image_path.strip():
        raise ValueError("Invalid glasses image path.")

    if not (0 <= vertical_offset <= 1):
        raise ValueError("Vertical offset parameter must be between 0 and 1.")

    # 读取人脸和眼镜图像
    img = cv2.imread(input_image_path)
    glass = cv2.imread(glasses_image_path, cv2.IMREAD_UNCHANGED)  # 保留图像类型
    height, weight, channel = glass.shape
    # 加载人脸识别联结器
    faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
    # 进行人脸检测
    faces = faceCascade.detectMultiScale(img, 1.15, 4)
    # 对每个检测到的人脸应用眼镜效果
    for (x, y, w, h) in faces:
        gw = w
        gh = int(height * gw / weight)
        # 调整眼镜图像大小以适应人脸宽度
        img_over_new = cv2.resize(glass, (gw, gh))
        # 将眼镜图像覆盖到人脸图像上
        img = over_img(img, img_over_new, x, y + int(h * vertical_offset))
        # 绘制脸部范围图框
        # cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5)
    return img


# 测试接口调用
if __name__ == "__main__":
    input_image_path = "Images/TwoManFace.png"
    glasses_image_path = "Images/glasses.png"

    try:
        output_img = apply_glasses(input_image_path, glasses_image_path, vertical_offset=0.0)
        cv2.imshow("output_img", output_img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        print("Glasses applied successfully.")
    except ValueError as ve:
        print(f"Error: {ve}")

四、注意事项

  1. 人脸识别结果可能有误,因此需要根据实际情况调整眼镜的位置和大小。
  2. 眼镜图像的背景应该是透明的,以便与人脸图像进行叠加。
  3. 调整眼镜大小时,应保持眼镜的比例,以确保效果自然。
  4. 确保输入图像路径和眼镜图像路径有效,以避免出现读取失败的情况。
  5. 在覆盖眼镜图像到人脸图像时,注意边界情况,防止超出图像范围。
  6. 眼镜的垂直位置调整参数应在0到1之间,表示眼镜在人脸垂直方向上的偏移量。
04-18 07:14