news 2026/9/5 16:58:15

树莓派5与深度相机构建无接触3D腰臀围测量仪

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
树莓派5与深度相机构建无接触3D腰臀围测量仪

这次我们来看一个把树莓派5当嵌入式主机、把深度相机当测量探头、把点云算法当量尺的完整方案:无接触 3D 智能腰臀围测量仪。它的核心不是“拉软尺”,也不是让测量员贴身去量,而是让被测者站到设备前面,3D 相机采集人体表面点云,后端通过点云切片、轮廓提取和周长计算,直接输出腰围、臀围数据。整条链路在本地完成,树莓派5 既是工控主机,同时也是 Web UI 和 API 服务节点。

先给结论:这个方向适合做服装远程尺码、健身房体测、健康筛查、康复随访这类偏“无接触体表尺寸”的设备原型。树莓派5 的优势很明确,4 核 Cortex-A76、8GB 内存版本可以撑住 Python 视觉栈,USB 3.0 可以接结构光或 ToF 深度相机,HDMI 接一体机屏幕,GPIO 还能接人体感应和补光灯控制。相比 x86 工控机,它的体积、功耗和部署灵活性更贴近“嵌入式一体机”的产品形态。

这篇文章会把整套系统的可复制方案拆开来讲,包括一体机硬件组成、树莓派5 系统环境准备、深度相机接入、点云转 3D 坐标、腰臀围切片算法流程、API 接口、批量测量模式、性能观察和常见坑。如果你正在做人体尺寸测量、体围扫描或者树莓派视觉一体机,这篇可以直接当搭建清单用。

阅读门槛不高。需要你熟悉一点 Python、Linux 基础命令,手里有一块树莓派5 和一台 USB 3D 相机。没有 GPU 也能跑,因为整个测量核心主要吃 CPU 和内存,单帧点云处理对树莓派5 的压力可控。

1. 核心能力速览

能力项说明
测量方式无接触 3D 点云切片,通过相机采集人体表面,不接触被测者
主控平台树莓派5,建议 8GB 内存版本,Ubuntu/Debian/Raspberry Pi OS 均可
传感器输入USB 3.0 结构光或 ToF 深度相机,需能输出深度图和彩色图
软件栈Python3、NumPy、OpenCV、SciPy,可选 Open3D/PCL 辅助显示
对外能力本地 Web UI、REST API、人员编号记录、CSV/SQLite 落盘
批量任务支持人员排队逐个测量,结果按编号写入记录文件
硬件扩展GPIO 可接人体感应开关、拍照按钮、补光灯继电器
隐私策略默认不保存原始彩色影像,体围数据匿名化处理
测量精度需现场标定,先用标准人体模型和软尺结果做误差校准
不适用边界非医疗器械,不适合医疗诊断级测量

这套能力里,最容易先验证的是“深度相机能否输出干净点云”和“同一高度切片轮廓是否稳定”。只要这两步跑通,后续接口和批量任务基本是水到渠成。

2. 适用场景与使用边界

适合用无接触 3D 腰臀围测量仪的场景有几类。

第一类是服装行业远程尺码采集。用户可以站在设备前扫一下,得到净体腰围、臀围,避免门店里人工贴身测量带来的尴尬和误差。第二类是健身房和运动康复。健身教练需要定期记录会员体围变化,无接触方案比卷尺更高效,还能留存每次测量的体围曲线。第三类是健康体检初筛,部分体检中心需要快速记录腰围、臀围并计算腰臀比,这种设备能减少人工操作。

不适合的场景也要说清楚。首先它不适合医疗诊断级测量,不能替代医生或营养师的专业工具。其次它要求被测者能够保持站立姿态并在设备前停留数秒,婴幼儿、无法站立的人就不适用。最后,单相机方案只能覆盖一个方向的人体表面,对侧面凹陷区域会有盲区。如果对精度要求很高,建议后期加第二台或第三台相机做点云融合,而不是只靠单相机硬算。

隐私和合规是必须重点处理的环节。腰围、臀围、体重这类数据属于个体健康信息,采集前要取得被测者同意。原始深度图和彩色图里可能包含人脸和周边环境,系统默认只保留测量数值和人员编号,不保留原图。如果为了算法优化需要保存原始点云,至少要做人脸区域遮盖和匿名化,数据存储在本地,不随意上传。

