V831学习笔记

前言:本文主要是以记录V831使用过程中一些经典历程使用笔记以及踩过的坑

一步一步向前走

1.介绍

在这里插入图片描述

2.例程

1.串口

先看这里https://wiki.sipeed.com/soft/maixpy3/zh/usage/hardware/UART.html
在 Linux 系统中,串口是以设备的形式存在(/dev/ttyS*),所使用的方式和原来的单片机方式有所不同。这是系统标准的 UART 通讯,和 Linux 系统中的串口操作相似。下面以 MaixII-Dock 为例子,来简单的简述一下如何使用 UART。

1.简单发送
import serial
ser = serial.Serial("/dev/ttyS1",115200)    # 连接串口
print('serial test start ...')              
ser.write(b"Hello Wrold !!!\n")             # 输入需要通讯的内容
for i in range(3):
    tmp = ser.readline()
    print(tmp)
    ser.write(tmp)

2.str与b

一、strbytes:
        第一种:在str类型前加b,即b"str"
        第二种:在str后加.encode("utf-8"),即str.encode("utf-8"),编码方式默认是utf-8,里面                  的"utf- 8"可以省略,下同。
二、bytesstr:
         只有一种方法:在bytes后加.decode("utf-8"),即bytes.encode("utf-8")

3.DOME

1.人脸识别

1.代码(2023.4.21修正)

1.经典

废话不多讲,先上代码

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

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/model/face_recognize/model_int8.param",
    "bin": "/home/model/face_recognize/model_int8.bin"
}
model_fe = {
    "param": "/home/model/face_recognize/fe_res18_117.param",
    "bin": "/home/model/face_recognize/fe_res18_117.bin"
}


for i in range(len(steps)):
    channel_num += input_size[1] / steps[i] * (input_size[0] / steps[i]) * 2
channel_num = int(channel_num)     #统计通道数量
options = {                             #准备人脸输出参数
    "model_type":  "awnn",
    "inputs": {
        "input0": input_size
    },
    "outputs": {
        "output0": (1, 4, channel_num) ,
        "431": (1, 2, channel_num) ,
        "output2": (1, 10, channel_num) 
    },
    "mean": [127.5, 127.5, 127.5],
    "norm": [0.0078125, 0.0078125, 0.0078125],
}
options_fe = {                             #准备特征提取参数
    "model_type":  "awnn",
    "inputs": {
        "inputs_blob": input_size_fe
    },
    "outputs": {
        "FC_blob": (1, 1, feature_len)
    },
    "mean": [127.5, 127.5, 127.5],
    "norm": [0.0078125, 0.0078125, 0.0078125],
}
keys = InputDevice('/dev/input/event0')

threshold = 0.5                                         #人脸阈值
nms = 0.3                                               
max_face_num = 1                                        #输出的画面中的人脸的最大个数
print("-- load model:", model)
m = nn.load(model, opt=options)
print("-- load ok")
print("-- load model:", model_fe)
m_fe = nn.load(model_fe, opt=options_fe)
print("-- load ok")
face_recognizer = FaceRecognize(m, m_fe, feature_len, input_size, threshold, nms, max_face_num)

def get_key():                                      #按键检测函数
    r,w,x = select([keys], [], [],0)
    if r:
        for event in keys.read(): 
            if event.value == 1 and event.code == 0x02:     # 右键
                return 1
            elif event.value == 1 and event.code == 0x03:   # 左键
                return 2
            elif event.value == 2 and event.code == 0x03:   # 左键连按
                return 3
    return 0

def map_face(box,points):                           #将224*224空间的位置转换到240*240或320*240空间内
    # print(box,points)
    if display.width() == display.height():
        def tran(x):
            return int(x/224*display.width())
        box = list(map(tran, box))
        def tran_p(p):
            return list(map(tran, p))
        points = list(map(tran_p, points))
    else:
        # 168x224(320x240) > 224x224(240x240) > 320x240
        s = (224*display.height()/display.width()) # 168x224
        w, h, c = display.width()/224, display.height()/224, 224/s
        t, d = c*h, (224 - s) // 2 # d = 224 - s // 2 == 28
        box[0], box[1], box[2], box[3] = int(box[0]*w), int((box[1]-28)*t), int(box[2]*w), int((box[3])*t)
        def tran_p(p):
            return [int(p[0]*w), int((p[1]-d)*t)] # 224 - 168 / 2 = 28 so 168 / (old_h - 28) = 240 / new_h
        points = list(map(tran_p, points))
    # print(box,points)
    return box,points

