V831人脸识别(具有掉电记忆功能,用来做智能家居绝佳)

实现过程

1.代码基于spieed家开源模型文件建立,模型特点:无需预训练指定人脸模型,具有自学习指定人脸功能(重点),首先进入模型训练官网,搜索人脸识别模型,选择下面这个人脸识别模型文件:

2.下载完后的文件

3.修改main.py代码为以下代码

'''
    Face recognize demo, download modle from maixhub first:
            https://maixhub.com/
'''

from maix import nn, display, camera, image
from maix.nn.app import face
from maix.nn.app.face import FaceRecognize
import time
from evdev import InputDevice
from select import select
import pickle
import os

def get_keys(device):
    '''
        @return is_left_pressed, is_right_pressed
    '''
    left = False
    right = False
    r,w,x = select([device], [], [], 0)
    if r:
        for event in device.read():
            if event.value == 1 and event.code == 0x02:
                right = True
            elif event.value == 1 and event.code == 0x03:
                left = True
    return left, right


class Face_Recognizer:
    def __init__(self, threshold = 0.5, nms = 0.3, max_face_num = 1):
        model = "retinaface.mud"
        model_fe = "fe_resnet.mud"
        self.input_size = (224, 224, 3)
        input_size_fe = (128, 128, 3)
        self.feature_len = 256
        self.features = []
        print("-- load model:", model)
        m = nn.load(model)
        print("-- load ok")
        print("-- load model:", model_fe)
        m_fe = nn.load(model_fe)
        print("-- load ok")

        self.recognizer = FaceRecognize(m, m_fe, self.feature_len, self.input_size, threshold, nms, max_face_num)
        print("-- init end")

    def get_faces(self, img, std_img = False):
        faces = self.recognizer.get_faces(img, std_img)
        return faces

    def __len__(self):
        return len(self.features)

    def add_user(self, name, feature):
        self.features.append([name, feature])
        return True

    def remove_user(self, name_del):
        rm = None
        for name, feature in self.features:
            if name_del == name:
                rm = [name, feature]
        if rm:
            self.features.remove(rm)
            return True
        return False

    def recognize(self, feature):
        max_score = 0
        uid = -1
        for i, user in enumerate(self.features):
            score = self.recognizer.compare(user[1], feature)
            if score > max_score:
                max_score = score
                uid = i
        if uid >= 0:
            return self.features[uid][0], max_score
        return None, 0


    def get_input_size(self):
        '''
            @return input_size (w, h, c)
        '''
        return self.input_size

    def get_feature_len(self):
        return self.feature_len

    def darw_info(self, img, box, points, disp_str, bg_color=(255, 0, 0, 255), font_color=(255, 255, 255, 255), font_size=32):
        font_wh = image.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)
        if disp_str:
            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)


    def darw_title(self, img, dis_size ,key_l = None, key_r =None):
        if key_l :
            key_l = "| "+ key_l
            img.draw_string( 1, 2 ,key_l , scale = 1, color = (255, 255, 255), thickness = 2)
        if key_r:
            key_r = key_r+" |"
            w = int(dis_size[0] - 4 - image.get_string_size(key_r)[0] * 1)
            img.draw_string( w, 2 ,key_r , scale = 1, color = (255, 255, 255), thickness = 2)



max_face_num = 4
detect_threshold = 0.5
detect_nms = 0.3
score_threshold = 70
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"]

face_recognizer = Face_Recognizer(detect_threshold, detect_nms, max_face_num = max_face_num)
camera.config(size=face_recognizer.get_input_size()[:2])

keys_device = InputDevice('/dev/input/event0')
def key_pressed():
    l, r = get_keys(keys_device)
    return l, r

key_l = False
key_r = False






for idx in range(10):
    file_path = "/root/"+names[idx]+".pickle"  # 使用 f-string 进行字符串格式化

    try:
        with open(file_path, 'rb') as file:
            feature = pickle.load(file)
            face_recognizer.add_user(names[idx], feature)
    except FileNotFoundError:
        break
while 1:
    img = camera.capture().resize(size=face_recognizer.get_input_size()[:2])
    if not img:
        time.sleep(0.02)
        continue
    faces = face_recognizer.get_faces(img)
    l, r = key_pressed()
    key_l = l | key_l
    key_r = r | key_r


    face_recognizer.darw_title(img , face_recognizer.get_input_size()[:2] , "rm" ,"add")

    if faces:
        # for prob, box, landmarks, feature, std_img in faces:
        for prob, box, landmarks, feature in faces:
            # [ prob, [x,y,w,h], [[x,y], [x,y], [x,y], [x,y], [x,y]], feature ]
            if key_r:
                if len(face_recognizer) < len(names):
                    idx = len(face_recognizer)
                    print("add user: {}, {}".format(idx, names[idx]))
                    face_recognizer.add_user(names[idx], feature)
                    with open("/root/"+names[idx]+".pickle",'wb') as f://主要修改
                        pickle.dump(feature, f)//主要修改
                        os.fsync(f.fileno())//主要修改
                        f.flush()//主要修改

                else:
                    print("user full")
                key_r = False
            name, score = face_recognizer.recognize(feature)
            if name:
                if score > score_threshold:
                    face_recognizer.darw_info(img, box, landmarks, "{}:{:.2f}".format(name, score), font_color=(0, 0, 255, 255), bg_color=(0, 255, 0, 255))
                    print("user: {}, score: {:.2f}".format(name, score))
                else:
                    face_recognizer.darw_info(img, box, landmarks, "{}:{:.2f}".format(name, score), font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))
                    print("maybe user: {}, score: {:.2f}".format(name, score))
            else:
                face_recognizer.darw_info(img, box, landmarks, "", font_color=(255, 255, 255, 255), bg_color=(255, 255, 255, 255))

            if key_l:
                if len(face_recognizer) > 0 and score > 40:
                    idx = names.index(name)
                    print("remove user:", names[idx])
                    face_recognizer.remove_user(names[idx])
                    file_path = "/root/"+names[idx]+".pickle"  # 使用 f-string 进行字符串格式化
                    while os.path.exists(file_path):  # 只要文件还存在
                            os.remove(file_path)  # 尝试删除文件
                else:
                    print("user empty")
                key_l = False
    display.show(img)

 功能演示

【小小怪驾到】第一支视频求三连!

 4.代码主要调用pickle库,实现feature文件保存到SD卡,但是多次尝试发现文件写入效果不稳定,有时候保存不了,最后采用os.fsync() 函数,强制写入到SD卡中,保存成功,每次上电只需要读取一次SD卡中的数据,保存到列表中,就可以实现掉电存储,代码是基于官网模型代码改的,仍保留左键删除指定人脸(以当前人脸识别率高于40),右键添加人脸数据功能,但目前有一点小BUG,就是左键删除人脸数据,存在掉电之前有效,掉电重启后仍能识别,我猜是我删除路径没写对或者os.remove没起作用,第一种可能性大,有空我改一下代码,本人小白一枚,第一次写博客,还请多多指教,有任何问题评论区见。

  • 19
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值