实现过程

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没起作用,第一种可能性大,有空我改一下代码,本人小白一枚,第一次写博客,还请多多指教,有任何问题评论区见。

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: