1. 项目概述:一个会“看人下菜碟”的智能糖果碗

每年万圣节,门口摆上一碗糖果,看着孩子们兴高采烈地来讨糖,是件乐事。但作为一个喜欢捣鼓硬件的玩家,我总觉得少了点“科技感”和“恶作剧”的趣味。能不能做一个不仅能分发糖果,还能跟人互动,甚至带点小惊吓的装置呢?这个想法催生了这个项目:一个基于机器学习和计算机视觉的智能万圣节糖果碗。

这个糖果碗的核心逻辑很简单:它有一双“眼睛”(USB摄像头)和一个“大脑”(Raspberry Pi)。当有人靠近时,它会先判断来者是否穿着万圣节服装。如果检测到对方穿着僵尸、女巫、吸血鬼等经典服装,它会保持安静,允许对方取走糖果——这是给“懂规矩”的捣蛋鬼的款待。反之,如果检测到有人没穿服装就试图拿糖,碗里会突然弹出一只恐怖的“鬼手”,配合可能的音效(本项目未实现,但可扩展),给“缺乏节日精神”的人一个小小的惊吓或提醒。

这不仅仅是一个简单的机械触发装置,而是一个完整的嵌入式AI应用。它涉及硬件改装(将普通电动南瓜碗升级为可编程平台)、机器学习模型部署(使用TensorFlow Lite进行人物和服装检测)、机器人控制(通过Viam平台管理硬件和编写行为逻辑)以及系统集成。整个过程就像给一个玩具注入灵魂,让它从被动响应变为主动感知和决策。无论你是想学习如何将AI模型部署到边缘设备,还是想打造一个独一无二的节日装饰,这个项目都能提供从硬件到软件的一站式实践指南。

2. 核心硬件选型与改造思路

2.1 硬件清单与选型理由

要复现这个项目,你需要准备以下硬件。这里的每一项选择都基于成本、易用性和项目需求的平衡:

  1. Raspberry Pi(树莓派) :项目的大脑。我推荐使用 Raspberry Pi 4B 2GB或4GB版本 。它的算力足以流畅运行TensorFlow Lite模型进行实时检测,GPIO引脚丰富,社区支持完善。更早的3B+型号理论上也可行,但处理速度可能会成为瓶颈。务必准备一张至少16GB的MicroSD卡用于安装系统。
  2. 万圣节动画南瓜碗(基础载体) :这是项目的“躯壳”。我在网上选择了一款内置直流电机、能控制“鬼手”弹出/收回的电动南瓜碗。选择的关键是:内部有足够的空间容纳树莓派和电机驱动板,并且其机械结构(通常是齿轮齿条或连杆)容易与原有电机分离并接入我们的控制电路。
  3. 电机驱动板 :树莓派的GPIO引脚无法直接驱动12V的直流电机,需要驱动板作为中介。我选用的是非常常见的 L298N双H桥直流电机驱动模块 。它价格低廉,驱动能力足够(本项目电机功率不大),并且与树莓派的3.3V/5V逻辑电平兼容。你也可以使用DRV8833等更小巧的驱动芯片模块。
  4. USB网络摄像头 :项目的“眼睛”。选择一款支持Linux UVC驱动的免驱摄像头即可,分辨率720p(1280x720)足够,更高的分辨率会增加处理负担。注意镜头尺寸,要能塞进我们为它准备的“眼窝”。
  5. 电源系统 :这是确保稳定运行的关键,需要 两路独立供电
    • 树莓派供电 :标准的5V/3A USB-C电源适配器。
    • 电机驱动板供电 :一个12V/1A以上的直流电源适配器,用于给电机提供动力。 切记:树莓派的5V和电机的12V电源地(GND)必须共地 ,即连接在一起,否则控制信号无法正确传递。
  6. 连接线 :杜邦线(母对母、公对母)若干,用于连接树莓派、驱动板和电机。

注意 :在购买电动南瓜碗时,最好选择内部结构清晰、电机便于拆卸的型号。有些产品为了防水或美观,会将电机完全封死,改造难度会大大增加。

2.2 南瓜碗的“外科手术”:硬件改造详解

拿到南瓜碗后,第一步就是拆解,了解其内部构造,并为我们自己的控制系统腾出空间。

  1. 安全拆解 :拧开底座或背部的螺丝,小心打开外壳。你会看到原有的控制板、电池盒、电机、可能的光敏电阻(作为原始的运动传感器)和LED眼睛。用手机拍下原始接线图,尤其是电机与主板的连接方式,这很重要。
  2. 移除冗余部件 :我们的树莓派将接管所有控制功能,因此原装的控制板、光敏传感器、LED和喇叭都可以拆除。只保留那个驱动“鬼手”的 直流电机 。小心地将电机的两根线从原装板上焊下或断开。
  3. 为摄像头开“天眼” :原有的LED眼睛位置是安装摄像头的绝佳位置。用电钻或手工工具,在其中一只“眼窝”处开一个与摄像头镜头直径相匹配的圆孔。开孔时务必小心,先从较小的钻头开始,逐步扩大,并不断用摄像头镜头比试,确保能紧密卡住,避免后期需要额外的固定支架。另一只眼窝可以保留或封住,以保持外观。
  4. 内部布局规划 :将树莓派、L298N驱动板放入碗内。考虑散热和走线,可以用尼龙柱或双面胶进行固定。确保摄像头的数据线能舒适地连接到树莓派的USB口。

2.3 电路连接:让大脑控制手臂

这是将各个硬件连接成系统的关键一步。接线错误可能导致设备不工作,甚至损坏树莓派。

连接示意图与原理:

[12V电源适配器] ---- (VCC, GND) ---- [L298N驱动板 电源输入端]
                                           |
[树莓派 GPIO 23] ---- IN1 ---- [L298N驱动板] ---- OUT1 ---- [直流电机 线A]
[树莓派 GPIO 24] ---- IN2 ---- [L298N驱动板] ---- OUT2 ---- [直流电机 线B]
[树莓派 GPIO 25] ---- ENA (PWM) ---- [L298N驱动板]
                                           |
[树莓派 5V Pin] ---- [L298N逻辑电源端] (可选,如果板载5V稳压)
[树莓派 GND Pin] ---- [L298N GND] ---- [12V电源 GND] (必须共地!)
[USB摄像头] ---- [树莓派 USB端口]

接线步骤与要点:

  1. 电机与驱动板 :将南瓜碗直流电机的两根线,分别连接到L298N模块的 OUT1 OUT2 输出端。电机没有正负极之分,接反了只会导致转动方向相反,我们可以在软件中调整。
  2. 驱动板电源 :将12V电源适配器的正极(VCC)接驱动板的 12V输入 ,负极(GND)接驱动板的 GND
  3. 树莓派与驱动板控制信号
    • 将树莓派的 GPIO 23 (物理引脚16) 连接到驱动板的 IN1
    • 将树莓派的 GPIO 24 (物理引脚18) 连接到驱动板的 IN2
    • 将树莓派的 GPIO 25 (物理引脚22) 连接到驱动板的 ENA (使能端,通常标为ENA)。
    • 关键一步:共地 。用一根杜邦线,将树莓派的任一 GND 引脚(如物理引脚6)与L298N驱动板上的 GND 引脚连接起来。这样,树莓派的控制信号和驱动板就有了共同的参考零电位。
  4. 驱动板逻辑电源 :很多L298N模块有一个独立的 5V 输入,用于给板载逻辑电路供电。如果模块有这个接口,可以从树莓派的 5V 引脚取电。如果模块能从12V输入自己稳压出5V(通常有一个跳线帽选择),则无需连接。请查阅你购买的L298N模块的具体说明书。
  5. 摄像头 :直接将USB摄像头插入树莓派的任意USB端口。

完成接线后,先不要急着上电。仔细检查所有连接,特别是电源部分,确保正负极没有接反,也没有短路的风险。

3. 软件基石:Viam平台配置与组件管理

硬件是躯体,软件是灵魂。为了让树莓派能方便地管理摄像头、电机,并运行我们的AI代码,我选择了 Viam机器人平台 。它提供了一个云端配置界面和本地代理服务(viam-server),能极大地简化机器人应用的开发流程,让我们可以专注于业务逻辑,而不是底层驱动和通信。

