V831 人脸识别
V831 人臉識別
- 人臉識別功能
- 參數說明
- 實例代碼
之前有個find_face,那個只是人臉檢測。今天測試的程序是人臉識別。首先看效果
選個人臉,按右鍵記錄一下
記錄成功,他現在就是“標本”然后以他為“標本”去識別其他人看看
懂我意思把,也可以左鍵刪除人臉特征,找另一個人右鍵錄入特征
人臉識別功能
人臉識別例程,右鍵錄入人臉特征,左鍵刪除人臉特征,屏幕顯示識別到的人臉標簽和分數,關機數據不保存。
文件地址 :https://github.com/sipeed/MaixPy3_scripts/blob/master/scripts/nn_face_recognition.py
注意自己的V831有沒有model_int8.param和model_int8.bin模型。
參數說明
該腳本使用人臉識別模塊 maix.nn.app.face。使用方法請參考:模塊 maix.nn.app.face
實例代碼
#!/usr/bin/python3 # MaixPy3人臉識別示例腳本 # 功能說明:通過V831上的按鍵控制學習人臉特征,并進行特征匹配 # 時間:2021年9月17日 # 作者:Neutree dianjixz from maix import nn from PIL import Image, ImageFont, ImageDraw from maix import camera, display import time from maix.nn.app.face import FaceRecognize from evdev import InputDevice from select import select import threading from evdev import InputDevice from select import selectclass funation: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/res/model_int8.param","bin": "/home/res/model_int8.bin"}model_fe = {"param": "/home/res/fe_res18_117.param","bin": "/home/res/fe_res18_117.bin"}fun_status = 0 #程序運行階段def __init__(self,device=None):for i in range(len(self.steps)):self.channel_num += self.input_size[1] / self.steps[i] * (self.input_size[0] / self.steps[i]) * 2self.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],}self.keys = InputDevice('/dev/input/event0')threading.Thread(target=self.load_mode).start() #開啟加載模型線程self.fun = [self.wait_run,self.run] #裝載階段程序self.event = self.fun[self.fun_status] #定義統一調用接口,相當于函數指針,此處將會裝載self.wait_run函數self.font = ImageFont.truetype("./res/baars.ttf",32, encoding="unic")def __del__(self):del self.m_fe #刪除特征識別模型del self.m #刪除人臉檢測模型del self.face_recognizer #刪除人臉識別類print("-- del face model success!")def get_key(self): #按鍵檢測函數r,w,x = select([self.keys], [], [],0)if r:for event in self.keys.read(): if event.value == 1 and event.code == 0x02: # 右鍵return 1elif event.value == 1 and event.code == 0x03: # 左鍵return 2elif event.value == 2 and event.code == 0x03: # 左鍵連按return 3return 0def load_mode(self): #模型加載函數,由模型加載線程啟動threshold = 0.5 #人臉閾值nms = 0.3 max_face_num = 1 #輸出的畫面中的人臉的最大個數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, threshold, nms, max_face_num)self.fun_status += 1self.event = self.fun[self.fun_status] #統一調用接口切換至self.run函數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,pointsdef darw_info(self,draw, box, points, disp_str, bg_color=(255, 0, 0, 255), font_color=(255, 255, 255, 255)): #畫框函數box,points = self.map_face(box,points)font_w, font_h = self.font.getsize(disp_str)for p in points:draw.rectangle((p[0] - 1, p[1] -1 , p[0] + 1, p[1] + 1), fill=bg_color)draw.rectangle((box[0], box[1], box[0] + box[2], box[1] + box[3]), fill=None, outline=bg_color, width=2)draw.rectangle((box[0], box[1] - font_h, box[0] + font_w, box[1]), fill=bg_color)draw.text((box[0], box[1] - font_h), disp_str, fill=font_color, font=self.font)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 wait_run(self): #等待模型加載階段tmp = camera.read(video_num = 1)display.show()def run(self): #模型加載完畢,準備運行階段img = camera.read(video_num = 1) #獲取224*224*3的圖像數據if not img:time.sleep(0.02)returnfaces = self.face_recognizer.get_faces(img,False) #提取人臉特征信息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 ]key_val = self.get_key()if key_val == 1: # 右鍵添加人臉記錄if len(self.users) < len(self.names):print("add user:", len(self.users))self.users.append(feature)else:print("user full")elif key_val == 2: # 左鍵刪除人臉記錄if len(self.users) > 0:print("remove user:", self.names[len(self.users) - 1])self.users.pop()else:print("user empty")draw = display.get_draw() #得到一張畫布if len(self.users): #判斷是否記錄人臉maxIndex = self.recognize(feature)if maxIndex[1] > self.score_threshold: #判斷人臉識別閾值,當分數大于閾值時認為是同一張臉,當分數小于閾值時認為是相似臉self.darw_info(draw, box, landmarks, "{}:{:.2f}".format(self.names[maxIndex[0]], maxIndex[1]), font_color=(0, 0, 255, 255), bg_color=(0, 255, 0, 255))print("user: {}, score: {:.2f}".format(self.names[maxIndex[0]], maxIndex[1]))else:self.darw_info(draw, box, landmarks, "{}:{:.2f}".format(self.names[maxIndex[0]], maxIndex[1]), font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))print("maybe user: {}, score: {:.2f}".format(self.names[maxIndex[0]], maxIndex[1]))else: #沒有記錄臉self.darw_info(draw, box, landmarks, "no face", font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))display.show()if __name__ == "__main__":import signaldef handle_signal_z(signum,frame):print("APP OVER")exit(0)signal.signal(signal.SIGINT,handle_signal_z)camera.config(size=(224,224))start = funation()while True:start.event()總結
- 上一篇: 微课与计算机技术的论文,微课计算机教学论
- 下一篇: 递归神经网络 matlab,机器学习系列