目录
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版本兼容的模型文件。
人脸眼睛检测是计算机视觉中的一项任务,旨在识别图像或视频中的人脸和眼睛。这项技术通常涉及以下步骤:
人脸检测:首先,使用人脸检测算法检测图像或视频中的人脸位置。这可以通过级联分类器(如Haar级联分类器)或深度学习方法(如卷积神经网络)来完成。检测到的人脸通常表示为矩形边界框。
眼睛检测:一旦检测到人脸,就可以在人脸区域内进行眼睛检测。眼睛检测可以通过类似的方法来实现,使用级联分类器或深度学习模型来识别眼睛的位置。检测到的眼睛通常也表示为矩形边界框。
眼睛特效添加:一旦检测到眼睛,就可以在眼睛区域上应用各种特效或滤镜。这些特效可以是基于图像处理技术的,例如在眼睛周围添加睫毛、改变眼睛的颜色或添加眼影等。也可以是基于计算机图形学的,例如在眼睛区域添加虚拟眼镜、变形或动画效果等。
通过将这些步骤组合在一起,可以实现人脸眼睛检测和添加眼睛特效的功能,从而为图像或视频增添趣味性或美化效果。
案例代码实现了在人脸图像中检测左眼,并在左眼上方添加睫毛效果的功能。以下是其实现的原理、具体步骤:
实现原理:
- 使用 OpenCV 加载人脸和眼睛检测器(Haar 级联分类器)。
- 对输入的人脸图像进行灰度化处理。
- 使用人脸检测器检测人脸区域。
- 对每个检测到的人脸区域,使用眼睛检测器检测眼睛。
- 对每个检测到的眼睛,确定其中心位置,判断是否为左眼(根据其在人脸中的位置)。
- 对于左眼,调整睫毛图像的大小以匹配眼睛大小,并根据竖直方向的偏移参数调整睫毛的位置。
- 将调整后的睫毛图像合成到原始图像中,形成最终效果。
具体步骤:
- 加载人脸和眼睛检测器。
- 读取输入的人脸图像,并对其进行灰度化处理。
- 使用人脸检测器检测人脸区域。
- 对每个检测到的人脸区域,使用眼睛检测器检测眼睛。
- 对每个检测到的眼睛,判断其是否为左眼,并获取其位置信息。
- 如果是左眼,根据竖直方向的偏移参数调整睫毛的位置。
- 将调整后的睫毛图像合成到原始图像中。
- 返回添加了睫毛效果的图像。
案例代码涉及的关键函数如下:
cv2.CascadeClassifier():
- 用途:加载 Haar 级联分类器模型。
- 参数:接受模型文件路径作为参数。
- 返回值:返回一个级联分类器对象,用于人脸或眼睛检测。
cv2.imread():
- 用途:读取图像文件。
- 参数:图像文件路径和读取方式作为参数。
- 返回值:返回一个包含图像数据的 NumPy 数组。
cv2.cvtColor():
- 用途:将图像从一种颜色空间转换到另一种颜色空间。
- 参数:输入图像和转换标志作为参数。
- 返回值:返回转换后的图像。
cv2.CascadeClassifier.detectMultiScale():
- 用途:检测图像中的人脸或眼睛。
- 参数:接受输入图像、尺度因子、最小邻域数和最小尺寸作为参数。
- 返回值:返回检测到的目标的边界框坐标。
cv2.resize():
- 用途:调整图像的大小。
- 参数:输入图像和目标尺寸作为参数。
- 返回值:返回调整大小后的图像。
over_img():
- 用途:在图像上叠加另一张图像。
- 参数:两个图像、叠加位置的坐标作为参数。
- 返回值:返回叠加后的图像。
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}")