3.1 初始设置:从树莓派到Viam云端

  1. 准备树莓派系统 :在SD卡上刷入最新的Raspberry Pi OS(推荐Lite版本以节省资源),完成基础系统设置,并确保能通过SSH远程登录。记下树莓派的本地主机名或IP地址,例如我的是 spooky@bowl.local
  2. 安装viam-server :在Viam官网注册账号并登录。在控制台创建一个新的机器人实例,命名为 spookybowl 。进入该机器人的 Setup 标签页,你会看到针对树莓派的安装命令。通过SSH登录到你的树莓派,复制并执行这些命令。这会在树莓派上安装 viam-server 守护进程,它会自动连接回Viam云端。
  3. 验证连接 :安装完成后稍等片刻,回到Viam应用网页的 Control 标签页。如果看到机器人的状态变为“在线”,并且可能有一个默认的“摄像机”组件出现(来自树莓派本身的CSI摄像头或USB摄像头),恭喜你,硬件与云端的桥梁已经搭好。

3.2 在Viam中配置硬件组件

Viam通过“组件”来抽象和管理每一个硬件。我们需要配置三个组件:板卡(代表树莓派自身)、电机、摄像头。

  1. 配置板卡组件

    • 进入机器人的 Config -> Components
    • 点击 Create component ,类型选择 board ,模型选择 pi ,名称填写 local 。这创建了一个代表树莓派GPIO板的组件,后续电机将通过它进行控制。
  2. 配置电机组件

    • 再次点击 Create component ,类型选择 motor ,模型选择 gpio
    • 名称填写 dcmotor
    • 在属性配置中:
      • board :选择刚才创建的 local
      • Max RPM :填写 100 。这是一个安全上限,实际速度由我们代码中的功率和RPM参数控制。
      • 将电机类型切换为 In1/In2 (这是L298N的常见控制模式)。
      • A/In1 :填写 16 (对应GPIO 23的BCM编码,物理引脚16)。
      • B/In2 :填写 18 (对应GPIO 24的BCM编码,物理引脚18)。
      • PWM :填写 22 (对应GPIO 25的BCM编码,物理引脚22,连接ENA)。
    • Depends On 中,添加 local ,确保板卡先初始化。
  3. 配置摄像头组件

    • 点击 Create component ,类型选择 camera ,模型选择 webcam
    • 名称填写 pumpcam
    • 通常情况下, Path 字段会自动识别出你的USB摄像头路径(如 /dev/video0 )。如果没有,你可能需要在树莓派上使用 ls /dev/video* 命令查看,并手动填写。

实操心得 :在配置电机引脚时,Viam使用的是 BCM编码 (即GPIO编号),而不是物理引脚序号。GPIO 23对应物理引脚16,GPIO 24对应物理引脚18,GPIO 25对应物理引脚22。混淆这两者是新手最常见的错误之一,会导致电机无反应。

3.3 硬件功能测试

配置保存后,转到 Control 标签页。你应该能看到 dcmotor pumpcam 的卡片。

  • 测试电机 :点击 dcmotor 卡片,会展开控制面板。尝试设置功率为50%,方向选择“正向”,点击“运行”。如果接线正确,你应该能看到南瓜碗里的“鬼手”缓慢伸出。再点击“停止”。这个测试至关重要,它能立即验证你的硬件连接和电机配置是否正确。
  • 测试摄像头 :在 pumpcam 卡片上,你应该能看到摄像头实时拍摄的画面。调整南瓜碗的角度,确保视野覆盖前来取糖的区域。

如果测试失败,首先检查 Config 中的引脚编号是否正确,然后回到硬件层面,用万用表检查线路是否连通,电源是否正常。

4. 注入智能:机器学习模型的部署与应用

硬件能动、能看之后,接下来就是让它“思考”。我们将部署两个机器学习模型:一个通用的“人物检测”模型,和一个我们自定义训练的“服装分类”模型。

4.1 部署预训练的人物检测模型