def darw_info(draw, box, points, disp_str, bg_color=(255, 0, 0), font_color=(255, 255, 255)):    #画框函数
    box,points = map_face(box,points)
    font_wh = image.get_string_size(disp_str)
    for p in points:
        draw.draw_rectangle(p[0] - 1, p[1] -1, p[0] + 1, p[1] + 1, color=bg_color)
    draw.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3], color=bg_color, thickness=2)
    draw.draw_rectangle(box[0], box[1] - font_wh[1], box[0] + font_wh[0], box[1], color=bg_color, thickness = -1)
    draw.draw_string(box[0], box[1] - font_wh[1], disp_str, color=font_color)
def recognize(feature):                                                                   #进行人脸匹配
    def _compare(user):                                                         #定义映射函数
        return face_recognizer.compare(user, feature)                      #推测匹配分数 score相关分数
    face_score_l = list(map(_compare,users))                               #映射特征数据在记录中的比对分数
    return max(enumerate(face_score_l), key=lambda x: x[-1])                #提取出人脸分数最大值和最大值所在的位置

def run():
    img = camera.capture()                       #获取224*224*3的图像数据
    AI_img = img.copy().resize(224, 224)
    if not img:
        time.sleep(0.02)
        return
    faces = face_recognizer.get_faces(AI_img.tobytes(),False)           #提取人脸特征信息
    if faces:
        for prob, box, landmarks, feature in faces:
            key_val = get_key()
            if key_val == 1:                                # 右键添加人脸记录
                if len(users) < len(names):
                    print("add user:", len(users))
                    users.append(feature)
                    with open("/root/face_data.pickle",'wb') as f:
                        pickle.dump(users, f)
                else:
                    print("user full")
            elif key_val == 2:                              # 左键删除人脸记录
                if len(users) > 0:
                    print("remove user:", names[len(users) - 1])
                    users.pop()
                    with open("/root/face_data.pickle",'wb') as f:
                        pickle.dump(users, f)
                else:
                    print("user empty")

            if len(users):                             #判断是否记录人脸
                maxIndex = recognize(feature)

                if maxIndex[1] > score_threshold:                                      #判断人脸识别阈值,当分数大于阈值时认为是同一张脸,当分数小于阈值时认为是相似脸
                    darw_info(img, box, landmarks, "{}:{:.2f}".format(names[maxIndex[0]], maxIndex[1]), font_color=(0, 0, 255, 255), bg_color=(0, 255, 0, 255))
                    print("user: {}, score: {:.2f}".format(names[maxIndex[0]], maxIndex[1]))
                else:
                    darw_info(img, box, landmarks, "{}:{:.2f}".format(names[maxIndex[0]], maxIndex[1]), font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))
                    print("maybe user: {}, score: {:.2f}".format(names[maxIndex[0]], maxIndex[1]))
            else:                                           #没有记录脸
                darw_info(img, box, landmarks, "error face", font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))


    display.show(img)



import os
if os.path.exists("/root/face_data.pickle"): 
    with open("/root/face_data.pickle",'rb')as f:
        users = pickle.load(f)
else:
    with open("/root/face_data.pickle",'wb') as f:
        pickle.dump(users, f)
while True:
        run()









2.加入串口
from maix import nn, camera, image, display
from maix.nn.app.face import FaceRecognize
import time
from evdev import InputDevice
from select import select
import pickle
from maix import pwm
import time
import pickle
import serial
ser = serial.Serial("/dev/ttyS1",115200)    # 连接串口
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/model/face_recognize/model_int8.param",
    "bin": "/home/model/face_recognize/model_int8.bin"
}
model_fe = {
    "param": "/home/model/face_recognize/fe_res18_117.param",
    "bin": "/home/model/face_recognize/fe_res18_117.bin"
}


for i in range(len(steps)):
    channel_num += input_size[1] / steps[i] * (input_size[0] / steps[i]) * 2
channel_num = int(channel_num)     #统计通道数量
options = {                             #准备人脸输出参数
    "model_type":  "awnn",
    "inputs": {
        "input0": input_size
    },
    "outputs": {
        "output0": (1, 4, channel_num) ,
        "431": (1, 2, channel_num) ,
        "output2": (1, 10, channel_num)
    },
    "mean": [127.5, 127.5, 127.5],
    "norm": [0.0078125, 0.0078125, 0.0078125],
}
options_fe = {                             #准备特征提取参数
    "model_type":  "awnn",
    "inputs": {
        "inputs_blob": input_size_fe
    },
    "outputs": {
        "FC_blob": (1, 1, feature_len)
    },
    "mean": [127.5, 127.5, 127.5],
    "norm": [0.0078125, 0.0078125, 0.0078125],
}
keys = InputDevice('/dev/input/event0')

