迪文科技论坛

 找回密码
 立即注册
搜索
查看: 92|回复: 0

【2023.3.11获奖项目】基于迪文屏的手势识别

[复制链接]

567

主题

167

回帖

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11978
发表于 2024-1-11 09:25:32 | 显示全部楼层 |阅读模式
【开源】基于迪文屏的手势识别

1.介绍
人工智能目前也是比较火热的一个方向,迪文屏也有一些摄像头识别的案例,今天我也来做一个关于人工智能方面的DEMO,也欢迎大家一起学习人工智能。

2.设计
(1)硬件设计:TinyMaix是面向单片机超轻量级的神经网络推理库,即TinyML推理库,可以让你在任意单片机上运行轻量级深度学习模型,这次设计主要采用了TinyMaix神经网络进行的手势识别功能。下图1是硬件连接图:


图1 硬件连接图
整体硬件连接框架如下图2所示:


图2 整体框架连接图
(2)手势识别检测进程流程图如下图3所示:



图3 手势识别检测流程图
3.界面设计
界面设计主要分为以下几个框架,文本显示,按键返回,基本图形。光照值部分部分本来想采用图片的,但是发现要用很多张图片,后采用基本图形画进度条。其中这个设计最复杂的地方,就是画出手势识别的路径,这个需要触摸和基本图形配合。首先我们看一下整体的界面设计,如下图4所示。


图4 整体界面设计

4.代码设计
(1)首先要检测按下区域,我直接调用的系统变量,获取当前触摸下是什么状态,对应的坐标是什么,如果检测到是按压,且按下的范围是输入框范围中,则进入显示路径函数,检测按下函数功能如下:

  1. <font size="3" face="宋体">void get_tp_status()
  2. {
  3.     u16 Va[3] = 0;
  4.     u8 i = 0;
  5.    

  6.     for(i = 0;i < 3;i++)
  7.     {
  8.         Va[i] = Read_Dgus(0x0016 + i);
  9.         if(Va[0] == 0x5A03)
  10.         {
  11. //            OneSendData3(Va[i] / 256);
  12. //            OneSendData3(Va[i] % 256);  
  13.         }
  14.         else
  15.         {
  16.             break;
  17.         }
  18.     }
  19.     if(i != 0)  //按压才进入
  20.     {
  21.         if(Va[1] >= RECTANGLE_START_X && Va[1] < RECTANGLE_END_X && Va[2] >= RECTANGLE_START_Y && Va[2] < RECTANGLE_END_Y)    //在矩形范围内
  22.         {
  23. //            OneSendData3(Va[1] / 256);
  24. //            OneSendData3(Va[1] % 256);
  25. //            OneSendData3(Va[2] / 256);
  26. //            OneSendData3(Va[2] % 256);
  27.             if(paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X)/10] == 0)
  28.             {
  29.                 paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X)/10] = 255;
  30.                 paint_rectangle_cmd(Va[1], Va[2]);
  31.             }
  32.             if(paint_status[(Va[2]-RECTANGLE_START_Y + 10)/10][(Va[1]-RECTANGLE_START_X)/10] == 0)
  33.             {
  34.                 paint_status[(Va[2]-RECTANGLE_START_Y + 10)/10][(Va[1]-RECTANGLE_START_X)/10] = 255;
  35.                 paint_rectangle_cmd(Va[1], Va[2] + 10);
  36.             }
  37.             if(paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X + 10)/10] == 0)
  38.             {
  39.                 paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X + 10)/10] = 255;
  40.                 paint_rectangle_cmd(Va[1] + 10, Va[2]);
  41.             }
  42.             if(paint_status[(Va[2]-RECTANGLE_START_Y + 10)/10][(Va[1]-RECTANGLE_START_X + 10)/10] == 0)
  43.             {
  44.                 paint_status[(Va[2]-RECTANGLE_START_Y + 10)/10][(Va[1]-RECTANGLE_START_X + 10)/10] = 255;
  45.                 paint_rectangle_cmd(Va[1] + 10, Va[2] + 10);
  46.             }
  47.         }
  48.     }
  49. }</font>
复制代码

(2)创建二维数组和描绘路径
创建一个二维数组,就是用于存储按下的位置,后面需要发送到手势识别检测的MCU上。当按下屏幕,对应的坐标需要设置标志位,上面代码中【paint_status[(Va[2]-RECTANGLE_START_Y)/10][(Va[1]-RECTANGLE_START_X)/10] = 255;】就是将对应二维数组中的标志位置数。

