这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【ArduinoNiclaVision】火焰检测系统——TinyML实践

共1条 1/1 1 跳转至

【ArduinoNiclaVision】火焰检测系统——TinyML实践

助工
2026-01-28 15:35:31     打赏

ArduinoNiclaVision火焰检测系统——TinyML实践

一、项目简介

本项目聚焦于打造一套可在Arduino Nicla Vision开发板上实时运行的火焰检测系统,核心优势在于全程脱离网络依赖,所有视觉感知、AI推理运算均在设备端独立完成,完美兼顾轻量化设计与实际应用需求。

该系统以合成数据突破真实火焰数据采集的瓶颈,结合TinyML模型实现边缘端快速推理,完整覆盖数据生成-模型训练-设备部署全流程。无论是作为嵌入式AI技术的入门实践案例,还是直接适配实际场景进行落地应用,都具备极高的实用价值。

 image.png

 

核心特性

² 硬件极简适配:依托Nicla Vision板载200万像素摄像头,无需额外外接传感器,便携性优势突出;

² 模型轻量化设计:采用TinyML领域的FOMO模型,专为资源受限的MCU架构量身打造,在速度与检测精度之间实现最优平衡;

² 数据采集革新:基于开源合成火焰数据,彻底规避真实火焰采集过程中的安全风险与场景局限;

² 实时性保障:模型体积控制在100KB以内,推理延迟低,完全满足边缘设备实时检测的核心需求。

 image.png

二、系统整体架构

本系统采用模块化闭环设计,流程清晰且具备高度可复现性,架构如下:

 image.png

 

核心逻辑:通过合成数据高效解决数据短缺+标注繁琐的行业痛点,借助轻量化模型突破边缘设备的资源限制,全程无需依赖云端算力,确保系统在离线环境下稳定可用。

 image.png

三、所需硬件与软件

1. 硬件清单

名称

说明

备注

Arduino Nicla Vision

搭载200万像素摄像头、ARM Cortex-M7内核及AI加速模块

核心控制单元,原生支持OpenMV固件

USB-C数据线

用于开发板供电、程序下载及文件传输

推荐使用原装或支持数据传输功能的线材,避免仅支持充电的线材

 image.png

 

2. 软件与平台

以下软件均提供免费版本,可完整覆盖项目开发全流程,按步骤安装即可顺利使用:

• Edge Impulse Studio:在线TinyML训练平台,无需本地配置复杂训练环境,支持FOMO模型一键训练与量化优化;

• OpenMV IDE:用于Nicla Vision开发板的固件烧录、推理脚本编写,支持实时预览摄像头画面与检测结果。

 

 image.png

 

 image.png

四、开源合成火焰数据(关键步骤)

合成火焰数据的目录结构如下,通过多视角模拟生成丰富样本,为模型训练提供充足数据支撑:

开源合成火焰数据集:

https://github.com/shahizat/Fire-detection-system

 

Plain Text
dataset/
 ├── cam_1/          # 摄像头1生成的图像样本
 │   ├── img_0001.png
 │   ├── img_0002.png
 │   └── ...
 └── cam_2/          # 摄像头2生成的图像样本
     ├── img_0001.png
     ├── img_0002.png
     └── ...

 image.png

五、在Edge Impulse训练TinyML模型

Edge Impulse作为易用性极强的在线TinyML平台,无需本地配置训练环境,可直接上传标注数据集,一键完成FOMO模型训练与边缘设备适配优化。

本项目开源地址:https://studio.edgeimpulse.com/public/878999/latest ,感兴趣的同学可以去克隆到自己的edge-impluse,查看项目的具体设置和训练性能。

 image.png

5.1 创建项目并上传数据集

1. 访问Edge Impulse Studio官方平台,完成账号注册与登录;

2. 新建项目:点击「Create new project」,项目命名为“Nicla Vision Fire Detection”,选择Project Type为「Image」,Task为「Object Detection」,点击「Create」确认创建;

3. 数据集上传:

○ 点击左侧导航栏「Data acquisitionUpload data」;

○ 选择“dataset_with_labels”目录下的所有图像文件与标签文件,按「Train」和「Test」分类上传(推荐数据划分比例为8:2,例如400张训练集、100张测试集);

○ 上传完成后,在「Data explorer」中校验数据,确认标签类别为“fire”ID 0),无标注错误或数据异常。

 image.png

5.2 选择模型并配置参数

为何选择FOMO模型?

FOMOFaster Objects, More Objects)是专为边缘设备研发的轻量级目标检测模型,相较于传统YOLO模型,具备以下核心优势:

优势点

具体说明

资源占用低

