模块特性

HuskyLens板载UART/I2C接口,可以连接到Arduino、Raspberry Pi、LattePanda、micro:bit、STM32等主流控制器,实现硬件无缝对接,直接输出识别结果给控制器,无需折腾复杂的算法,就能制作非常有创意的项目。
该智能硬件模组于2020年2月正式出售(预售价329RMB),通过一段官方演示视频进一步了解该模组。
Huskylens内置了许多类型的图像处理算法,可支持拍照、运算、识别和处理为一体,最终将识别结果通过UART/I2C输出到控制器,其接口说明如下所示:
-
USB 接口:接上电源自动开机,断掉电源自动关机,配上上位机,可以更新固件; -
传感器接口:支持 UART 或 I2C 协议,通过该接口,可连接常用的主控板,如 Arduino、树莓派、micro:bit;该接口也支持供电; -
功能按键:左右拨动,切换选择内置的功能;向下短按,调出或隐藏菜单;向下长按,进入当前功能的参数设置; -
学习按键:按下“学习按键”,学习指定物体。支持长按操作,长按期间,将持续学习; -
屏幕:2.0 寸 IPS 显示器,实时看到各种状态下的结果,方便调试,所见即所得。
Huskylens主要有六大功能,简介如下所示:
-
物体追踪:追踪指定的物体,可以是任何有明显轮廓的物体,甚至是各种手势; -
人脸识别:侦测脸部轮廓,可同时识别多人; -
物体识别:识别这是什么物体(仅限于内置的 20 种物体); -
巡线追踪:识别指定的线条,并做路径规划; -
颜色识别:识别指定的颜色及其位置(由于光线的变化,对于相近的颜色,摄像头有时会误识别); -
标签识别:侦测二维码标签,识别出指定标签(目前摄像头不能识别复杂二维码,如微信上用的二维码)。
模块调测
由于Huskylens将识别的结果通过UART/I2C传输到控制器,所以我们只需要在Huskylens上训练好识别对象,解析接口协议即可,这里我使用的是UART通信协议(57600 (bps) 8N1),该模块的协议格式如下所示:
协议解析如下:
-
数据头1和数据头2以0x55和0xAA固定格式开头,因为0x55二进制是0101 0101,0xAA二进制是1010 1010,在通讯编码原理中,应该尽可能避免过多的重复0或1,因为当你的传输变成一个长0/1时,一个脉冲干扰就会将你的数据截断,增加误码的机会。 若你的通讯机不能正确接受10101010或01010101,那么你的线路等肯定出现问题。 这个只是一个快速判断线路状态的一个手段,在做内现存测试的时候也经常使用这两个数据字段,也是同样的道理; -
地址占用一个字节,本模块默认地址是0x11; -
数据长度占用一个字节,指数据的长度,注意不是整个数据帧的长度; -
命令ID占用一个字节; -
数据长度为10位,数据信息为检测到对象的像素尺寸和对象属性,顺序为:检测对象X点中心低位字节、检测对象X点中心高位字节、检测对象Y点中心低位字节、检测对象Y点中心高位字节、检测对象宽度低位字节、检测对象宽度高位字节、检测对象高度低位字节、检测对象高度高位字节,剩余两个字节为检测到的对象; -
8位累加和校验,不进位,例如:0x55+0xAA+0x11+0x0A+0x10+0x2C+0x01+0xC8+0x00+0x0A+0x00+0x14+0x00+0x01+0x00=0x23E,则校验位为0x3E。
Huskylens无需请求指令,自动发送毫秒级的设备状态数据帧,打开串口调测助手即可直接分析,下面以人脸识别功能为例,分析协议帧结构。
这里选取了周杰伦的图像作为识别对象, Huskylens人脸识别训练操作流程如下所示:
在尚未检测到目标对象的情况下,打开串口调测助手,模组发送大量数据(均相同),选择其中一条分析。

训练周杰伦的人脸作为识别对象,如下所示:

此时模块发送的协议帧,可以识别出0001号ID,也就是周杰伦的人脸图像尺寸,如下所示:

可以打开模块的多人脸训练模式,训练阿信为第二个识别对象,如下所示:

多人模式模块发送的协议帧中识别对象ID和单人模式有所区别,此时识别周杰伦(创建的第一个对象)。
模块发送协议如下所示:
协议帧中数据0xFFFE代表多人识别中第二个对象(阿信)未识别到。
再识别阿信(创建的第二个对象),如下所示:
模块发送协议如下所示:
其中0xFFFF代表多人识别中第一个对象(周杰伦)未识别到。
HuskyLens人工智能摄像头的应用就简要讲解人脸识别的功能,其他功能都是大同小异,小伙伴们了解协议帧就可以轻松应对。
模块应用
由于目前手头上只有STM32系列开发板,遂基于STM32+HuskyLens实现人脸识别开关灯小案例,多人对象识别,未识别到周杰伦开灯,未识别到阿信熄灯,实现代码、效果如下所示,主要是拆解、校验协议。
uint8_t UART2_ReceivedChar=0,check = 0;uint8_t USART2_RxData[16];uint32_t USART2_RX_DATA_BUF_CNT=0;int8_t USART2_RX_Flag=0;uint16_t data_id=0;void USART2_IRQHandler(void){//UART2接收数据if(LL_USART_IsActiveFlag_RXNE(USART2)){UART2_ReceivedChar = 0;//读取接收寄存器,读数据会清中断UART2_ReceivedChar = LL_USART_ReceiveData8(USART2);//判断若以0x55开头,接收16个字符if(UART2_ReceivedChar==0x55){USART2_RX_Flag=1;}if(USART2_RX_Flag==1&&USART2_RX_DATA_BUF_CNT<16){USART2_RxData[USART2_RX_DATA_BUF_CNT++] = UART2_ReceivedChar;}//接收16个字符后进行处理else{//因为模块发送速度过快,需要校验if(USART2_RxData[0]==0x55&&USART2_RxData[1]==0xAA&&USART2_RxData[2]==0x11){//进行累加和校验,对比发送和接收的是否一致for(int8_t i=0;i<15;i++){LL_mDelay(10);check+=USART2_RxData[i];}LL_mDelay(200);//若接收正确,处理if(check==USART2_RxData[15]){//装载低位、高位识别对象IDdata_id=USART2_RxData[14];data_id<<=8;data_id|=USART2_RxData[13];//未检测到周杰伦if(data_id==0xFFFF){//LED灯灭LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_9);}//未检测到阿信else if(data_id==0xFFFE){//LED灯亮LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_9);}}}//清除标志USART2_RX_Flag=0;USART2_RX_DATA_BUF_CNT=0;check=0;}//清除溢出标志LL_USART_ClearFlag_ORE(USART2);}}
小伙伴们通过设定断点可以看到每一次的上次数据和发送到串口调试助手的一致。
点击“阅读原文”可以在CSDN与我交流
文章转载自公众号:非0即1,已获授权,如需转载麻烦联系原作者
往期回顾
听说创客们都收藏了这个网站……
自制的大疆S1战车来了!
当谷歌小恐龙变成了一个小人……
焊武帝,他来了!
Arduino大家都熟,你听过Freeduino么?
【福利】Arduino系列引脚大全
拾色手电:颜色万千,只取一种
【小白福利】如何入门Arduino(上)
【小白福利】如何入门Arduino(下)
留下
👇


