本帖最后由 tobot 于 2024-5-30 23:27 编辑
0x01 数字识别的GUI呈现
为了显示数字识别(包括具体数字和数字所在位置),需要有一个GUI界面,本来准备使用LVGL做在LCD屏上,但无奈出差在外,手边材料不足。于是考虑借助网络传输,将数据使用浏览器呈现出来。
浏览器中需要包含两个部分:原始图像采集和结果输出。
使用python的flask模块来搭建http server。并且在循环中用yield返回一个生成器,这样就可以多次采集数据并以视频方式呈现在网页中。具体方案包括:
1)图像采集:
使用opencv-python(cv2)从摄像头采集图像,采集出来的图像为单一的画面帧,设置一个循环,不断地从摄像头读取帧。
2)生成器函数:
创建一个生成器函数,该函数包含一个无限循环,将采集到的图像以压缩格式发送出来,
使用yield关键字返回。
3)处理图像并返回
与原始图像类似,再做一个生成器返回处理完成的图像。
4)视频流处理:
创建两个路由,分别调用生成器函数,实现在网页逐帧返回图像数据。这样就生成一个“视频流”。
5)网页呈现:
在flask的模板中,通过标签调用视频流。
6)数据传输:
为了减少延迟和带宽消耗,考虑对图像数据进行压缩,使用JPEG格式。
0x02 图像处理
1)图像分割
将采集到的图像变为灰度图,经过腐蚀和退化,二值化,并且使用cv2.canny函数描边,再通过cv2.boundingRect切出最小矩形。将矩形边框略微放大一点,采集二值化的图像。
2)数字识别
由于训练采用mnist图集,图片大小都是28*28,且为黑底白字,因此需要将分割后图像进行预处理,以适应模型的输入格式。放入之前推理过程,进行数字识别,并返回结果。
3)结果生成
定义一副白色背景图片,根据采集图像矩形的位置和高度和推理返回值,写出对应数字。完成后的图像作为最终结果返回。
0x03 系统安装
在原生的操作系统中,python的库不全,需要重新编译。
按照https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-SDK部署SDK环境,新安装Ubuntu 22.04之后,更新并安装对应软件。
安装完成后,继续按照文档git,文档中直接git,会发现权限不够,需要增加sudo。命令为
sudo git clone https://gitee.com/LuckfoxTECH/luckfox-pico.git
视网络情况,可能需要几分钟~几小时来拉取(我这边就是几小时的那种)。
关于编译环境配置和SDK安装写得挺详细,不用再重复。
完成后先编译一次,再使用menuconfig增加需要的python库文件,重新编译并烧入。
使用adb方式把写好的代码放入开发板。
0x04 使用
板卡运行代码,主机使用浏览器打开网页,在浏览器中就可以看到原始图像和识别后的结果了。
0x05 最终效果
播放器加载失败: 未检测到Flash Player,请到
安装
录制_2024_05_30_23_17_28_987
0x06 改进想法
1)识别错误
从结果上看,目前手写数字推理的正确率不高,远远达不到训练时90%以上的正确率,推测有可能是用于训练的数据集与真正用来识别的数据集有一定差异,这个一方面考虑改进增加训练数据的多样性和数量,重新训练;另外自制的网络结构过于简单(只有三层),这个可能也是拟合度不高的原因之一,考虑尝试更复杂的网络结构,多做几个卷积,增加网络的深度和宽度(必然带来效率降低);训练时可以试试调参和损失函数,比如对学习率、批量大小、优化器等,但具体方向并不明确,只能摸索。
2)代码效率
目前看来效率不高,图像明显卡顿,这个一方面是性能原因,另一方应该是优化不足造成。具体如何优化目前还没太好思路。
3)图像分割
可以看到在有些画面中,同一个数字被分割成了多个图片分别识别,这个一方面是手写数字可能有笔画不连续的情况,另一方面腐蚀的时候有可能把连通图给腐蚀成多个图片,具体怎么优化这方面,我觉得也只能尝试调整图像处理矩阵来优化。
- 其它
二值化图像时,实际上我是取了个巧,选择特定光照下的图片,事实上,图片在不同亮度下,很可能结果完全不一样。要把数字识别真正进入实用环节,还有很长一段路需要走。