图像分类
概述
我们正处于人工智能(AI)革命的浪潮中,正如 Gartner 所言,边缘 AI 与计算机视觉已成为极具影响力的技术,而且“现在”正是落地的时机!
在视觉领域的机器学习(ML)应用中,最基础也是最经典的任务就是图像分类,它既是 ML 的“Hello World”,又蕴含着深刻的技术内涵。
Seeed Studio XIAOML Kit 以 XIAO ESP32-S3 Sense 为核心,集成了 OV3660 摄像头和 SD 卡支持,非常适合 TinyML 视觉 AI 的入门与实验。
本实验将通过零代码工具 SenseCraft AI 体验图像分类,并进一步结合 Edge Impulse Studio 与 Arduino IDE 深入开发。
学习目标
- 部署预训练模型:通过 SenseCraft AI Studio 快速体验计算机视觉应用
- 采集与管理图像数据集:为自定义分类任务规范组织数据
- 迁移学习训练自定义模型:基于 MobileNet V2 架构进行微调
- 模型边缘部署优化:量化与高效预处理,适配嵌入式设备
- 后处理管道实现:集成 GPIO 控制与实时推理
- 开发路径对比:理解零代码与高级 ML 平台在嵌入式场景下的差异
图像分类简介
图像分类是计算机视觉的基础任务之一,目标是将整张图片归入预定义的某一类别。其核心是分析图像内容,根据主要物体或场景特征,输出一个标签。
图像分类广泛应用于数字图库、社交媒体、自动驾驶等领域,是让系统理解环境的关键。典型的深度学习架构如卷积神经网络(CNN),包括 AlexNet、VGGNet、ResNet 等,极大推动了图像分类的发展。这些模型通过学习视觉数据的层次化特征,在 ImageNet 等数据集上取得了卓越的准确率。
图像分类不仅是许多视觉系统的基石,也是目标检测、图像分割等更复杂任务的基础。接下来,我们以 Person Classification(“有人/无人”)为例,体验 SenseCraft AI 上的即用型视觉模型。

在 SenseCraft AI Workspace 上体验图像分类
首先通过 USB-C 连接 XIAOML Kit(或仅 XIAO ESP32S3 Sense,断开扩展板),打开 SenseCraft AI Workspace 并连接设备。

连接后,点击 [Select Model...],在搜索框输入“Person Classification”,选择基于 MobileNet V2 训练的模型(鼠标悬停可查看模型详情)。

点击模型并确认部署,固件将自动上传至设备。
上传过程中会显示进度百分比。如未显示,可尝试重新插拔设备并按下 boot 键。
上传完成后,可在 Preview 区域实时查看摄像头画面与分类结果(Person 或 Not a Person),Device Logger 区域显示推理详情。
可调整 Inference Frame Interval(推理帧间隔,默认实时)和 Mode(数据输出方式,默认 UART/USB)。

在 Device Logger 可见模型预处理延迟 52~78ms,推理约 532ms,总时延约 600ms,即 1.7 FPS。
运行 Mobilenet V2 0.35 时,XIAO 峰值电流 [email protected],功耗约 830mW。
后处理(Post-Processing)
图像分类项目的关键环节是定义推理结果的应用场景。例如,检测到有人时自动开灯。

在 SenseCraft AI 的 Output -> GPIO 区域可配置触发动作。点击 Add,设置条件(如置信度大于 60% 时点亮内置 LED)。实际应用中可用 GPIO(如 D0、D1、D2、D11、D12)控制继电器等外设。

确认后,已创建的 Trigger Action 会显示,点击 Send 上传至 XIAO。

此后,摄像头检测到人时,内置 LED 会自动点亮。

更多触发与后处理技巧将在后续实验中深入介绍。
图像分类项目实践
下面以 SenseCraft AI Studio 为例,完整体验一个图像分类项目。下图为典型的机器学习管道:

在 SenseCraft AI Studio,打开 Training 标签页:

默认用 WebCam 采集数据,建议选择 XIAOESP32S3 Sense。点击绿色 [Connect],选择端口并连接。

此时可实时预览摄像头画面。
目标设定
首先明确项目目标。假设工业场景需自动分拣轮子与盒子。

我们模拟场景,采集玩具 box、wheel 及 background(无物体)三类图片。

数据采集
依次创建类别,建议按字母顺序:
- Class1: background
- Class2: box
- Class3: wheel

选择类别,长按绿色按钮(Hold to Record)采集图片。移动摄像头多角度采集,松开按钮可调整物体后继续采集。

采集后可回顾并删除不合格图片。

每类采集约 50 张,完成后进入训练环节。
可下载采集图片用于 Edge Impulse Studio 等平台。
训练
确认设备为 XIAO ESP32S3 Sense,点击 [Start Training]。

