文章目录
颜值打分
定义可视化图像函数
导入三维人脸关键点检测模型
导入可视化函数和可视化样式
将图像模型输入,获取预测结果
BGR转RGB
将RGB图像输入模型,获取预测结果
预测人人脸个数
获取脸上关键点轮廓的坐标,并且将相应的坐标标注出来,在标注点之间绘制连线(例如:左眼左眼角的识别点标号为33号)
# 颜值打分--五眼指标
import cv2 as cv
import mediapipe as mp
import numpy as np
from tqdm import tqdm
import time
import matplotlib.pyplot as plt
# 定义可视化图像函数
def look_img(img):
img_RGB=cv.cvtColor(img,cv.COLOR_BGR2RGB)
plt.imshow(img_RGB)
plt.show()
# 导入三维人脸关键点检测模型
mp_face_mesh=mp.solutions.face_mesh
# help(mp_face_mesh.FaceMesh)
model=mp_face_mesh.FaceMesh(
static_image_mode=True,#TRUE:静态图片/False:摄像头实时读取
refine_landmarks=True,#使用Attention Mesh模型
max_num_faces=40,
min_detection_confidence=0.5, #置信度阈值,越接近1越准
min_tracking_confidence=0.5,#追踪阈值
)
# 导入可视化函数和可视化样式
mp_drawing=mp.solutions.drawing_utils
# mp_drawing_styles=mp.solutions.drawing_styles
draw_spec=mp_drawing.DrawingSpec(thickness=2,circle_radius=1,color=[66,77,229])
img=cv.imread("img.png")
# 将图像模型输入,获取预测结果
# BGR转RGB
img_RGB=cv.cvtColor(img,cv.COLOR_BGR2RGB)
scaler=1
h,w=img.shape[0],img.shape[1]
# 将RGB图像输入模型,获取预测结果
results=model.process(img_RGB)
# # 预测人人脸个数
# len(results.multi_face_landmarks)
#
# print(len(results.multi_face_landmarks))
if results.multi_face_landmarks:
for face_landmarks in results.multi_face_landmarks:
mp_drawing.draw_landmarks(
image=img,
landmark_list=face_landmarks,
connections=mp_face_mesh.FACEMESH_CONTOURS,
landmark_drawing_spec=draw_spec,
connection_drawing_spec=draw_spec
)
for idx, coord in enumerate(face_landmarks.landmark):
cx = int(coord.x * w)
cy = int(coord.y * h)
img = cv.putText(img, ' FACE DELECTED', (25, 50), cv.FONT_HERSHEY_SIMPLEX, 0.1,
(218, 112, 214), 1, 1)
img = cv.putText(img, str(idx), (cx, cy), cv.FONT_HERSHEY_SIMPLEX, 0.3,
(218, 112, 214), 1, 1)
else:
img = cv.putText(img, 'NO FACE DELECTED', (25, 50), cv.FONT_HERSHEY_SIMPLEX, 1.25,
(218, 112, 214), 1, 8)
look_img(img)
cv.imwrite('face_id.jpg',img)
# 连轮廓最左侧点
FL=results.multi_face_landmarks[0].landmark[234];
FL_X,FL_Y=int(FL.x*w),int(FL.y*h);FL_Color=(234,0,255)
img=cv.circle(img,(FL_X,FL_Y),20,FL_Color,-1)
look_img(img)
# 脸上侧边缘
FT=results.multi_face_landmarks[0].landmark[10];# 10 坐标为上图中标注的点的序号
FT_X,FT_Y=int(FT.x*w),int(FT.y*h);FT_Color=(231,141,181)
img=cv.circle(img,(FT_X,FT_Y),20,FT_Color,-1)
look_img(img)
# 下侧边缘
FB=results.multi_face_landmarks[0].landmark[152];# 152 坐标为上图中标注的点的序号
FB_X,FB_Y=int(FB.x*w),int(FB.y*h);FB_Color=(231,141,181)
img=cv.circle(img,(FB_X,FB_Y),20,FB_Color,-1)
look_img(img)
# 右侧
FR=results.multi_face_landmarks[0].landmark[454];# 454 坐标为上图中标注的点的序号
FR_X,FR_Y=int(FR.x*w),int(FR.y*h);FR_Color=(0,255,0)
img=cv.circle(img,(FR_X,FR_Y),20,FR_Color,-1)
look_img(img)
# 左眼左眼角
ELL=results.multi_face_landmarks[0].landmark[33];# 33坐标为上图中标注的点的序号
ELL_X,ELL_Y=int(ELL.x*w),int(ELL.y*h);ELL_Color=(0,255,0)
img=cv.circle(img,(ELL_X,ELL_Y),20,ELL_Color,-1)
look_img(img)
#左眼右眼角
ELR=results.multi_face_landmarks[0].landmark[133];# 133坐标为上图中标注的点的序号
ELR_X,ELR_Y=int(ELR.x*w),int(ELR.y*h);ELR_Color=(0,255,0)
img=cv.circle(img,(ELR_X,ELR_Y),20,ELR_Color,-1)
look_img(img)
# 右眼左眼角362
ERL=results.multi_face_landmarks[0].landmark[362];# 133坐标为上图中标注的点的序号
ERL_X,ERL_Y=int(ERL.x*w),int(ERL.y*h);ERL_Color=(233,255,128)
img=cv.circle(img,(ERL_X,ERL_Y),20,ERL_Color,-1)
look_img(img)
# 右眼右眼角263
ERR=results.multi_face_landmarks[0].landmark[263];# 133坐标为上图中标注的点的序号
ERR_X,ERR_Y=int(ERR.x*w),int(ERR.y*h);ERR_Color=(23,255,128)
img=cv.circle(img,(ERR_X,ERR_Y),20,ERR_Color,-1)
look_img(img)
# 从左往右六个点的横坐标
Six_X=np.array([FL_X,ELL_X,ELR_X,ERL_X,ERR_X,FR_X])
# 从最左到最右的距离
Left_Right=FR_X-FL_X
# 从左向右六个点的间隔的五个距离一并划归
Five_Distance=100*np.diff(Six_X)/Left_Right
# 两眼宽度的平均值
Eye_Width_Mean=np.mean((Five_Distance[1],Five_Distance[3]))
# 五个距离分别与两眼宽度均值的差
Five_Eye_Diff=Five_Distance-Eye_Width_Mean
# 求L2范数,作为颜值的指标
Five_Eye_Metrics=np.linalg.norm(Five_Eye_Diff)
cv.line(img,(FL_X,FT_Y),(FL_X,FB_Y),FL_Color,3)
cv.line(img,(ELL_X,FT_Y),(ELL_X,FB_Y),ELL_Color,3)
cv.line(img,(ELR_X,FT_Y),(ELR_X,FB_Y),ELR_Color,3)
cv.line(img,(ERL_X,FT_Y),(ERL_X,FB_Y),ERL_Color,3)
cv.line(img,(ERR_X,FT_Y),(ERR_X,FB_Y),ERR_Color,3)
cv.line(img,(FR_X,FT_Y),(FR_X,FB_Y),FR_Color,3)
cv.line(img,(FL_X,FT_Y),(FR_X,FT_Y),FT_Color,3)
cv.line(img,(FL_X,FB_Y),(FR_X,FB_Y),FB_Color,3)
scaler=1
img = cv.putText(img, 'Five Eye Metrics{:.2f}'.format(Five_Eye_Metrics), (25, 50), cv.FONT_HERSHEY_SIMPLEX, 1,
(218, 112, 214), 6, 6)
img = cv.putText(img, 'Distance 1{:.2f}'.format(Five_Eye_Diff[0]), (25, 100), cv.FONT_HERSHEY_SIMPLEX, 1,
(218, 112, 214), 5, 5)
img = cv.putText(img, 'Distance 1{:.2f}'.format(Five_Eye_Diff[2]), (25, 150), cv.FONT_HERSHEY_SIMPLEX, 1,
(218, 112, 214), 4, 4)
img = cv.putText(img, 'Distance 1{:.2f}'.format(Five_Eye_Diff[4]), (25, 200), cv.FONT_HERSHEY_SIMPLEX,1,
(218, 112, 214), 3, 4)
look_img(img)
cv.imwrite("yanzhi.jpg",img)