模型体积可控制在100KB以内,无需GPU加速,完美适配Nicla VisionMCU架构

推理速度快

省去复杂的框回归计算步骤,推理帧率可达10+ FPS,充分满足实时检测需求

部署便捷性高

Edge Impulse可直接导出适配OpenMV的固件,无需手动进行模型格式适配

推荐训练参数配置

1. 点击左侧导航栏「Create impulse」,按以下配置设置:

○ Input block:选择「Image」,设置Input size96×96(平衡检测精度与运行速度,适配Nicla Vision硬件性能);

○ Processing block:选择「Image data」,色彩空间设置为「Grayscale」(灰度图可有效减少计算量,提升模型推理速度);

○ Learning block:选择「Object Detection (FOMO)」,点击「Save impulse」保存配置。

2. 模型训练参数配置:

○ 点击左侧导航栏「Object Detection (FOMO)Configure」;

○ Learning rate:设置为0.005(平衡训练收敛速度与模型稳定性);

○ Epochs:设置为100(确保模型充分收敛,若训练后期精度无明显提升,可手动提前停止训练);

○ Quantization:选择「Int8」(采用整数量化技术,减少模型体积与推理延迟,适配边缘设备运行环境);

○ 其他参数保持默认配置,点击「Save parameters」确认。

 image.png

 

5.3 启动训练并评估结果

1. 点击「Start training」启动模型训练,等待训练完成(训练时长约10-20分钟,具体取决于数据集大小与网络传输速度);

2. 训练结果评估:训练完成后,在「Model performance」面板查看核心指标,达标标准如下:

○ F1 Score:建议达到85%以上(本项目实测值约85-90%),该指标直接反映模型的综合检测能力;

○ 模型大小:实测约56 KB,远低于Nicla Vision的存储上限;

○ 推理时间:在Nicla Vision开发板上实测约80-100 ms/帧,完全满足实时检测需求。

3. 优化建议:若F1 Score低于80%,可通过以下方式优化:扩充合成数据量(如增加至800张)、调整标注阈值、添加数据增强手段(如随机翻转、亮度扰动等),之后重新启动训练。

 image.png

六、部署到Arduino Nicla Vision

本阶段将训练完成的模型导出为适配OpenMV的格式,烧录至Nicla Vision开发板,实现火焰实时检测功能落地。

6.1 导出模型

1. Edge Impulse项目页面,点击左侧导航栏「Deployment」;

2. 选择部署目标为「OpenMV」,点击「Build」生成固件压缩包;

 image.png

 

生成 OpenMV Firmware 会把对应目标器件的固件和运行代码一起打包了,会更加方便使用。

6.2 配置Nicla Vision 

1. OpenMV固件安装:

打开OpenMV IDE,点击顶部菜单栏「Tools加载自定义固件选择edge_impluse生成的Arduino Nicla Vision固件」;


 image.png

6.3 编写并运行实时检测脚本

以下为核心推理逻辑脚本,可直接在OpenMV IDE中运行,实现摄像头实时图像采集、模型推理及检测结果可视化展示。

 

1.OpenMV IDE打开edge_impluse生成的配套「ei_object_detection.py」。

Python
# Edge Impulse - OpenMV FOMO Object Detection Example

#

# This work is licensed under the MIT license.

# Copyright (c) 2013-2024 OpenMV LLC. All rights reserved.

# https://github.com/openmv/openmv/blob/master/LICENSE

 

import sensor

import time

import ml

from ml.utils import NMS

import math

import image

 

sensor.reset()  # Reset and initialize the sensor.

sensor.set_pixformat(sensor.RGB565)  # Set pixel format to RGB565 (or GRAYSCALE)

sensor.set_framesize(sensor.QVGA)  # Set frame size to QVGA (320x240)

sensor.skip_frames(time=2000)  # Let the camera adjust.

 

min_confidence = 0.85

threshold_list = [(math.ceil(min_confidence * 255), 255)]

 

# Load built-in model

model = ml.Model("trained")

# print(model)  # Commented out to reduce serial output

 

# Alternatively, models can be loaded from the filesystem storage.

# model = ml.Model('<object_detection_modelwork>.tflite', load_to_fb=True)

# labels = [line.rstrip('\n') for line in open("labels.txt")]

 

colors = [  # Add more colors if you are detecting more than 7 types of classes at once.

    (255, 0, 0),

    (0, 255, 0),

    (255, 255, 0),

    (0, 0, 255),

    (255, 0, 255),

    (0, 255, 255),

    (255, 255, 255),

]

 

# FOMO outputs an image per class where each pixel in the image is the centroid of the trained

# object. So, we will get those output images and then run find_blobs() on them to extract the

# centroids. We will also run get_stats() on the detected blobs to determine their score.

# The Non-Max-Supression (NMS) object then filters out overlapping detections and maps their

# position in the output image back to the original input image. The function then returns a

# list per class which each contain a list of (rect, score) tuples representing the detected

# objects.

def fomo_post_process(model, inputs, outputs):

    n, oh, ow, oc = model.output_shape[0]

    nms = NMS(ow, oh, inputs[0].roi)

    for i in range(oc):

        img = image.Image(outputs[0][0, :, :, i] * 255)

        blobs = img.find_blobs(

            threshold_list, x_stride=1, area_threshold=1, pixels_threshold=1

        )

        for b in blobs:

            rect = b.rect()

            x, y, w, h = rect

            score = (

                img.get_statistics(thresholds=threshold_list, roi=rect).l_mean() / 255.0

            )

            nms.add_bounding_box(x, y, x + w, y + h, score, i)

    return nms.get_bounding_boxes()

 

clock = time.clock()

frame_counter = 0  # 自定义帧计数器

 

while True:

    clock.tick()

    frame_counter += 1

 

    img = sensor.snapshot()

    total_detections = 0  # 总目标数量计数器

 

    for i, detection_list in enumerate(model.predict([img], callback=fomo_post_process)):

        if i == 0:

            continue  # background class

        if len(detection_list) == 0:

            continue  # no detections for this class?

 

        total_detections += len(detection_list)  # 累加该类别的检测数量

        # print("********** %s **********" % model.labels[i])  # Commented out to reduce serial output

        for (x, y, w, h), score in detection_list:

            center_x = math.floor(x + (w / 2))

            center_y = math.floor(y + (h / 2))

            # print(f"x {center_x}  y {center_y}    score {score}")  # Commented out to reduce serial output

            img.draw_circle((center_x, center_y, 12), color=colors[i])

 

    # Print total detections only when there are detected objects

    if total_detections > 0:

        print(f"Total Detections: {total_detections}", end="\n")

   

    # 利用frame_counter变量,每10次循环输出一次帧率

    if frame_counter % 10 == 0:

        frame_counter = 0

        print(f"FPS: {clock.fps():.2f}", end="\n")

 

 

我在edge-impluse自动生成代码上实现了显著减少不必要的串口输出以提高系统性能,增加了检测目标数量的统计和输出功能,优化了检测数量输出逻辑使其仅在有检测结果时才输出,同时还优化了帧率输出逻辑确保每10次循环准确输出一次帧率。修改后的代码更加简洁高效,适合在资源受限的设备上运行实时目标检测任务。

2.运行脚本:点击OpenMV IDE顶部「Run」按钮,脚本将自动下载至Nicla Vision开发板并启动运行;

3.效果查看:在OpenMV IDE右侧预览窗口中,可实时观察摄像头画面。当检测到火焰时,将以红色框选目标区域,并显示“fire”字样及对应置信度,系统帧率稳定在10+ FPS  默认的min_confidence  0.4 ,为避免误判需要提高到0.8.

 

七、效果测试与实际表现

该系统可完全脱离网络独立运行,无云端算力依赖,检测准确率与实时性均达到室内火灾早期预警的标准。同时,系统体积小巧、无需外接传感器,无论是家庭实验室、工业车间等场景,都可便捷部署,具备极强的实用性。

八、项目心得与总结

从头到尾完成这个火焰检测项目,不仅摸清了 TinyML 在边缘设备上的落地逻辑,更在实际操作中解决了不少之前没预料到的问题,收获远超预期。

深度学习项目最困难最繁琐的步骤是训练材料的预处理,本项目使用了开源的训练素材,暂时放下深度学习最困难的环节,先完成整个项目的流程验证,增强了对完成实际项目的信心和可行性。 这个项目不仅实现了火焰检测的核心功能,更让我对 TinyML 和边缘 AI 有了实操层面的认知,也积累了“从 0 1 落地嵌入式 AI 项目”的经验。如果你也想入门 Nicla Vision TinyML,这个项目会是很好的起点——它不依赖复杂的硬件和昂贵的设备,却能完整覆盖核心技术链路,动手实践后收获的远比理论学习更扎实。

希望本教程能帮助你快速上手 Arduino Nicla Vision TinyML 技术,开启边缘 AI 项目开发之旅!

感兴趣的小伙伴可以下载附件里的固件和运行代码进行测试,如果有不明白的地方或者希望跟我交流的可以给我发邮件(251199510@qq.com

 fire_detection-open-mv-fw-v1.zip





关键词: ArduinoNiclaVision     OpenMV    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]