3. 整体架构与硬件选型

这套“树莓派5 嵌入式一体机”的方案,整机架构可以分成四层:感知层、主控层、算法层、服务层。

  • 感知层:3D 深度相机 + 人体感应传感器。相机负责出深度图和彩色图,人体感应器负责判断是否有人靠近,从而触发测量流程。
  • 主控层:树莓派5。运行操作系统、相机 SDK、Python 环境,也负责 GPIO 输入输出和供电管理。
  • 算法层:点云预处理、人物区域提取、腰臀水平定位、切片轮廓周长计算。
  • 服务层:本地 Web UI 和 REST API,提供给触屏或第三方体检系统调用。

硬件组成可以参考这张表。

硬件选型要点作用
树莓派5 8GB内存尽量选 8GB,跑 Python 视觉栈更从容系统主控、算法运算、接口服务
3D 深度相机优先 USB 3.0 接口,提供深度 SDK输出深度图、彩色图或点云
触摸显示屏HDMI 显示 + USB 触摸现场操作界面
补光灯可接 GPIO 或继电器改善环境光照,减少深度图暗部噪点
稳定电源/UPS树莓派5 建议 5V 5A 供电防止相机启动瞬间电流不足
机柜或支架固定相机高度和角度保证测量位置一致

树莓派5 的 GPIO 引脚在这套设备里不是必须的,但很有用。你可以把一个人体红外感应模块接到 GPIO,有人在设备前站定时自动触发“开始测量”;也可以在测量开始时通过 GPIO 点亮补光灯,结束后关闭。这样能降低相机一直运行带来的发热和功耗。

相机型号不在这里绑定死,因为实际项目里有人用结构光相机,有人用 ToF 相机。只要是能输出深度图并且官方有 Linux/ARM64 Python SDK 的相机就能接入。选型时优先看三件事:是否支持树莓派/ARM64 平台、是否提供 Python API、深度分辨率是否支持至少 640x480@15fps。

4. 环境准备与前置条件

开始之前先把树莓派5 的系统准备好。

我推荐直接用官方适配的 Raspberry Pi OS Bookworm 64 位版本,或者 Ubuntu 24.04 Server 这类新镜像。这里说一句:如果搜资料看到“树莓派5 上用 Ubuntu 22.04”,复制前要谨慎,树莓派5 官方适配是从较新的内核版本才开始的,硬装 Ubuntu 22.04 很容易卡在内核、蓝牙和相机驱动上。想省时间就选官方适配的系统。

系统安装完成后,先做源更新和基础包安装。如果树莓派网络下载软件包比较慢,可以把 APT 源切换成清华镜像源,注意选择与当前系统版本匹配的源地址。

sudo apt update && sudo apt upgrade -y sudo apt install -y python3-pip python3-venv git build-essential \ python3-opencv python3-numpy

Python 环境建议建一个虚拟环境,避免把系统 Python 弄乱。后面所有依赖都装进measure_env里。

mkdir -p ~/body-measure cd ~/body-measure python3 -m venv measure_env source measure_env/bin/activate pip install numpy opencv-python scipy flask fastapi uvicorn

如果你计划用 Open3D 做点云可视化和网格处理,可以在虚拟环境里继续安装 open3d。但要注意一点:树莓派是 ARM64 架构,部分 Open3D pip 包可能没有对应的 aarch64 wheel,装不上时不要硬刚,可以去掉 Open3D,只用 NumPy/CV 做后台处理,可视化放到电脑端完成。

环境检查项整理如下。

检查项要求
系统架构aarch64/arm64
Python3.9 以上
numpy / opencv能 import 成功
相机权限当前用户能访问 /dev/video*
磁盘空间至少留 10GB,存放日志和测试素材

5. 3D 相机接入与点云采集

环境准备好后,先验证相机能不能被树莓派5 识别。把深度相机插到树莓派5 的 USB 3.0 蓝色接口上,然后执行 lsusb 看设备:

lsusb ls /dev/video*

如果设备出现在 lsusb 里但没有生成 /dev/video*,多半是相机驱动或权限问题。不同相机的驱动方式差别很大,结构光相机往往需要先安装厂商 SDK,ToF 相机可能直接走 UVC 协议。以厂商官方文档为准。

