Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之三 简单人脸眼睛检测添加睫毛效果

发布于:2024-04-20 ⋅ 阅读:(24) ⋅ 点赞:(0)

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之三 简单人脸眼睛检测添加睫毛效果

目录

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之三 简单人脸眼睛检测添加睫毛效果

一、简单介绍

二、简单人脸眼睛检测添加睫毛效果实现原理

三、简单人脸眼睛检测添加睫毛效果案例实现简单步骤

四、注意事项


一、简单介绍

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

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

人脸检测的两个重要概念:哈尔特征分类器(Haar Feature Classifier)和级联分类器(Cascade Classifier)是用于。

哈尔特征分类器:

    定义:哈尔特征分类器是一种基于哈尔特征的机器学习算法,用于检测图像中的对象或特定区域。

    原理:哈尔特征是一种基于图像局部特征的数学描述方法,通过对图像中不同区域像素值的差异进行计算,提取出具有区分度的特征。这些特征可以是边缘、线段、角点等。哈尔特征分类器通过训练过程学习到一组有效的特征模式,用于区分目标和非目标区域。

    应用:哈尔特征分类器常用于对象检测任务,如人脸检测、眼睛检测等。在训练过程中,通常需要提供正样本(包含目标的图像)和负样本(不包含目标的图像),让分类器学习区分目标和非目标的特征模式。

级联分类器:

    定义:级联分类器是一种多级联组成的分类器结构,由多个弱分类器组成,通过级联方式实现目标检测。

    原理:级联分类器将多个简单的分类器组合成一个复杂的分类器,每个简单分类器都是一个弱分类器,对目标区域进行初步筛选或过滤。级联分类器通过级联多个弱分类器,每个分类器都负责判断一组特征是否满足条件,通过级联的方式实现高效的目标检测。

    应用:级联分类器常用于实时目标检测任务,如人脸检测、车辆检测等。OpenCV 中的 Haar 级联分类器是基于哈尔特征的级联分类器,通过级联多个分类阶段来实现高效的人脸检测。级联分类器的优势在于其高速、高效的检测性能,适用于实时应用场景。

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. 眼睛检测:一旦检测到人脸,就可以在人脸区域内进行眼睛检测。眼睛检测可以通过类似的方法来实现,使用级联分类器或深度学习模型来识别眼睛的位置。检测到的眼睛通常也表示为矩形边界框。

  3. 眼睛特效添加:一旦检测到眼睛,就可以在眼睛区域上应用各种特效或滤镜。这些特效可以是基于图像处理技术的,例如在眼睛周围添加睫毛、改变眼睛的颜色或添加眼影等。也可以是基于计算机图形学的,例如在眼睛区域添加虚拟眼镜、变形或动画效果等。

通过将这些步骤组合在一起,可以实现人脸眼睛检测和添加眼睛特效的功能,从而为图像或视频增添趣味性或美化效果。

案例代码实现了在人脸图像中检测左眼,并在左眼上方添加睫毛效果的功能。以下是其实现的原理、具体步骤:

实现原理:

  1. 使用 OpenCV 加载人脸和眼睛检测器(Haar 级联分类器)。
  2. 对输入的人脸图像进行灰度化处理。
  3. 使用人脸检测器检测人脸区域。
  4. 对每个检测到的人脸区域,使用眼睛检测器检测眼睛。
  5. 对每个检测到的眼睛,确定其中心位置,判断是否为左眼(根据其在人脸中的位置)。
  6. 对于左眼,调整睫毛图像的大小以匹配眼睛大小,并根据竖直方向的偏移参数调整睫毛的位置。
  7. 将调整后的睫毛图像合成到原始图像中,形成最终效果。

具体步骤:

  1. 加载人脸和眼睛检测器。
  2. 读取输入的人脸图像,并对其进行灰度化处理。
  3. 使用人脸检测器检测人脸区域。
  4. 对每个检测到的人脸区域,使用眼睛检测器检测眼睛。
  5. 对每个检测到的眼睛,判断其是否为左眼,并获取其位置信息。
  6. 如果是左眼,根据竖直方向的偏移参数调整睫毛的位置。
  7. 将调整后的睫毛图像合成到原始图像中。
  8. 返回添加了睫毛效果的图像。

