• 人脸开锁



    前言
    一、读取模型文件
    二、识别人脸
    1.找人脸
    2.添加人脸
    3.识别人脸
    三、代码实现
    总结

    人脸开锁

    一、读取模型文件
    class Face_recognize :
    score_threshold = 70 #识别分数阈值
    input_size = (224, 224, 3) #输入图片尺寸
    input_size_fe = (128, 128, 3) #输入人脸数据
    feature_len = 256 #人脸数据宽度
    steps = [8, 16, 32] #
    channel_num = 0 #通道数量
    users = [] #初始化用户列表
    threshold = 0.5 #人脸阈值
    nms = 0.3
    max_face_num = 3 #输出的画面中的人脸的最大个数
    names = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] #人脸标签定义
    model = {
    "param": "/home/model/face_recognize/model_int8.param",
    "bin": "/home/model/face_recognize/model_int8.bin"
    }
    model_fe = {
    "param": "/home/model/face_recognize/fe_res18_117.param",
    "bin": "/home/model/face_recognize/fe_res18_117.bin"
    }
    def __init__(self):
    from maix import nn, camera, image, display
    from maix.nn.app.face import FaceRecognize
    for i in range(len(self.steps)):
    self.channel_num += self.input_size[1] / self.steps[i] * (self.input_size[0] / self.steps[i]) * 2
    self.channel_num = int(self.channel_num) #统计通道数量
    self.options = { #准备人脸输出参数
    "model_type": "awnn",
    "inputs": {
    "input0": self.input_size
    },
    "outputs": {
    "output0": (1, 4, self.channel_num) ,
    "431": (1, 2, self.channel_num) ,
    "output2": (1, 10, self.channel_num)
    },
    "mean": [127.5, 127.5, 127.5],
    "norm": [0.0078125, 0.0078125, 0.0078125],
    }
    self.options_fe = { #准备特征提取参数
    "model_type": "awnn",
    "inputs": {
    "inputs_blob": self.input_size_fe
    },
    "outputs": {
    "FC_blob": (1, 1, self.feature_len)
    },
    "mean": [127.5, 127.5, 127.5],
    "norm": [0.0078125, 0.0078125, 0.0078125],
    }
    print("-- load model:", self.model)
    self.m = nn.load(self.model, opt=self.options)
    print("-- load ok")
    print("-- load model:", self.model_fe)
    self.m_fe = nn.load(self.model_fe, opt=self.options_fe)
    print("-- load ok")
    self.face_recognizer = FaceRecognize(self.m, self.m_fe, self.feature_len, self.input_size, self.threshold, self.nms, self.max_face_num)

    def map_face(self, box,points): #将224*224空间的位置转换到240*240空间内
    def tran(x):
    return int(x/224*240)
    box = list(map(tran, box))
    def tran_p(p):
    return list(map(tran, p))
    points = list(map(tran_p, points))
    return box,points

    def recognize(self, feature): #进行人脸匹配
    def _compare(user): #定义映射函数
    return self.face_recognizer.compare(user, feature) #推测匹配分数 score相关分数
    face_score_l = list(map(_compare,self.users)) #映射特征数据在记录中的比对分数
    return max(enumerate(face_score_l), key=lambda x: x[-1]) #提取出人脸分数最大值和最大值所在的位置
    def __del__(self):
    del self.face_recognizer
    del self.m_fe
    del self.m

    global face_recognizer
    face_recognizer = Face_recognize()

    二、识别人脸
    1.找人脸
    from maix import camera, image, display
    while True:
    img = camera.capture() #获取224*224*3的图像数据
    AI_img = img.copy().resize(224, 224)
    faces = face_recognizer.face_recognizer.get_faces(AI_img.tobytes(),False) #提取人脸特征信息

    if faces:
    for prob, box, landmarks, feature in faces:
    disp_str = "Unmarked face"
    bg_color = (255, 0, 0)
    font_color=(255, 255, 255)
    box,points = face_recognizer.map_face(box,landmarks)
    font_wh = img.get_string_size(disp_str)
    for p in points:
    img.draw_rectangle(p[0] - 1, p[1] -1, p[0] + 1, p[1] + 1, color=bg_color)
    img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3], color=bg_color, thickness=2)
    img.draw_rectangle(box[0], box[1] - font_wh[1], box[0] + font_wh[0], box[1], color=bg_color, thickness = -1)
    img.draw_string(box[0], box[1] - font_wh[1], disp_str, color=font_color)
    display.show(img)

    2.添加人脸
    from maix import camera, image, display
    face_flage = 1
    while face_flage:
    img = camera.capture() #获取224*224*3的图像数据
    AI_img = img.copy().resize(224, 224)
    faces = face_recognizer.face_recognizer.get_faces(AI_img.tobytes(),False) #提取人脸特征信息

    if faces:
    for prob, box, landmarks, feature in faces:
    if len(face_recognizer.users) < len(face_recognizer.names):
    face_recognizer.users.append(feature)
    face_flage = 0
    else:
    print("user full")
    disp_str = "add face"
    bg_color = (0, 255, 0)
    font_color=(0, 0, 255)
    box,points = face_recognizer.map_face(box,landmarks)
    font_wh = img.get_string_size(disp_str)
    for p in points:
    img.draw_rectangle(p[0] - 1, p[1] -1, p[0] + 1, p[1] + 1, color=bg_color)
    img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3], color=bg_color, thickness=2)
    img.draw_rectangle(box[0], box[1] - font_wh[1], box[0] + font_wh[0], box[1], color=bg_color, thickness = -1)
    img.draw_string(box[0], box[1] - font_wh[1], disp_str, color=font_color)
    display.show(img)


    3.识别人脸
    from maix import camera, image, display
    while True:
    img = camera.capture() #获取224*224*3的图像数据
    AI_img = img.copy().resize(224, 224)
    faces = face_recognizer.face_recognizer.get_faces(AI_img.tobytes(),False) #提取人脸特征信息

    if faces:
    for prob, box, landmarks, feature in faces:
    if len(face_recognizer.users): #判断是否记录人脸
    maxIndex = face_recognizer.recognize(feature)

    if maxIndex[1] > face_recognizer.score_threshold: #判断人脸识别阈值,当分数大于阈值时认为是同一张脸,当分数小于阈值时认为是相似脸
    disp_str = "{}".format(face_recognizer.names[maxIndex[0]])
    bg_color = (0, 255, 0)
    font_color=(0, 0, 255)
    box,points = face_recognizer.map_face(box,landmarks)
    font_wh = img.get_string_size(disp_str)
    for p in points:
    img.draw_rectangle(p[0] - 1, p[1] -1, p[0] + 1, p[1] + 1, color=bg_color)
    img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3], color=bg_color, thickness=2)
    img.draw_rectangle(box[0], box[1] - font_wh[1], box[0] + font_wh[0], box[1], color=bg_color, thickness = -1)
    img.draw_string(box[0], box[1] - font_wh[1], disp_str, color=font_color)
    else:
    disp_str = "error face"
    bg_color = (255, 0, 0)
    font_color=(255, 255, 255)
    box,points = face_recognizer.map_face(box,landmarks)
    font_wh = img.get_string_size(disp_str)
    for p in points:
    img.draw_rectangle(p[0] - 1, p[1] -1, p[0] + 1, p[1] + 1, color=bg_color)
    img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3], color=bg_color, thickness=2)
    img.draw_rectangle(box[0], box[1] - font_wh[1], box[0] + font_wh[0], box[1], color=bg_color, thickness = -1)
    img.draw_string(box[0], box[1] - font_wh[1], disp_str, color=font_color)
    else: #没有记录脸
    disp_str = "error face"
    bg_color = (255, 0, 0)
    font_color=(255, 255, 255)
    box,points = face_recognizer.map_face(box,landmarks)
    font_wh = img.get_string_size(disp_str)
    for p in points:
    img.draw_rectangle(p[0] - 1, p[1] -1, p[0] + 1, p[1] + 1, color=bg_color)
    img.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3], color=bg_color, thickness=2)
    img.draw_rectangle(box[0], box[1] - font_wh[1], box[0] + font_wh[0], box[1], color=bg_color, thickness = -1)
    img.draw_string(box[0], box[1] - font_wh[1], disp_str, color=font_color)
    display.show(img)

    三、代码实现
    通过右键录入人脸,左键删除人脸。

    from maix import nn, camera, image, display
    from maix.nn.app.face import FaceRecognize
    import time
    from evdev import InputDevice
    from select import select
    import pickle
    from maix import pwm
    import time
    pwm6 = pwm.PWM(6) #选择通道 这里接PH6
    pwm6.export() #设置出口
    pwm6.period = 20000000 # 表示 pwm 的周期,单位 ns
    pwm6.duty_cycle = 10000000 # 表示占空比,单位 ns
    pwm6.enable = True # 表示是否使能 pwm
    score_threshold = 70 #识别分数阈值
    input_size = (224, 224, 3) #输入图片尺寸
    input_size_fe = (128, 128, 3) #输入人脸数据
    feature_len = 256 #人脸数据宽度
    steps = [8, 16, 32] #
    channel_num = 0 #通道数量
    users = [] #初始化用户列表
    names = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] #人脸标签定义
    model = {
    "param": "/home/model/face_recognize/model_int8.param",
    "bin": "/home/model/face_recognize/model_int8.bin"
    }
    model_fe = {
    "param": "/home/model/face_recognize/fe_res18_117.param",
    "bin": "/home/model/face_recognize/fe_res18_117.bin"
    }


    for i in range(len(steps)):
    channel_num += input_size[1] / steps[i] * (input_size[0] / steps[i]) * 2
    channel_num = int(channel_num) #统计通道数量
    options = { #准备人脸输出参数
    "model_type": "awnn",
    "inputs": {
    "input0": input_size
    },
    "outputs": {
    "output0": (1, 4, channel_num) ,
    "431": (1, 2, channel_num) ,
    "output2": (1, 10, channel_num)
    },
    "mean": [127.5, 127.5, 127.5],
    "norm": [0.0078125, 0.0078125, 0.0078125],
    }
    options_fe = { #准备特征提取参数
    "model_type": "awnn",
    "inputs": {
    "inputs_blob": input_size_fe
    },
    "outputs": {
    "FC_blob": (1, 1, feature_len)
    },
    "mean": [127.5, 127.5, 127.5],
    "norm": [0.0078125, 0.0078125, 0.0078125],
    }
    keys = InputDevice('/dev/input/event0')

    threshold = 0.5 #人脸阈值
    nms = 0.3
    max_face_num = 1 #输出的画面中的人脸的最大个数
    print("-- load model:", model)
    m = nn.load(model, opt=options)
    print("-- load ok")
    print("-- load model:", model_fe)
    m_fe = nn.load(model_fe, opt=options_fe)
    print("-- load ok")
    face_recognizer = FaceRecognize(m, m_fe, feature_len, input_size, threshold, nms, max_face_num)

    def get_key(): #按键检测函数
    r,w,x = select([keys], [], [],0)
    if r:
    for event in keys.read():
    if event.value == 1 and event.code == 0x02: # 右键
    return 1
    elif event.value == 1 and event.code == 0x03: # 左键
    return 2
    elif event.value == 2 and event.code == 0x03: # 左键连按
    return 3
    return 0

    def map_face(box,points): #将224*224空间的位置转换到240*240空间内
    def tran(x):
    return int(x/224*240)
    box = list(map(tran, box))
    def tran_p(p):
    return list(map(tran, p))
    points = list(map(tran_p, points))
    return box,points
    def darw_info(draw, box, points, disp_str, bg_color=(255, 0, 0), font_color=(255, 255, 255)): #画框函数
    box,points = map_face(box,points)
    font_wh = draw.get_string_size(disp_str)
    for p in points:
    draw.draw_rectangle(p[0] - 1, p[1] -1, p[0] + 1, p[1] + 1, color=bg_color)
    draw.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3], color=bg_color, thickness=2)
    draw.draw_rectangle(box[0], box[1] - font_wh[1], box[0] + font_wh[0], box[1], color=bg_color, thickness = -1)
    draw.draw_string(box[0], box[1] - font_wh[1], disp_str, color=font_color)
    def recognize(feature): #进行人脸匹配
    def _compare(user): #定义映射函数
    return face_recognizer.compare(user, feature) #推测匹配分数 score相关分数
    face_score_l = list(map(_compare,users)) #映射特征数据在记录中的比对分数
    return max(enumerate(face_score_l), key=lambda x: x[-1]) #提取出人脸分数最大值和最大值所在的位置

    def run():
    img = camera.capture() #获取224*224*3的图像数据

    AI_img = img.copy().resize(224, 224)
    if not img:
    time.sleep(0.02)
    return
    faces = face_recognizer.get_faces(AI_img.tobytes(),False) #提取人脸特征信息
    if faces:
    for prob, box, landmarks, feature in faces:
    key_val = get_key()
    if key_val == 1: # 右键添加人脸记录
    if len(users) < len(names):
    print("add user:", len(users))
    users.append(feature)

    else:
    print("user full")
    elif key_val == 2: # 左键删除人脸记录
    if len(users) > 0:
    print("remove user:", names[len(users) - 1])
    users.pop()
    else:
    print("user empty")

    if len(users): #判断是否记录人脸
    maxIndex = recognize(feature)

    if maxIndex[1] > score_threshold: #判断人脸识别阈值,当分数大于阈值时认为是同一张脸,当分数小于阈值时认为是相似脸
    pwm6.duty_cycle = 15000000
    darw_info(img, box, landmarks, "{}:{:.2f}".format(names[maxIndex[0]], maxIndex[1]), font_color=(0, 0, 255, 255), bg_color=(0, 255, 0, 255))
    print("user: {}, score: {:.2f}".format(names[maxIndex[0]], maxIndex[1]))

    else:
    pwm6.duty_cycle = 10000000
    darw_info(img, box, landmarks, "{}:{:.2f}".format(names[maxIndex[0]], maxIndex[1]), font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))
    print("maybe user: {}, score: {:.2f}".format(names[maxIndex[0]], maxIndex[1]))
    else: #没有记录脸
    darw_info(img, box, landmarks, "error face", font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))


    display.show(img)

    if __name__ == "__main__":
    import signal
    def handle_signal_z(signum,frame):
    print("APP OVER")
    exit(0)
    signal.signal(signal.SIGINT,handle_signal_z)
    while True:
    run()

  • 相关阅读:
    SVN 初级教程
    572 node包管理工具
    571 node的events模块
    570 node内置模块fs
    569 node内置模块path
    568 node之JavaScript模块化:exports,module.exports,import,对象的引用赋值,require查找规则,export、import关键字,CommonJS的加载过程,ES Module加载过程
    567 node概述:Node程序传递参数,常见的全局对象,特殊的全局对象
    566 手写37个 原生JavaScript 系列汇总(含promise A+)
    565 手写promise源码
    564 函数的防抖和节流
  • 原文地址:https://www.cnblogs.com/lykbk/p/dsgddgz4543545545.html
Copyright © 2020-2023  润新知