【电赛学习笔记】MaixCAM 的OCR图片文字识别

前言

本文是对MaixPy官方文档MaixCAM MaixPy 实现 OCR 图片文字识别 - MaixPy项目实践整理与拓展,侵权即删。

功能介绍

OCR是MaixCAM中功能强大的数字文字识别模块,可以做到轻松的识别各种数字与文字。

OCR官方例程解析

工程源码

python 复制代码
from maix import camera, display, image, nn, app

model = "/root/models/pp_ocr.mud"
ocr = nn.PP_OCR(model)

cam = camera.Camera(ocr.input_width(), ocr.input_height(), ocr.input_format())
disp = display.Display()

image.load_font("ppocr", "/maixapp/share/font/ppocr_keys_v1.ttf", size = 20)
image.set_default_font("ppocr")

while not app.need_exit():
    img = cam.read()
    objs = ocr.detect(img)
    for obj in objs:
        points = obj.box.to_list()
        img.draw_keypoints(points, image.COLOR_RED, 4, -1, 1)
        img.draw_string(obj.box.x4, obj.box.y4, obj.char_str(), image.COLOR_RED)
    disp.show(img)

拆解

把整段代码拆成"零基础小白语言",一行一行嚼碎了解释。

读完你就能知道:"这段程序到底在干嘛?每个括号里的东西是什么意思?"


🔑 先记住 3 个角色

角色 作用 比喻
摄像头 拍照 眼睛
PP_OCR 认字 大脑里的"识字老师"
屏幕 把结果给你看 画板

🧩 逐行讲解

1️⃣ 把"识字老师"请进门
复制代码
from maix import camera, display, image, nn, app
  • 告诉 Python:我要用 摄像头、屏幕、画图、识字老师、退出按钮 这 5 个工具包。

    model = "/root/models/pp_ocr.mud"

  • 识字老师的"教材"放在板子里的 /root/models/pp_ocr.mud

  • .mud 就是 MaixPy 的模型文件(提前烧好的)。

    ocr = nn.PP_OCR(model)

  • ocr 就是这位老师的名字。

  • nn.PP_OCR(...):用刚才那本教材,创建出识字老师。


2️⃣ 打开眼睛(摄像头)
复制代码
cam = camera.Camera(ocr.input_width(), ocr.input_height(), ocr.input_format())
  • ocr.input_width():老师告诉我们"照片必须宽 320 像素"(举例)。

  • ocr.input_height():照片必须高 320 像素。

  • ocr.input_format():照片必须是 RGB888 格式。

  • 摄像头就按这三条要求拍照。


3️⃣ 准备画板(屏幕)
复制代码
disp = display.Display()
  • 把板载 LCD 初始化成"画板",后面用 disp.show(...) 把图刷上去。

4️⃣ 换一支能写中文的笔
复制代码
image.load_font("ppocr", "/maixapp/share/font/ppocr_keys_v1.ttf", size=20)
image.set_default_font("ppocr")

先把字体文件加载进来并取名 "ppocr",再告诉系统"以后写字默认就用它"。

这样后面 draw_string 写中文时就不会缺字或乱码。

  • load_font:把 ppocr_keys_v1.ttf 这张"字体卡片"装进内存,取名叫 "ppocr"

  • set_default_font:后面写字都默认用这张卡片,字号 20。

  • 把它想象成 ​"给电脑安装并设置默认输入法"​ 的三步:


    ① 把字体文件装进内存
    复制代码
    image.load_font("ppocr", "/maixapp/share/font/ppocr_keys_v1.ttf", size = 20)
    参数 白话解释 类比
    "ppocr" 给这套字体起个"小名",后面写字时直接叫这个小名 把「搜狗拼音」安装后,系统里出现一个叫"搜狗"的输入法
    "/maixapp/share/font/ppocr_keys_v1.ttf" 字体文件真正存放的位置 输入法安装包在硬盘上的路径
    size = 20 默认字号 20 像素 安装时把默认字体大小调成 20 号

    执行完这行,内存里就多了一套叫 "ppocr" 的字体,字号默认 20。


    ② 把这套字体设为"默认"
    复制代码
    image.set_default_font("ppocr")
  • 以后所有 draw_string(...) 如果不另外指定,就用刚才那套 "ppocr" 字体

  • 就像 Windows 里把"搜狗"设为默认输入法,以后打字不用每次手动切换。


5️⃣ 无限循环:拍照 → 认字 → 画画 → 显示
复制代码
while not app.need_exit():
  • 一直循环,直到你按 Home 键或 IDE 停止。

  • app.need_exit() 就像"有人按了暂停键吗?"


5.1 拍照
复制代码
    img = cam.read()
  • 摄像头立即拍一张图,存到变量 img 里。