相机接入后,先用厂商提供的 viewer 工具验证深度图。没有 viewer 时,直接用 Python SDK 读取一帧深度图和彩色图,然后保存成本地图片。这时候能看到正常深度影像,说明相机 OK。

5.1 深度图转 3D 点云的通用公式

相机输出的深度图本质是一张二维图,每个像素值代表该点到相机平面的距离。要知道点在 3D 空间中的坐标,必须结合相机内参和外参。通用的转换公式如下:

import numpy as np def depth_to_points(depth_img, fx, fy, cx, cy, depth_scale=0.001): """ depth_img: H x W 的深度图, 单位毫米或由 depth_scale 控制 fx, fy, cx, cy: 相机内参 depth_scale: 深度像素值换算成米的倍率 返回 N x 3 的点云数组 """ h, w = depth_img.shape v, u = np.indices((h, w)) # 深度像素值可能是 uint16, 先转 float z = depth_img.astype(np.float32) * depth_scale x = (u - cx) * z / fx y = (v - cy) * z / fy points = np.stack([x, y, z], axis=-1) # 去掉深度为 0 的无效点 valid = z > 0 return points[valid]

这段代码的逻辑在所有深度相机上都适用。不同厂商 SDK 的差异只在内参获取方式、深度单位、是否做好彩色图和深度图对齐。如果你的相机会输出彩色图,建议先把彩色图和深度图对齐,再做点云生成,这样后面可以直接用彩色图来定位测量水平线。

5.2 固定机位的人体背景滤除

树莓派5 算力有限,不要把所有背景点都送进算法。固定机位测量时,人体大致站在相机前方 1 米左右,可以先做一个深度范围裁剪,把 0.5 米以内、2 米以远的点全部去掉。

def crop_by_depth(points, z_min=0.4, z_max=2.0): mask = (points[:, 2] > z_min) & (points[:, 2] < z_max) return points[mask]

如果现场有复杂背景,单纯深度裁剪不够。建议在相机前留出较空的测量区,或者在算法里加一个 2D 人体检测框,先锁定人体在画面中的位置,再取可见深度点。自己训练 YOLOv5 系列模型时,可以先导出 ONNX,再通过 OpenCV DNN 或 NCNN 在树莓派 CPU 上运行。只做人体位姿粗定位的话,不需要高帧率,一秒一两帧就够。

6. 腰臀围测量算法流程与效果验证

点云拿到手之后,真正的难点是“在哪里算腰围,在哪里算臀围,以及怎么把点云周长变成贴近软尺的体表长度”。

6.1 腰围和臀围在点云里的定义

从人体测量学角度看,腰围通常指肋弓下缘与髂嵴之间最细处的水平围长;臀围则是臀部最丰满处的水平围长。这些位置在点云里没有明确的颜色标签,需要先用人体关键点或人工参考来缩小范围,再在局部区域搜索。

工程上比较稳的方式是混合定位:

  1. 先通过 2D 彩色图人体关键点模型,获得髋关节、肚脐等参考点的高度。
  2. 根据参考点高度在点云中圈出“腰部可能区域”和“臀部可能区域”。
  3. 在腰部区域内沿垂直方向每隔 5-10mm 做一个水平切片,计算轮廓周长。
  4. 取腰部区域内周长最接近极小值的位置,作为腰围测量高度。
  5. 在臀部区域内取周长最大位置,作为臀围测量高度。

这样做的原因是腰腹之间最细处不一定正好落在肚脐高度,臀围也不一定刚好在关键点高度,只有通过连续搜索才能找到实际表面变化。

6.2 水平切片轮廓周长计算

核心算法是:把某个高度附近的一组 3D 点投影到水平面,得到一堆 2D 点,然后用扇形分桶法取该角度方向的表层点,最后沿角度顺序计算折线周长。

下面给出一段示意代码,能用,但工程落地时还需要结合点云密度和噪声做平滑。