threshold = 0.5                                         #人脸阈值
nms = 0.3
max_face_num = 1                                        #输出的画面中的人脸的最大个数
print("-- load model:", model)
m = nn.load(model, opt=options)
print("-- load ok")
print("-- load model:", model_fe)
m_fe = nn.load(model_fe, opt=options_fe)
print("-- load ok")
face_recognizer = FaceRecognize(m, m_fe, feature_len, input_size, threshold, nms, max_face_num)

def get_key():                                      #按键检测函数
    r,w,x = select([keys], [], [],0)
    if r:
        for event in keys.read():
            if event.value == 1 and event.code == 0x02:     # 右键
                return 1
            elif event.value == 1 and event.code == 0x03:   # 左键
                return 2
            elif event.value == 2 and event.code == 0x03:   # 左键连按
                return 3
    return 0

def map_face(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,points
def darw_info(draw, box, points, disp_str, bg_color=(255, 0, 0), font_color=(255, 255, 255)):    #画框函数
    box,points = map_face(box,points)
    font_wh = draw.get_string_size(disp_str)
    for p in points:
        draw.draw_rectangle(p[0] - 1, p[1] -1, p[0] + 1, p[1] + 1, color=bg_color)
    draw.draw_rectangle(box[0], box[1], box[0] + box[2], box[1] + box[3], color=bg_color, thickness=2)
    draw.draw_rectangle(box[0], box[1] - font_wh[1], box[0] + font_wh[0], box[1], color=bg_color, thickness = -1)
    draw.draw_string(box[0], box[1] - font_wh[1], disp_str, color=font_color)
def recognize(feature):                                                                   #进行人脸匹配
    def _compare(user): 
        global users
        return face_recognizer.compare(user, feature)                      #推测匹配分数 score相关分数
    face_score_l = list(map(_compare,users))                               #映射特征数据在记录中的比对分数
    return max(enumerate(face_score_l), key=lambda x: x[-1])                #提取出人脸分数最大值和最大值所在的位置

def run():
    img = camera.capture()                       #获取224*224*3的图像数据

    AI_img = img.copy().resize(224, 224)
    if not img:
        time.sleep(0.02)
        return
    faces = face_recognizer.get_faces(AI_img.tobytes(),False)           #提取人脸特征信息
    if faces:
        for prob, box, landmarks, feature in faces:
            key_val = get_key()
            if key_val == 1:                                # 右键添加人脸记录
                if len(users) < len(names):
                    print("add user:", len(users))
                    users.append(feature)
                    with open("/root/face_data.pickle",'wb') as f:
                        pickle.dump(users, f)
                else:
                    print("user full")
            elif key_val == 2:                              # 左键删除人脸记录
                if len(users) > 0:
                    print("remove user:", names[len(users) - 1])
                    users.pop()
                    with open("/root/face_data.pickle",'wb') as f:
                        pickle.dump(users, f)
                else:
                    print("user empty")

            if len(users):                             #判断是否记录人脸
                maxIndex = recognize(feature)

                if maxIndex[1] > score_threshold:                                      #判断人脸识别阈值,当分数大于阈值时认为是同一张脸,当分数小于阈值时认为是相似脸
                    darw_info(img, box, landmarks, "{}:{:.2f}".format(names[maxIndex[0]], maxIndex[1]), font_color=(0, 0, 255, 255), bg_color=(0, 255, 0, 255))
                   # print("user: {}, score: {:.2f}".format(names[maxIndex[0]], maxIndex[1]))
                    ser.write(str(maxIndex[0]+1).encode("utf-8"))            # 输入需要通讯的内容
                else:
                    darw_info(img, box, landmarks, "{}:{:.2f}".format(names[maxIndex[0]], maxIndex[1]), font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))
                   # print("maybe user: {}, score: {:.2f}".format(names[maxIndex[0]], maxIndex[1]))
                    ser.write(b"X\n") 
            else:                                           #没有记录脸
                darw_info(img, box, landmarks, "error face", font_color=(255, 255, 255, 255), bg_color=(255, 0, 0, 255))
                ser.write(b"X\n")


    display.show(img)
import os
if os.path.exists("/root/face_data.pickle"): 
    with open("/root/face_data.pickle",'rb')as f:
        users = pickle.load(f)
else:
    with open("/root/face_data.pickle",'wb') as f:
        pickle.dump(users, f)

while True:
        run()






2.部署

V831和K210区别还是挺大的,V831 AI内存64MB,K210可以使用的也仅仅只有可怜的6MB,摄像头像素也是有很明显的差距,跑人脸识别的时候差距更明显。进入正题吧。
人脸检测模型是内置的,在home里面,直接调用就行,之后原理也不多讲就是特征值。

  • 确认 MaixPy3 版本为 0.4.0 以上
  • 使用的硬件为 MaixII-Dock
  • 内存卡内是最新版本的镜像系统

