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

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

系统工作原理分为三层:

AI 视觉层:通过摄像头实时监测长者表情及动作。
逻辑控制层:行空板(Unihiker)作为核心网关,运行训练好的分类模型,并采用“滑动窗口”算法根据识别结果逻辑判断是否触发干预。
物理执行层(五感重构):
嗅觉:通过继电器控制微型喷雾器释放特定香氛。
听觉:通过行空板(Unihiker)内置声卡与外接扬声器播放长者熟悉的经典旋律。
视觉:在行空板屏幕上循环播放长者年轻时的照片或家人的生活影集,同时联动氛围灯带(NeoPixel)营造温暖光环境。
二、项目演示


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

场景二:干预场景
长者表现出焦虑(如紧锁眉头、频繁转头),系统连续5秒内识别到焦虑占比超70%,瞬间响应:
1. 行空板屏幕跳出“记忆相册”。
2. 行空板内置声卡开始随机播放怀旧金曲(如《甜蜜蜜》)。
3. 继电器吸合,香薰机冒出细雾释放薰衣草香气。灯带转为温暖的橙黄色。

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

三、制作过程
1. 硬件清单与接线图
硬件清单:

接线定义:

2. 实物改装与外观设计
为了作品融入居家环境,我们将硬件改装成复古实木“记忆盒子”的形态:
外壳定制:使用木质盒子(20x10x10cm)。
面板布局:行空板屏幕嵌入正面作为“相册窗口”,二哈识图的摄像头通过盒子顶部的小孔安装在盒子顶部。

内部结构:

中间:放置隔离板,隔出左右两个区域,开发板线路和喷雾区干湿分离。
右侧:放置微型超声波喷雾装置,顶部开镂空出雾口。
左侧:安装继电器,连接喷雾器开关走线及外接电源线,通过顶部Type-c固定行空板。
前端:底部放置灯带和透明外罩。
外接音箱:
在usb音箱接线时,发现行空版左侧的usb插上音箱后 usb头影响整体布局(木盒小了),改为了蓝牙音箱替代,行空板M10如何连接蓝牙音箱参考这个帖子有详细介绍:行空板M10连接蓝牙音箱详细教程- Makelog(造物记)
![]() | ![]() |
三、 AI 模型训练过程
为了保护隐私并获取极端视角下的高质量样本,本项目创新地采用了基于 Prompt 驱动的 豆包AI文生图功能生成三种状态的长者图片来训练模型。每个动作标签录入至少 200 张图片。
在 Mind+ V2 中进行图像分类模型训练:
1. 标签设计:
Agitated (焦虑/焦躁):紧锁眉头、张口惊恐、频繁转头。
Calm (平静):表情舒缓、目光安定。
Happy (愉悦):嘴角上扬、眼角带笑。

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

在 Mind+ V2 模型训练界面,采用图像分类算法迭代30轮,确保 Agitated 标签的准确率达到 90% 以上。
![]() | ![]() |
随后校验模型准确率,并导出模型文件 Experience_model.zip,准备在下一步模型部署时使用。

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

3. 部署:
二哈2固件更新:
部署模型前务必更新二哈2固件更新到最新版本 V1.2.2
最新版本系统可在 HUSKYLENS2 最新固件下载 找到。
固件更新请参考:二哈识图 2 固件更新教程

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

二哈视图2 上测试自训练模型识别效果。
![]() | ![]() |
四、 核心代码实现 (Python/Mind+)
本项目的代码核心在于“环境联动控制”与“滑动窗口算法”。 为了避免情绪误判造成的频繁开关,我们编写了基于5秒历史数据的滑动窗口判断逻辑:只有当近5秒内“焦虑”状态占比超过70%时才触发干预;干预持续至少10秒后,若长者情绪转为“平静/愉悦”占比超半,才恢复常态。


以下是完整的行空板 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),达到更深度的个性化干预。

最好的孝顺,是守护他们的尊严。 对于患有认知障碍的长者来说,“黄昏时段”往往是最难熬的。传统的监控和报警器虽然安全,却时刻提醒着他们“你是病人”。
“寻味唤醒舱”试图改变这一切。它没有冰冷的摄像头,没有束缚的手环。它用看不见的AI和闻得到的芳香,在长者情绪波动的那一刻悄悄介入。
消除看护盲区,捍卫长者尊严,释放医疗资源。 这不仅是技术的重构,更是对生命的温柔以待。

返回首页
回到顶部








评论