Forked from anoken/191204_face_recognition_m5stickv.py
Last active
November 2, 2023 06:53
-
-
Save kirurobo/f28139af75440c58d728317cedda5b7a to your computer and use it in GitHub Desktop.
参考 #M5StickV でお顔認証する手順 https://qiita.com/nnn112358/items/ef3435d113c03d44d574
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# @anoken2017 | |
# demo_face_recognition m5-custom firm needed | |
# fork https://github.com/sipeed/MaixPy_scripts/blob/master/machine_vision/demo_face_recognition.py | |
# 参考 #M5StickV でお顔認証する手順 https://qiita.com/nnn112358/items/ef3435d113c03d44d574 | |
import sensor,image,lcd #関連ライブラリ | |
import KPU as kpu | |
import time | |
from Maix import FPIOA,GPIO,utils | |
from fpioa_manager import fm | |
from board import board_info | |
print(kpu.memtest()) | |
# kflash で書きこむ場所に合わせる | |
task_fd = kpu.load(0x200000) #FaceDetection.smodel 顔検出モデルのロード | |
task_ld = kpu.load(0x300000) #FaceLandmarkDetection.smodel 顔に5ポイントキーポイント検出モデルを読み込む | |
task_fe = kpu.load(0x400000) #FeatureExtraction.smodel 顔の196次元の固有値モデルを読み込む | |
print(kpu.memtest()) | |
clock = time.clock() #システムクロックを初期化し、フレームレートを計算する | |
fm.register(board_info.BUTTON_A, fm.fpioa.GPIO1) #設定ボタンピン | |
key_gpio=GPIO(GPIO.GPIO1, GPIO.IN, GPIO.PULL_UP) | |
last_key_state=1 | |
key_pressed=0 #キーピンを初期化する | |
def check_key(): #ループでキーが押されたかどうかを検出するために使用されるキー検出機能、立ち下がりエッジが有効 | |
global last_key_state | |
global key_pressed | |
val=key_gpio.value() | |
if last_key_state == 1 and val == 0: | |
key_pressed=1 | |
else: | |
key_pressed=0 | |
last_key_state = val | |
lcd.init(type=3) #LCD初期化。ファームウェア v0.6以降では type が必要なよう | |
lcd.rotation(0) #センサーカメラを初期化する | |
sensor.reset() | |
sensor.set_pixformat(sensor.RGB565) | |
sensor.set_framesize(sensor.QVGA) | |
sensor.set_hmirror(1) #カメラミラーリングの設定 | |
sensor.set_vflip(1) #カメラのフリップを設定する | |
sensor.run(1) #カメラを有効にする | |
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025) #anchor for face detect | |
#顔検出用アンカー | |
dst_point = [(44,59),(84,59),(64,82),(47,105),(81,105)] | |
#標準顔のキーポイントの位置標準顔の5つのキーポイント座標は、左目、右目、鼻、左口の角、右口の角 | |
a = kpu.init_yolo2(task_fd, 0.5, 0.3, 5, anchor) #顔検出モデルを初期化する | |
img_lcd=image.Image() | |
img_face=image.Image(size=(128,128)) | |
a=img_face.pix_to_ai() | |
record_ftr=[] | |
record_ftrs=[] | |
names = ['Mr.1', 'Mr.2', 'Mr.3', 'Mr.4', 'Mr.5', 'Mr.6', 'Mr.7', 'Mr.8', 'Mr.9' , 'Mr.10'] | |
while(1): | |
check_key() | |
img = sensor.snapshot() | |
clock.tick() | |
# 手元の環境ではしばらく経過後に失敗することがあったため | |
if not img: | |
continue | |
code = kpu.run_yolo2(task_fd, img) | |
if code: | |
for i in code: | |
# Cut face and resize to 128x128 | |
a = img.draw_rectangle(i.rect()) | |
face_cut=img.cut(i.x(),i.y(),i.w(),i.h()) | |
face_cut_128=face_cut.resize(128,128) | |
a=face_cut_128.pix_to_ai() | |
#a = img.draw_image(face_cut_128, (0,0)) | |
# Landmark for face 5 points | |
fmap = kpu.forward(task_ld, face_cut_128) | |
plist=fmap[:] | |
le=(i.x()+int(plist[0]*i.w() - 10), i.y()+int(plist[1]*i.h())) | |
re=(i.x()+int(plist[2]*i.w()), i.y()+int(plist[3]*i.h())) | |
nose=(i.x()+int(plist[4]*i.w()), i.y()+int(plist[5]*i.h())) | |
lm=(i.x()+int(plist[6]*i.w()), i.y()+int(plist[7]*i.h())) | |
rm=(i.x()+int(plist[8]*i.w()), i.y()+int(plist[9]*i.h())) | |
a = img.draw_circle(le[0], le[1], 4) | |
a = img.draw_circle(re[0], re[1], 4) | |
a = img.draw_circle(nose[0], nose[1], 4) | |
a = img.draw_circle(lm[0], lm[1], 4) | |
a = img.draw_circle(rm[0], rm[1], 4) | |
# align face to standard position | |
src_point = [le, re, nose, lm, rm] | |
T=image.get_affine_transform(src_point, dst_point) | |
a=image.warp_affine_ai(img, img_face, T) | |
a=img_face.ai_to_pix() | |
#a = img.draw_image(img_face, (128,0)) | |
del(face_cut_128) | |
# calculate face feature vector | |
fmap = kpu.forward(task_fe, img_face) | |
feature=kpu.face_encode(fmap[:]) | |
## 196次元の特徴ベクトルをコンマ区切りで出力 | |
#print(','.join([str(c) for c in feature])) | |
reg_flag = False | |
scores = [] | |
for j in range(len(record_ftrs)): | |
score = kpu.face_compare(record_ftrs[j], feature) | |
scores.append(score) | |
max_score = 0 | |
index = 0 | |
for k in range(len(scores)): | |
if max_score < scores[k]: | |
max_score = scores[k] | |
index = k | |
if max_score > 85: | |
a = img.draw_string(i.x(),i.y(), ("%s :%2.1f" % (names[index], max_score)), color=(0,255,0),scale=2) | |
else: | |
a = img.draw_string(i.x(),i.y(), ("X :%2.1f" % (max_score)), color=(255,0,0),scale=2) | |
if key_pressed == 1: | |
key_pressed = 0 | |
record_ftr = feature | |
record_ftrs.append(record_ftr) | |
break | |
fps =clock.fps() | |
#print("%2.1f fps"%fps) | |
a = lcd.display(img) | |
#kpu.memtest() | |
#a = kpu.deinit(task_fe) | |
#a = kpu.deinit(task_ld) | |
#a = kpu.deinit(task_fd) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment