回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【创意智造组】“寻味唤醒舱”—— 基于 AI 视觉的情绪感知与五感记忆干预系统 简单

头像 火星涛 2026.04.15 36 0

在老龄化社会的背景下,阿尔茨海默症(认知症)长者常面临“黄昏综合症”,即在傍晚时分产生莫名的焦躁、恐惧和游离感。传统的药物干预副作用大,而医学研究表明,**非药物疗法(如特定的嗅觉刺激和怀旧音乐)**能有效稳定长者情绪,唤醒深层记忆。 本项目旨在重构居家看护环境,利用前沿的边缘AI视觉技术,为长者打造一个无感监测、主动干预的“记忆避风港”。

unnamed (2).png

一、项目介绍

“寻味唤醒舱”是一套结合视觉AI与物理环境重构的情感干预系统。利用 Mind+ V2 的图像分类技术与二哈识图2(Huskylens V2)识别长者的情绪状态。当系统捕捉到长者出现焦虑或不安时,会自动联动硬件开启“记忆干预模式”——通过释放熟悉的香气、播放怀旧金曲、展示老照片,用技术手段安抚长者情绪。

unnamed (3).png

系统工作原理分为三层:

unnamed (5).png

AI 视觉层:通过摄像头实时监测长者表情及动作。

逻辑控制层:行空板(Unihiker)作为核心网关,运行训练好的分类模型,并采用“滑动窗口”算法根据识别结果逻辑判断是否触发干预。

物理执行层(五感重构)

嗅觉:通过继电器控制微型喷雾器释放特定香氛。

听觉:通过行空板(Unihiker)内置声卡与外接扬声器播放长者熟悉的经典旋律。

视觉:在行空板屏幕上循环播放长者年轻时的照片或家人的生活影集,同时联动氛围灯带(NeoPixel)营造温暖光环境。

二、项目演示

7e0c30e64180b8107dcb4bcc33ca799f.gif
4月15日 (4)(1).gif

场景一:常态场景

系统屏幕显示温馨的电子时钟,环境灯带呈冷光微亮状态。

image.png

场景二:干预场景

长者表现出焦虑(如紧锁眉头、频繁转头),系统连续5秒内识别到焦虑占比超70%,瞬间响应:

1. 行空板屏幕跳出“记忆相册”。

2. 行空板内置声卡开始随机播放怀旧金曲(如《甜蜜蜜》)。

3. 继电器吸合,香薰机冒出细雾释放薰衣草香气。灯带转为温暖的橙黄色。

image.png

场景三:反馈场景

长者被音乐和香气吸引,情绪逐渐转为愉悦(Calm/Happy),系统检测到情绪平复后,自动停止香薰、音乐,恢复待机时钟界面。

image.png

三、制作过程

1. 硬件清单与接线图

硬件清单:

image.png

接线定义:

image.png

2. 实物改装与外观设计

为了作品融入居家环境,我们将硬件改装成复古实木“记忆盒子”的形态:

外壳定制:使用木质盒子(20x10x10cm)。

面板布局:行空板屏幕嵌入正面作为“相册窗口”,二哈识图的摄像头通过盒子顶部的小孔安装在盒子顶部。

image.png

内部结构

5fb919a921db4be157da0d0f36758882.jpg

中间:放置隔离板,隔出左右两个区域,开发板线路和喷雾区干湿分离。

右侧:放置微型超声波喷雾装置,顶部开镂空出雾口。

左侧:安装继电器,连接喷雾器开关走线及外接电源线,通过顶部Type-c固定行空板。

前端:底部放置灯带和透明外罩。

外接音箱:

在usb音箱接线时,发现行空版左侧的usb插上音箱后 usb头影响整体布局(木盒小了),改为了蓝牙音箱替代,行空板M10如何连接蓝牙音箱参考这个帖子有详细介绍:行空板M10连接蓝牙音箱详细教程- Makelog(造物记)

Snipaste_2026-04-15_11-04-06.png
Snipaste_2026-04-15_11-04-16.png

三、 AI 模型训练过程

