跳到主要内容

第 9 课 · AI 摄像头入门

这一课学什么?

前面的模块大多是在读取一个数值,比如距离、亮度或命令编号。
AI 摄像头更进一步,它读取的是画面里的目标和特征。

这一课不追求一次把所有视觉能力都混在一起,而是先学会稳定读取结果,再把结果映射成动作。

AI 摄像头模块

交通卡片示意

学习目标

  • 理解 init()change_algo() 和读取函数之间的关系
  • 知道为什么视觉任务要一次只做一个
  • 会从卡片识别、颜色识别、巡线三种任务里各跑通一个最小示例
  • 会把视觉结果翻译成屏幕反馈或机器人动作

用到的硬件和功能

这一课建议先以 cocube_sengo2 为例。
如果你使用的是 cocube_sengo1,核心思路和大部分函数名都非常接近。

会用到的接口主要有:

  • sg2.init():初始化摄像头并等待就绪。通常只在程序开始调用一次。
  • sg2.change_algo(mode):切换算法。mode 可选 "Color Recog""Blob Detect""AprilTag""Line Detect""Deep Learning""Card Recog""Face Recog""Obj20Class""QRcode""Motion Detect"
  • sg2.read_card():读取卡片名称,常见结果有 forwardturn_leftturn_rightturn_aroundparkgreen_lightred_lightspeed_40speed_60speed_80
  • sg2.get_card(tag):读取卡片检测框参数。tag 可选 "x""y""w""h";分别表示检测框位置和大小,本课主要用 "w" 过滤太小的目标。
  • sg2.read_color():读取颜色名称,常见结果有 blackwhiteredgreenblueyellowunknown
  • sg2.get_color_rgb(channel):读取颜色的 RGB 分量。channel 可选 "R""G""B",返回 0~255
  • sg2.get_line(tag):读取巡线结果。tag 可选 "x1""y1""x2""y2""degree"x1/y1x2/y2 是线段两端点,degree 是线条角度。
  • display.init():初始化屏幕,返回 tft 对象,颜色识别示例里会用它做界面反馈。
  • display.color565(r, g, b):把 0~255 的 RGB 三通道值转换成屏幕可用颜色。r / g / b 分别是红、绿、蓝分量。
  • display.write(text, x, y, color=display.WHITE, bg=display.BLACK, size="normal"):显示文字。text 是字符串;x / y 是坐标;color 是字色;bg 是背景色;size 可选 smallnormalbig
  • tft.fill(color):整屏填色。color 一般传 display.color565(...) 的结果。
  • cocube.move_ms(direction, speed, ms):按时间直行或后退。directioncocube.FORWARD / cocube.BACKWARDspeed 是速度;ms 是时长。
  • cocube.rotate_ms(direction, speed, ms):按时间转向。directioncocube.LEFT / cocube.RIGHTspeed 是转向速度;ms 是时长。
  • cocube.set_wheel(left, right):直接设置左右轮输出。left / right 范围是 -50~50;正数表示前进,负数表示后退,巡线时会持续调整这两个值。
  • cocube.brake():丢失目标或需要停车时主动刹车。

sg2.change_algo(mode) 里最常用、也最容易混淆的是算法名称。当前固件支持:

  • Card Recog:卡片识别
  • Color Recog:颜色识别
  • Line Detect:巡线
  • Blob Detect:色块检测
  • AprilTag:AprilTag 标签识别
  • Deep Learning:自学习类别识别
  • Face Recog:人脸识别
  • Obj20Class:20 类物体识别
  • QRcode:二维码识别
  • Motion Detect:运动检测

这一课先只用 Card RecogColor RecogLine Detect 这 3 种。

先认识这个能力

这一课最重要的一条原则是:

  • 一次只做一种视觉任务

比较稳妥的顺序是:

  1. 先初始化摄像头
  2. 切到一种算法
  3. 先把结果打印出来
  4. 再把结果变成动作或显示

开始编程

1. 卡片识别:看到哪张卡,就执行哪种动作

卡片识别的好处是结果很明确,也最适合当第一种视觉任务。

import time
import cocube
import cocube_sengo2 as sg2

sg2.init()
time.sleep_ms(1000)
sg2.change_algo("Card Recog")

while True:
card = sg2.read_card()

if isinstance(card, str) and sg2.get_card("w") > 25:
print("card =", card)

if card == "forward":
cocube.move_ms(cocube.FORWARD, 25, 500)
elif card == "turn_left":
cocube.rotate_ms(cocube.LEFT, 25, 700)
elif card == "turn_right":
cocube.rotate_ms(cocube.RIGHT, 25, 700)
elif card == "park":
cocube.brake()

time.sleep_ms(100)

这里的关键点是 sg2.get_card("w") > 25
它能帮助你过滤掉太远、太小的卡片识别结果。

2. 颜色识别:把摄像头看到的颜色直接显示出来

颜色识别很适合和屏幕显示组合在一起。

颜色映射效果灵感

import time
import display
import cocube_sengo2 as sg2

tft = display.init()
sg2.init()
time.sleep_ms(1000)
sg2.change_algo("Color Recog")

while True:
color_name = sg2.read_color()

if isinstance(color_name, str):
r = sg2.get_color_rgb("R")
g = sg2.get_color_rgb("G")
b = sg2.get_color_rgb("B")
color = display.color565(r, g, b)

tft.fill(color)
display.write(color_name, 70, 110, display.WHITE, color)

time.sleep_ms(150)

3. 巡线:根据线条位置持续修正方向

巡线比前两种任务更强调控制过程,因为它要持续根据画面修正左右轮速度。

巡线反馈示意

import time
import cocube
import cocube_sengo2 as sg2

sg2.init()
time.sleep_ms(1000)
sg2.change_algo("Line Detect")

base_speed = 20

while True:
x2 = sg2.get_line("x2")
angle = sg2.get_line("degree")

if isinstance(x2, int) and isinstance(angle, int):
error = (x2 - 50) / 6 + (90 - angle) / 6
left = int(base_speed + error)
right = int(base_speed - error)

left = max(-50, min(50, left))
right = max(-50, min(50, right))
cocube.set_wheel(left, right)
else:
cocube.brake()

time.sleep_ms(50)

运行时观察什么

运行视觉程序时,重点看这些现象:

  • 算法没切对时,读取函数会直接报错
  • 卡片太远时,最好先过滤再触发动作
  • 颜色识别更适合做界面反馈
  • 巡线任务里,偏差越大,修正通常也要越明显

常见问题 / 使用提醒

  • init(),再 change_algo(...),最后才调用对应读取函数
  • 第一次接触视觉任务时,优先先跑卡片识别
  • 先把一种算法跑稳,再切到另一种
  • 如果要调巡线,先保证背景和线条对比清楚

挑战一下

先从下面三种任务里任选一种,单独跑通:

  1. 看牌行动:看到前进卡、左转卡、停车卡就执行动作
  2. 颜色映射:看见什么颜色,屏幕就变成什么颜色
  3. 巡线前进:沿着一条清晰的黑线持续修正方向

如果这三种都已经跑稳,再考虑把其中两个组合起来。

快速参考

这一课最常用的写法是:

import cocube_sengo2 as sg2

sg2.init()
sg2.change_algo("Card Recog")
print(sg2.read_card())
  • sg2.init():初始化摄像头
  • sg2.change_algo(...):切换算法
  • sg2.read_card():读取卡片名称
  • sg2.read_color():读取颜色名称
  • sg2.get_line(...):读取巡线参数

如果想继续查视觉接口,可以查看 摄像头模块说明cocube_sengo2 快速参考