Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之八 简单进行鼻子检测并添加特效的功能实现
目录
Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之八 简单进行鼻子检测并添加特效的功能实现
一、简单介绍
二、简单进行鼻子检测并添加特效的功能实现原理方法
三、简单进行鼻子检测并添加特效的功能实现案例实现简单步骤
四、注意事项
五、源码下载地址
一、简单介绍
Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。
这里使用 Python 基于 OpenCV 进行视觉图像处理,......
OpenCV 提供了一些已经训练好的级联分类器,这些级联分类器以XML文件的方式保存在以下路径中:
python">...\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级联分类器)在视频帧中检测人脸的位置和大小。
眼睛检测:在检测到的人脸区域内,使用眼睛检测算法(也可以使用Haar级联分类器)来检测眼睛的位置和大小。这可以帮助确定人脸的方向和角度。
鼻子检测:在人脸区域内,使用鼻子检测算法(如Haar级联分类器)来检测鼻子的位置和大小。
特效叠加:在检测到的鼻子区域上,将预先准备好的鼻子特效图片叠加。为了使鼻子特效与人脸的方向和角度保持一致,可能需要对特效图片进行旋转。
显示结果:将叠加了鼻子特效的视频帧显示在屏幕上,以实时展示给用户。
通过这些步骤,可以实现在视频中检测人脸、眼睛和鼻子,并在检测到的人脸区域上添加鼻子特效的功能。这种技术常用于实现视频特效、增强现实应用、娱乐软件等领域。
实现原理
- 使用OpenCV的级联分类器来检测人脸、眼睛和鼻子。
- 通过检测到的眼睛位置计算眼睛中心线的斜率,然后将其作为鼻子特效旋转的角度。
- 使用OpenCV的图像处理功能来旋转鼻子特效图片,并将旋转后的鼻子特效叠加在原始视频帧上。
实现方法
- 加载人脸、眼睛和鼻子检测器以及鼻子特效图片。
- 打开视频文件,并循环读取视频的每一帧。
- 将每一帧转换为灰度图像。
- 在灰度图像上检测人脸,并遍历每个检测到的人脸。
- 对于每个人脸,通过检测眼睛并计算眼睛中心线的斜率来确定鼻子特效的旋转角度。
- 在检测到的人脸区域内检测鼻子,并对每个检测到的鼻子进行处理。
- 将旋转后的鼻子特效叠加在原始视频帧上。
- 显示处理后的视频帧,并等待用户按下键盘上的“q”键退出。
案例中涉及了一些关键函数,这些函数用于实现人脸、眼睛和鼻子的检测,以及对鼻子特效图片进行旋转和叠加。下面是这些关键函数的说明:
cv2.CascadeClassifier():
- 这个函数用于加载级联分类器,用于对象检测,如人脸、眼睛和鼻子等。
- 参数是级联分类器文件的路径。
- 示例中使用了三个级联分类器:人脸(
haarcascade_frontalface_default.xml
)、眼睛(haarcascade_eye.xml
)和鼻子(haarcascade_mcs_nose.xml
)。cv2.imread():
- 这个函数用于读取图像文件。
- 参数包括图像文件路径和读取模式,示例中使用了
cv2.IMREAD_UNCHANGED
模式读取鼻子特效图片。cv2.VideoCapture():
- 这个函数用于打开视频文件或捕获设备的视频流。
- 参数是视频文件路径或设备索引。
cv2.cvtColor():
- 这个函数用于将图像从一个颜色空间转换为另一个颜色空间,通常用于灰度化。
- 参数是要转换的图像和目标颜色空间。
cv2.warpAffine():
- 这个函数用于对图像进行仿射变换,如平移、旋转、缩放等。
- 参数包括原始图像、变换矩阵和目标图像的大小。
cv2.getRotationMatrix2D():
- 这个函数用于计算仿射变换的旋转矩阵。
- 参数包括旋转中心点、旋转角度和缩放因子。
np.clip():
- 这个NumPy函数用于将数组中的元素限制在指定范围内。
- 参数包括待限制的数组、最小值和最大值。
np.arctan():
- 这个NumPy函数用于计算数组元素的反正切值。
- 参数是待计算的数组。
cv2.imshow() 和 cv2.waitKey():
- 这两个函数一起使用来显示图像并等待用户按下键盘上的键。
imshow()
函数用于显示图像窗口,参数包括窗口名称和要显示的图像。waitKey()
函数用于等待用户按键输入,并返回按下的键的ASCII码,参数是等待时间(毫秒)。cap.release() 和 cv2.destroyAllWindows():
- 这两个函数用于释放视频捕获对象和关闭所有图像窗口。
release()
函数释放视频捕获对象的资源。destroyAllWindows()
函数关闭所有通过OpenCV创建的图像窗口。
如果通过眼睛计算的偏转角度不够准确,可以尝试以下方法进行处理:
使用更准确的角度计算方法:眼睛中心的斜率可能不是最准确的角度计算方法。考虑使用更精确的方法来计算角度,例如通过计算两个眼睛中心的连线与水平线的夹角来确定偏转角度。
使用更多的特征点:除了眼睛的中心点,还可以考虑使用更多的特征点来计算偏转角度,例如眼睛的角点或眉毛的位置。通过综合考虑多个特征点的位置和方向,可以更准确地估计人脸的偏转角度。
引入平滑处理:考虑对计算出的角度进行平滑处理,例如使用滑动窗口或滤波器来平均多个帧的角度值,以减少突变和不稳定性。
调整参数:尝试调整眼睛检测算法的参数,例如缩放因子、邻近点数量和最小尺寸,以获取更准确的眼睛检测结果。
使用机器学习方法:考虑使用机器学习方法,例如深度学习模型,通过大量数据训练来学习人脸的姿态和偏转角度,以提高预测准确性。
通过以上方法的组合或单独应用,可以更准确地计算人脸的偏转角度,从而改善通过眼睛计算的偏转角度的准确性。
三、简单进行鼻子检测并添加特效的功能实现案例实现简单步骤
1、编写代码
2、运行效果
3、具体代码
python">"""
简单进行鼻子检测并添加特效的功能实现1、加载人脸、眼睛和鼻子检测器以及鼻子特效图片。2、打开视频文件,并循环读取视频的每一帧。3、将每一帧转换为灰度图像。4、在灰度图像上检测人脸,并遍历每个检测到的人脸。5、对于每个人脸,通过检测眼睛并计算眼睛中心线的斜率来确定鼻子特效的旋转角度。6、在检测到的人脸区域内检测鼻子,并对每个检测到的鼻子进行处理。7、将旋转后的鼻子特效叠加在原始视频帧上。8、显示处理后的视频帧,并等待用户按下键盘上的“q”键退出。
"""import cv2
import numpy as np
import osdef 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.piangle = 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()
四、注意事项
- 确保OpenCV的数据文件(如级联分类器文件)和鼻子特效图片文件路径正确。
- 对于鼻子检测器,代码使用了一个外部的级联分类器文件(
haarcascade_mcs_nose.xml
)。如果该文件不存在或路径错误,检测鼻子的功能将无法正常工作。 - 对于眼睛检测器,调整
minNeighbors
和minSize
参数可以影响检测的准确性和速度。 - 旋转角度的计算可能会受到眼睛检测的准确性和偏差的影响,因此可能需要调整参数以获得最佳效果。
- 如果报错: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