# 导入模块库
import numpy as np
import dlib
import cv2
from PIL import Image, ImageDraw, ImageFont
# 在图片写汉字
def to_chinese_text(img, vtext, pointx, pointy):
cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 实现array到image的转换
pil_img = Image.fromarray(cv2img)
# PIL图片上打印汉字
draw = ImageDraw.Draw(pil_img)
# 参数1:字体文件路径,参数2:字体大小
font = ImageFont.truetype("./方正粗黑宋简体.ttf", 38, encoding="utf-8")
# 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
draw.text((pointx, pointy), vtext, (255, 0, 0), font=font)
# 将PIL图片转cv2 图片
cv2_img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
return cv2_img
# 将脸部的68个特征点坐标放到一个numpy数组中
# 参数obj_shape是识别出来的一张人脸对象(这个对象用矩形框框住的人脸图像部分)
def obj_to_np(obj_shape):
# 以下语句创建一个68*2的数组,这个数组中每个元素的值都是0,
# obj_shape.num_part返回人脸对象包含子元素的个数,
# 由于是基于68特征点预测器生成人脸对象obj_shape,
# 所以obj_shape.num_part的返回的值是68
face_feature_array = np.zeros((obj_shape.num_parts, 2), dtype="int")
# 遍历obj_shape中68个特征点,取出特征点的坐标
for i in range(0, obj_shape.num_parts):
# 将每个特征点的坐标值(这个坐标值是这个特征点在图像上位置)赋值给数组face_feature_array
face_feature_array[i] = (obj_shape.part(i).x, obj_shape.part(i).y)
return face_feature_array
# 在图片中将一个坐标集合中,指定的点连接成线
# 参数img是图像,参数face_obj_ndarray是一个包含系列点的坐标值的数组,
# 参数point_start是坐标点起始索引,参数point_end是坐标点终止索引
# 参数isjaw是boolean型,表示是否是脸颊,如果不是就将特征点首尾相连,如果是就不连接首尾这两个点
def draw_line(img, face_obj_ndarray, point_start, point_end, isjaw=False):
# 将point_start到point_end的点的坐标取出来
points = face_obj_ndarray[point_start:point_end]
# 循环每个坐标点,从第二个点开始循环
for i in range(1, len(points)):
# 取出前一个坐标点
point_a = tuple(points[i - 1])
# 取出当前坐标点
point_b = tuple(points[i])
# 在图片中将两个点连成线
cv2.line(img, point_a, point_b, (0, 0, 255), 2)
# 如果不是脸颊,将特征点首尾两个点相连
if not isjaw:
# 取出最后一个特征点的坐标
p_a = tuple(points[len(points) - 1])
# 取出第一个特征点的坐标
p_b = tuple(points[0])
cv2.line(img, p_a, p_b, (0, 0, 255), 2)
# 在人脸上标识出各部分,即给各个人脸各部位涂上颜色
# 参数img是图像,参数gray是img的灰度图
# 参数rects是识别出来的人脸对象(这些对象用矩形框框住的人脸图像部分)
# 参数alpha指定透明度
def face_mark(img, gray, rects, alpha=0.6):
# 对原图片进行copy生成图片mark_lay
# mark_lay这个图片用来标识人脸各部位
mark_lay = image.copy()
# 设置要标识人脸部位的颜色
color_1 = (60, 66, 168)
# 取出每张人脸对象,rect保存每张人脸对象
for (i_, rect) in enumerate(rects):
# 在灰度图中将每张人脸用68个特征值分析
face_obj = predictor(gray, rect)
# 将每张脸的68特征点的坐标放到numpy数组中,这些坐标值是在原图片上的坐标
face_obj_ndarray = obj_to_np(face_obj)
# #循环取得字典face_point_68中的每个键
for (i, key_name) in enumerate(face_point_68.keys()):
# 得到每一个键(人脸的一个部位)中的特征点起始与结束点
(j, k) = face_point_68[key_name]
# 取出人脸一个部位的特征点对应的坐标
points = face_obj_ndarray[j:k]
# 如果是这个人脸部位是脸颊,就用连线标出这个部位
if key_name == "脸颊":
# 调用函数画连结线
draw_line(img, face_obj_ndarray, j, k, isjaw=True)
else:
# 取得包含这个部位特征点坐标的凸包
hull = cv2.convexHull(points)
# 根据图片mark_lay上,在凸包内部填充颜色
cv2.drawContours(mark_lay, [hull], -1, color_1, -1)
# 将图片mark_lay叠加在原图img上,叠加后的图像赋值给img
cv2.addWeighted(mark_lay, alpha, img, 1 - alpha, 0, img)
# 显示图形
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 取得人脸上某个部位并显示的函数
# 参数img是图像,参数gray是img的灰度图
# 参数rects是识别出来的人脸对象(这个对角用矩形框框住的)
# 参数part_name人脸的部位名称,如脸颊、左眼、右眼等
def get_one_part(img, gray, rects, part_name):
# 通过循环取每张人脸对象
for (i_, rect) in enumerate(rects):
# 用基于68个特征点分析器,在灰度图中取出68个特征点保存在变量face_obj
face_obj = predictor(gray, rect)
# 将每张脸的68特征点的坐标放到numpy数组中,这些坐标值是在原图片上的坐标
face_obj_ndarray = obj_to_np(face_obj)
# 循环取得字典face_point_68中的人脸的部位名称、每个部位特征点的起始值
for (name, (i, j)) in face_point_68.items():
# 如果人脸的部位名与参数part_name一致
if name == part_name:
# 调用函数在原图上坐标为(10,30)位置上写出这个人脸部位的名称
img = to_chinese_text(img, name, 10, 30)
# 循环取出这个部位的每个特征点的坐标
for (pointx, pointy) in face_obj_ndarray[i:j]:
# 在相应坐标上画直径为3px的红色圆点,最后一个参数-1表示用相应颜色填充几何图形圆
cv2.circle(img, (pointx, pointy), 3, (0, 0, 255), -1)
isjaw = False
if part_name == "脸颊":
isjaw = True
# 调用函数将这个部分特征点用连接起来
draw_line(img, face_obj_ndarray, i, j, isjaw)
# 取出包围这个人脸部位的最小矩形,cv2.boundingRect()返回矩形左上角的坐标以及矩形的宽和高
(x, y, w, h) = cv2.boundingRect(np.array([face_obj_ndarray[i:j]]))
# 在图形取出这个矩形(包含人脸部位的图片部分)
part_one = image[y:y + h, x:x + w]
# 显示这个人脸部位
cv2.imshow("part-one", part_one)
# 显示原图
cv2.imshow("Image", img)
cv2.waitKey(0)
# 主程序main
if __name__ == '__main__':
# 生成一个人脸识别器对象
detector = dlib.get_frontal_face_detector()
# 生成一个基于68个特征点的预测器
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 生一个字典,将脸部每个部位的特征点起始值作为键值,这个键值与人脸各部位对应
face_point_68 = {
'脸颊': (0, 17),
'右眉': (17, 22),
'左眉': (22, 27),
'鼻子': (27, 36),
'右眼': (36, 42),
'左眼': (42, 48),
'嘴巴': (48, 68)
}
# 将一张图片对入内存中
image = cv2.imread('./test.jpg')
# 取出图片的高与宽取出来,因为图片在计算机实际是以三维数据形式保存
# 数组的第一维长度就是图片高
没有合适的资源?快使用搜索试试~ 我知道了~
2python人工智能算法五官识别.zip
共11个文件
xml:5个
ttf:2个
gitignore:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 129 浏览量
2023-10-14
12:35:45
上传
评论
收藏 6.46MB ZIP 举报
温馨提示
2python人工智能算法五官识别,利用数据模型,将人脸部位的68个特征进行识别,分别是脸颊,眉毛,眼睛等,仅供参考。
资源推荐
资源详情
资源评论
收起资源包目录
2python人工智能算法五官识别.zip (11个子文件)
人的五官识别(分享)
test.jpg 87KB
simhei.ttf 9.3MB
five_sense_organs.py 9KB
.idea
人的五官识别.iml 417B
other.xml 239B
workspace.xml 5KB
misc.xml 189B
inspectionProfiles
profiles_settings.xml 174B
modules.xml 295B
.gitignore 0B
方正粗黑宋简体.ttf 2.65MB
共 11 条
- 1
资源评论
2201_75761617
- 粉丝: 21
- 资源: 7339
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功