5.2 交给老师认字
复制代码
    objs = ocr.detect(img)
  • ocr.detect(img):老师看图,返回 一堆"字对象" 列表 objs

  • 每个对象里包含:

    • 字的内容(obj.char_str()

    • 字的方框 4 个顶点 (obj.box)


5.3 把每个字框出来并写字
复制代码
    for obj in objs:
  • 对每一个识别到的字,做下面两件事。

    复制代码
          points = obj.box.to_list()
  • 把字的 4 个角坐标变成列表,例如 [x1,y1,x2,y2,x3,y3,x4,y4]

    复制代码
          img.draw_keypoints(points, image.COLOR_RED, 4, -1, 1)
  • 在 4 个角上画红色小圆点("红点钉")。

    参数:

    • points:要画的点

    • image.COLOR_RED:颜色红

    • 4:点大小 4 像素

    • -1:实心填充

    • 1:线宽 1(此处实心所以忽略)

      复制代码
          img.draw_string(obj.box.x4, obj.box.y4, obj.char_str(), image.COLOR_RED)
  • 在方框右下角 (x4, y4) 写文字本身。

    参数:

    • obj.box.x4, obj.box.y4:文字左上角坐标

    • obj.char_str():识别到的文字(如"你"、"好")

    • image.COLOR_RED:红色


5.4 把画好的图给屏幕
复制代码
    disp.show(img)
  • 把整幅图立即刷到 LCD,你就能看到红框红字。

🎯 一句话总结

摄像头不停拍照 → PP_OCR 认字 → 程序把每个字用红框标出来并写上字本身 → 屏幕实时显示。

OCR应用拓展

本部分将实现,通过OCR识别文字然后通过串口协议通讯发送到MSPM0G3507单片机。

串口通讯部分内容可查看【电赛学习笔记】MaxiCAM 项目实践------与单片机的串口通信-CSDN博客

python 复制代码
from maix import camera, display, image, nn, app, uart, time
import struct
from serial_protocol import SerialProtocol   # 同目录下的协议类

# ---------- 初始化 OCR ----------
model = "/root/models/pp_ocr.mud"
ocr = nn.PP_OCR(model)

# ---------- 初始化摄像头 ----------
cam = camera.Camera(ocr.input_width(), ocr.input_height(), ocr.input_format())
disp = display.Display()

# ---------- 加载中文字体 ----------
image.load_font("ppocr", "/maixapp/share/font/ppocr_keys_v1.ttf", size=20)
image.set_default_font("ppocr")

# ---------- 初始化串口 ----------
device = "/dev/ttyS0"              # UART1:IO15(TX)  IO16(RX)
serial = uart.UART(device, 115200)
proto  = SerialProtocol()          # 协议打包/解包工具

while not app.need_exit():
    img = cam.read()
    objs = ocr.detect(img)

    # 本地可视化(可选)
    for obj in objs:
        points = obj.box.to_list()
        img.draw_keypoints(points, image.COLOR_RED, 4, -1, 1)
        img.draw_string(obj.box.x4, obj.box.y4, obj.char_str(), image.COLOR_RED)

    # 串口发送:改为索引遍历
    MAX_SEND = 3
    for idx in range(min(MAX_SEND, len(objs))):
        obj = objs[idx]
        text_utf8 = obj.char_str().encode('utf-8')
        payload = struct.pack('<H', idx) + text_utf8
        packet = proto.encode(payload)
        serial.write(packet)
        print(packet.hex(' '))

    disp.show(img)
    time.sleep_ms(50)

下面把 整段代码 拆成 "一句话一行" 的幼儿园级别讲解,每个括号、每个参数都说明白。你可以直接对着代码看注释。


0️⃣ 工具箱:把要用的"工具"搬进来

复制代码
from maix import camera, display, image, nn, app, uart, time
  • 告诉 Python:我要用 摄像头、屏幕、画图、神经网络、退出按钮、串口、延时 这些工具。

    import struct

  • 用来把数字/文字 打包成字节,方便串口发送。

    from serial_protocol import SerialProtocol

  • 把我们自己写的"串口协议 "小工具请进来,负责加帧头、校验、帧尾


1️⃣ 初始化"识字老师"

复制代码
model = "/root/models/pp_ocr.mud"
  • OCR 老师的"教材"文件路径(提前烧在板子里)。

    ocr = nn.PP_OCR(model)

  • 用这本教材 创建 OCR 识别器对象 ,名字叫 ocr


2️⃣ 打开"眼睛"和"画板"

复制代码
cam = camera.Camera(ocr.input_width(), ocr.input_height(), ocr.input_format())
  • 摄像头 拍照尺寸与老师要求一致:
    ocr.input_width() → 宽(如 320)
    ocr.input_height() → 高(如 224)
    ocr.input_format() → 像素格式(RGB/BGR)

    disp = display.Display()

  • 初始化屏幕,准备把图刷上去。


3️⃣ 换一支"能写中文的笔"

复制代码
image.load_font("ppocr", "/maixapp/share/font/ppocr_keys_v1.ttf", size=20)
  • 把字体文件 ppocr_keys_v1.ttf 装进内存,给它起小名叫 "ppocr",字号 20。

    image.set_default_font("ppocr")

  • 以后写字默认都用 "ppocr" 这套字体。


4️⃣ 打开"嘴巴"(串口)

复制代码
device = "/dev/ttyS0"
  • 告诉系统:我要用 UART1 (板子上 IO15=TX,IO16=RX)。

    serial = uart.UART(device, 115200)

  • 把串口波特率设成 115200,8N1,准备说话。

    proto = SerialProtocol()

  • 实例化"协议打包器",负责给每句话加 帧头 AA、校验和、帧尾 55


5️⃣ 主循环:一直干到死循环

复制代码
while not app.need_exit():
  • 如果没人按"停止"键,就一直循环。

5.1 拍照
复制代码
img = cam.read()
  • 摄像头立刻拍一张图,存进变量 img

5.2 让"识字老师"看图
复制代码
objs = ocr.detect(img)
  • 把图交给 ocr 识别,返回一个 OCR_Objects 列表,里面每条是一个字/一行文字。

5.3 本地画画(可选,但看得见)
复制代码
for obj in objs:
  • 对识别到的 每个文字块 做下面两件事。

    复制代码
      points = obj.box.to_list()
  • 四边形框 的四个顶点变成 [x1,y1,x2,y2,x3,y3,x4,y4]

    复制代码
      img.draw_keypoints(points, image.COLOR_RED, 4, -1, 1)
  • 在四个角画 红色实心小圆点(大小 4 像素)。

    复制代码
      img.draw_string(obj.box.x4, obj.box.y4, obj.char_str(), image.COLOR_RED)
  • 在右下角 写文字本身,颜色红色。


5.4 串口发送:最多发 3 条
复制代码
MAX_SEND = 3
  • 每帧最多发 3 条文字,防止串口拥堵。

    for idx in range(min(MAX_SEND, len(objs))):

  • 实际条数取 "3 与识别数量" 的较小值,避免越界。

    复制代码
      obj = objs[idx]
  • 拿第 idx 条文字对象。

    复制代码
      text_utf8 = obj.char_str().encode('utf-8')
  • 把文字转成 UTF-8 字节流(1 个汉字 3 字节左右)。

    复制代码
      payload = struct.pack('<H', idx) + text_utf8
  • 小端 16 位序号(2 字节)+ 文字字节流 → 组成 payload。

    复制代码
      packet = proto.encode(payload)
  • 用协议类给 payload 加帧头、长度、校验、帧尾

    复制代码
      serial.write(packet)
  • 把完整的 协议帧 通过 UART1 发出去。

    复制代码
      print(packet.hex(' '))      # 调试用
  • 在控制台打印十六进制,肉眼检查帧格式。


5.5 把画好的图刷到屏幕
复制代码
disp.show(img)
  • 把带红框红字的图像显示到 LCD。

    time.sleep_ms(50)

  • 每帧后休息 50 毫秒,让 CPU 喘口气;可删。


🎯 一句话总结

摄像头拍照 → OCR 认字 → 画框写字 → 用协议打包 → 串口发出 → 屏幕显示

逐字、逐参数、逐括号都拆完了,直接复制即可跑。

相关推荐
火云洞红孩儿3 分钟前
2026年,用PyMe可视化编程重塑Python学习
开发语言·python·学习
2401_841495644 分钟前
【LeetCode刷题】两两交换链表中的节点
数据结构·python·算法·leetcode·链表·指针·迭代法
幻云20105 分钟前
Next.js 之道:从入门到精通
前端·javascript·vue.js·人工智能·python
SunnyDays10118 分钟前
使用 Python 自动查找并高亮 Word 文档中的文本
经验分享·python·高亮word文字·查找word文档中的文字
深蓝电商API14 分钟前
Selenium处理弹窗、警报和验证码识别
爬虫·python·selenium
栗少14 分钟前
英语逻辑词
学习
深蓝电商API18 分钟前
Selenium模拟滚动加载无限下拉页面
爬虫·python·selenium
小王子102423 分钟前
Redis Queue 安装与使用
redis·python·任务队列·rq·redis queue
人工智能AI技术25 分钟前
【Agent从入门到实践】26 使用Chroma搭建本地向量库,实现Agent的短期记忆
人工智能·python
赤狐先生26 分钟前
第三步--根据python基础语法完成一个简单的深度学习模拟
开发语言·python·深度学习