为了保护隐私并获取极端视角下的高质量样本,本项目创新地采用了基于 Prompt 驱动的 豆包AI文生图功能生成三种状态的长者图片来训练模型。每个动作标签录入至少 200 张图片。

Mind+ V2 中进行图像分类模型训练:

1. 标签设计

Agitated (焦虑/焦躁):紧锁眉头、张口惊恐、频繁转头。

Calm (平静):表情舒缓、目光安定。

Happy (愉悦):嘴角上扬、眼角带笑。

image.png

2. 采集与训练

模拟黄昏弱光环境采集数据集,确保模型在复杂光影下的鲁棒性。

image.png

在 Mind+ V2 模型训练界面,采用图像分类算法迭代30轮,确保 Agitated 标签的准确率达到 90% 以上。

image.png
image.png

随后校验模型准确率,并导出模型文件 Experience_model.zip,准备在下一步模型部署时使用。

4月15日 (1)-1 (1).gif

切换到高级模式,导出数据集文件“数据集Experience.zip”,准备下一步在模型部署时使用。

image.png

3. 部署

二哈2固件更新:

部署模型前务必更新二哈2固件更新到最新版本 V1.2.2

最新版本系统可在 HUSKYLENS2 最新固件下载 找到。

固件更新请参考:二哈识图 2 固件更新教程

image.png

将训练好的模型转换部署至二哈识图2(算法ID:128)。
自训练模型部署教程:无代码方式训练并部署模型(本地)

Snipaste_2026-04-14_20-55-15.png
Snipaste_2026-04-14_21-02-37.png
Snipaste_2026-04-14_21-05-53.png

二哈视图2 上测试自训练模型识别效果。

4月15日 (3).gif
4月15日 (2).gif

四、 核心代码实现 (Python/Mind+)

本项目的代码核心在于“环境联动控制”“滑动窗口算法”。 为了避免情绪误判造成的频繁开关,我们编写了基于5秒历史数据的滑动窗口判断逻辑:只有当近5秒内“焦虑”状态占比超过70%时才触发干预;干预持续至少10秒后,若长者情绪转为“平静/愉悦”占比超半,才恢复常态。

unnamed (6).png
unnamed (7).png

以下是完整的行空板 Python 逻辑代码:

代码
# -*- coding: UTF-8 -*-
# MindPlus V2 - 寻味唤醒舱
import time
import random
from pinpong.board import Board, Pin, NeoPixel
from pinpong.extension.unihiker import *
from dfrobot_huskylensv2 import *
from unihiker import GUI, Audio

# 1. 初始化GUI界面
gui = GUI()
# 初始化音频播放对象 (行空板内置声卡)
audio = Audio()

# 2. 变量与常量初始化
emotion_history = []  # 滑动窗口记录情绪状态
WINDOW_SIZE = 10      # 采样窗口大小 (缩小为1秒,每次循环0.1秒)
AGITATED_THRESHOLD = 0.5 # 50%的焦虑判定阈值,更容易触发
INTERVENTION_DURATION = 10 # 强制干预最少时间(秒)

# 轮播相册配置
PHOTOS = ["photo1.png", "photo2.png", "photo3.png", "photo4.png"]
PHOTO_INTERVAL = 3 # 图片轮播间隔(秒)

# 音乐配置
MUSICS = [
    "角音疏肝曲.mp3",
    "茉莉花.mp3",
    "南泥湾.mp3",
    "平湖秋月.mp3",
    "甜蜜蜜.mp3",
    "我的祖国.mp3",
    "渔舟唱晚.mp3"
]

# 状态机变量
is_intervening = False
intervention_start_time = 0
current_photo_index = 0
last_photo_change_time = 0
photo_obj = None
current_music = ""

# 3. 初始化硬件
Board().begin()
huskylens = HuskylensV2_I2C()
huskylens.knock()

# 初始化引脚和外设
p_p21_out = Pin(Pin.P21, Pin.OUT)  # 继电器控制香薰机
p_p21_out.write_digital(1) # 初始化时关闭香薰机(0和1互换,1为关)
np1 = NeoPixel(Pin(Pin.P22), 16)   # 氛围灯带,改为16颗灯珠
np1.brightness(128)

