MAKER:lukehsiao/译:趣无尽 Cherry(转载请注明出处)
CribSense 是一款能监测宝宝活动并能发出警报的监视器。只需一个周末的时间,你完全可以根据教程 DIY 来实现。根据自家宝宝的情况配置好软件部分,例如如果监测到宝宝不动了,则会发出警报。另外,项目中所有软件都是免费的,并且易于扩展。
该监视器是基于 Video Magnification 的 C++ 实现:
http://people.csail.mit.edu/mrub/vidmag/
所有的源文件和文档信息请点击下方链接:
https://github.com/lukehsiao/CribSense
我们将其作为一个有趣的原型项目项目来研究,任何市场上的产品都需要做更多的测试。因此,如果你使用这个项目,还需要自行做额外的探索。
材料清单
树莓派摄像头配置工具
树莓派 3 Model B×1
5V 2.5A Micro USB 电源×1
树莓派 NoIR(夜视红外)摄像头模块V2×1
MicroSD 卡×1
树莓派软排线12英寸×1
3.5mm 输入扬声器×1
HDMI 显示器×1
USB 键盘×1
USB 鼠标×1
树莓派散热片(可选)×1
弱光操作下的 IR LED 电路
1N4001 二极管×3
1 ohm 1W 电阻×1
1W 红外 LED×1
电线×2
烙铁×1
外壳
3D 打印外壳×1(9.9″ 长 x 7.8″ 宽 x 5.9″ 高)
热熔胶×1
准备工作
在项目开始之前,请在 SD 卡上安装了最新版本的 Raspbian,并确保树莓派的功能正常。
https://shumeipai.nxez.com/2013/09/07/raspberry-pi-under-windows-system-installation-to-sd-card.html
你还需要启用摄像头模块,才能访问摄像头。
https://shumeipai.nxez.com/2014/09/21/raspicam-documentation.html
安装 CribSense 软件
CribSense 依赖于 autoconf,libtool,OpenCV 和 libcanberra 等常见的软件工具。
https://www.gnu.org/software/autoconf/autoconf.html
https://www.gnu.org/software/libtool/
https://opencv.org/
http://0pointer.de/lennart/projects/libcanberra/
autoconf 和 libtool 用于许多平台(例如 Linux,OSX 和树莓派),可以自动配置 Makefile 和构建脚本。
OpenCV 是一款强大的计算机视觉软件包,它是以 Video Magnification 和运动检测代码的基础,用于进行图像处理。它具有强大的支持,易于使用且性能良好。
libcanberra 是一个简单播放声音的库。用于播放 CribSense 的警报声。
你可以访问它们的页面,获取完整的信息。
在树莓派上打开一个终端并运行以下命令来安装它们:
sudo apt-get install git build-essential autoconf libtool libopencv-dev libcanberra-dev
接下来,将 bcm2835-v4l2 添加到 /etc/modules-load.d/modules.conf
中,摄像头驱动程序将设置为自动加载。你的 modules.conf 应该是这样:
# /etc/modules: kernel modules to load at boot time. # # The file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. i2c-dev bcm2835-v4l2
文件编辑完后,重新启动树莓派。CribSense 将从 NoIR 摄像头获取画面。
然后,通过运行以下命令来复制存储库:
git clone https://github.com/lukehsiao/CribSense.git
接下来,进入存储库并通过运行以下命令构建软件。
cd CribSense ./autogen.sh --prefix=/usr --sysconfdir=/etc --disable-debug make sudo make install sudo systemctl daemon-reload
现在,所有的软件都安装完毕。
配置
CribSense 可通过简单的 INI 配置文件进行自定义。运行
make install
后,配置文件位于 /etc/cribsense/config.ini 中。你可以通过运行以下命令查看和编辑这些参数。
sudo nano /etc/cribsense/config.ini
默认配置中对每个参数,都做了简要说明。更多详细信息请点击:
https://lukehsiao.github.io/CribSense/setup/config/
运行 CribSense
CribSense 是通过使用 systemd 服务在启动时运行的。使用键盘和鼠标连接到树莓派,确保配置参数适用于你的婴儿床。如果将其移动,则需要重新调整这些参数。
当你调整参数时,请输入以下命令,就可在命令行随意运行 cribsense。
cribsense --config /etc/cribsense/config.ini
调试完成后,就可以启用自动运行。
sudo systemctl enable cribsense
你可以通过输入以下命令来停止 cribsense 的自动运行。
sudo systemctl disable cribsense
软件简介
CribSense 软件是该项目的核心和灵魂。在 MIT 的有很多关于 Video Magnification 的优秀演示。
http://people.csail.mit.edu/mrub/vidmag/
我想在树莓派上运行类似的算法。为了在树莓派上实时运行,就必须要求 tbl3rd 在其 C++ Video Magnification 实现的要比原来快 10 倍以上。
https://github.com/tbl3rd/Pyramids
这就需要优化指导我们的软件设计。
CribSense 通过软件实现下面的循环。
1、它将每个 640×480 的灰度视频帧分为三个水平部分(640×160),以便实现更好的缓存位置。
2、它会在单独的线程中放大每个段,并监视帧中看到的运动。在监视运动几秒钟后,它确定运动的主要区域并将帧裁剪到该区域。这种算法减少了需要处理的像素总数。
3、CribSense 监视裁剪后的视频流中的运动量,如果在配置的时间内未感知到运动,就会发出警报。CribSense 会定期重新打开视图并监视整个帧,如果婴儿已移动并在新的区域,将其范围进行重新修剪。
4、视频放大率用于提高例如婴儿呼吸之类的细微运动的信噪比。较大的动作不会起作用,但对于非常细微的动作却有很大的帮助。请注意,我们项目的实现只能粗略适用于 MIT 中描述的算法并且使用他们的代码,性能没有那么好。
多线程优化,自适应裁剪和编译器优化之类的优化分别使我们的速度提高了约 3 倍,3 倍和 1.2 倍。这就使我们达到了在树莓派上运行所需的 10 倍提速。
更多详细信息可以在 CribSense 存储库的 Software Architecture 上找到。
https://lukehsiao.github.io/CribSense/setup/sw-setup/#software-architecture-details
更多有关 Video Magnification 的信息,请点击 MIT 页面查看。
http://people.csail.mit.edu/mrub/vidmag/
硬件部分
连接摄像头
将摄像头附带的 6″ 软排线换成 12″ 的。
IR LED
CribSense 相对容易构建,并且项目所需组件也容易购买。如图所示,项目由五个主要的硬件构成,其中只有两个是定制的。下面将逐步介绍如何构建 IR LED 电路,先来介绍如何构建底盘。
这一部分你需要烙铁、电线、二极管、IR LED 和电阻器。如图所示构建电路。
为了在夜间提供充足的照明,我们使用了红外 LED,人眼不可看,但 NoIR 摄像头可见。与树莓派相比,IR LED 不会消耗很多功率,因此为方便,我们将 IR LED 保持打开状态。
在早期版本的树莓派中,针脚的最大电流输出为 50mA。
https://pinout.xyz/pinout/pin1_3v3_power
树莓派 B+ 将其增加到 500mA。但为简单起见,我们仅使用 5V 电源针脚,它可以提供高达 1.5A 的电流。
https://pinout.xyz/pinout/pin2_5v_power
根据测量,IR LED 的正向电压约为 1.7-1.9V。尽管 IR LED 可以吸收500mA 电流而不出现损坏,但我们还是将电流减小到 200mA 左右,以减少热量和总功耗。实验结果还表明,在输入电流为 200mA 的情况下,红外 LED 足够亮。为了桥接 5V 和 1.9V 之间的间隙,我们使用了三个 1N4001 二极管和一个与 IR LED 串联的 1 Ohm 的电阻。导线,二极管和电阻上的电压分别约降为 0.2V、0.9V(每一个)和 0.2V。因此,IR LED 上的电压为 5V-0.2V-(3 * 0.9V)-0.2V = 1.9V。LED 的散热量为 0.18W,电阻的散热量为 0.2W,均在其最大额定值之内。
为了更好与 3D 打印的外壳相匹配,我们使 IR LED 透镜从底座中伸出,并使 PCB 板与孔齐平。右下角的小光电二极管会挡住。如图所示,为了解决这个问题,我们将其拆焊并将其翻转到板子的另一侧。这个光电二极管不需要,因为我们希望 LED 一直亮着。只需将其换到另一侧,即可保持原始 LED 电路不变。
注意:焊接电线时,请确保电线至少 12″ 长,并可与树莓派 GPIO 上的针脚接头。
外壳
源文件包括:
外壳的 STL
https://github.com/lukehsiao/CribSense/blob/master/chassis/case.stl
外壳 机型
https://raw.githubusercontent.com/lukehsiao/CribSense/master/chassis/case.makerbot
盖子 STL
https://github.com/lukehsiao/CribSense/blob/master/chassis/cover.stl
盖子的机型
https://raw.githubusercontent.com/lukehsiao/CribSense/master/chassis/cover.makerbot
打印的最小尺寸为:9.9″(L)x 7.8″(W)x 5.9″(H)。你可在某宝打印外壳。最小打印分辨率为 0.015″。建议使用 PLA 打印外壳。
3D 打印的外壳可以容纳树莓派、摄像头和 LED。是否使用这个外壳可选,但这款外壳可以防止幼儿接触裸露的电子电路。因为每个婴儿床都不一样,因此外壳不包括安装支架。
关于支架有以下几个选项:电线扎带、3M 双锁、魔术贴以及胶带。
组装硬件
准备好所有硬件后,即可开始组装。在过程中建议使用热熔胶,速干且可易于移除后再使用。
1、将树莓派装入外壳。你需要稍微弯曲一下才能插入音频端口。安装到位后,请确保仍可以访问所有端口。
2、使用热熔胶将树莓派固定到位,然后将摄像头连接到树莓派。你也可以选择螺丝固定。
3、将 LED 和摄像头粘到前盖。将 NoIR 摄像头粘到摄像头孔中。确保摄像头紧贴并与外壳对齐。请不要使用太多胶水,否则你将无法将摄像头安装到主机壳中。给树莓派通电后,检查摄像头(例如raspistill -v
),确保其具有良好的视野。如果视角不佳,将重新放置。
4、将 IR LED 粘贴到盖子颈部的孔中。颈部与婴儿床侧面成 45°。在光线不足的情况下会产生更多阴影,需要增加图像的对比度,便于更容易检测运动。
5、如图所示,将 IR LED 电线连接到树莓派。
6、小心处理内部的电线,将所有组件安装到位后,使用热熔胶密封到位。
校准部分
有关配置参数的详细信息,请参见 CribSense 存储库文档。
https://lukehsiao.github.io/CribSense/setup/config/
也可观看视频校准 CribSense。
这是配置文件的示例:
[io] ; I/O configuration ; input = path_to_file ; Input file to use input_fps = 15 ; fps of input (40 max, 15 recommended if using camera) full_fps = 4.5 ; fps at which full frames can be processed crop_fps = 15 ; fps at which cropped frames can be processed camera = 0 ; Camera to use width = 640 ; Width of the input video height = 480 ; Height of the input video time_to_alarm = 10 ; How many seconds to wait with no motion before alarm. [cropping] ; Adaptive Cropping Settings crop = true ; Whether or not to crop frames_to_settle = 10 ; # frames to wait after reset before processing roi_update_interval = 800 ; # frames between recalculating ROI roi_window = 50 ; # frames to monitor before selecting ROI [motion] ; Motion Detection Settings erode_dim = 4 ; dimension of the erode kernel dilate_dim = 60 ; dimension of the dilate kernel diff_threshold = 8 ; abs difference needed before recognizing change duration = 1 ; # frames to maintain motion before flagging true pixel_threshold = 5 ; # pixels that must be different to flag as motion show_diff = false ; display the diff between 3 frames [magnification] ; Video Magnification Settings amplify = 25 ; The % amplification desired low-cutoff = 0.5 ; The low frequency of the bandpass. high-cutoff = 1.0 ; The high frequency of the bandpass. threshold = 50 ; The phase threshold as % of pi. show_magnification = false ; Show the output frames of each magnification [debug] print_times = false ; Print analysis times
算法的校准是一个反复的工作,没有确切的解决方案。你可以尝试各种值,并将它们与调试功能结合起来,以便找到最适合你的环境的参数组合。在开始校准之前,请确保将 show_diff 和 show_magnification 设置为 true。
原则上,增加放大率和 phase_threshold 值会增加应用于输入视频的放大倍数。你应该更改这些值,直到在视频帧中清楚地看到物体的运动为止。如果你看到伪影,在保持相同放大率的同时减小 phase_threshold 可能会有所帮助。
运动检测参数有助于补偿噪声。在检测运动区域时,使用 erode_dim 和 dilate_dim 来确定用于腐蚀和扩张运动的 OpenCV 内核的尺寸,以便首先消除噪声,然后将剩余的运动信号用于扩张以使运动区域明显。
https://docs.opencv.org/2.4/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html
如果你的婴儿床的对比度很高,则可能需要调整这些参数。在一般情况下,你需要设置更高的 erode_dim 高对比度,以及较低的 erode_dim 低对比度。
如果在 show_diff = true 的情况下运行 CribSense,会发现累加器输出的大部分为白色,或者视频的某些完全不相关的部分被检测为运动(例如,闪烁的灯),增加 erode_dim 直到视频的一部分仅对应婴儿的部分,大部分为白色。如图所示,侵蚀尺寸对于帧中的运动而言太小。
校准良好。
校准之后,请确保将 pixel_threshold 设置为一个值,以使“像素移动”仅报告像素移动的峰值,而不是所有峰值(你需要消除噪声)。理想情况下,你将在终端中看到类似这样的输出,存在一个与运动相对应的清晰的周期性模式:
[info] Pixel Movement: 0 [info] Motion Estimate: 1.219812 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 1.219812 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 1.219812 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 1.219812 Hz [info] Pixel Movement: 44 [info] Motion Estimate: 1.219812 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 1.219812 Hz [info] Pixel Movement: 161 [info] Motion Estimate: 1.219812 Hz [info] Pixel Movement: 121 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 86 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 97 [info] Motion Estimate: 0.841416 Hz [info] Pixel Movement: 74 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 60 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 48 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 38 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 29 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 28 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 22 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.839298 Hz [info] Pixel Movement: 0 [info] Motion Estimate: 0.839298 Hz
你的输出想这样:
[info] Pixel Movement: 921 [info] Motion Estimate: 1.352046 Hz [info] Pixel Movement: 736 [info] Motion Estimate: 1.352046 Hz [info] Pixel Movement: 666 [info] Motion Estimate: 1.352046 Hz [info] Pixel Movement: 663 [info] Motion Estimate: 1.352046 Hz [info] Pixel Movement: 1196 [info] Motion Estimate: 1.352046 Hz [info] Pixel Movement: 1235 [info] Motion Estimate: 1.352046 Hz [info] Pixel Movement: 1187 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 1115 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 959 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 744 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 611 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 468 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 371 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 307 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 270 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 234 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 197 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 179 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 164 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 239 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 733 [info] Motion Estimate: 1.456389 Hz [info] Pixel Movement: 686 [info] Motion Estimate: 1.229389 Hz [info] Pixel Movement: 667 [info] Motion Estimate: 1.229389 Hz [info] Pixel Movement: 607 [info] Motion Estimate: 1.229389 Hz [info] Pixel Movement: 544 [info] Motion Estimate: 1.229389 Hz [info] Pixel Movement: 499 [info] Motion Estimate: 1.229389 Hz [info] Pixel Movement: 434 [info] Motion Estimate: 1.229389 Hz [info] Pixel Movement: 396 [info] Motion Estimate: 1.229389 Hz [info] Pixel Movement: 375 [info] Motion Estimate: 1.229389 Hz [info] Pixel Movement: 389 [info] Motion Estimate: 1.229389 Hz [info] Pixel Movement: 305 [info] Motion Estimate: 1.312346 Hz [info] Pixel Movement: 269 [info] Motion Estimate: 1.312346 Hz [info] Pixel Movement: 1382 [info] Motion Estimate: 1.312346 Hz [info] Pixel Movement: 1086 [info] Motion Estimate: 1.312346 Hz [info] Pixel Movement: 1049 [info] Motion Estimate: 1.312346 Hz [info] Pixel Movement: 811 [info] Motion Estimate: 1.312346 Hz [info] Pixel Movement: 601 [info] Motion Estimate: 1.312346 Hz [info] Pixel Movement: 456 [info] Motion Estimate: 1.312346 Hz
调整 pixel_threshold 和 diff_threshold 直到只看到峰值,否则像素移动为 0。
安装示例
这是一段关于 CribSense 工作的演示。仪器安装在婴儿床的侧面。
将仪器安装到婴儿床时,需要优化婴儿和摄像头之间的距离。理想情况下,婴儿的胸部将不超过帧的 1/3。摄像头太远,得到的低分辨率的视频,画面放大后也没有内容。摄像头相机太近,容易造成婴儿跑出画面。如果婴儿“包裹”在毯子下,毯子和婴儿胸部之间接触有限,可能很难检测到运动。
你还需要考虑婴儿床周围的照明情况。如果你的婴儿床就在窗户旁边,当天气多云时或窗外物体移动时会形成的阴影或者需要改变光线值。照明环境始终如一效果最好。
在未来,软件会得到提升,从而使校准过程更加顺利。还可以添加其他功能,例如推送通知等。
故障排除
安装 CribSense 时,你可能会遇到一些常见问题。例如,在构建或运行程序时遇到问题,或听不到任何声音。你需要进行调整,当你进行改进时,请反应到我的 GitHub 库。
https://github.com/lukehsiao/CribSense
以下是我们收集的一些故障排除技巧。
1、没有闹钟响。
请检查的扬声器是否在工作。
你在 CribSense 闹钟之外是否播放了由树莓派发出的其他声音吗?
你的树莓派是否尝试通过 HDMI 而不是音频端口播放音频?检查“树莓派音频配置”页面,以确保你选择了正确的输出。
https://www.raspberrypi.org/documentation/configuration/audio-config.md
CribSense 软件是否检测到运动?如果 CribSense 在后台运行,请在终端中使用 journalctl -f 进行检查。
如果 CribSense 感应到很多运动,则可能需要校准 CribSense。
2、红外指示灯不工作。
当你查看红外线 LED 时,你能看到淡红色的环吗?LED 亮起时,应该可以看到。
检查连接的极性。如果 +5V 和 GND 接反,则将不起作用。
将 LED 连接到电压/电流限制为 5V/0.5A 的电源。通常,它在 5V 时应消耗 0.2A 的电流。如果不是,则你的 LED 可能故障。
3、即使没有婴儿,CribSense 仍在检测运动。
你是否正确校准 CribSense?
请记住,CribSense 只在寻找时像素值的变化。
画面内是否有阴影的移动?
是否有闪烁或灯光的变化?
CribSense 是否安装妥当(即如果有人经过它,它不会摇动)?
画面中是否还有其他运动源(镜面反射光等)?
4、即使有运动,CribSense也不会检测到运动。
你是否正确校准 CribSense?
摄像头上是否有其他东西?
是否从树莓派连接到摄像头?在终端中运行 raspistill -v 进行检查,打开树莓派上的摄像头几秒钟。
查看sudo systemctl status cribsense,可 CribSense 是否在运行?
查看婴儿是否在被“包裹”起来的毛毯下,导致无法检测到婴儿?如果毯子和婴儿之间存在较大的间隙,毯子可能挡住运动。
如果放大视频后,是否可以看到动画?
如果你调整低频和高频截止频率,是否能看到运动?
如果仅在弱光下发生这种情况,确定校准是否在弱光下工作吗?
5、CribSense无法建立。
你是否安装了所有依赖项软件?
6、不能运行 cribsense 的命令行。
在运行软件时 ./autogen.sh –prefix=/usr –sysconfdir=/etc –disable-debug 时是否存在偶然性输入错误?
cribsense 是否存在于 /usr/bin 中?
如果运行“which cribsense”,将提供什么路径?
via