测试
训练完成后可实时预览推理结果。
注意:此时模型未运行在设备上,仅在 Studio 端实时推理。

接下来将模型真正部署到设备。
部署
在 Supported Devices 选择训练好的模型和 XIAO ESP32S3 Sense,点击 [Deploy to device]。

SenseCraft AI 会跳转到 Vision Workplace,确认部署,选择端口并连接。

模型烧录后自动重启,设备开始运行。Device Logger 显示推理延迟约 426ms,预处理约 110ms,即 1.8 FPS。
Settings 可调整模型置信度阈值。

运行该模型时,XIAO 峰值电流 [email protected],功耗约 730mW。
同样可在 Output –> GPIO 区域配置基于类别的 LED 或 GPIO 控制。例如检测到 wheel 时点亮 LED。

模型保存
SenseCraft AI Studio 支持模型保存,便于后续部署。回到 Training 标签,点击 [Save to SenseCraft]:

按提示填写模型名称、描述、图片等信息。

训练好的模型(如 Int8 MobileNet V2,320KB)可下载分析(如用 Netron),输入张量为 224x224x3。后续将在 Edge Impulse Studio 体验不同超参数。

模型可随时再次部署到设备,SenseCraft AI Workspace 会自动打开。
基于数据集的图像分类项目
本项目目标是在 XIAO ESP32S3 Sense 上训练并推理模型。训练需大量数据。
但首先要明确分类目标!
TinyML 受限于嵌入式设备资源,建议分类类别不超过三四类。可用前述采集的 Box 与 Wheel 图片,也可用如 Kaggle fruit-and-vegetable-image-recognition 等公开数据集。
下载前述采集的数据集,点击每类右上角菜单(3 点),选择 Export Data。

数据集将以 .ZIP 形式下载,每类一个文件。解压后应有三个类别文件夹。

可补充新图片,参考 setup 实验的采集代码。
Edge Impulse Studio 训练模型
Edge Impulse 是领先的边缘 ML 开发平台。注册并登录后,新建项目。
数据采集
进入 Data acquisition,选择 + Add data,弹窗中选 UPLOAD DATA。

选择文件夹,点击 [Choose Files],选中某一类别文件夹,点击 [Upload]。

上传后选择 Automatically split between training and testing,输入类别标签,点击 [Upload data]。上传完成后,若询问是否为目标检测项目,选择 [no]。

为所有类别重复操作,注意更换标签。若标签错误,数据会混合,可后续手动调整。
关闭上传窗口,回到 Data acquisition,可见数据集已上传,顶部显示总数及类别分布,19% 自动分配为测试集。

Impulse 设计
Impulse 流程:原始数据(图片)→ 特征提取(缩放)→ 学习模块(分类)
图像分类需大量数据,本例每类约 50 张,远远不够。可通过迁移学习(Transfer Learning, TL),在预训练模型基础上微调,提升小数据集表现。

本例采用 TL,将图片缩放至 $(96\times 96)$,输入至迁移学习模块。可在 Impulse 设计时指定目标设备(如 Espressif ESP-EYE,性能略低于 XIAO ESP32S3)。

保存 Impulse,进入 Image 步骤。
预处理(特征生成)
可选择灰度或 RGB,建议选 [RGB],每条数据为 96x96x3=27,648 特征。点击 [Save Parameters],进入 Generate Features,点击 [Generate Features] 生成特征。
模型设计、训练与测试
MobileNet 系列(V1/V2/V3)是 Google 针对移动端设计的高效视觉模型。通过宽度因子 α 控制模型大小与速度,α 越小模型越轻量。
Edge Impulse Studio 支持 MobileNet V1(96x96)、V2(96x96/160x160),α 从 0.05 到 1.0。α 越大准确率越高,但内存与延迟也越大。极致轻量配置(V1, α=0.10)仅需 53.2K RAM/101K ROM。
本例采用 MobileNet V2 0.35,输出层 16 神经元,Dropout 10% 防止过拟合。
深度学习常用**数据增强(Data Augmentation)**提升模型泛化能力。Edge Impulse 默认实现了翻转、裁剪、亮度扰动等增强策略:
# 实现数据增强策略
def augment_image(image, label):
image = tf.image.random_flip_left_right(image)
resize_factor = random.uniform(1, 1.2)
new_height = math.floor(resize_factor * INPUT_SHAPE[0])
new_width = math.floor(resize_factor * INPUT_SHAPE[1])
image = tf.image.resize_with_crop_or_pad(image, new_height, new_width)
image = tf.image.random_crop(image, size=INPUT_SHAPE)
image = tf.image.random_brightness(image, max_delta=0.2)
return image, label
本例超参数:
- Epochs: 20
- Batch Size: 32
- Learning Rate: 0.0005
- Validation size: 20%
训练结果如下:

模型预测需 233 KB RAM,546 KB Flash,XIAO ESP32S3 资源充足。Studio 估算延迟约 1160ms,但实际 XIAO 性能更强。
测试集准确率 100%,即使 INT8 量化,因任务简单、类别区分明显,实际项目中难以复现。
模型部署
可将模型导出为:
.TFLITE,用于 SenseCraft AIArduino Library,用于 Edge Impulse Studio
先介绍更直观的 SenseCraft 部署。
SenseCraft AI 部署模型
在 Dashboard 可下载多种格式模型,选择 TensorFlow Lite (int8 quantized)(约 623KB)。

在 SenseCraft AI Studio Workspace,选择 XIAO ESP32S3 和端口,连接设备。
点击 [Upload Model],弹窗中填写模型名、文件、类别(按字母顺序:0: background,1: box,2: wheel),点击 [Send]。

上传后,摄像头实时画面与分类结果显示于 Preview,可在 Settings 调整置信度阈值。
Device Logger 显示串口信息,预处理约 81ms,推理 205ms,3.4 FPS,比 SenseCraft 训练模型快一倍(因输入尺寸 96x96 < 224x224)。
总延迟约为 Edge Impulse Studio 在 Xtensa LX6 CPU 上估算的 1/4,实际 XIAO 使用更快的 LX7。

后处理
可通过串口获取推理结果(延迟、类别、置信度),XIAO 可作为 AI 传感器,通过 MQTT、UART、I2C、SPI 等协议输出结果。
相关用法可参考 Seeed Grove Vision AI V2 图像分类后处理实验。
下图为 I2C 总线连接示例,更多信息见 Seeed Studio Wiki。
XIAO ESP32S3 图像分类代码详解
本代码通过板载摄像头采集图像,进行处理,并利用 Edge Impulse Studio 训练的模型对图像进行分类(如“Box”、“Wheel”或“Background”)。代码持续运行,实现边缘设备上的实时推理。
简要流程:
摄像头 → JPEG 图像 → RGB888 转换 → 缩放至 96x96 → 神经网络 → 分类结果 → 串口输出
关键组成部分
库引用与依赖
#include <Box_versus_Wheel_-_XIAO_ESP32S3_inferencing.h> #include "edge-impulse-sdk/dsp/image/image.hpp" #include "esp_camera.h"- Edge Impulse 推理库:包含训练好的模型与推理引擎
- 图像处理:提供图像操作相关函数
- ESP 摄像头:摄像头硬件接口
摄像头引脚配置
XIAO ESP32S3 Sense 支持多种摄像头(如 OV2640、OV3660),不同型号引脚定义不同。代码中定义了三套配置:
// 配置 1:常见 OV2640 配置 #define CONFIG_1_XCLK_GPIO_NUM 10 #define CONFIG_1_SIOD_GPIO_NUM 40 #define CONFIG_1_SIOC_GPIO_NUM 39 // ... 其他引脚这种灵活性使代码能自动尝试不同引脚映射,提升对不同硬件版本的兼容性。
内存管理设置
#define EI_CAMERA_RAW_FRAME_BUFFER_COLS 320 #define EI_CAMERA_RAW_FRAME_BUFFER_ROWS 240 #define EI_CLASSIFIER_ALLOCATION_HEAP 1- 帧缓冲区尺寸:定义原始图像大小(320x240 像素)
- 堆分配:采用动态内存分配,灵活高效
- PSRAM 支持:ESP32S3 拥有 8MB PSRAM,可存储大数据如图像
setup() - 初始化
void setup() {
Serial.begin(115200);
while (!Serial);
if (ei_camera_init() == false) {
ei_printf("Failed to initialize Camera!\r\n");
} else {
ei_printf("Camera initialized\r\n");
}
ei_sleep(2000); // 启动前等待 2 秒
}
该函数:
- 初始化串口,便于调试输出
- 自动检测并初始化摄像头
- 启动前等待 2 秒
loop() - 主处理循环
主循环持续执行以下步骤:
步骤 1:内存分配
snapshot_buf = (uint8_t*)ps_malloc(EI_CAMERA_RAW_FRAME_BUFFER_COLS *
EI_CAMERA_RAW_FRAME_BUFFER_ROWS *
EI_CAMERA_FRAME_BYTE_SIZE);
为图像缓冲区分配内存,优先使用 PSRAM(更快的外部 RAM),如不足则退回普通堆内存。
步骤 2:图像采集
if (ei_camera_capture((size_t)EI_CLASSIFIER_INPUT_WIDTH,
(size_t)EI_CLASSIFIER_INPUT_HEIGHT,
snapshot_buf) == false) {
ei_printf("Failed to capture image\r\n");
free(snapshot_buf);
return;
}
从摄像头采集图像并存入缓冲区。
步骤 3:推理
ei_impulse_result_t result = { 0 };
EI_IMPULSE_ERROR err = run_classifier(&signal, &result, false);
对采集到的图像运行机器学习模型。
步骤 4:输出结果
for (uint16_t i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
ei_printf(" %s: %.5f\r\n",
ei_classifier_inferencing_categories[i],
result.classification[i].value);
}
输出每个类别的置信度分数。
ei_camera_init() - 智能摄像头初始化
该函数实现了智能初始化流程:
bool ei_camera_init(void) {
// 尝试配置 1(常见 OV2640)
update_camera_config(1);
esp_err_t err = esp_camera_init(&camera_config);
if (err == ESP_OK) goto camera_init_success;
// 尝试配置 2(OV3660)
esp_camera_deinit();
update_camera_config(2);
err = esp_camera_init(&camera_config);
if (err == ESP_OK) goto camera_init_success;
// 继续尝试其他配置...
}
主要流程:
- 依次尝试多套引脚配置
- 测试不同时钟频率(10MHz/16MHz)
- 优先用 PSRAM,不行则退回 DRAM
- 根据检测到的传感器应用专属设置
ei_camera_capture() - 图像处理流程
bool ei_camera_capture(uint32_t img_width, uint32_t img_height, uint8_t *out_buf) {
// 1. 从摄像头获取帧
camera_fb_t *fb = esp_camera_fb_get();
// 2. JPEG 转 RGB888 格式
bool converted = fmt2rgb888(fb->buf, fb->len, PIXFORMAT_JPEG, snapshot_buf);
// 3. 归还帧缓冲区
esp_camera_fb_return(fb);
// 4. 如需缩放则处理
if (do_resize) {
ei::image::processing::crop_and_interpolate_rgb888(...);
}
}
该函数:
- 从摄像头采集 JPEG 图像
- 转换为 RGB888 格式(模型所需)
- 缩放至模型输入尺寸(96x96 像素)
推理
- 将代码上传至 XIAO ESP32S3 Sense
⚠️ 注意
- Xiao ESP32S3 必须启用 PSRAM。可在 Arduino IDE 菜单栏
Tools–>PSRAM:OPI PSRAM检查- Arduino Boards 包(
esp32 by Espressif Systems)应为 2.017 版本,请勿升级