摄像头实时检测颜值打分
最后一部分代码是调用摄像头的模板,可以直接使用
关键步骤在代码注释中有体现
import cv2 as cv
import mediapipe as mp
import numpy as np
from tqdm import tqdm
import time
import matplotlib.pyplot as plt
# 定义可视化图像函数
def look_img(img):
img_RGB=cv.cvtColor(img,cv.COLOR_BGR2RGB)
plt.imshow(img_RGB)
plt.show()
# 导入三维人脸关键点检测模型
mp_face_mesh=mp.solutions.face_mesh
# help(mp_face_mesh.FaceMesh)
model=mp_face_mesh.FaceMesh(
static_image_mode=False,#TRUE:静态图片/False:摄像头实时读取
refine_landmarks=True,#使用Attention Mesh模型
max_num_faces=5,
min_detection_confidence=0.5, #置信度阈值,越接近1越准
min_tracking_confidence=0.5,#追踪阈值
)
# 导入可视化函数和可视化样式
mp_drawing=mp.solutions.drawing_utils
# mp_drawing_styles=mp.solutions.drawing_styles
draw_spec=mp_drawing.DrawingSpec(thickness=2,circle_radius=1,color=[66,77,229])
landmark_drawing_spec=mp_drawing.DrawingSpec(thickness=1,circle_radius=2,color=[66,77,229])
# 轮廓可视化
connection_drawing_spec=mp_drawing.DrawingSpec(thickness=2,circle_radius=1,color=[233,155,6])
# 处理帧函数
def process_frame(img):
start_time = time.time()
scaler = 1
h, w = img.shape[0], img.shape[1]
img_RGB = cv.cvtColor(img, cv.COLOR_BGR2RGB)
results = model.process(img_RGB)
if results.multi_face_landmarks:
# for face_landmarks in results.multi_face_landmarks:
# 连轮廓最左侧点
FL = results.multi_face_landmarks[0].landmark[234];
FL_X, FL_Y = int(FL.x * w), int(FL.y * h);
FL_Color = (234, 0, 255)
img = cv.circle(img, (FL_X, FL_Y), 5, FL_Color, -1)
look_img(img)
# 脸上侧边缘
FT = results.multi_face_landmarks[0].landmark[10]; # 10 坐标为上图中标注的点的序号
FT_X, FT_Y = int(FT.x * w), int(FT.y * h);
FT_Color = (231, 141, 181)
img = cv.circle(img, (FT_X, FT_Y), 5, FT_Color, -1)
look_img(img)
# 下侧边缘
FB = results.multi_face_landmarks[0].landmark[152]; # 152 坐标为上图中标注的点的序号
FB_X, FB_Y = int(FB.x * w), int(FB.y * h);
FB_Color = (231, 141, 181)
img = cv.circle(img, (FB_X, FB_Y), 5, FB_Color, -1)
look_img(img)
# 右侧
FR = results.multi_face_landmarks[0].landmark[454]; # 454 坐标为上图中标注的点的序号
FR_X, FR_Y = int(FR.x * w), int(FR.y * h);
FR_Color = (0, 255, 0)
img = cv.circle(img, (FR_X, FR_Y), 5, FR_Color, -1)
look_img(img)
# 左眼左眼角
ELL = results.multi_face_landmarks[0].landmark[33]; # 33坐标为上图中标注的点的序号
ELL_X, ELL_Y = int(ELL.x * w), int(ELL.y * h);
ELL_Color = (0, 255, 0)
img = cv.circle(img, (ELL_X, ELL_Y), 5, ELL_Color, -1)
look_img(img)
# 左眼右眼角
ELR = results.multi_face_landmarks[0].landmark[133]; # 133坐标为上图中标注的点的序号
ELR_X, ELR_Y = int(ELR.x * w), int

本文介绍了如何利用Mediapipe库实现摄像头实时的人脸颜值评估,通过计算五官比例、三庭比例、达芬奇比例等指标,详细展示了关键点检测、面部特征分析和美观度计算的过程。
最低0.47元/天 解锁文章
1711





