图像分类
概述
我们正处于人工智能(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 代码