根据使用的操作系统的下载相应的SR9900驱动程序。
将驱动压缩包解压至桌面路径->进入设备管理器中选中当前未识别的设备(名称为USB 10/100 LAN
或带有SR9900
字符)->右键选择自定义更新->选中压缩包解压的路径->点击确认,等待更新完成。
解压驱动压缩包->双击打开SR9900_v1.x.pkg文件->根据提示点击下一步安装。(压缩包内包含了详细版本的驱动安装教程pdf)
sudo ifconfig en10 down
sudo ifconfig en10 up
连接USB进行供电后,UnitV2将自动启动,电源指示灯将显示红色白色,启动完成后熄灭。UnitV2 内部集成由M5Stack开发的基础Ai识别应用,内置多种识别功能(如人脸识别,对象跟踪等常用功能),能够快速帮助用户构建Ai识别应用。通过以下两种连接方式,PC端/移动端能够通过浏览器访问域名unitv2.py
或IP:10.254.239.1
访问通过识别功能的预览网页。识别过程中,UnitV2将通过串口(底部HY2.0-4P接口)不断输出识别样本数据(JSON格式,UART: 115200bps 8N1
)
Safari
浏览器上存在部分的兼容性问题,推荐使用Chrome
浏览器访问。Ethernet模式连接
: UnitV2内置了一张有线网卡, 当你通过TypeC接口连接PC时,将自动与UnitV2建立起网络连接。
AP模式连接
: UnitV2启动后,将默认开启AP热点(SSID: M5UV2_XXX: PWD:12345678)
,用户可以通过WiFi接入与UnitV2建立起网络连接。
识别过程中,UnitV2将通过串口(底部HY2.0-4P接口)不断输出识别样本数据(JSON格式,UART: 115200bps 8N1
)。
通过点击功能页面的导航栏
或通过设备的Serial接口发送JSON指令
的方式切换不同的识别功能。 注意: 发送的指令字符串除了结尾处, 其他位置不允许插入换行符。
Audio FFT
Code Detector
Face Detector
Lane Line Tracker
Motion Tracker
Shape Matching
Camera Stream
Online Classifier
Color Tracker
Face Recognition
Target Tracker
Shape Detector
Object Recognition
{
"function":"Object Recognition",
"args":[
"yolo_20class"
]
}
{
"msg":"function switched to Object Recognition."
}
{
"error":"function Object Recognition not exist"
}
{
"error":"invalid function."
}
480P实时视频预览
{
"function": "Camera Stream",
"args": ""
}
识别画面中的二维码,返回二维码的坐标与内容。
{
"function": "Code Detector",
"args": ""
}
{
"running":"Code Detector",
"num":2, // 二维码的数目
"code":[
{
"prob": 0.987152, // 置信率
"x":10, // 0 ~ 640
"y":10, // 0 ~ 480
"w":30,
"h":30, // 二维码的边界框
"type":"QR/DM/Maxi", // include "Background", "QR/DM/Maxi", "SmallProgramCode", "PDF-417", "EAN", "Unknown"
"content":"m5stack"
},
{
"prob": 0.987152, // 置信率
"x":10,
"y":10,
"w":30,
"h":30, // 二维码的边界框
"type":"QR/DM/Maxi", // include "Background", "QR/DM/Maxi", "SmallProgramCode", "PDF-417", "EAN", "Unknown"
"content":"m5stack"
}
]
}
基于YOLO Fastest与NanoDet的目标检测。支持V-Training。
//选择参数“nanodet_80class”切换至该功能
{
"function": "Object Recognition",
"args": ["nanodet_80class"]
}
镜像默认内置了nanodet_80class, yolo_20classs模型, 可直接使用, 以下是模型所支持识别的对象
yolo_20class: [
"aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog",
"horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"
]
nanodet_80class: [
"person","bicycle","car","motorbike","aeroplane","bus","train","truck","boat","traffic light",
"fire hydrant","stop sign","parking meter","bench","bird","cat","dog","horse","sheep","cow",
"elephant","bear","zebra","giraffe","backpack","umbrella","handbag","tie","suitcase","frisbee",
"skis","snowboard","sports ball","kite","baseball bat","baseball glove","skateboard","surfboard",
"tennis racket","bottle","wine glass","cup","fork","knife","spoon","bowl","banana","apple",
"sandwich","orange","broccoli","carrot","hot dog","pizza","donut","cake","chair","sofa","pottedplant",
"bed","diningtable","toilet","tvmonitor","laptop","mouse","remote","keyboard","cell phone","microwave",
"oven","toaster","sink","refrigerator","book","clock","vase","scissors","teddy bear","hair drier","toothbrush"
]
{
"num": 1,
"obj": [
{
"prob": 0.938137174,
"x": 179,
"y": 186,
"w": 330,
"h": 273,
"type": "person"
}
],
"running": "Object Recognition"
}
检测指定的颜色区域,返回颜色区域的坐标。
可以直接调整LAB阈值滑条可以滤除背景,得到感兴趣的颜色区域。也可以在画面直接框出感兴趣的颜色区域,系统将自动计算出目标区域占比最多的颜色并将背景滤除,你可以在计算的基础上进一步调整滑条取得更好的过滤效果。点击"To Mask Mode"按钮将会切换至Mask模式,在该模式下你可以直接看到滤除效果。再点击"To RGB Mode" 按钮将会切换回RGB模式。
{
"function": "Color Tracker",
"args": ""
}
// * LAB阈值映射为0~255
{
"config":"Color Tracker",
"l_min":0, // 0 ~ 255
"l_max":0, // 0 ~ 255
"a_min":0, // 0 ~ 255
"a_max":0, // 0 ~ 255
"b_min":0, // 0 ~ 255
"b_max":0 // 0 ~ 255
}
{
"running":"Color Tracker",
"msg":"Data updated."
}
{
"config":"Color Tracker",
"x":0, // 0 ~ 640
"y":0, // 0 ~ 480
"w":30,
"h":30,
}
// * va与vb指的是ROI内的色彩离散程度,若离散度较高则追踪效果较差。
{
"running":"Color Tracker",
"a_cal":0.0,
"b_cal":0.0, // 计算阈值
"va":0.0,
"vb":0.0, // 颜色分散率
"l_min":0, // 固定值 0
"l_max":255, // 固定值 255
"a_min":0, // a_cal - (10 + (int)(va / 2.0f))
"a_max":0, // a_cal + (10 + (int)(va / 2.0f))
"b_min":0, // b_cal - (10 + (int)(vb / 2.0f))
"b_max":0 // b_cal + (10 + (int)(vb / 2.0f))
}
{
"running":"Color Tracker",
"cx": 0, // 中心 X 轴坐标
"cy": 0, // 中心 Y 轴坐标
"r": 0, // 半径
"mx": 0, // moment x position
"my": 0 // moment y position
}
检测画面中的道路线,将其拟合成直线,返回直线角度与坐标。
{
"function": "Lane Line Tracker",
"args": ""
}
"config":Lane Line Tracker"
即可。{
"running":"Lane Line Tracker",
"x":0,
"y":0, // 拟合线的基点
"k":0 // 拟合线斜率
}
在画面上选中目标并追踪,使用的是MOSSE算法。只需要在画面上框出感兴趣的目标即可实现追踪。
{
"function": "Target Tracker",
"args": ""
}
{
"running":"Target Tracker",
"x":0,//0~640
"y":0,//0~480
"w":0,
"h":0
}
检测并追踪移动的目标,返回目标的坐标与角度。点击 'Set as background' 按钮确定背景。该算法可以适应缓慢变化的背景。
{
"function": "Motion Tracker",
"args": ""
}
// 发送这条指令将会确定背景
{
"config":"Motion Tracker",
"operation":"update"
}
{
"running":"Motion Tracker",
"msg":"Background updated."
}
{
"running":"Motion Tracker",
"num":2,
"roi":[
{
"x":0,
"y":0,
"w":0,
"h":0,
"angle":0.0,
"area":0
},
{
"x":0,
"y":0,
"w":0,
"h":0,
"angle":0.0,
"area":0
}
]
}
这个功能可以实时训练并分类绿色目标框内的物体,训练得到的特征值可以被保存在设备上供下次使用。
Reset
按钮清除已有的类别,并进入训练模式。+
按钮创建新的类别。Train
按钮完成一次训练。save&run
按钮将训练结果保存在设备上,并退出训练模式,进行物体识别分类。
{
"function": "Online Classifier",
"args": ""
}
//这条指令将使设备进入训练模式,并提取一次特征存储到指定的分类下。若class_id不存在,则会创建这个类。
{
"config":"Online Classifier",
"operation":"train",
"class_id":1, // Integer (0 ~ N), class的ID
"class":"class_1" // String, class的名字
}
{
"running":"Online Classifier",
"msg":"Training [class name] [num of training] times"
}
{
"config":"Online Classifier",
"operation":"saverun",
}
{
"running":"Online Classifier",
"msg":"Save and run."
}
{
"config":"Online Classifier",
"operation":"reset",
}
{
"running":"Online Classifier",
"msg":" Please take a picture."
}
{
"running":"Online Classifier",
"class_num":2, // 识别出的class数目
"best_match":"class_1", // 最佳匹配class
"best_score":0.83838, // 最佳匹配分数
"class":[ // 每一个class的分数
{
"name":"class_1",
"score":0.83838
},
{
"name":"class_2",
"score":0.66244
}
]
}
检测并识别人脸。
{
"function": "Face Recognition",
"args": ""
}
//若要创建一个新的面孔,请按顺序提供face_id (0 ~ N)。
{
"config":"Face Recognition",
"operation":"train",
"face_id":1, // Integer (0 ~ N), 面孔的ID
"name":"tom" // String, 面孔的名字
}
//举例,目前已经有了3个面孔(0~2),要创建新的面孔,需要将id指定为3。
{
"running":" Face Recognition ",
"msg":"Training tom"
}
{
"running":"Face Recognition",
"msg":"Invalid face id"
}
{
"config":" Face Recognition ",
"operation":" stoptrain",
}
{
"running":"Face Recognition",
"msg":"Exit training mode."
}
{
"config":" Face Recognition ",
"operation":"saverun",
}
{
"running":"Face Recognition",
"msg":"Faces saved."
}
{
"config":"Face Recognition",
"operation":"reset",
}
{
"running":"Face Recognition",
"msg":"Reset success"
}
{
"running":"Face Recognition",
"status":"training", // training(培训) or missing(丢失)
"x":0,
"y":0,
"w":0,
"h":0, // 面部识别边界框
"prob":0, // 检测置信率
"name":0,
}
{
"running":"Face Recognition",
"num":1, // 识别出面部的数目
"face":[
{
"x":0, // 0 ~ 320
"y":0, // 0 ~ 240
"w":30,
"h":30, // 面部识别边界框
"prob":0, // 检测置信率
"match_prob":0.8, // 匹配置信率
"name": "tom",
"mark":[ // landmarks
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
]
},
]
}
{
"running":"Face Recognition",
"num":1, // 识别出面部的数目
"face":[
{
"x":0, // 0 ~ 320
"y":0, // 0 ~ 240
"w":30,
"h":30, // 面部识别边界框
"prob":0, // 置信率
"name": "unidentified",
"mark":[ // landmarks
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
]
},
]
}
检测画面中的人脸并给出5点landmark。
{
"function": "Face Detector",
"args": ""
}
{
"running":"Face Detector",
"num":1, // 识别出面部的数目
"face":[
{
"x":0,
"y":0,
"w":30,
"h":30, // 面部识别边界框
"prob":0, // 置信率
"mark":[ // landmark
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
{
"x":0,
"y":0
},
{
"x":0,
"y":0
}
]
}
]
}
检测画面中的形状并计算其面积。能够识别正方形、长方形、三角形、五边形、圆形。点击 'Set as background' 按钮确定背景。该算法可以适应缓慢变化的背景。
{
"function": "Shape Detector",
"args": ""
}
{
"config":"Shape Detector",
"operation":"update"
}
{
"running":"Shape Detector",
"msg":"Background updated."
}
{
"running":"Shape Detector",
"num":2,
"shape":[
{
"name":"Rectangle", // "unidentified", "triangle", "square", "rectangle", "pentagon", "circle"
"x":0,
"y":0,
"w":0,
"h":0,
"angle":0.0, // 可在形状为正方形或矩形时使用
"area":0
},
{
"name":"Rectangle", // "unidentified", "triangle", "square", "rectangle", "pentagon", "circle"
"x":0,
"y":0,
"w":0,
"h":0,
"angle":0.0, // 可在形状为正方形或矩形时使用
"area":0
}
]
}
匹配给定的任意形状(但是形状最好不要含有曲线),上传的形状会被转换为特征数据被保存在设备上以供下次使用。
Set as background
按钮确定背景。该算法可以适应缓慢变化的背景。暂未支持
// 这里返回的shape就是上传的模板的文件名,请注意若置信率低于30%则会被标识为unidentified。
{
"running":"Shape Matching",
"num":2,
"shape":[
{
"name":"arrow", // 您的自定义形状名称,当置信率小于30时无法识别
"max_score":83, // 置信率评分,如果形状不明,就没有
"x":0,
"y":0,
"w":0,
"h":0,
"area":0
},
{
"name":"unidentified", // 您的自定义形状名称,当信心分数小于30时无法识别
"x":0,
"y":0,
"w":0,
"h":0,
"area":0
},
]
}
通过设备上的麦克风捕获音频,进行实时FFT(快速傅里叶变换)并绘制出时间-频率图。下方的绿色图表是音频的RMS,表示当前的响度。
None
None
通过Python脚本调用内部模型
from json.decoder import JSONDecodeError
import subprocess
import json
import base64
import serial
import time
from datetime import datetime
from PIL import Image
import os
import io
uart_grove = serial.Serial('/dev/ttyS0', 115200, timeout=0.1)
reconizer = subprocess.Popen(['/home/m5stack/payload/bin/object_recognition', '/home/m5stack/payload/uploads/models/nanodet_80class'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
reconizer.stdin.write("_{\"stream\":1}\r\n".encode('utf-8'))
reconizer.stdin.flush()
img = b''
while True:
today = datetime.now()
path = str(today.strftime("%Y_%m_%d") + "/")
newpath = "/media/sdcard/" + path
line = reconizer.stdout.readline().decode('utf-8').strip()
if not line:
break # Process finished or empty line
try:
doc = json.loads(line)
if 'img' in doc:
byte_data = base64.b64decode(doc["img"])
img = bytes(byte_data)
elif 'num' in doc:
for obj in doc['obj']:
uart_grove.write(str(obj['type'] + '\n').encode('utf-8'))
if obj['type'] == "aeroplane":
print('aeroplane ' + today.strftime("%Y_%m_%d_%H_%M_%S"))
if os.path.exists(newpath):
image_path = newpath + today.strftime("%Y_%m_%d_%H_%M_%S") + ".jpg"
img = Image.open(io.BytesIO(byte_data))
img.save(image_path, 'jpeg')
else:
os.mkdir(newpath)
image_path = newpath + today.strftime("%Y_%m_%d_%H_%M_%S") + ".jpg"
img = Image.open(io.BytesIO(byte_data))
img.save(image_path, 'jpeg')
time.sleep(1)
else:
print('Not detect '+ today.strftime("%Y_%m_%d_%H_%M_%S"))
except JSONDecodeError as e:
print("Error: Invalid JSON string")
print("JSONDecodeError:", str(e))