- 打开串口监视器
- 对准物体,观察串口输出结果

后处理
在边缘 AI 应用中,推理结果只有被有效利用才有价值。串口输出便于调试,但实际部署需即时、直观的人机反馈,无需外接显示器。
XIAOML Kit 配备的 0.42 英寸 OLED 显示屏(72×40 像素)是关键的后处理组件,可将 ML 推理结果直接以类别名和置信度显示在设备上,实现真正的独立边缘 AI 部署,适用于工业、农业、零售等场景,便于现场快速确认 AI 预测。
我们可以修改代码,使其自动适配 Edge Impulse 训练的模型,直接读取类别名和数量。显示屏将以大字体显示类别简称(3 字母),提升在小屏幕上的可读性。代码可参考 GitHub:XIAOML-Kit-Img_Class_OLED_Gen。
运行效果如下:

总结
XIAO ESP32S3 Sense 是一款极具能力和灵活性的图像分类平台。本实验展示了两种开发路径,适合不同水平和需求的开发者:
- SenseCraft AI Studio 提供零代码入口,便于快速原型和部署预训练模型(如人物检测),支持实时推理与后处理,无需深厚编程或 ML 基础。
- Edge Impulse Studio 适合进阶开发,支持完整 ML 流程,包括自定义数据集管理、迁移学习(如 MobileNet)、模型优化等。
本实验的关键收获包括:分辨率权衡、迁移学习对小数据集的有效性,以及边缘 AI 部署中的功耗与内存等实际考量。
本实验体现了 TinyML 的核心原则:资源受限推理、实时处理需求、从数据采集到模型部署的完整流程。XIAO 不仅是推理引擎,更是集成 GPIO 控制与通信协议的完整 AI 传感器平台。
通过本实验的基础,你将能胜任更复杂的计算机视觉任务,理解现代边缘 AI 如何让视觉智能普惠、低成本、易部署,适用于工业自动化、智能家居等实际场景。
参考资源
- XIAO ESP32S3 入门
- SenseCraft AI Studio 首页
- SenseCraft Vision Workspace
- 数据集示例
- Edge Impulse 项目
- XIAO 作为 AI 传感器
- Seeed Arduino SSCMA 库
- XIAOML Kit 代码