1.介绍 人工智能目前也是比较火热的一个方向,迪文屏也有一些摄像头识别的案例,今天我也来做一个关于人工智能方面的Demo,也欢迎大家一起学习人工智能。 2.设计 TinyMaix是面向单片机超轻量级的神经网络推理库,即TinyML推理库,可以让你在任意单片机上运行轻量级深度学习模型,这次设计主要采用了TinyMaix神经网络进行的手势识别功能。 下图1是硬件连接图: 图1 硬件连接图 整体硬件连接框架如下图2所示: 图2 整体框架连接图 手势识别检测进程流程图如下图3所示: 图3 手势识别检测流程图 3.界面设计 界面设计主要分为以下几个框架,文本显示,按键返回,基本图形。 光照值部分部分本来想采用图片的,但是发现要用很多张图片,后采用基本图形画进度条。 其中这个设计最复杂的地方,就是画出手势识别的路径,这个需要触摸和基本图形配合。首先我们看一下整体的界面设计,如下图4所示。 图4 整体界面设计 接下来就是代码的讲解了,首先要检测按下区域,我直接调用的系统变量,获取当前触摸下是什么状态,对应的坐标是什么,如果检测到是按压,且按下的范围是输入框范围中,则进入显示路径函数,检测按下函数功能如下: - void get_tp_status()
- {
- u16 Va[3] = 0;
- u8 i = 0;
-
- for(i = 0;i < 3;i++)
- {
- Va[i] = Read_Dgus(0x0016 + i);
- if(Va[0] == 0x5A03)
- {
- // OneSendData3(Va[i] / 256);
- // OneSendData3(Va[i] % 256);
- }
- else
- {
- break;
- }
- }
- if(i != 0) //按压才进入
- {
- if(Va[1] >= RECTANGLE_START_X && Va[1] < RECTANGLE_END_X && Va[2] >= RECTANGLE_START_Y && Va[2] < RECTANGLE_END_Y) //在矩形范围内
- {
- // OneSendData3(Va[1] / 256);
- // OneSendData3(Va[1] % 256);
- // OneSendData3(Va[2] / 256);
- // OneSendData3(Va[2] % 256);
- if(paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X)/10] == 0)
- {
- paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X)/10] = 255;
- paint_rectangle_cmd(Va[1], Va[2]);
- }
- if(paint_status[(Va[2]-RECTANGLE_START_Y + 10)/10][(Va[1]-RECTANGLE_START_X)/10] == 0)
- {
- paint_status[(Va[2]-RECTANGLE_START_Y + 10)/10][(Va[1]-RECTANGLE_START_X)/10] = 255;
- paint_rectangle_cmd(Va[1], Va[2] + 10);
- }
- if(paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X + 10)/10] == 0)
- {
- paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X + 10)/10] = 255;
- paint_rectangle_cmd(Va[1] + 10, Va[2]);
- }
- if(paint_status[(Va[2]-RECTANGLE_START_Y + 10)/10][(Va[1]-RECTANGLE_START_X + 10)/10] == 0)
- {
- paint_status[(Va[2]-RECTANGLE_START_Y + 10)/10][(Va[1]-RECTANGLE_START_X + 10)/10] = 255;
- paint_rectangle_cmd(Va[1] + 10, Va[2] + 10);
- }
- }
- }
- }
复制代码
首先要创建一个二维数组,就是用于存储按下的位置,后面需要发送到手势识别检测的MCU上。当按下屏幕,对应的坐标需要设置标志位,上面代码中【paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X)/10] = 255;】就是将对应二维数组中的标志位置数。 之后就要在迪文屏上描绘路径了,这部分最为复杂,我主要以十个像素为一个点,这样描绘出一个矩形框,然后根据触摸的位置,对不同位置的基本图形进行画矩形,为了减少重复刷屏的压力,我一个基本图形只描绘14个矩形框,串口命令传输的长度也在256个字节以内,一共是28x28,所以需要56个基本图形控件,在设计界面那里也是可以看出来的。然后警告对触摸和基本图形控件的配置,最终用下面的算法实现了触摸哪里,哪里就会显示路径。 - void paint_rectangle_cmd(u16 x_point, u16 y_point)
- {
- static u16 x_point_last = 0, y_point_last = 0;
- u8 Cmd[150] = {DTHD1,DTHD2,0X93,0X82,0X20,0x00,0x00,0x04,0x00,0x0E};
- u8 rectangle_i = 0;
- u8 i = 0;
- u8 y_index, x_index; //数组的第几个
- if(abs(x_point_last - x_point) < 10 && abs(y_point_last - y_point < 10))
- return;
- x_point_last = x_point;
- y_point_last = y_point;
- y_index = (y_point - RECTANGLE_START_Y) / 10;
- x_index = (x_point - RECTANGLE_START_X) / 140;
- //哪个变量
- Cmd[4] = (((y_point - RECTANGLE_START_Y) / 10) * 2) + ((x_point - RECTANGLE_START_X) / 140) + 0x20;
-
- for(i = 0;i < 14;i++)
- {
- Cmd[10 * i + 10] = (RECTANGLE_START_X + 10 * i + x_index * 140) / 256;
- Cmd[10 * i + 11] = (RECTANGLE_START_X + 10 * i + x_index * 140) % 256;
- Cmd[10 * i + 12] = (RECTANGLE_START_Y + y_index * 10) / 256;
- Cmd[10 * i + 13] = (RECTANGLE_START_Y + y_index * 10) % 256;
- Cmd[10 * i + 14] = ((RECTANGLE_START_X + 10 * i + x_index * 140) + 10) / 256;
- Cmd[10 * i + 15] = ((RECTANGLE_START_X + 10 * i + x_index * 140) + 10) % 256;
- Cmd[10 * i + 16] = ((RECTANGLE_START_Y + y_index * 10) + 10) / 256;
- Cmd[10 * i + 17] = ((RECTANGLE_START_Y + y_index * 10) + 10) % 256;
- if(paint_status[y_index][x_index * 14 + i] == 255)
- {
- Cmd[10 * i + 18] = 0x07;
- Cmd[10 * i + 19] = 0xFF;
- }
- else
- {
- Cmd[10 * i + 18] = 0x0B;
- Cmd[10 * i + 19] = 0x6F;
- }
- }
- // for(i = 0;i < 150;i++)
- // OneSendData3(Cmd[i]);
- for(rectangle_i=((Cmd[2]-3)/2)-1;rectangle_i<((Cmd[2]-3)/2);rectangle_i--)
- Write_Dgus(((Cmd[4]<<8)+Cmd[5]+rectangle_i),((Cmd[6+2*rectangle_i]<<8)+Cmd[7+2*rectangle_i]));
- //base_cnt++;
- }
复制代码
4.展示 一共可以识别0~9,下面我演示了0,1,2的数字输入,效果如下图所示。 5.总结 人工智能可以做的东西有很多,迪文屏能实现的界面也有很多,这两者结合起来可以实现的Demo也有很多,后续我会继续设计一个人工智能+迪文屏的设计,和大家共同进步~
|