对于通用人物检测,我们使用一个现成的、轻量级的TensorFlow Lite模型,例如EfficientDet-Lite0。Viam平台简化了这个过程。

  1. 准备模型文件 :你需要两个文件: .tflite 模型文件(包含模型权重和结构)和对应的 .txt 标签文件(每行一个类别名,如“person”,“dog”,“car”等)。可以从TensorFlow官方模型库或项目提供的仓库中获取。
  2. 上传模型 :在Viam应用中,进入 Data -> Models 。点击 New Model ,命名为 effdettest ,类型选择 Object detection 。上传你的 .tflite 文件和 .txt 标签文件。
  3. 创建ML模型服务 :进入 Config -> Services 。点击 Create service ,类型选择 ML Model ,模型选择 TFLite CPU ,名称填写 ml_model_test 。在配置面板中, Deployment 选择 Deploy model on robot ,然后在 Model 下拉框中选择刚刚上传的 effdettest 模型。这会将模型文件下载到你的树莓派上运行。
  4. 创建视觉检测服务 :再次点击 Create service ,类型选择 Vision ,模型选择 ML Model ,名称填写 detections_test 。在配置面板中, ML Model 选择上一步创建的 ml_model_test 服务。
  5. 创建变换摄像头(Transform Camera) :这是关键一步,它将原始的摄像头流和检测服务绑定在一起,生成一个带有检测框的新视频流。进入 Config -> Components ,创建新组件,类型 camera ,模型 transform ,名称 detections_cam 。在属性JSON中填入:
    {
      "source": "pumpcam",
      "pipeline": [
        {
          "type": "detections",
          "attributes": {
            "detector_name": "detections_test",
            "confidence_threshold": 0.5
          }
        }
      ]
    }
    
    别忘了在 Depends On 中添加 pumpcam

保存所有配置。现在进入 Control 标签页,你应该能看到一个名为 detections_cam 的新摄像头组件。打开它的视频流,当有人进入画面时,你应该能看到人物被实时框选出来,并标注为“Person”。这证明你的AI“视觉”已经生效了。

4.2 训练与部署自定义服装检测模型

为了让糖果碗能区分是否穿着服装,我们需要一个能识别特定服装(如女巫、僵尸)的模型。这里我们使用Viam内置的数据管理和训练工具。

  1. 收集与上传图像数据集

    • 收集 :这是最耗时但最重要的一步。你需要为每类服装(如 witch , zombie , vampire )收集至少20-30张图片。图片应尽可能多样化:不同的人、不同的姿势、不同的光照条件、不同的背景。可以从开源数据集或使用搜索引擎(注意版权)获取,最好自己拍摄一些。
    • 上传 :将图片文件夹通过SCP命令上传到树莓派: scp -r /本地/图片/路径 spooky@bowl.local:/home/spooky/costume_images 。然后在Viam的 Config -> Services 中,创建一个 Data Management 服务,命名为 costume-images ,配置其同步你树莓派上的图片目录(如 /home/spooky/costume_images )。
  2. 数据标注

    • 进入 Data -> Images ,你可以看到上传的图片。
    • 点击一张图片,使用标注工具在穿着目标服装的人物周围绘制边界框(Bounding Box),并选择正确的标签(如 witch )。重复这个过程,为数据集中的大量图片进行标注。标注质量直接决定模型性能。
  3. 训练模型

    • 标注足够的数据后(Viam要求每个标签至少10张图,但越多越好),在 Data -> Models 页面,点击 Train model
    • 命名模型为 costumedetections ,类型选择 Object detection ,勾选你创建的所有服装标签。
    • 提交训练任务。Viam会在云端使用这些标注数据训练一个新的TensorFlow Lite模型。这个过程可能需要几分钟到几十分钟,取决于数据量和复杂度。
  4. 部署自定义模型

    • 训练完成后,重复4.1中的步骤3和4。
    • 创建一个新的ML模型服务(如 ml_model_costumes ),选择部署刚训练好的 costumedetections 模型。
    • 创建一个新的视觉服务(如 costumes_det ),模型选择 ML Model ,并关联 ml_model_costumes 服务。

