使用のオペレーティングシステムに応じて、適切なSR9900駆動プログラムをダウンロードしてください。
駆動圧縮ファイルをデスクトップに解凍->デバイスマネージャーで現在未識別のデバイス(名称はUSB 10/100 LANまたはSR9900を含む)を選択->右クリックでカスタム更新を選択->解凍した圧縮ファイルのパスを選択->確定をクリックして、更新を待ちます。
駆動圧縮ファイルを解凍->SR9900_v1.x.pkgファイルをダブルクリックで開きます->指示に従い、次へをクリックしてインストールします。(圧縮ファイル内に詳細バージョンの駆動インストール教程pdfが含まれています)
sudo ifconfig en10 down
sudo ifconfig en10 up
USBを接続して電源を供給すると、UnitV2は自動的に起動し、電源LEDは赤と白を表示し、起動完了後は消滅します。UnitV2内部にM5Stack開発の基礎AI識別アプリが統合され、複数の識別機能(顔認識、オブジェクト追跡等の常用機能)が内蔵され、ユーザーは迅速にAI識別アプリを構築することができます。下記の二つの接続方法を通じて、PC端/モバイル端はブラウザでドメインunitv2.pyまたはIP:10.254.239.1を訪問し、識別機能のプレビューページを表示できます。識別過程中、UnitV2はUART(底部HY2.0-4P接口)を通じて、JSON形式の識別サンプルデータ(UART: 115200bps 8N1)を出力します。
注意: 内蔵識別サービスはSafariブラウザ上に部分的な互換性問題が存在、推奨Chromeブラウザで訪問してください。
Ethernetモード接続: UnitV2内蔵有線NICを有している、TypeCインタフェースをPCに接続すると、自動的にUnitV2とネットワーク接続が確立されます。
APモード接続: UnitV2起動後、既定のAPホットスポット(SSID: M5UV2_XXX: PWD:12345678)を開設、ユーザーはWiFi接続を通じてUnitV2とネットワーク接続を確立できます。
功能ページのナビゲーションバーをクリック、またはSerial Port通信を通じてJSON指令を送信し、異なる識別功能を切替えることができます。 注意: 送信する指令文字列は、末尾以外の位置に改行文字を挿入することはできません。
//function键的值可被指定为下列功能的任意一个
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
//请注意args必须为一个列表。
{
"function":"Object Recognition",
"args":[
"yolo_20class"
]
}
//若功能切换成功,将收到回复
{
"msg":"function switched to Object Recognition."
}
//若指定的功能不存在,将收到回复
{
"error":"function Object Recognition not exist"
}
//若功能切换失败,将收到回复
{
"error":"invalid function."
}
480Pリアルタイムビデオプレビュー。
480P real-time video preview.
切换功能至 Camera Stream
{
"function": "Camera Stream",
"args": ""
}
画面内の二维码を認識し、二维码の座標と内容を返却します。
機能をCode Detectorに切替えしてください
{
"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をサポート。
機能を"Object Recognition"に切り替える
//选择参数“yolo_20class”切换至该功能
{
"function": "Object Recognition",
"args": ["yolo_20class"]
}
//选择参数“nanodet_80class”切换至该功能
{
"function": "Object Recognition",
"args": ["nanodet_80class"]
}
内蔵モデルがサポートする物体認識
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モードに戻ります。
以下の操作を実行前に、機能を"Color Tracker"に切り替える
{
"function": "Color Tracker",
"args": ""
}
4.3.1 指定LAB阈値
// * 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."
}
4.3.2 指定ROI (自動計算阈値)
{
{
"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
}
画面内の車道線を検出し、直線に近似化し、その角度と座標を返却します。
LAB阈値のスライダーを調整することで背景を除去し、興味のある色の領域を取得できます。 また、画面上直接に興味のある色の領域を選択し、システムは自動的に該当領域で最も多く占める色を計算し、背景を除去します。計算の基礎上に、さらなるスライダーの調整を行いよりよい除去効果を得ることができます。 "To Mask Mode"ボタンをクリックすると、Maskモードに切り替えられ、該当の除去効果を直接確認できます。再び"To RGB Mode"ボタンをクリックすると、RGBモードに戻ります。
以下の操作を実行前に、機能を"LaneLine Tracker"に切り替える
{
"function": "Lane Line Tracker",
"args": ""
}
5.3.1 指定 LAB 阈值
// * LAB阈值映射为0~255
{
"config":"Lane Line 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":"Lane Line Tracker",
"msg":"Data updated."
}
5.3.2 指定ROI (自动计算阈值)
{
"config":"Lane Line Tracker",
"x":0, // 0 ~ 640
"y":0, // 0 ~ 480
"w":30,
"h":30,
}
//* va与vb指的是ROI内的色彩离散程度,若离散度较高则分割效果较差。
{
"running":"Lane Line 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":"Lane Line Tracker",
"x":0,
"y":0, // 拟合线的基点
"k":0 // 拟合线斜率
}
画面上の指定した目標を追跡します。MOSSEアルゴリズムを使用。
画面上で興味のある目標を選択するだけ。
以下の操作を実行前に、機能を"Target Tracker"に切り替える
{
"function": "Target Tracker",
"args": ""
}
{
"running":"Target Tracker",
"x":0,//0~640
"y":0,//0~480
"w":0,
"h":0
}
動くものを検出し追跡し、その座標と角度を返却します。
'Set as background'ボタンをクリックして背景を確定します。このアルゴリズムは緩やかに変化する背景にも対応できます。
以下の操作を実行前に、機能を"Motion Tracker"に切り替える
{
"function": "Motion Tracker",
"args": ""
}
7.3.1 背景の確定
Send
// 发送这条指令将会确定背景
{
"config":"Motion Tracker",
"operation":"update"
}
Receive
{
"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
}
]
}
緑色の目標枠内の物体をリアルタイムで訓練し分類できます。訓練得られた特徴量はデバイス上に保存して、次回利用できます。
以下の操作を実行前に、機能を"Online Classifier"に切り替える
{
"function": "Online Classifier",
"args": ""
}
8.3.1 Train
Send
//这条指令将使设备进入训练模式,并提取一次特征存储到指定的分类下。若class_id不存在,则会创建这个类。
{
"config":"Online Classifier",
"operation":"train",
"class_id":1, // Integer (0 ~ N), class的ID
"class":"class_1" // String, class的名字
}
Receive
{
"running":"Online Classifier",
"msg":"Training [class name] [num of training] times"
}
8.3.2 Save&Run
Send
{
"config":"Online Classifier",
"operation":"saverun",
}
Receive
{
"running":"Online Classifier",
"msg":"Save and run."
}
8.3.3 Reset
Send
//这条指令将会使设备进入训练模式并清除所有的分类。
{
"config":"Online Classifier",
"operation":"reset",
}
Receive
{
"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
}
]
}
人臉を検出し認識します。
以下の操作を実行前に、機能を"Face Recognition"に切り替える
{
"function": "Face Recognition",
"args": ""
}
9.3.1 Train
//若要创建一个新的面孔,请按顺序提供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"
}
9.3.2 Stop Train
Send
{
"config":" Face Recognition ",
"operation":" stoptrain",
}
Receive
{
"running":"Face Recognition",
"msg":"Exit training mode."
}
9.3.3 Save&Run
Send
{
"config":" Face Recognition ",
"operation":"saverun",
}
Receive
{
"running":"Face Recognition",
"msg":"Faces saved."
}
9.3.4 Reset
Send
//这条指令将会删除全部的面孔。
{
"config":"Face Recognition",
"operation":"reset",
}
Receive
{
"running":"Face Recognition",
"msg":"Reset success"
}
9.4.1 Training Mode
{
"running":"Face Recognition",
"status":"training", // training(培训) or missing(丢失)
"x":0,
"y":0,
"w":0,
"h":0, // 面部识别边界框
"prob":0, // 检测置信率
"name":0,
}
9.4.2 Normal Mode (匹配得分>0.5)
{
"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
},
]
},
]
}
9.4.3 Normal Mode (匹配得分<=0.5)
{
"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点のランドマークを出力。
以下の操作を実行前に、機能を"Shape Detector"に切り替える
{
"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」ボタンをクリックして背景を確認します。このアルゴリズムは緩やかな変化の背景にも対応します。
以下の作業を行う前に、Shape Detectorに機能を切り替えてくださいますように
{
"function": "Shape Detector",
"args": ""
}
Send
// 发送这条指令将会确定背景
{
"config":"Shape Detector",
"operation":"update"
}
Receive
{
"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
}
]
}
デバイス上のマイクを通じて音声をキャプチャし、リアルタイムFFT(高速フーリエ変換)を施行し、時間-周波数のグラフを描画します。下の緑色のグラフは音声のRMS、即ち現在の音量を表示。
未サポート、現在開発中です。
// 这里返回的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
识别过程中,UnitV2将通过串口(底部HY2.0-4P接口)不断输出识别样本数据(JSON格式,UART: 115200bps 8N1
)。下方分别为不同平台下读取识别结果的案例程序。
認識過程中、UnitV2はシリアルポート(底部HY2.0-4P接口)を介して、継続的に認識サンプルデータ(JSON形式、UART: 115200bps 8N1)を出力します。以下は異なるプラットフォーム下の認識結果の読み取りのサンプルプログラムです。
void setup() {
Serial.begin(115200);
Serial2.begin(115200, SERIAL_8N1, 16, 17);
}
void loop() {
if(Serial2.available()) {
String recvStr = Serial2.readStringUntil('/n');
if(recvStr[0] == '{'){
Serial.print(recvStr);
}
}
}
import machine
import json
uart1 = machine.UART(1, tx=16, rx=17)
uart1.init(115200, bits=8, parity=None, stop=1)
PROTOCOL_START = b'{'[0]
while True:
if uart1.any():
data = uart1.readline()
if data[0] == PROTOCOL_START:
json_data = json.loads(data)
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))