感谢爱好者-李工的再次投稿!
我用树莓派CM0做了个人脸检测,结果大家全在要代码和模型!
用树莓派CM0做物体识别,小白一键跑通!
新品树莓派CM0,用于智能家居?
我用树莓派CM0做了一个数字识别!本文介绍了树莓派 CM0 Dev Board 的实现网页手写数字识别的项目设计,包括准备工作、环境搭建、MNIST 数据集和 ONNX 模型、流程图、关键代码以及效果演示等。
项目介绍
准备工作:包括所需 Python 环境、数据集训练、模型下载、软件包的安装部署等;
网页手写数字识别:通过 Web 网页端构建手写面板,CM0 接收手写数字图片,调用预训练模型完成板端推理,回传识别结果至网页端。
MNIST 数据集
Modified National Institute of Standards and Technology (MNIST) 是一个包含手写数字的数据集,里面有上万张数字图片,每张图片都标注了对应的数字标签(0到9)。该数据集可用来训练识别手写数字的神经网络。
详见:https://yann.lecun.com/exdb/mnist/
ONNX
Open Neural Network Exchange (ONNX) 是一个开放的生态系统,为 AI 开发人员提供支持 随着项目的发展选择正确的工具。
ONNX 为 AI 模型(包括深度学习和传统 ML)提供开源格式。它定义了一个可扩展的计算图模型,以及内置运算符和标准的定义 数据类型。
详见:https://github.com/onnx/onnx
准备工作
系统安装及环境搭建详见:https://edatec.cn/docs/zh/cm0/um/3-booting-the-device/
硬件连接
- 若采用 SSH 远程登录操作,则仅需连接电源供电即可;若采用本地登录,则需连接 HDMI 视频流传输线、USB 键盘连接线等;
库安装
执行指令 sudo apt install python3-opencv 安装 OpenCV
安装解析 ONNX 模型所需的 onnxruntime 库,终端执行
sudo apt install python3-pipsudo pip3 install onnxruntime --break-system-packages
模型下载
下载 模型文件至本地 ./model 文件;
mkdir modelcd modelwget https://github.com/onnx/models/blob/main/validated/vision/classification/mnist/model/mnist-12.onnx
详见:
https://github.com/onnx/models/tree/main/validated/vision/classification/mnist
流程图
文件目录
/home/ljl/MNIST├── hnr_mnist_web.py # 主程序 Flask 入口├── model/│ └── mnist-12.onnx # ONNX 模型文件└── web/└── index.html # 网页文件
代码
终端执行 touch hnr_mnist_web.py 指令新建文件,并 nano hnr_mnist_web.py 添加如下代码
#!/usr/bin/env python3import cv2, numpy as np, onnxruntime as ort, base64, io, timefrom flask import Flask, render_template_string, request, jsonifyapp = Flask(__name__)MODEL = './model/mnist-12.onnx'sess = ort.InferenceSession(MODEL, providers=['CPUExecutionProvider'])in_name = sess.get_inputs()[0].name # Input3out_name = sess.get_outputs()[0].name # Plus214_Output_0def softmax(x):"""稳定版 softmax,返回概率数组"""x = x - np.max(x) # 防溢出exp_x = np.exp(x)return exp_x / np.sum(exp_x)def decode_canvas(data_url):header, encoded = data_url.split(',', 1)img = cv2.imdecode(np.frombuffer(base64.b64decode(encoded), np.uint8),cv2.IMREAD_GRAYSCALE)return img@app.route('/')def index():with open('./web/index.html') as f:return render_template_string(f.read())@app.route('/predict', methods=['POST'])def predict():t0 = time.time()img = decode_canvas(request.json['image'])img = cv2.bitwise_not(img) # 白底黑字-转换为-黑底白字img = cv2.resize(img, (28, 28))blob = img.astype(np.float32) / 255.0blob = blob.reshape(1, 1, 28, 28) # NCHWpred = sess.run([out_name], {in_name: blob})[0][0] # logitsprob = softmax(pred) # 归一化到 0~1digit = int(np.argmax(prob))conf = float(prob[digit]) # 置信度cost = (time.time() - t0) * 1000return jsonify({'digit': digit, 'conf': round(conf, 3), 'time': round(cost, 1)})if __name__ == '__main__':app.run(host='0.0.0.0', port=8080, debug=False)
保存代码。
网页设计
终端执行 mkdir web 新建文件夹,用于存放网页文件;
进入 web 文件夹,执行 touch index.html 指令新建网页文件,并 nano index.html 添加如下代码
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><title>CM0 手写识别</title><style>body{font-family:Arial,Helvetica,sans-serif;text-align:center;background:#f2f2f2}canvas{border:1px solid#999;display:block;margin:10px auto;background:#fff}button{font-size:18px;margin:6px;padding:6px 14px}#res{color:#d44;font-size:20px;font-weight:bold}</style></head><body><h2>树莓派 CM0 手写数字识别</h2><canvas id="c" width="280" height="280"></canvas><div><button id="clear">清空</button><button id="go">识别</button></div><p id="res">等待识别…</p><script>const canvas = document.getElementById('c');const ctx = canvas.getContext('2d');ctx.fillStyle='#fff'; ctx.fillRect(0,0,280,280);ctx.lineWidth=20; ctx.lineCap='round'; ctx.strokeStyle='#000';let drawing=false;function pos(e){const r=canvas.getBoundingClientRect();return [e.clientX-r.left,e.clientY-r.top];}canvas.onmousedown=e=>{drawing=true;ctx.beginPath();ctx.moveTo(...pos(e));};canvas.onmousemove=e=>{if(drawing){ctx.lineTo(...pos(e));ctx.stroke();}};canvas.onmouseup=()=>drawing=false;document.getElementById('clear').onclick=()=>{ctx.fillStyle='#fff';ctx.fillRect(0,0,280,280);document.getElementById('res').textContent='等待识别…';};document.getElementById('go').onclick=async()=>{const tmp=document.createElement('canvas');tmp.width=tmp.height=28;const tctx=tmp.getContext('2d');tctx.drawImage(canvas,0,0,28,28);const dataURL=tmp.toDataURL('image/png');const r=await fetch('/predict',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({image:dataURL})}).then(r=>r.json());document.getElementById('res').textContent=`识别结果:${r.digit} (置信度 ${(r.conf*100).toFixed(1)}%) 耗时:${r.time} ms`;};</script></body></html>
保存代码。
效果
终端执行指令 python hnr_mnist_web.py 运行程序;
终端打印网页访问地址、访问信息等;
-
- 同一局域网下,浏览器输入终端输出的网页地址 192.168.1.125:8080
-
- 打开目标网页;用鼠标或触摸板在面板区域手写数字,点击 识别 按钮,下方立即显示识别结果、置信度、耗时等信息;
- 更多手写数字识别效果如下
总结
本文介绍了树莓派 CM0 Dev Board 的实现网页手写数字识别的项目设计,包括准备工作、环境搭建、MNIST 数据集和 ONNX 模型、流程图、关键代码以及效果演示等,为相关产品在 AI 视觉领域的开发设计和快速应用提供了参考。
如果你想查看具体产品内容,可以通过原文进行了解:
https://blog.csdn.net/qq_36654593/article/details/154186831
官方网站:https://edatec.cn/zh/cm0
淘宝店铺:https://edatec.taobao.com/
全面升级!树莓派 CM0NANO 单板计算机发布!
1199