至此,你的机器人已经拥有了“双重视觉”:一个用于看“是否有人”,一个用于看“穿什么衣服”。

5. 行为逻辑编程:用Python赋予灵魂

硬件就绪,AI模型就位,最后一步就是编写控制程序,定义糖果碗的“性格”。我们将使用Viam的Python SDK。

5.1 开发环境搭建与基础连接

首先,在你的开发电脑(可以是树莓派本身,也可以是另一台电脑)上设置环境。

# 安装Viam Python SDK
pip3 install viam-sdk

在Viam应用的 Code Sample 标签页,选择Python,它会生成一段包含机器人连接密钥和地址的模板代码。核心的连接函数如下:

import asyncio
import os
from viam.robot.client import RobotClient
from viam.rpc.dial import Credentials, DialOptions

robot_secret = os.getenv('ROBOT_SECRET')  # 从环境变量读取密钥
robot_address = os.getenv('ROBOT_ADDRESS') # 从环境变量读取地址

async def connect():
    creds = Credentials(
        type='robot-location-secret',
        payload=robot_secret
    )
    opts = RobotClient.Options(
        refresh_interval=0,
        dial_options=DialOptions(credentials=creds)
    )
    return await RobotClient.at_address(robot_address, opts)

安全提示 ROBOT_SECRET 是你的机器人密钥,相当于密码。务必通过环境变量或安全的方式管理,不要直接硬编码在代码中。

5.2 核心动作函数:惊吓与款待

我们需要定义两个核心行为函数。

  1. jumpscare 函数 :控制电机完成“鬼手”快速弹出并收回的动作。

    from viam.components.motor import Motor
    
    async def jumpscare(dcmotor: Motor):
        # 鬼手弹出:电机正转
        await dcmotor.set_power(power=0.75)  # 设置功率为75%
        await dcmotor.go_for(rpm=70, revolutions=1)  # 以70 RPM的速度正转1圈
        # 注意:go_for是阻塞的,会等待动作完成
    
        # 鬼手收回:电机反转
        await dcmotor.set_power(power=-0.75) # 设置功率为-75%(反转)
        await dcmotor.go_for(rpm=-70, revolutions=1) # 以70 RPM的速度反转1圈
    
        # 动作完成后,停止电机(可选,防止持续通电)
        # await dcmotor.stop()
    

    参数调优 power rpm 的值需要根据你的具体电机和机械结构进行调整。 revolutions=1 表示电机转1圈,这需要你测试1圈对应“鬼手”弹出/收回的完整行程是否合适。可能你需要0.8圈或1.2圈。通过反复测试找到最佳值。

  2. trickOrTreater 函数 :主逻辑循环,协调视觉检测与动作。

    from viam.services.vision import VisionClient
    
    # 定义我们想要识别的服装类别
    COSTUMES = ["witch", "mummy", "vampire", "cowboy", "zombie"]
    
    async def trickOrTreater(dcmotor: Motor, detections_test: VisionClient, costume_det: VisionClient):
        while True:  # 无限循环,持续监测
            # 1. 使用通用检测器找“人”
            people_detections = await detections_test.get_detections_from_camera("pumpcam")
            # 2. 使用服装检测器找“特定服装”
            costume_detections = await costume_det.get_detections_from_camera("pumpcam")
    
            seen_person_to_scare = False
            seen_costumed_person = False
    
            # 逻辑判断
            for detection in people_detections:
                # 置信度高于阈值且类别是“人”
                if detection.confidence > 0.6 and detection.class_name == "Person":
                    print("[INFO] 检测到未着装人员!")
                    seen_person_to_scare = True
                    break  # 检测到一个就够
    
            if seen_person_to_scare:
                # 执行惊吓动作
                await jumpscare(dcmotor)
                # 惊吓后等待一段时间,避免连续触发
                await asyncio.sleep(5)
            else:
                # 如果没有检测到要吓的人,再检查是否有穿服装的人
                for detection in costume_detections:
                    if detection.confidence > 0.6 and detection.class_name in COSTUMES:
                        print("[INFO] 检测到着装人员,节日快乐!请取糖。")
                        seen_costumed_person = True
                        # 这里可以添加其他友好行为,比如点亮LED,播放欢迎音效
                        break
                # 如果既没有检测到要吓的人,也没有检测到穿服装的人,可能是空场景或误检
                if not seen_costumed_person:
                    print("[INFO] 等待中...")
    
            # 每次循环间隔一小段时间,避免CPU占用过高
            await asyncio.sleep(0.5)
    

    逻辑精讲 :这里采用了一个优先级逻辑。 先检查是否有“人”(无论着装) 。如果检测到人且置信度高,默认其未着装(因为通用模型不识别服装),直接触发惊吓。 只有在这个检查未通过时 ,才去运行更耗资源的自定义服装检测模型。这样做有两个好处:一是提高了响应速度(服装检测模型通常更复杂、更慢),二是降低了计算负载。 confidence_threshold (置信度阈值)是调节灵敏度的关键参数,0.6是一个起点,你可以根据实际测试调整(例如,在光线暗的环境下可以调低至0.5,在复杂背景下可以调高至0.7以减少误报)。

