From 3b62e5999aa93b4555b3187044796648d4d7d89a Mon Sep 17 00:00:00 2001 From: Neucrack Date: Thu, 11 Jul 2024 16:13:03 +0800 Subject: [PATCH] add face recognize app --- .../vision/ai_vision/nn_face_recognize.py | 100 +--------------- projects/app_face_recognizer/.gitignore | 5 + projects/app_face_recognizer/app.yaml | 10 ++ projects/app_face_recognizer/face.json | 1 + projects/app_face_recognizer/main.py | 111 ++++++++++++++++++ projects/app_yolov8_seg/app.yaml | 2 +- 6 files changed, 130 insertions(+), 99 deletions(-) create mode 100644 projects/app_face_recognizer/.gitignore create mode 100644 projects/app_face_recognizer/app.yaml create mode 100644 projects/app_face_recognizer/face.json create mode 100644 projects/app_face_recognizer/main.py diff --git a/examples/vision/ai_vision/nn_face_recognize.py b/examples/vision/ai_vision/nn_face_recognize.py index 1a58a5b..259cd1f 100644 --- a/examples/vision/ai_vision/nn_face_recognize.py +++ b/examples/vision/ai_vision/nn_face_recognize.py @@ -1,100 +1,4 @@ -from maix import nn, camera, display, image, time, touchscreen, app -import os -import math - - -recognizer = nn.FaceRecognizer(detect_model="/root/models/retinaface.mud", feature_model = "/root/models/face_feature.mud") - -# if os.path.exists("/root/faces.bin"): -# recognizer.load_faces("/root/faces.bin") - -cam = camera.Camera(recognizer.input_width(), recognizer.input_height(), recognizer.input_format()) -disp = display.Display() -ts = touchscreen.TouchScreen() -back_btn_pos = (0, 0, 70, 30) # x, y, w, h -learn_btn_pos = (0, recognizer.input_height() - 30, 60, 30) -clear_btn_pos = (recognizer.input_width() - 60, recognizer.input_height() - 30, 60, 30) -back_btn_disp_pos = image.resize_map_pos(cam.width(), cam.height(), disp.width(), disp.height(), image.Fit.FIT_CONTAIN, back_btn_pos[0], back_btn_pos[1], back_btn_pos[2], back_btn_pos[3]) -learn_btn_disp_pos = image.resize_map_pos(cam.width(), cam.height(), disp.width(), disp.height(), image.Fit.FIT_CONTAIN, learn_btn_pos[0], learn_btn_pos[1], learn_btn_pos[2], learn_btn_pos[3]) -clear_btn_disp_pos = image.resize_map_pos(cam.width(), cam.height(), disp.width(), disp.height(), image.Fit.FIT_CONTAIN, clear_btn_pos[0], clear_btn_pos[1], clear_btn_pos[2], clear_btn_pos[3]) -pressed_flag = [False, False, False] - -def draw_btns(img : image.Image): - img.draw_rect(back_btn_pos[0], back_btn_pos[1], back_btn_pos[2], back_btn_pos[3], image.Color.from_rgb(255, 255, 255), 2) - img.draw_string(back_btn_pos[0] + 4, back_btn_pos[1] + 8, "< back", image.COLOR_WHITE) - img.draw_rect(learn_btn_pos[0], learn_btn_pos[1], learn_btn_pos[2], learn_btn_pos[3], image.Color.from_rgb(255, 255, 255), 2) - img.draw_string(learn_btn_pos[0] + 4, learn_btn_pos[1] + 8, "learn", image.COLOR_WHITE) - img.draw_rect(clear_btn_pos[0], clear_btn_pos[1], clear_btn_pos[2], clear_btn_pos[3], image.Color.from_rgb(255, 255, 255), 2) - img.draw_string(clear_btn_pos[0] + 4, clear_btn_pos[1] + 8, "clear", image.COLOR_WHITE) - -def is_in_button(x, y, btn_pos): - return x > btn_pos[0] and x < btn_pos[0] + btn_pos[2] and y > btn_pos[1] and y < btn_pos[1] + btn_pos[3] - -def on_touch(x, y, pressed): - ''' - Return learn, clear, ret - ''' - global pressed_flag - if pressed: - if is_in_button(x, y, back_btn_disp_pos): - pressed_flag[2] = True - elif is_in_button(x, y, learn_btn_disp_pos): - pressed_flag[0] = True - elif is_in_button(x, y, clear_btn_disp_pos): - pressed_flag[1] = True - else: # cancel - pressed_flag = [False, False, False] - else: - if pressed_flag[0]: - print("learn btn click") - pressed_flag[0] = False - return True, False, False - if pressed_flag[1]: - print("clear btn click") - pressed_flag[1] = False - return False, True, False - if pressed_flag[2]: - print("back btn click") - pressed_flag[2] = False - return False, False, True - return False, False, False - -# Init key will cancel the default ok button function(exit app) -learn_id = 0 -last_learn_img = None -last_learn_t = 0 - -while not app.need_exit(): - x, y, pressed = ts.read() - learn, clear, back = on_touch(x, y, pressed) - if back: - break - elif clear: - for i in range(len(recognizer.labels) - 1): - recognizer.remove_face(0) - img = cam.read() - faces = recognizer.recognize(img, 0.5, 0.45, 0.8, learn, learn) - for obj in faces: - color = image.COLOR_RED if obj.class_id == 0 else image.COLOR_GREEN - img.draw_rect(obj.x, obj.y, obj.w, obj.h, color = color) - radius = math.ceil(obj.w / 10) - img.draw_keypoints(obj.points, color, size = radius if radius < 5 else 4) - msg = f'{recognizer.labels[obj.class_id]}: {obj.score:.2f}' - img.draw_string(obj.x, obj.y, msg, color = color) - if learn and obj.class_id == 0: # unknown face, we add it - name = f"id_{learn_id}" - print("add face:", name) - recognizer.add_face(obj, name) - learn_id += 1 - if learn: - last_learn_img = obj.face - last_learn_t = time.ticks_s() - # show learned face on left-top - if last_learn_img and time.ticks_s() - last_learn_t < 5: - img.draw_image(0, 0, last_learn_img) - if learn: - recognizer.save_faces("/root/faces.bin") - draw_btns(img) - disp.show(img) +# see https://github.com/sipeed/maixpy/blob/main/projects/app_face_recognizer +# and https://wiki.sipeed.com/maixpy/doc/zh/vision/face_recognition.html diff --git a/projects/app_face_recognizer/.gitignore b/projects/app_face_recognizer/.gitignore new file mode 100644 index 0000000..babf76a --- /dev/null +++ b/projects/app_face_recognizer/.gitignore @@ -0,0 +1,5 @@ + +build +dist +/CMakeLists.txt + diff --git a/projects/app_face_recognizer/app.yaml b/projects/app_face_recognizer/app.yaml new file mode 100644 index 0000000..a1722b8 --- /dev/null +++ b/projects/app_face_recognizer/app.yaml @@ -0,0 +1,10 @@ +id: face_recognizer +name: Face Recognizer +version: 1.0.0 +author: Sipeed Ltd +icon: face.json +desc: Learn and recognize face. +files: + - face.json + - app.yaml + - main.py diff --git a/projects/app_face_recognizer/face.json b/projects/app_face_recognizer/face.json new file mode 100644 index 0000000..cd308b8 --- /dev/null +++ b/projects/app_face_recognizer/face.json @@ -0,0 +1 @@ +{"v":"4.10.2","fr":25,"ip":0,"op":150,"w":102,"h":102,"nm":"Face ID","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Calque de forme 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[51,51,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[89.129,89.512],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[22],"e":[55]},{"t":87}],"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0,0.824,0.757,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":2,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.064,0.256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[94.27,94.27],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[12],"e":[2]},{"t":83}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[26],"e":[33]},{"t":83}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[0],"e":[-25]},{"t":87}],"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":4525,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[51,51,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[89.129,89.512],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[22],"e":[55]},{"t":87}],"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0,0.824,0.757,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":2,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.064,0.256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[94.27,94.27],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[37],"e":[21]},{"t":83}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[52],"e":[64]},{"t":83}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[0],"e":[-30]},{"t":87}],"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":4525,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Calque de forme 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[51,51,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[89.129,89.512],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[22],"e":[55]},{"t":87}],"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0,0.824,0.757,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":2,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.064,0.256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[94.27,94.27],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[61],"e":[54]},{"t":83}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[77],"e":[83]},{"t":83}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[0],"e":[-27]},{"t":87}],"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":4525,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Calque de forme 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[51,51,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[89.129,89.512],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[22],"e":[55]},{"t":87}],"ix":4},"nm":"Tracé rectangulaire 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0,0.824,0.757,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":2,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.064,0.256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[94.27,94.27],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[92],"e":[98]},{"t":83}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[76],"e":[68]},{"t":83}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":77,"s":[39],"e":[8]},{"t":87}],"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":4525,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Précomp. 3","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[51,51,0],"ix":2},"a":{"a":0,"k":[51,51,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":102,"h":102,"ip":0,"op":4525,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"check Silhouettes","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[53.202,50.422,0],"ix":2},"a":{"a":0,"k":[28.559,24.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-21.104,-2.096],[-3.247,17.046],[21.104,-17.046]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0.824,0.757,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4.982,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[28.559,24.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.572],"y":[0.724]},"o":{"x":[0],"y":[0]},"n":["0p572_0p724_0_0"],"t":117.5,"s":[0],"e":[100]},{"i":{"x":[0.681],"y":[0.465]},"o":{"x":[0.346],"y":[-0.93]},"n":["0p681_0p465_0p346_-0p93"],"t":121.5,"s":[100],"e":[85]},{"i":{"x":[0.677],"y":[0.199]},"o":{"x":[0.343],"y":[-0.889]},"n":["0p677_0p199_0p343_-0p889"],"t":124,"s":[85],"e":[91.479]},{"i":{"x":[0.68],"y":[1]},"o":{"x":[0.346],"y":[1.828]},"n":["0p68_1_0p346_1p828"],"t":125.667,"s":[91.479],"e":[93]},{"t":126.5}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":4525,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"nez Silhouettes","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":110,"s":[100],"e":[0]},{"t":116}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":34.093,"s":[50.7,48.168,0],"e":[50.7,48.168,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":44.921,"s":[50.7,48.168,0],"e":[63.7,48.168,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.473,"s":[63.7,48.168,0],"e":[63.7,48.168,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":64,"s":[63.7,48.168,0],"e":[51.022,42.605,0],"to":[0,0,0],"ti":[6.33444213867188,-0.08209228515625,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":71,"s":[51.022,42.605,0],"e":[41.921,48.168,0],"to":[-6.33444213867188,0.08209228515625,0],"ti":[-0.14103698730469,-3.08209228515625,0]},{"i":{"x":0.574,"y":0.761},"o":{"x":0.167,"y":0.167},"n":"0p574_0p761_0p167_0p167","t":76.112,"s":[41.921,48.168,0],"e":[47.306,51.918,0],"to":[0.14103698730469,3.08209228515625,0],"ti":[-2.96309494972229,2.36847585645308e-15,0]},{"i":{"x":0.704,"y":1},"o":{"x":0.338,"y":0.2},"n":"0p704_1_0p338_0p2","t":80,"s":[47.306,51.918,0],"e":[50.7,48.168,0],"to":[2.65059494972229,-2.11868668734073e-15,0],"ti":[0,0,0]},{"t":83}],"ix":2},"a":{"a":0,"k":[12.25,28.75,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.449,0],[-0.266,4.731],[0,0],[-3.449,0],[0,-3.406],[0,0],[0,0],[10.743,0],[0,3.405]],"o":[[3.746,0],[0,0],[0,-3.406],[3.449,0],[0,0],[0,0],[-0.57,11.147],[-3.449,0],[0,-3.406]],"v":[[-5.755,16.167],[-0.49,10.17],[-0.49,-22.334],[5.755,-28.5],[12,-22.334],[12,10.333],[11.992,10.644],[-5.755,28.5],[-12,22.334]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.824,0.757,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[12.25,28.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":750,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"yeux Silhouettes 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":99.018,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":99.391,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":100.509,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":100.882,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":110,"s":[100],"e":[0]},{"t":116}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":34.093,"s":[67.1,42.168,0],"e":[67.1,42.168,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":44.921,"s":[67.1,42.168,0],"e":[75.1,42.168,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.473,"s":[75.1,42.168,0],"e":[75.1,42.168,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":64.043,"s":[75.1,42.168,0],"e":[67.244,37.793,0],"to":[0,0,0],"ti":[5.18186950683594,-0.01980590820312,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":70.777,"s":[67.244,37.793,0],"e":[61.544,42.168,0],"to":[-5.18186950683594,0.01980590820312,0],"ti":[0.04396057128906,-1.76980590820312,0]},{"i":{"x":0.574,"y":0.824},"o":{"x":0.167,"y":0.167},"n":"0p574_0p824_0p167_0p167","t":76.574,"s":[61.544,42.168,0],"e":[64.952,45.918,0],"to":[-0.04396057128906,1.76980590820312,0],"ti":[-2.17288208007812,-0.01980590820312,0]},{"i":{"x":0.704,"y":1},"o":{"x":0.338,"y":0.145},"n":"0p704_1_0p338_0p145","t":80,"s":[64.952,45.918,0],"e":[67.1,42.168,0],"to":[2.17288208007812,0.01980590820312,0],"ti":[0,0,0]},{"t":83}],"ix":2},"a":{"a":0,"k":[6.25,13.75,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":98.272,"s":[{"i":[[0,0],[-3.313,0],[0,-3.441],[0,0],[3.313,0],[0,3.44]],"o":[[0,-3.441],[3.313,0],[0,0],[0,3.44],[-3.313,0],[0,0]],"v":[[-6,-7.269],[0,-13.5],[6,-7.269],[6,7.27],[0,13.5],[-6,7.27]],"c":true}],"e":[{"i":[[0,0],[-3.313,0],[0,-3.441],[0,0],[3.313,0],[0,3.44]],"o":[[0,-3.441],[3.313,0],[0,0],[0,3.44],[-3.313,0],[0,0]],"v":[[-6,0.231],[0,-6],[6,0.231],[6,0.708],[0,6.938],[-6,0.708]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":99.391,"s":[{"i":[[0,0],[-3.313,0],[0,-3.441],[0,0],[3.313,0],[0,3.44]],"o":[[0,-3.441],[3.313,0],[0,0],[0,3.44],[-3.313,0],[0,0]],"v":[[-6,0.231],[0,-6],[6,0.231],[6,0.708],[0,6.938],[-6,0.708]],"c":true}],"e":[{"i":[[0,0],[-3.313,0],[0,-3.441],[0,0],[3.313,0],[0,3.44]],"o":[[0,-3.441],[3.313,0],[0,0],[0,3.44],[-3.313,0],[0,0]],"v":[[-6,0.231],[0,-6],[6,0.231],[6,0.708],[0,6.938],[-6,0.708]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":100.509,"s":[{"i":[[0,0],[-3.313,0],[0,-3.441],[0,0],[3.313,0],[0,3.44]],"o":[[0,-3.441],[3.313,0],[0,0],[0,3.44],[-3.313,0],[0,0]],"v":[[-6,0.231],[0,-6],[6,0.231],[6,0.708],[0,6.938],[-6,0.708]],"c":true}],"e":[{"i":[[0,0],[-3.313,0],[0,-3.441],[0,0],[3.313,0],[0,3.44]],"o":[[0,-3.441],[3.313,0],[0,0],[0,3.44],[-3.313,0],[0,0]],"v":[[-6,-7.269],[0,-13.5],[6,-7.269],[6,7.27],[0,13.5],[-6,7.27]],"c":true}]},{"t":102}],"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.824,0.757,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[6.25,13.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":750,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"yeux Silhouettes","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":110,"s":[100],"e":[0]},{"t":116}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":34.093,"s":[35.9,42.168,0],"e":[35.9,42.168,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":44.921,"s":[35.9,42.168,0],"e":[43.9,42.168,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.473,"s":[43.9,42.168,0],"e":[43.9,42.168,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":64.043,"s":[43.9,42.168,0],"e":[36.056,38.48,0],"to":[0,0,0],"ti":[3.555908203125,-0.08230590820312,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":70.777,"s":[36.056,38.48,0],"e":[30.344,42.168,0],"to":[-3.555908203125,0.08230590820312,0],"ti":[-0.03103637695312,-2.20730590820312,0]},{"i":{"x":0.574,"y":0.826},"o":{"x":0.167,"y":0.167},"n":"0p574_0p826_0p167_0p167","t":76.574,"s":[30.344,42.168,0],"e":[33.748,45.918,0],"to":[0.03103637695312,2.20730590820312,0],"ti":[-2.23937940597534,0,0]},{"i":{"x":0.704,"y":1},"o":{"x":0.338,"y":0.15},"n":"0p704_1_0p338_0p15","t":80,"s":[33.748,45.918,0],"e":[35.9,42.168,0],"to":[1.6760071516037,0,0],"ti":[0,0,0]},{"t":83}],"ix":2},"a":{"a":0,"k":[6.25,13.75,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-3.313,0],[0,-3.441],[0,0],[3.313,0],[0,3.44]],"o":[[0,-3.441],[3.313,0],[0,0],[0,3.44],[-3.313,0],[0,0]],"v":[[-6,-7.269],[0,-13.5],[6,-7.269],[6,7.27],[0,13.5],[-6,7.27]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.824,0.757,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[6.25,13.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":750,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"bouche Silhouettes","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":110,"s":[100],"e":[0]},{"t":116}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":34.093,"s":[51.5,68.446,0],"e":[51.5,68.446,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":45.176,"s":[51.5,68.446,0],"e":[59.5,68.446,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52,"s":[59.5,68.446,0],"e":[59.5,68.446,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":64,"s":[59.5,68.446,0],"e":[51.619,64.696,0],"to":[0,0,0],"ti":[5.30685424804688,-0.11619567871094,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":70.721,"s":[51.619,64.696,0],"e":[45.937,68.446,0],"to":[-5.30685424804688,0.11619567871094,0],"ti":[0.0618896484375,-1.61619567871094,0]},{"i":{"x":0.574,"y":0.828},"o":{"x":0.167,"y":0.167},"n":"0p574_0p828_0p167_0p167","t":76.574,"s":[45.937,68.446,0],"e":[49.349,72.196,0],"to":[-0.0618896484375,1.61619567871094,0],"ti":[-2.80197405815125,-0.01979235187173,0]},{"i":{"x":0.704,"y":1},"o":{"x":0.338,"y":0.137},"n":"0p704_1_0p338_0p137","t":80,"s":[49.349,72.196,0],"e":[51.5,68.446,0],"to":[2.92718553543091,0.0625,0],"ti":[0,0,0]},{"t":83}],"ix":2},"a":{"a":0,"k":[36.868,12.054,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.916,8.522],[-2.323,2.356],[-2.393,-2.287],[-10.708,0],[-6.58,6.29],[-2.322,-2.356],[2.393,-2.287],[13.747,0]],"o":[[-2.393,-2.287],[2.321,-2.356],[6.58,6.29],[10.708,0],[2.393,-2.287],[2.323,2.356],[-8.916,8.522],[-13.746,0]],"v":[[-34.167,-0.985],[-34.295,-9.392],[-25.758,-9.517],[-0.001,-0.087],[25.758,-9.517],[34.295,-9.392],[34.168,-0.985],[-0.001,11.804]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.824,0.757,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[36.867,12.054],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":750,"st":0,"bm":0}]} \ No newline at end of file diff --git a/projects/app_face_recognizer/main.py b/projects/app_face_recognizer/main.py new file mode 100644 index 0000000..1000c04 --- /dev/null +++ b/projects/app_face_recognizer/main.py @@ -0,0 +1,111 @@ +from maix import nn, camera, display, image, time, touchscreen, app +import math + +pressed_flag = [False, False, False] +learn_id = 0 + +def main(disp): + recognizer = nn.FaceRecognizer(detect_model="/root/models/retinaface.mud", feature_model = "/root/models/face_feature.mud") + + # if os.path.exists("/root/faces.bin"): + # recognizer.load_faces("/root/faces.bin") + + cam = camera.Camera(recognizer.input_width(), recognizer.input_height(), recognizer.input_format()) + ts = touchscreen.TouchScreen() + back_btn_pos = (0, 0, 70, 30) # x, y, w, h + learn_btn_pos = (0, recognizer.input_height() - 30, 60, 30) + clear_btn_pos = (recognizer.input_width() - 60, recognizer.input_height() - 30, 60, 30) + back_btn_disp_pos = image.resize_map_pos(cam.width(), cam.height(), disp.width(), disp.height(), image.Fit.FIT_CONTAIN, back_btn_pos[0], back_btn_pos[1], back_btn_pos[2], back_btn_pos[3]) + learn_btn_disp_pos = image.resize_map_pos(cam.width(), cam.height(), disp.width(), disp.height(), image.Fit.FIT_CONTAIN, learn_btn_pos[0], learn_btn_pos[1], learn_btn_pos[2], learn_btn_pos[3]) + clear_btn_disp_pos = image.resize_map_pos(cam.width(), cam.height(), disp.width(), disp.height(), image.Fit.FIT_CONTAIN, clear_btn_pos[0], clear_btn_pos[1], clear_btn_pos[2], clear_btn_pos[3]) + + def draw_btns(img : image.Image): + img.draw_rect(back_btn_pos[0], back_btn_pos[1], back_btn_pos[2], back_btn_pos[3], image.Color.from_rgb(255, 255, 255), 2) + img.draw_string(back_btn_pos[0] + 4, back_btn_pos[1] + 8, "< back", image.COLOR_WHITE) + img.draw_rect(learn_btn_pos[0], learn_btn_pos[1], learn_btn_pos[2], learn_btn_pos[3], image.Color.from_rgb(255, 255, 255), 2) + img.draw_string(learn_btn_pos[0] + 4, learn_btn_pos[1] + 8, "learn", image.COLOR_WHITE) + img.draw_rect(clear_btn_pos[0], clear_btn_pos[1], clear_btn_pos[2], clear_btn_pos[3], image.Color.from_rgb(255, 255, 255), 2) + img.draw_string(clear_btn_pos[0] + 4, clear_btn_pos[1] + 8, "clear", image.COLOR_WHITE) + + def is_in_button(x, y, btn_pos): + return x > btn_pos[0] and x < btn_pos[0] + btn_pos[2] and y > btn_pos[1] and y < btn_pos[1] + btn_pos[3] + + def on_touch(x, y, pressed): + ''' + Return learn, clear, ret + ''' + global pressed_flag, learn_id + if pressed: + if is_in_button(x, y, back_btn_disp_pos): + pressed_flag[2] = True + elif is_in_button(x, y, learn_btn_disp_pos): + pressed_flag[0] = True + elif is_in_button(x, y, clear_btn_disp_pos): + pressed_flag[1] = True + else: # cancel + pressed_flag = [False, False, False] + else: + if pressed_flag[0]: + print("learn btn click") + pressed_flag[0] = False + return True, False, False + if pressed_flag[1]: + print("clear btn click") + pressed_flag[1] = False + learn_id = 0 + return False, True, False + if pressed_flag[2]: + print("back btn click") + pressed_flag[2] = False + return False, False, True + return False, False, False + + # Init key will cancel the default ok button function(exit app) + last_learn_img = None + last_learn_t = 0 + + while not app.need_exit(): + x, y, pressed = ts.read() + learn, clear, back = on_touch(x, y, pressed) + if back: + break + elif clear: + for i in range(len(recognizer.labels) - 1): + recognizer.remove_face(0) + img = cam.read() + faces = recognizer.recognize(img, 0.5, 0.45, 0.8, learn, learn) + for obj in faces: + color = image.COLOR_RED if obj.class_id == 0 else image.COLOR_GREEN + img.draw_rect(obj.x, obj.y, obj.w, obj.h, color = color) + radius = math.ceil(obj.w / 10) + img.draw_keypoints(obj.points, color, size = radius if radius < 5 else 4) + msg = f'{recognizer.labels[obj.class_id]}: {obj.score:.2f}' + img.draw_string(obj.x, obj.y - 10, msg, color = color) + if learn and obj.class_id == 0: # unknown face, we add it + name = f"id_{learn_id}" + print("add face:", name) + recognizer.add_face(obj, name) + learn_id += 1 + if learn: + last_learn_img = obj.face + last_learn_t = time.ticks_s() + # show learned face on left-top + if last_learn_img and time.ticks_s() - last_learn_t < 5: + img.draw_image(0, 0, last_learn_img) + if learn: + recognizer.save_faces("/root/faces.bin") + draw_btns(img) + disp.show(img) + + +disp = display.Display() +try: + main(disp) +except Exception: + import traceback + msg = traceback.format_exc() + img = image.Image(disp.width(), disp.height()) + img.draw_string(0, 0, msg, image.COLOR_WHITE) + disp.show(img) + while not app.need_exit(): + time.sleep_ms(100) diff --git a/projects/app_yolov8_seg/app.yaml b/projects/app_yolov8_seg/app.yaml index 5cbf94a..42f4a9d 100644 --- a/projects/app_yolov8_seg/app.yaml +++ b/projects/app_yolov8_seg/app.yaml @@ -3,7 +3,7 @@ name: YOLOv8 Segmentation version: 1.0.0 author: Sipeed Ltd icon: icon.png -desc: Detect human body 17 keypoints. +desc: YOLOv8 detect objects and segment object files: - icon.png - app.yaml