复制我的代码运行就可以了,哈哈哈。废话一堆。

3.踩过的坑

V831人俩识别maixpy给的教程挺详细的,之后使用的话一开始上手有点难,认真阅读代码后感觉还好。
跑人脸检测例程什么的都是OK,问题就是出现在怎么把人脸特征值储存在本地,困扰了我好久,一上午没找到什么有效地解决方案。。。。。。用官网给的储存例程是OK的,但是读取就出了问题,也尝试移植K210的本地存储,结果有字节模块没法运行,这里也是自己的一个坑。之后看了

import pickle
with open("/root/face_data.pickle",'rb')as f:
     users = pickle.load(f)
     print(users)

这个代码运行,运行读取是OK的,人脸特征值能读取出来,这里特此感谢https://blog.csdn.net/qq_51963216/article/details/123810347?ops_request_misc=&request_id=&biz_id=102&utm_term=V831%E2%80%94%E2%80%94%E4%BA%BA%E8%84%B8%E8%AF%86%E5%88%AB%E5%BC%80%E9%94%81&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-4-123810347.142v80insert_down38,201v4add_ask,239v2insert_chatgpt&spm=1018.2226.3001.4187
读取出来之后事情就简单的多了,之后在程序里面加入读取也没问题,但是人脸特征值就是添加不上,又是一个小时。。。。。。。。
最后各种调试打印,看到users列表在recognize竟然是空的,瞬间无语。很简单就是他只是def的局部变量,之后使用global users定义为全局变量问题解决。
真的是 山重水复疑无路,柳暗花明又一村 淦

  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: V831是一款高性能的数据采集芯片,该芯片具有多种功能和特性。首先,V831具有高速数据采集的能力,能够在一个周期内对大量的数据进行采集和处理。其次,V831具有高稳定性和可靠性,能够在各种环境条件下正常工作,保证数据的准确性和可靠性。此外,V831还具有低功耗特性,能够节省能源并延长电池寿命。该芯片还具备较高的集成度,体积小巧,使用方便。它支持多种接口,包括I2C和SPI,可以与其他设备进行通信和联接。另外,V831也具有多种辅助功能,如电流传感器和温度传感器等,可以满足不同应用场景的需求。总的来说,V831是一款功能强大、性能稳定的数据采集芯片,适用于各种需要数据采集和处理的应用领域。 ### 回答2: v831datasheet是指v831芯片的技术规格书或数据手册,其中包含了该芯片的详细信息。 v831芯片是一种集成电路芯片,广泛应用于通信领域。它具有高性能、低功耗和高集成度的特点,能够满足各种通信设备的需求。 在v831datasheet中,会详细介绍该芯片的外观尺寸、引脚布局、电气特性、工作条件等各项参数。这些参数可以帮助工程师们在设计电路时了解该芯片的功能和性能,并根据需求进行合理的选型和应用。 此外,v831datasheet还可能包含有该芯片的功能描述、引脚定义、工作模式、时序图、寄存器配置等详细信息。这些内容有助于工程师们深入理解该芯片的工作原理和操作方式,从而更好地进行系统设计和集成。 通过研读v831datasheet,工程师们可以了解到该芯片的性能优势、电源需求、通信接口、支持的功能等关键信息,从而能够更好地进行系统设计、芯片选型和产品开发。 总之,v831datasheet是v831芯片的技术规格书或数据手册,通过研读它,可以全面了解该芯片的功能、性能和规格参数,对于工程师们开发和应用通信设备具有重要的参考价值。 ### 回答3: v831数据手册是一份关于v831芯片的详细说明文件。这个芯片是一种高集成度的集成电路,具有多种功能和性能。通过阅读v831数据手册,我们可以了解到关于芯片的各种技术规格和特性。 v831芯片是一种具有先进的处理能力和低功耗的芯片。它用于各种应用领域,例如移动通信、物联网、嵌入式系统等。芯片尺寸小,功耗低,适合于电池供电的应用。 数据手册中详细介绍了v831芯片的主要功能模块。它包括微处理器、存储器、通信接口等。微处理器是芯片的核心,负责执行各种计算和控制任务。存储器用于存储数据和程序。通信接口支持多种通信协议,包括UART、SPI、I2C等。 此外,数据手册还提供了关于v831芯片的电气特性和性能参数。这些参数可以帮助工程师设计和优化相关电路。例如,工作电源电压范围、工作温度范围、功耗等。 另外,数据手册中还提供了v831芯片的引脚图和引脚功能说明。这对于设计电路板时非常重要,可以确保正确连接和使用芯片。 总之,v831数据手册是一份宝贵的参考资料。通过认真阅读和理解,我们可以获得关于v831芯片的深入了解,为相关应用设计和开发提供有力支持。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值