5.3 主程序与资源管理

最后,编写主函数将所有部分串联起来,并确保资源被正确初始化和清理。

async def main():
    # 连接到机器人
    robot = await connect()
    print("成功连接到机器人!")

    try:
        # 从机器人获取组件和服务的“资源”对象
        dcmotor = Motor.from_robot(robot, "dcmotor")  # 电机组件
        detections_test = VisionClient.from_robot(robot, "detections_test")  # 通用检测服务
        costume_det = VisionClient.from_robot(robot, "costume_det")  # 服装检测服务

        print("所有资源初始化完毕,开始执行主逻辑...")
        # 运行主行为逻辑循环
        await trickOrTreater(dcmotor, detections_test, costume_det)

    except asyncio.CancelledError:
        print("程序被中断。")
    except Exception as e:
        print(f"程序运行出错: {e}")
    finally:
        # 无论发生什么,最后都要断开连接
        await robot.close()
        print("机器人连接已关闭。")

if __name__ == "__main__":
    # 运行异步主函数
    asyncio.run(main())

将上述所有代码块整合到一个名为 main.py 的文件中。通过SSH将文件上传到树莓派(例如 /home/spooky/ 目录下)。在树莓派上,设置好 ROBOT_SECRET ROBOT_ADDRESS 环境变量后,运行 python3 main.py ,你的智能糖果碗就应该开始工作了!

6. 系统优化与实战问题排查

项目搭建完成后,在真实环境中部署可能会遇到各种问题。以下是我在调试过程中总结的一些常见问题和优化技巧。

6.1 性能优化与稳定性提升

  1. 模型轻量化与速度 :如果发现检测帧率很低(例如低于5 FPS),导致反应迟钝。首先,确保使用的 .tflite 模型是面向移动/嵌入式设备优化的版本(如EfficientDet-Lite系列,MobileNet SSD)。其次,可以在Viam的 transform camera 配置中,降低输入给模型的图像分辨率。例如,在 pipeline detections 属性中添加 "input_image_width": 320, "input_image_height": 240 。这会牺牲一些精度,但能大幅提升速度。
  2. 电源管理 :电机启动瞬间电流较大,可能引起树莓派电压不稳导致重启。确保使用足额的5V/3A电源给树莓派供电。在电机电源(12V)输入端并联一个较大容量的电解电容(如1000uF/25V),可以吸收电机启停产生的电流冲击。
  3. 防止误触发 :在 trickOrTreater 函数的 jumpscare 动作后,我添加了 await asyncio.sleep(5) 。这是一个“冷却时间”,防止同一个人因为持续被检测到而连续触发惊吓。这个时间可以根据实际情况调整。
  4. 日志与调试 :在代码中多使用 print 语句输出关键信息,如检测到的类别、置信度、循环状态等。这能帮助你在SSH终端里实时监控程序运行逻辑,快速定位问题。

6.2 常见问题排查速查表