# 切换二哈识图2至图像分类算法 (假设128为自定义图像分类模型ID)
huskylens.switchAlgorithm(128)

# ----------------- 自定义UI与逻辑函数 -----------------

status_text = gui.draw_text(x=120, y=280, text="等待识别...", origin="center", color="green", font_size=12)

def show_standby_ui():
    """待机界面:显示时钟与监控状态"""
    gui.clear()
    gui.draw_text(x=120, y=140, text="14:30", origin="center", color="black", font_size=40)
    gui.draw_text(x=120, y=200, text="情绪监测中...", origin="center", color="gray", font_size=15)
    global status_text
    status_text = gui.draw_text(x=120, y=280, text="等待识别...", origin="center", color="green", font_size=12)
    # 灯带常态:关闭或微亮冷色
    for i in range(16):
        np1[i] = (0, 0, 10)

def show_intervention_ui():
    """干预界面:显示怀旧照片与干预提示"""
    global status_text, photo_obj, current_photo_index, last_photo_change_time
    gui.clear()
    
    current_photo_index = 0
    last_photo_change_time = time.time()
    # 绘制背景照片
    try:
        photo_obj = gui.draw_image(image=PHOTOS[current_photo_index], x=0, y=0)
    except Exception as e:
        print("加载图片失败,请检查目录下是否有 photo1.png 等文件:", e)
        photo_obj = None
        
    gui.draw_text(x=120, y=120, text="记忆相册", origin="center", color="blue", font_size=30)
    # 显示当前正在播放的音乐名称 (去掉.mp3后缀)
    music_name = current_music.replace(".mp3", "") if current_music else "甜蜜蜜"
    gui.draw_text(x=120, y=180, text=f"♪ {music_name}", origin="center", color="black", font_size=18)
    gui.draw_text(x=120, y=220, text="释放薰衣草香气...", origin="center", color="purple", font_size=15)
    status_text = gui.draw_text(x=120, y=280, text="等待识别...", origin="center", color="green", font_size=12)
    # 灯带干预态:温暖的橙黄色
    for i in range(10):
        np1[i] = (255, 100, 0)

def start_intervention():
    """触发干预模式:联动五感硬件"""
    global is_intervening, intervention_start_time, current_music
    is_intervening = True
    intervention_start_time = time.time()
    
    # 随机选择一首音乐
    current_music = random.choice(MUSICS)
    
    # 1. 开启香薰机 (继电器0和1互换,0为吸合/开启)
    p_p21_out.write_digital(0)
    time.sleep(0.05) # 增加微小延时,防止继电器吸合的电磁干扰影响 I2C
    
    # 2. 播放怀旧音乐 (使用行空板内置声卡播放)
    try:
        audio.start_play(current_music)
    except Exception as e:
        print("播放音乐失败:", e)
    # 3. 屏幕与灯带视觉反馈
    show_intervention_ui()
    print(f"-> 触发干预模式:播放音乐({current_music}),开启香薰,展示相册")

def stop_intervention():
    """停止干预模式,恢复常态"""
    global is_intervening
    is_intervening = False
    
    # 1. 关闭香薰机 (继电器0和1互换,1为断开/关闭)
    p_p21_out.write_digital(1)
    time.sleep(0.05) # 增加微小延时,防止继电器断开的电磁干扰影响 I2C
    
    # 2. 停止音乐
    try:
        audio.stop_play()
    except Exception as e:
        print("停止音乐失败:", e)
    # 3. 恢复待机界面
    show_standby_ui()
    print("-> 情绪已平复,恢复待机模式")


# ----------------- 主程序循环 -----------------
show_standby_ui()

