mediapipe+opencv
MediaPipe本身不提供图像处理功能,它主要用于检测和跟踪人脸、手势、姿势等。如果您想要从图像中仅提取人脸主要信息并去除其他信息.
# coding=utf-8
"""@project: teat@Author:念卿 刘@file: test.py@date:2023/12/2 11:32"""
import cv2
import mediapipe as mp
import numpy as np# 初始化 MediaPipe 的面部特征检测器
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(min_detection_confidence=0.5, min_tracking_confidence=0.5)# 读取图像
image = cv2.imread("hc.png")# 将图像转换为 RGB 格式
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 进行人脸检测
results = face_mesh.process(image_rgb)
# 创建一个与图像相同大小的蒙版
mask = np.zeros_like(image)
le, r, u, lo = 0, 0, 0, 0
# 获取检测到的人脸关键点信息
if results.multi_face_landmarks:for landmarks in results.multi_face_landmarks:X, Y = [], []for landmark in landmarks.landmark:# 将标记点的归一化坐标转换为图像坐标ih, iw, _ = image.shapex, y = int(landmark.x * iw), int(landmark.y * ih)X.append(x)Y.append(y)# 提取人脸轮廓部分points = cv2.convexHull(np.array([(X[i], Y[i]) for i in range(len(landmarks.landmark))]))cv2.fillConvexPoly(mask, points, (255, 255, 255))le, r, u, lo = min(Y), max(Y), min(X), max(X)# # 仅保留人脸主要信息
result = cv2.bitwise_and(image, mask)result = result[le - 10: r + 10, u - 10: lo + 10]
# 将图像转换为灰度
gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)# 创建一个掩码,将黑色区域变成白色
mask = gray < 5 # 假设阈值为5,可以根据实际情况调整# 使用掩码将黑色区域变成白色
result[mask] = [255, 255, 255]
# # 保存结果图像
cv2.imwrite("face_only.jpg", result)
#
# # 显示结果图像(可选)
cv2.imshow("Face Only", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
关键代码
X, Y = [], []for landmark in landmarks.landmark:# 将标记点的归一化坐标转换为图像坐标ih, iw, _ = image.shapex, y = int(landmark.x * iw), int(landmark.y * ih)X.append(x)Y.append(y)
""" 在循环中遍历人脸关键点,将每个关键点的归一化坐标转换为图像坐标,
并将 x 和 y 坐标分别添加到 X 和 Y 列表中。这个循环通过遍历所有的关键点,
将它们的坐标提取出来,最终得到 X 和 Y 列表,其中包含了所有关键点的 x 和 y 坐标。 """
cv2.fillConvexPoly(mask, points, (255, 255, 255)):"""创建了一个与原始图像大小相同的空白掩码(mask),用于标记要保留的区域。
使用 cv2.fillConvexPoly 函数,将上一步计算得到的凸包(轮廓)填充到掩码上,
并将填充的区域标记为白色(255, 255, 255)。
这一步的结果是在掩码上生成了一个白色区域,该区域对应于人脸的轮廓。"""
result = cv2.bitwise_and(image, mask):"""使用 cv2.bitwise_and 函数,将原始图像 (image) 与掩码 (mask) 进行按位与运算,
以仅保留掩码中白色区域对应的原始图像区域。
这样,result 变量将包含原始图像中仅保留了人脸轮廓部分的图像,
其他区域将被去除,从而仅保留人脸的主要信息。"""le, r, u, lo = min(Y), max(Y), min(X), max(X)
""" 获取人脸范围 """
result = result[le - 10: r + 10, u - 10: lo + 10]
"""这一行代码从 result 图像中提取一个子图像,通过使用切片操作来定义提取的区域"""
# 将图像转换为灰度
gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)
"""这一行代码将提取的子图像 result 转换为灰度图像,以便进行下一步的阈值处理"""
# 创建一个掩码,将黑色区域变成白色
mask = gray < 5 # 假设阈值为5,可以根据实际情况调整
"""这一行代码创建一个掩码,根据灰度值小于5的像素来标记图像中的区域。
也就是说,任何灰度值小于5的像素都将在掩码中标记为 True,而大于等于5的像素将标记为 False"""
# 使用掩码将黑色区域变成白色
result[mask] = [255, 255, 255]
"""这一行代码使用掩码,将在掩码中为 True 的像素,也就是灰度值小于5的像素,
设置为白色(255, 255, 255)"""