问题现象 可能原因 排查步骤与解决方案
电机完全不动作 1. 电源未接通或电压不足。
2. GPIO引脚配置错误。
3. 电机驱动板使能端(ENA)未激活。
1. 用万用表测量12V电源输出和树莓派5V输出。
2. 在Viam Control 标签页手动测试电机,如果手动可以,代码不行,检查代码中电机资源名称 ”dcmotor” 是否拼写正确。
3. 确保代码中使用了 set_power 设置非零功率。检查L298N的ENA跳线帽是否已移除(如果使用PWM控制)。
摄像头无画面 1. 摄像头未被系统识别。
2. Viam中摄像头路径错误。
3. 摄像头被其他进程占用。
1. SSH到树莓派,运行 ls /dev/video* lsusb ,确认摄像头设备存在。
2. 在Viam摄像头组件配置中,核对 Path 字段(如 /dev/video0 )。
3. 尝试重启 viam-server 服务: sudo systemctl restart viam-server
检测服务无结果/报错 1. 模型文件未正确上传或部署。
2. 标签文件与模型不匹配。
3. 树莓派内存或算力不足。
1. 检查Viam Services 中ML模型和Vision服务的状态是否为“活跃”。重新部署模型。
2. 确认 .txt 标签文件内容正确,且第一行通常是“???”(根据模型而定)。
3. 使用 htop 命令查看树莓派资源占用。考虑使用更轻量的模型或减少同时运行的服务。
程序运行一次后停止 1. 代码中存在未捕获的异常导致程序崩溃。
2. 网络断开导致机器人连接丢失。
1. 在主函数中加强异常捕获( try...except ),打印详细错误信息。
2. 检查树莓派网络连接。考虑在代码中添加重连逻辑,或使用Viam的 Process 配置让程序崩溃后自动重启(见下文)。
服装检测准确率低 1. 训练数据集质量差、数量少或多样性不足。
2. 现场光照条件与训练数据差异大。
3. 置信度阈值设置不合理。
1. 增加训练数据量,确保涵盖各种姿势、光照和背景。对图像进行增强(旋转、裁剪、调整亮度)。
2. 在部署环境补充类似光照条件下的图片进行训练。
3. 调整 confidence_threshold ,在Viam的Vision服务配置或代码中尝试不同的值(如0.5, 0.7)。

6.3 实现开机自启动

你肯定不希望每次断电重启后都要手动SSH进去运行程序。利用Viam的 Process 管理功能,可以轻松实现开机自启。

  1. 在Viam应用的 Config -> Processes 标签页,点击 Create process
  2. 进程名称填 run-forever
  3. 可执行文件填 python3
  4. 参数填你的主程序文件名,例如 main.py
  5. 工作目录填你的程序所在的绝对路径,例如 /home/spooky/
  6. 点击 Create process 并保存配置。

这样,每当树莓派启动并连接上Viam云端后,这个进程就会自动启动你的Python脚本。即使脚本因为异常退出,Viam也会尝试重新启动它(取决于配置)。

6.4 扩展思路

这个项目是一个完美的起点,你可以在此基础上进行无限扩展:

  • 增加音效 :在树莓派上连接一个USB声卡或利用GPIO驱动一个小喇叭,在 jumpscare 函数中触发一段恐怖的音效,体验加倍。
  • 增加灯光效果 :利用树莓派的GPIO控制一些LED灯条,在检测到不同情况时闪烁不同颜色的光。
  • 云端通知 :集成短信或邮件API,当糖果快被拿完时,给你发送提醒。
  • 多策略识别 :结合人脸识别,对熟人不惊吓,或者对同一个人在一段时间内只惊吓一次。
  • 更复杂的机械动作 :改造电机控制,让“鬼手”可以做出更复杂的动作序列,而不是简单的弹出收回。

这个项目最迷人的地方在于,它清晰地展示了一条从想法到实现的路径:硬件拆解改造 -> 平台化配置管理 -> AI模型部署 -> 逻辑编程 -> 系统集成与调试。每一个环节都有可深入挖掘的知识点,希望这份详细的指南能帮你成功打造出自己的那个“有想法的”万圣节糖果碗,享受创造和学习的乐趣。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