while True:
    try:
        huskylens.getResult(128)
    except Exception as e:
        print("获取识别结果失败(I2C冲突):", e)
        time.sleep(0.1)
        continue
        
    current_emotion = "Unknown"
    
    if huskylens.available(128):
        # 获取所有的分类结果,防止有些版本总是把所需结果放在其他索引
        results = []
        try:
            # 官方库有的版本是用 read() 或者是读取全部缓存,这里简单尝试取 index=0
            result = huskylens.getCachedResultByIndex(128, 0)
            if result:
                results.append(result)
        except Exception:
            pass
            
        if results:
            result = results[0]
            
            # 使用 result.name 提取实际分类标签名
            label_name = getattr(result, "name", "").strip()
            
            if label_name:
                current_emotion = label_name
            else:
                current_emotion = "Unknown"
            
            # 显示识别结果
            status_text.config(text=f"状态: {current_emotion}")
    else:
        status_text.config(text="等待识别...")
    
    # 1. 更新情绪滑动窗口 (保留最近10个数据,对应1秒)
    emotion_history.append(current_emotion)
    if len(emotion_history) > WINDOW_SIZE:
        emotion_history.pop(0)
        
    # 2. 计算窗口内各情绪占比
    agitated_count = emotion_history.count("Agitated")
    # 除了 Agitated 外的情绪都认为是正常/平静
    normal_count = WINDOW_SIZE - agitated_count
    
    # 3. 状态机逻辑判断
    if not is_intervening:
        # 未干预状态:窗口内焦虑识别率达标,触发干预
        if len(emotion_history) == WINDOW_SIZE and (agitated_count / WINDOW_SIZE) >= AGITATED_THRESHOLD:
            start_intervention()
            emotion_history.clear() # 触发后清空历史,重新计算
    else:
        # 干预状态:至少干预设定的最短时间(10秒)
        if time.time() - intervention_start_time > INTERVENTION_DURATION:
            # 情绪转为平静 (非Agitated占比过半),停止干预
            if len(emotion_history) == WINDOW_SIZE and (normal_count / WINDOW_SIZE) >= 0.5:
                stop_intervention()
                emotion_history.clear()
                
        # 轮播图片逻辑
        if is_intervening and (time.time() - last_photo_change_time > PHOTO_INTERVAL):
            current_photo_index = (current_photo_index + 1) % len(PHOTOS)
            if photo_obj:
                try:
                    photo_obj.config(image=PHOTOS[current_photo_index])
                except Exception:
                    pass
            last_photo_change_time = time.time()
                
    # 4. 保留原有的手动测试按键逻辑 (A键播音乐,B键点动继电器)
    if button_a.is_pressed():
        try:
            current_music = random.choice(MUSICS)
            audio.start_play(current_music)
            print(f"手动测试:播放 {current_music}")
        except Exception as e:
            print("播放音乐失败:", e)
        time.sleep(0.5)
    if button_b.is_pressed():
        p_p21_out.write_digital(0) # 按下开启
        time.sleep(0.15)
        p_p21_out.write_digital(1) # 释放关闭
        time.sleep(0.5)
        
    time.sleep(0.1)

五、项目总结

项目创新点

✅ 从被动到主动:不同于传统的跌倒报警或呼叫装置,本项目实现了 AI 对物理环境的“实时重构”,通过嗅觉和听觉的干预,将危机化解在萌芽状态。

✅ 多感官协同:完美结合了行空板的屏幕交互与音频输出、二哈识图的AI视觉和继电器物理控制,展现了软硬件高度整合的能力与产品化思维。

✅ 未来展望: 后续计划接入心率监测传感器,结合视觉 AI 形成“多模态情感计算”,使情绪识别更加精准。同时,干预音乐可以根据长者的心率步频动态调整节奏(BPM),达到更深度的个性化干预。

unnamed (10).png

最好的孝顺,是守护他们的尊严。 对于患有认知障碍的长者来说,“黄昏时段”往往是最难熬的。传统的监控和报警器虽然安全,却时刻提醒着他们“你是病人”。

“寻味唤醒舱”试图改变这一切。它没有冰冷的摄像头,没有束缚的手环。它用看不见的AI和闻得到的芳香,在长者情绪波动的那一刻悄悄介入。

消除看护盲区,捍卫长者尊严,释放医疗资源。 这不仅是技术的重构,更是对生命的温柔以待。

项目文件

寻味唤醒舱.zip


链接: https://pan.baidu.com/s/1dDd-BNhh5ZtoF_8gZlzL6Q?pwd=mind

提取码: mind

评论

user-avatar