import numpy as np def body_slice_circumference(points, z_center, z_half=0.02, n_bins=72): """ 在 z_center 附近取厚度约 2*z_half 的点云切片, 将点投影到水平面, 按角度等分成 n_bins 个扇区, 每个扇区取距离质心最远的点作为表面包络点, 再计算扇形包络点的多边形周长。 points: N x 3 的点云, z 轴近似表示身体高度方向 返回弧长估算值, 单位与 points 一致 """ mask = (points[:, 2] > z_center - z_half) & (points[:, 2] < z_center + z_half) slice_pts = points[mask][:, :2] if len(slice_pts) < 20: raise RuntimeError("该高度切片有效点数过少") # 用中位数作为中心, 降低离群点干扰 cx, cy = np.median(slice_pts, axis=0) center = np.array([cx, cy]) # 距离中心太远的点可能是背景, 先剔除 dist = np.linalg.norm(slice_pts - center, axis=1) slice_pts = slice_pts[(dist > 0.05) & (dist < 1.0)] angles = np.arctan2(slice_pts[:, 1] - cy, slice_pts[:, 0] - cx) radii = np.linalg.norm(slice_pts - center, axis=1) bin_idx = np.floor((angles + np.pi) / (2 * np.pi / n_bins)).astype(int) bin_idx = bin_idx % n_bins border_points = [] for b in range(n_bins): pts_bin = slice_pts[bin_idx == b] if len(pts_bin) > 2: d = np.linalg.norm(pts_bin - center, axis=1) border_points.append(pts_bin[np.argmax(d)]) if len(border_points) < 12: raise RuntimeError("包络点数量不足,无法计算可靠周长") ordered = np.array(border_points) order_angles = np.arctan2(ordered[:, 1] - cy, ordered[:, 0] - cx) ordered = ordered[np.argsort(order_angles)] perimeter = 0.0 n = len(ordered) for i in range(n): p1 = ordered[i] p2 = ordered[(i + 1) % n] perimeter += np.linalg.norm(p1 - p2) return perimeter

这段代码的含义是先取表面某高度的一个“横截面外轮廓”,然后按角度找最外层点并算周长。如果你的被测者体形比较均匀,这种方法得到的近似值可以作为基础结果。真正做产品时,不建议直接用简单凸包算法,因为人的腰臀横截面并不是标准凸形,凸包会把腹部两侧的凹陷段也算大。

6.3 功能测试与效果验证

算法写到能输出数值后,先不要急着接第三方系统,应该做一轮对比验证。验证流程建议这样安排:

  1. 找标准人体模型或几位测试者,保持站立姿势。
  2. 先用软尺在人工标记位置测量腰围和臀围,记录为基准值。
  3. 让同一人站在树莓派5 测量设备前,重复测量 3 次。
  4. 对比点云结果与软尺结果,记录每次偏差。
  5. 如果点云结果系统偏大或偏小,不要先调阈值,先检查切片高度定位和噪点。

这里要提醒一点:点云切片周长指的是人体表面某个水平高度切面外轮廓的弧长,软尺量的是体表软组织的贴体长度。两者天然存在细小差异,实际产品都要建立“相机测量值 → 标准软尺值”的校正关系,也就是线性回归修正。不能直接说“算法算出来多少就是真实腰围”。

判断算法是否成功的标准有三个:

  • 同一人重复测三次,结果是否稳定在可接受范围内。
  • 腰围搜索结果是否落在肉眼可见的最细位置附近。
  • 臀围搜索结果是否落在臀部最丰满位置附近。

如果连续测量结果抖动很大,先检查是不是点云里混入了手、手臂或者衣服下摆,而不是急着优化周长公式。

7. 接口 API 与批量任务模式

测量一体机不可能只在树莓派本地 Python 脚本里敲命令使用。实际产品里,触摸屏需要一个交互页面,后台需要把测量记录同步出去,这时候就要把测量能力封装成 REST API。

下面用一个 Flask 示例说明接口服务怎么写。实际使用时,把measure_current_person换成你自己的测量函数即可。

from flask import Flask, request, jsonify from measure_core import measure_current_person app = Flask(__name__) @app.route("/api/measure", methods=["POST"]) def measure(): data = request.get_json(force=True) person_id = data.get("person_id", "unknown") # person_id 用于编号,不要把姓名直接放在日志里 result = measure_current_person(person_id=person_id) return jsonify({ "person_id": person_id, "waist_cm": round(result["waist_cm"], 1), "hip_cm": round(result["hip_cm"], 1), "status": "ok" }) @app.route("/api/records", methods=["GET"]) def records(): # 查询历史记录,可以对接 SQLite return jsonify({"query": "ok"}) if __name__ == "__main__": app.run(host="0.0.0.0", port=8000)