之后就要在迪文屏上描绘路径了,这部分最为复杂,我主要以十个像素为一个点,这样描绘出一个矩形框,然后根据触摸的位置,对不同位置的基本图形进行画矩形,为了减少重复刷屏的压力,我一个基本图形只描绘14个矩形框,串口命令传输的长度也在256个字节以内,一共是28x28,所以需要56个基本图形控件,在设计界面那里也是可以看出来的。然后警告对触摸和基本图形控件的配置,最终用下面的算法实现了触摸哪里,哪里就会显示路径。

  1. <font size="3" face="宋体">void paint_rectangle_cmd(u16 x_point, u16 y_point)
  2. {
  3.     static u16 x_point_last = 0, y_point_last = 0;
  4.     u8 Cmd[150] = {DTHD1,DTHD2,0X93,0X82,0X20,0x00,0x00,0x04,0x00,0x0E};
  5.     u8 rectangle_i = 0;
  6.     u8 i = 0;
  7.     u8 y_index, x_index;    //数组的第几个

  8.     if(abs(x_point_last - x_point) < 10 && abs(y_point_last - y_point < 10))
  9.         return;

  10.     x_point_last = x_point;
  11.     y_point_last = y_point;
  12.     y_index = (y_point - RECTANGLE_START_Y) / 10;
  13.     x_index = (x_point - RECTANGLE_START_X) / 140;
  14.     //哪个变量
  15.     Cmd[4] = (((y_point - RECTANGLE_START_Y) / 10) * 2) + ((x_point - RECTANGLE_START_X) / 140) + 0x20;
  16.    
  17.     for(i = 0;i < 14;i++)
  18.     {
  19.         Cmd[10 * i + 10] = (RECTANGLE_START_X + 10 * i + x_index * 140) / 256;
  20.         Cmd[10 * i + 11] = (RECTANGLE_START_X + 10 * i + x_index * 140) % 256;
  21.         Cmd[10 * i + 12] = (RECTANGLE_START_Y + y_index * 10) / 256;
  22.         Cmd[10 * i + 13] = (RECTANGLE_START_Y + y_index * 10) % 256;
  23.         Cmd[10 * i + 14] = ((RECTANGLE_START_X + 10 * i + x_index * 140) + 10) / 256;
  24.         Cmd[10 * i + 15] = ((RECTANGLE_START_X + 10 * i + x_index * 140) + 10) % 256;
  25.         Cmd[10 * i + 16] = ((RECTANGLE_START_Y + y_index * 10) + 10) / 256;
  26.         Cmd[10 * i + 17] = ((RECTANGLE_START_Y + y_index * 10) + 10) % 256;
  27.         if(paint_status[y_index][x_index * 14 + i] == 255)
  28.         {
  29.             Cmd[10 * i + 18] = 0x07;
  30.             Cmd[10 * i + 19] = 0xFF;
  31.         }
  32.         else
  33.         {
  34.             Cmd[10 * i + 18] = 0x0B;
  35.             Cmd[10 * i + 19] = 0x6F;
  36.         }
  37.     }
  38. //    for(i = 0;i < 150;i++)
  39. //        OneSendData3(Cmd[i]);

  40.     for(rectangle_i=((Cmd[2]-3)/2)-1;rectangle_i<((Cmd[2]-3)/2);rectangle_i--)
  41.         Write_Dgus(((Cmd[4]<<8)+Cmd[5]+rectangle_i),((Cmd[6+2*rectangle_i]<<8)+Cmd[7+2*rectangle_i]));

  42.     //base_cnt++;   
  43. }</font>
复制代码

4.效果展示
一共可以识别0~9,下面我演示了0,1,2的数字输入,效果如下图所示。






5.总结
人工智能可以做的东西有很多,迪文屏能实现的界面也有很多,这两者结合起来可以实现的DEMO也有很多,后续我会继续设计一个人工智能+迪文屏的设计,和大家共同进步。





备注说明:如需源码,请参考此链接:http://inforum.dwin.com.cn:20080/forum.php?mod=viewthread&tid=7645&_dsign=f06c5912







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-11-24 09:16 , Processed in 0.065011 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表