# V-function ?>本教程适用于M5StickV/UnitV ## 功能介绍 V-Function是由M5Stack团队针对V系列设备开发的多个**视觉识别**功能固件,基于不同的功能固件(对象追踪,移动检测等),用户能够快速的进行视觉识别的功能的搭建。本教程将向你介绍,如何烧录固件至你的设备中,并通过UIFlow图形化编程进行调用。 ?>固件串口输出波特率固定为115200
功能列表
运动目标检测 目标追踪 颜色追踪 人脸识别 二维码识别 条形码识别 Datamatrix码识别 Apriltag码识别 自定义标签识别 巡线
## 烧录固件 >请根据您所使用的操作系统,点击下方按钮下载相应的M5Burner固件烧录工具.解压打开应用程序。

Windows10

MacOS

Linux

?>注意:MacOS用户安装完成后请将应用放入Application文件夹内,如下图所示。 > ?>注意:Linux用户请切换至解压文件路径下,在终端中运行`./M5Burner`, 运行应用。 >左侧设备栏选择设备为M5StickV/UnitV, 根据使用需求选择对应的功能固件, 进行下载。 将设备通过数据线连接至电脑,选择其对应的端口,点击Burn开始烧录。 >当烧录日志提示`Burn Successfully`时,则表示固件已经烧录完成。 ## UIFlow引用 ### 引入拓展 >烧录完功能固件的M5StickV/UnitV将作为Unit形式的从设备进行使用,因此用户需要使用其他的M5主机设备来与其交互。关于其他主控产品的UIFlow基本使用与操作,请访问其对应的产品文档页面进行获取。 >访问https://flow.m5stack.com/ 进入UIFlow。 点右侧功能面板中的Unit添加按钮,选中UnitV拓展进行添加。添加时,请根据实际使用的端口,进行配置。点击ok进行添加。 >添加完成后,在功能块菜单中的Unit选项,即可找到包含的功能块。将其拖拽至右侧编程区域,即可进行使用。更多内容请查看下方案例程序。 ### 注意事项 >使用将从设备(M5StickV/UnitV)连接至主控后,主控端若存在数据获取不正常情况,请重启M5StickV/UnitV。等待固件启动成功后重新尝试连接。 ## 案例程序 ### 运动目标检测 >检测当面画面的变化情况,判断检测区域内的物体是否存在运动。 >程序块介绍 - `初始化` + 初始化 - `设置变化率阈值` + 设置变化率阈值:当变化量小于该数值的像素,将不被认为发生了变化,其变化量则不纳入画面变量率中。 - `设置检测模式` + dynamic: 动态检测模式,配置后将不断拍摄图片,对比前后两帧之间的变化 + static:静态检测模式,执行后将拍摄并保存一张基准图片,后续的画面将不断与该图片进行对比。若需要拍摄新的基准图片,需要先切换回动态检测模式,然后再次执行静态检测模式设置。 - `获取画面变化率` + 画面变化率: 检测比较前后两帧之间变化像素的变化量。假设有2个像素发生了变化,像素A变化了27,像素B变化了10,则改数值为27+10=37。将两个像素点的R.G.B分量的差求值和即为变化量。 - `获取最高变化率` + 最高变化率:变化最剧烈的像素的变化量。 - `设置扫描间隔x轴 y轴` + 设置在x轴以及y轴上的扫描间隔。 - `获取边界框数数目` + 获取由像素变化产生的边界框数数目。 - `获取x号边界框信息` + x号边界框的详细信息以列表返回,包括该边界框内变化像素的数量,边界框x轴坐标,边界框y轴坐标,编边界框宽度,边界框高度。 >程序案例:启用动态检测模式,通过读取画面的最高变化率数值大小,判断画面内目标是否存在运动情况。当变化率数值大于预期值时,显示"Moved",否则显示"Not Move"。屏幕显示当前的最高变化率数值。 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/Motion_Detect) ### 运动目标检测-数据包格式 #### 回传JSON ```clike { "FUNC": "MOTION DETECT V1.0", "DIFF TOTAL": 10000, //画面变动率 "DIFF MAX": 75, // 最高变化率 "TOTAL": 3, //边界框数量 "0": { "x": 45, "y": 18, "w": 126, "h": 72, "area": 342 //该边界框内变化像素的数量 }, "1": { "x": 0, "y": 169, "w": 130, "h": 24, "area": 173 }, "2": { "x": 39, "y": 204, "w": 276, "h": 34, "area": 141 } } ``` #### 设置JSON ```clike { "MOTION DETECT": 1.0, //功能标记,不可缺省 "mode": "COMPUTE_MODE_STATIC", //可缺省 "COMPUTE_MODE_STATIC" 静态检测模式 or "COMPUTE_MODE_DYNAMIC" 动态检测模式 "thr_w": 20, //可缺省 边界框宽阈值,[3,200] "thr_h": 20, //可缺省 边界框长阈值,[3,200] "stepx": 1, //可缺省 X扫描间隔,[0, 40],设置为0则关闭边界框检测 "stepy": 2, //可缺省 Y扫描间隔,[0, 40],设置为0则关闭边界框检测 "delta": 20, //可缺省 变化率阈值,[0, 99] "merge": 10 //可缺省 边界框合并阈值,[0, 40] } ``` ### 目标追踪 >设置追踪目标,实时获取目标对象处于画面中位置信息。 >程序块介绍 - `初始化` + 初始化 - `设置跟踪框坐标 x y 跟踪框 宽 高` + 设置框选目标,参数为当前目标所在图像上的位置 (尽可能选取具有显著颜色特征的目标) - `获取跟踪框轨迹详情` + 读取框选目标所在图像上的坐标,返回值为列表形式,其中包含选框的左上角坐标x,y以及选框的宽度,高度 >程序案例:通过按键A设置框选目标,读取目标坐标值,用于控制屏幕上的矩形元素移动,模拟显示物体的运动轨迹。 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/Target_Track) ### 目标追踪-数据包格式 #### 回传JSON ```clike { "FUNC": "TARGET TRACKER V1.0", "x": 282, "y": 165, "w": 13, "h": 15 } ``` #### 设置JSON ```clike { "TARGET TRACKER": " V1.0", "x": 282, //xywh均不可缺省 "y": 165, "w": 13, "h": 15 } ``` ### 颜色追踪 >设置LAB颜色阈值,追踪画面中符合阈值目标,并实时获取目标对象处于画面中位置信息。 >程序块介绍 - `初始化` + 初始化。 - `设置目标颜色 L阈值最小 0 L阈值最大 0 A阈值最小 A阈值最大 B阈值最小 B阈值最大 ` + 设置追踪的LAB阈值(LAB颜色空间的颜色值,在该范围外的颜色将会被过滤)。 - `设置扫描间隔 x 轴 y 轴` + 设置X轴和y轴上的扫描间隔,[0, 40],设置为0则关闭边界框检测。 - `设置边框合并阈值` + 设置边界框合并阈值。 - `设置边框宽阈值 0 高阈值 0` + 设置边框宽阈值 0 高阈值 0。 - `获取边框数目` + 获取边框数目。 - `获取边框的详情` + 获取边框的详情,包括该边界框内变化像素的数量,边界框x轴坐标,边界框y轴坐标,边界框宽,边界框高。 #### 设置LAB阈值 >点击下方按钮,下载LAB取色工具。(目前仅支持windows系统) 下载LAB取色工具 >使用手机或者是其他设备拍摄样本图片,双击打开应用,点击`open`-->`image`导入图片。 >点击想要用作颜色识别的物体,记录下方生成的LAB数值,在UIFlow中配置使用。补充:拖动LAB数值的区间条,可以用于自定义LAB数值。 >程序案例:设置识别的LAB阈值,实现颜色追踪效果,并获取被追踪对象在画面中的坐标数据,符合阈值的像素数量。 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/Color_Track) ### 颜色追踪-数据包格式 #### 回传JSON ```clike { "FUNC": "COLOR TRACKER V1.0", "TOTAL": 3, //边界框数量 "0": { "x": 45, "y": 18, "w": 126, "h": 72, "area": 342 //该边界框内变化像素的数量 }, "1": { "x": 0, "y": 169, "w": 130, "h": 24, "area": 173 }, "2": { "x": 39, "y": 204, "w": 276, "h": 34, "area": 141 } } ``` #### 设置JSON ```clike { "COLOR TRACKER": 1.0, //功能标记,不可缺省 "thr_w": 20, //可缺省 边界框宽阈值,[3,200] "thr_h": 20, //可缺省 边界框长阈值,[3,200] "stepx": 1, //可缺省 X扫描间隔,[0, 40],设置为0则关闭边界框检测 "stepy": 2, //可缺省 Y扫描间隔,[0, 40],设置为0则关闭边界框检测 "merge": 10, //可缺省 边界框合并阈值,[0, 40] "Lmin": 0, //可缺省 L阈值下限 [0, 100] "Lmax": 0, //可缺省 L阈值上限 [0, 100] "Amin": 0, //可缺省 A阈值下限 [0, 255] "Amax": 0, //可缺省 A阈值上限 [0, 255] "Bmin": 0, //可缺省 B阈值下限 [0, 255] "Bmax": 0, //可缺省 B阈值上限 [0, 255] } ``` ### 人脸识别 >识别画面中的人脸信息,并返回识别个数,对象坐标,置信率。 >程序块介绍 - `初始化` + 初始化 - `获取人脸数目` + 读取识别到的人脸数量 - `获取第x张人脸详情` + 读取指定编号的人脸详情数据,返回格式为列表,其中包含人脸框选坐标,长度宽度,以及置信率 >程序案例:读取画面中人脸识别结果,以及置信率。 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/Face_Detect) ### 人脸识别-数据包格式 #### 回传JSON ```clike { "FUNC": "FACE DETECT", // 功能说明 "count": 3, // 识别到的人脸数量 "2": { // 人脸编号 "x": 97, // ROI "y": 26, "w": 64, "h": 86, "value": 0.859508, // 置信率 "classid": 0, "index": 2, "objnum": 3 }, "1": { "x": 70, "y": 157, "w": 38, "h": 63, "value": 0.712100, "classid": 0, "index": 1, "objnum": 3 }, "0": { "x": 199, "y": 145, "w": 31, "h": 40, "value": 0.859508, "classid": 0, "index": 0, "objnum": 3 } } ``` ## 二维码识别 >识别画面中的二维码,并返回识别结果,以及版本。使用固件`Find code` >程序块介绍 - `初始化` + 初始化 - `获取QR码信息` + 读取识别到的二维码内容 - `获取QR码版本` + 读取识别到的二维码版本 >程序案例:读取二维码信息以及版本号。 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/QR_Code) #### 回传JSON ```clike { "count": 1, "FUNC": "FIND QRCODE", "0": { "x": 57, "y": 16, "w": 197, "h": 198, "payload": "m5stack", //二维码数据 "version": 1, //二维码版本 "ecc_level": 1, //二维码ECC水平 "mask": 2, //二维码掩码 "data_type": 4, //二维码数据类型 "eci": 0 //返回二维码的ECI。 } } ``` ## 条形码识别 >识别画面中的条形码,并返回识别结果,以及版本。使用固件`Find code` >程序块介绍 - `初始化` + 初始化 - `获取识别到的条形码内容` + 读取识别到的条形码内容 - `获取识别到的条形码旋转角度` + 读取识别到的条码旋转角度 - `获取识别到的条形码的类别` + 读取识别到的条码类别 - `获取识别到的条码位置信息` + 读取识别到的条码的框选坐标,长度宽度,返回值为列表 >程序案例:案例能反映条形码信息,条形码类型,条形码旋转角度以及条形码的详细位置信息。 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/Bar_Code) #### 回传JSON ```clike { "0": { "x": 62, "y": 90, "w": 100, "h": 45, "payload": "123", //数据 "type": 15, //条码类别 "rotation": 0.000000, //条码旋转角度 "quality": 28 //条码在图像中被扫描的次数 }, "count": 1, "FUNC": "FIND BARCODE" } ``` ## Datamatrix码识别 >识别画面中的Datamatrix码,并返回识别结果,以及码旋转角度,坐标数据。使用固件`Find code` >程序块介绍 - `初始化` + 初始化 - `获取Data Matrix码信息` + 读取识别到的Datamatrix码内容 - `获取Data Matrix码旋转角度` + 读取识别到的Datamatrix码旋转角度 - `获取Data Matrix码位置信息` + 读取识别到的Datamatrix码的框选坐标,长度宽度,返回值为列表 >程序案例:案例能反映Data Matrix码信息,旋转角度以及其的详细位置信息。 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/Datamatrix_Code) #### 回传JSON ```clike { "0": { "x": 20, "y": 116, "w": 96, "h": 96, "payload": "m5stack", "rotation": 1.588250, //DM码旋转角度 "rows": 16, //DM码行数 "columns": 16, //DM码列数 "capacity": 12, //DM码容量(字节) "padding": 1 //DM码剩余容量(字节) }, "count": 1, "FUNC": "FIND DATAMATRIX" } ``` ## Apriltag码识别 >识别画面中的Apriltag码(仅支持Tag36H11类型),并获取其位置的偏移。使用固件`Find code` >程序块介绍 - `初始化` + 初始化 - `获取AprilTag码旋转度数` + 返回以弧度计的AprilTag的旋度(int) - `获取AprilTag码坐标` + 读取识别到的Datamatrix码的框选坐标,中心坐标,长度宽度,返回值为列表 - `获取AprilTag码移动单位数` + 读取Apriltag码的位置偏移 >程序案例:案例能反映AprilTag码旋转度数,移动单位数,以及AprilTag码的详细位置信息。 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/AprilTag_Code) #### 回传JSON ```clike { "0": { "x": 71, "y": 5, "w": 85, "h": 88, "id": 1, "family": 16,// AprilTag的类别 "cx": 115, "cy": 49, "rotation": 6.219228,// 返回以弧度计的AprilTag的旋度(int)。 "decision_margin": 0.451959,// AprilTag匹配的色饱和度(取值0.0 - 1.0),其中1.0为最佳。 "hamming": 0,// AprilTag的可接受的数位误差数值 "goodness": 0.000000, //AprilTag图像的色饱和度 "x_translation": 0.868200, //旋转后将图像移动到左侧或右侧的单位数 "y_translation": 0.245313,//旋转后将图像上移或下移的单位数 "z_translation": -2.725188,//是通过图像缩放的量。默认情况下1.0 "x_rotation": 3.093776,//x轴在帧缓冲器中旋转图像的度数 "y_rotation": 0.065489,//y轴在帧缓冲器中旋转图像的度数 "z_rotation": 6.219228 //z轴在帧缓冲器中旋转图像的度数 }, "count": 1, "FUNC": "FIND APRILTAG" } ``` #### 识别模式设置JSON >以上多个识别码功能,均使用同一个固件`Find Code`实现,用户可以通过发送下方JSON数据,配置模式切换。 ```clike { "FIND CODE": 1.0, "mode":"DATAMATRIX" //识别模式,可选QRCODE,APRILTAG,DATAMATRIX,BARCODE } ``` ### 自定义标签识别 >检测画面中的标签卡,并返回二进制序列。注:仅识别固定标签卡格式,请参考下方图片 >程序块介绍 - `初始化` + 初始化 - `获取当前识别到的标签卡数量` + 当前画面识别到的标签卡数量 - `获取识别结果的二进制字符串` + 识别结果的二进制数据的字符串,当有多个卡片时,传入下标可选择不同的卡片内容。 - `获取uint64_t类型的代码内容` + uint64_t类型的内容二进制代码,本键值最大编码64位(8 x 8)的TAG。 - `获取标签的位置信息` + 标签卡的坐标与长宽信息 ```clike 00000000 00000000 00111100 00@@@@00 @@@@ 01000010 0@0000@0 @ @ 01000010 -> 0@0000@0 -> @ @ 01011010 0@0@@0@0 @ @@ @ 01000010 0@0000@0 @ @ 01000010 0@0000@0 @ @ 00000000 00000000 ``` >程序案例:识别卡片信息,并显示在屏幕上 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/Tag_Reader) ### 自定义标签识别-数据包格式 #### 回传JSON ```clike { "FUNC": "TAG READER V2.0", "TOTAL": 1, "0": { "x": 113, "y": 65, "w": 117, "h": 105, "p0x": 113, // p0x ~ p3y: TAG 4个顶点的坐标 "p0y": 77, "p1x": 211, "p1y": 65, "p2x": 230, "p2y": 156, "p3x": 127, "p3y": 170, "rotation": 8, // TAG 的相对旋转角度 "rows": 8, // TAG 的行数(本数值不含定位框) "columns": 8, // TAG 的列数(本数值不含定位框) "size": 64, // TAG 实际内容的数据长度,该值 = 内容的行数 * 内容的列数 = (rows) * (columns) "code": "0x003C42425A424200", // uint64_t类型的内容二进制代码,本键值最大编码64位(8 x 8)的TAG "binstr": "0000000000111100010000100100001001011010010000100100001000000000" //二进制数据的字符串形式,本键值可以编码任意长宽的TAG } } ``` ### 巡线 >检测画面中指定的颜色线条,并返回偏移角度。 >程序块介绍 - `初始化` + 初始化 - `获取线条偏移角度` + 获取线条偏移角度 - `设置追踪目标颜色 L阈值最小 0 L阈值最大 0 A阈值最小 A阈值最大 B阈值最小 B阈值最大` + 设置追踪的LAB阈值(LAB颜色空间的颜色值,在该范围外的颜色将会被过滤) - `设置线条weight0区域权重,weight1区域权重,weight2区域权重` + 设置线条区域权重:三个权重分别对应图中三个区域对角度的贡献值。比如把weight_2的值设置的大一些,则当转弯时角度变化将更加剧烈。 #### 设置LAB阈值 >参考上方`颜色追踪`功能中的LAB取色工具的使用方法,拍摄需要巡线的线条与场景,并记录下方生成的LAB数值,在UIFlow中配置使用。 >程序案例:获取线条偏移角度,并显示在屏幕上 - [Click here to download the UIFlow example](https://github.com/m5stack/M5-ProductExampleCodes/tree/master/V_Function/Line_Tracker) ### 巡线-数据包格式 #### 回传JSON ```clike { "FUNC": "LINE TRACKER V1.0", "angle": 3.8593475818634033 //小车转弯的角度 } ``` #### 设置JSON ```clike { "LINE TRACKER": 1.0, //功能标记,不可缺省 "thr_w": 20, //可缺省 边界框宽阈值,[3,200] "thr_h": 20, //可缺省 边界框长阈值,[3,200] "stepx": 1, //可缺省 X扫描间隔,[0, 40],设置为0则关闭边界框检测 "stepy": 2, //可缺省 Y扫描间隔,[0, 40],设置为0则关闭边界框检测 "merge": 10, //可缺省 边界框合并阈值,[0, 40] "Lmin": 0, //可缺省 L阈值下限 [0, 100] "Lmax": 0, //可缺省 L阈值上限 [0, 100] "Amin": 0, //可缺省 A阈值下限 [0, 255] "Amax": 0, //可缺省 A阈值上限 [0, 255] "Bmin": 0, //可缺省 B阈值下限 [0, 255] "Bmax": 0, //可缺省 B阈值上限 [0, 255] "weight_0": 0.1, // 可缺省 权重 "weight_1": 0.3, // 可缺省 权重 "weight_2": 0.7 // 可缺省 权重 } ``` ## 更多内容 Github