服务启动后,用 curl 测试接口:

curl -X POST http://127.0.0.1:8000/api/measure \ -H "Content-Type: application/json" \ -d '{"person_id": "T001", "clothing": "贴身衣物"}'

期望返回类似这样的 JSON:

{ "person_id": "T001", "waist_cm": 86.4, "hip_cm": 98.2, "status": "ok" }

如果需要在体检或服装门店批量使用,可以加一个“人员队列”模式。最省事的做法是准备一个 CSV 人员列表,脚本按顺序读取编号,每个编号执行一次测量并写入结果。树莓派5 的 CPU 不适合并行处理多个深度流,所以测量任务建议串行执行。

# 批量测量脚本示意 python batch_measure.py --input ./person_list.csv --output ./result.csv

批量模式要特别处理失败重试。比如某次没有检测到人体,脚本不应该直接跳过,而应该等 3 秒后重试,重试 3 次仍失败才记录 error。否则一个人没站好,后面所有记录都错位。

树莓派一体机开机自启时,建议用 systemd 托管 Flask 服务。创建/etc/systemd/system/measure-api.service

[Unit] Description=Body Measure API Service After=network.target [Service] User=pi WorkingDirectory=/home/pi/body-measure ExecStart=/home/pi/body-measure/measure_env/bin/python app.py Restart=always RestartSec=5 [Install] WantedBy=multi-user.target

然后执行:

sudo systemctl enable --now measure-api sudo systemctl status measure-api

这样树莓派5 上电后,测量

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 16:57:39

基于Vue+SpringBoot+MySQL的超市商品管理系统全栈开发实战

简介&#xff1a;这是一套面向计算机专业本科生的高分毕业设计级超市商品管理系统&#xff0c;采用VueSpringBootMySQL技术栈实现前后端分离架构&#xff0c;适用于毕设开发、课程设计及Java全栈实战学习。资源包共包含源码、MySQL数据库脚本、详细功能文档、开题报告与外文文献…

作者头像 李华
网站建设 2026/9/5 16:57:15

基于uni-app与Serverless的英语学习小程序全栈开发实践

简介&#xff1a;这是一套面向英语学习者与小程序开发者的微信小程序源码项目&#xff0c;聚焦考研英语备考、日常词汇积累与口语能力提升三大核心场景。项目基于uniapp前端框架与uniCloud Serverless云服务架构实现&#xff0c;具备生词本管理、拍照识别单词、离线词典查询、A…

作者头像 李华
网站建设 2026/9/5 16:57:06

技术博客选题落地:从影视特效到可复现的工程实践

没法把“蜘蛛侠vs超人”写成技术博客。这个选题面向的是影视角色比较&#xff0c;不属于可落地、可复现的工程主题&#xff0c;和本博客定位不一致。 如果想在技术社区写作&#xff0c;围绕这个方向可以换成这些可展开的选题&#xff1a; 从 OpenGL / Vulkan 渲染管线理解超人…

作者头像 李华
网站建设 2026/9/5 16:53:17

抖音快手点赞平台源码技术深度解析与实战避坑指南

简介&#xff1a;这是一套面向短视频运营从业者与PHP开发者的技术型源码资源&#xff0c;用于快速搭建抖音、快手、火山等平台的视频点赞任务分发与管理平台&#xff0c;解决多账号任务调度、用户激励与数据统计等核心运营需求。资源包共2000个文件&#xff0c;主体为1068个PHP…

作者头像 李华
网站建设 2026/9/5 16:48:21

树莓派4B开源语音控制机器人:openduckmini部署与调试全解析

openduckmini 是一个开源机器人项目&#xff0c;圈子里一般叫它“开源机器鸭”。树莓派4B版本最值得关注的能力&#xff0c;就是让桌面级机器人支持语音控制&#xff1a;你喊一句“小鸭抬头”或者“介绍一下自己”&#xff0c;它能先录音、识别&#xff0c;再根据指令执行动作或…

作者头像 李华