案例代码涉及的关键函数如下:

  1. cv2.CascadeClassifier()

    • 用途:加载 Haar 级联分类器模型。
    • 参数:接受模型文件路径作为参数。
    • 返回值:返回一个级联分类器对象,用于人脸或眼睛检测。
  2. cv2.imread()

    • 用途:读取图像文件。
    • 参数:图像文件路径和读取方式作为参数。
    • 返回值:返回一个包含图像数据的 NumPy 数组。
  3. cv2.cvtColor()

    • 用途:将图像从一种颜色空间转换到另一种颜色空间。
    • 参数:输入图像和转换标志作为参数。
    • 返回值:返回转换后的图像。
  4. cv2.CascadeClassifier.detectMultiScale()

    • 用途:检测图像中的人脸或眼睛。
    • 参数:接受输入图像、尺度因子、最小邻域数和最小尺寸作为参数。
    • 返回值:返回检测到的目标的边界框坐标。
  5. cv2.resize()

    • 用途:调整图像的大小。
    • 参数:输入图像和目标尺寸作为参数。
    • 返回值:返回调整大小后的图像。
  6. over_img()

    • 用途:在图像上叠加另一张图像。
    • 参数:两个图像、叠加位置的坐标作为参数。
    • 返回值:返回叠加后的图像。
  7. apply_glasses()

    • 用途:识别人脸中的左眼并添加睫毛效果。
    • 参数:输入图像路径、睫毛图像路径和竖直偏移参数作为参数。
    • 返回值:返回添加了睫毛效果的图像。

三、简单人脸眼睛检测添加睫毛效果案例实现简单步骤

1、编写代码

2、运行效果

3、具体代码

"""
简单人脸眼睛检测添加睫毛效果
    1、加载人脸和眼睛检测器。
    2、读取输入的人脸图像,并对其进行灰度化处理。
    3、使用人脸检测器检测人脸区域。
    4、对每个检测到的人脸区域,使用眼睛检测器检测眼睛。
    5、对每个检测到的眼睛,判断其是否为左眼,并获取其位置信息。
    6、如果是左眼,根据竖直方向的偏移参数调整睫毛的位置。
    7、将调整后的睫毛图像合成到原始图像中。
    8、返回添加了睫毛效果的图像。
"""

import cv2


def apply_eyelash_left_eye(image_path, eyelash_image_path, vertical_offset=0.0):
    """
    在人脸图像上添加左眼睫毛效果
    :param image_path: (str) 输入的人脸图像路径
    :param eyelash_image_path: (str) 睫毛图像的路径
    :param vertical_offset: (float) 睫毛竖直方向位置调节参数,范围为-1到1,默认值为0(中心位置)
    :return: numpy.ndarray 添加了睫毛效果的图像数据
    """

    # 参数安全性校验
    if not isinstance(image_path, str) or not image_path.strip():
        raise ValueError("Invalid input image path.")
    if not isinstance(eyelash_image_path, str) or not eyelash_image_path.strip():
        raise ValueError("Invalid eyelash image path.")
    if not (-1 <= vertical_offset <= 1):
        raise ValueError("Vertical offset parameter must be between -1 and 1.")

    # 读取图像
    image = cv2.imread(image_path)
    eyelash_image = cv2.imread(eyelash_image_path, cv2.IMREAD_UNCHANGED)

    # 加载人脸和眼睛检测器
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')

    # 灰度化图像
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

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

    # 对每个人脸进行操作
    for (x, y, w, h) in faces:
        # 提取人脸区域
        face_roi = image[y:y + h, x:x + w]
        gray_roi = gray[y:y + h, x:x + w]

        # 检测眼睛
        eyes = eye_cascade.detectMultiScale(gray_roi)

        # 画出左右眼范围的矩形框
        for (ex, ey, ew, eh) in eyes:
            eye_center = (x + ex + ew // 2, y + ey + eh // 2)
            cv2.rectangle(image, (x + ex, y + ey), (x + ex + ew, y + ey + eh), (255, 0, 0), 2)

            # 仅对左眼进行操作
            if eye_center[0] < x + w // 2:
                # 调整睫毛图像大小以匹配眼睛
                resized_eyelash = cv2.resize(eyelash_image, (ew, eh))

                # 调整睫毛竖直方向位置
                offset_y = int(eh * vertical_offset)
                ey = max(0, ey + offset_y)

                # 将睫毛图像合成到原始图像中
                for c in range(0, 3):
                    for i in range(eh):
                        for j in range(ew):
                            if resized_eyelash[i, j, 3] != 0:
                                image[y + ey + i, x + ex + j, c] = resized_eyelash[i, j, c]

    # 返回添加了左眼睫毛效果的图像
    return image


# 测试接口调用
if __name__ == "__main__":
    input_image_path = "Images/ManWoman.jpeg"
    eyelash_image_path = "Images/eyelash.png"

    try:
        output_img = apply_eyelash_left_eye(input_image_path, eyelash_image_path, vertical_offset=-0.1)
        cv2.imshow("Eyelash Effect", output_img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        print("Eyelash applied successfully.")
    except ValueError as ve:
        print(f"Error: {ve}")

四、注意事项

  1. 确保人脸和眼睛检测器的准确性和鲁棒性,以提高检测效果。
  2. 在调整睫毛位置时,确保不会超出图像边界。
  3. 调整睫毛图像的大小以匹配眼睛的大小,确保睫毛效果自然。
  4. 在合成睫毛图像到原始图像时,考虑到睫毛图像可能具有 alpha 通道,需要正确处理透明度。
  5. 考虑睫毛效果的竖直方向调节参数,以便用户根据具体情况进行调整。