专栏名称: 程序员极客实验室
极客范聚焦极客主题,分享各种新、奇、酷的东西。
目录
相关文章推荐
Foodaily每日食品  ·  配角掀桌,从默默无闻到霸占C位:卖疯了的坚果 ... ·  2 天前  
艾格吃饱了  ·  有时候觉得上班也挺好的。。。 ·  4 天前  
每天学点做饭技巧  ·  可媲美大牌的平价冲牙器,360度全方位清洁口 ... ·  4 天前  
51好读  ›  专栏  ›  程序员极客实验室

激光扫描+3D建模,用树莓派自制建模仪

程序员极客实验室  · 公众号  ·  · 2021-01-14 11:50

正文

由于公众号文章的推送规则已经改成了不按照发布时间排序,所以为了大家能够准时收到我们的文章推送,请记得猛戳右下角的 「在看」 并点击公号主页右上角的“ ... ”将 程序员极客实验室 设为星标~这样就不会错过每一篇精彩的推送啦~


作者:mfx2
转自: 趣无尽



只需要将物体放入到一个盒子里,就可以得到它的 3D 模型数据,是不是很方便呢?

今天我们就用树莓派制作一台三维激光扫描建模仪。 能够将物体数字化为 .obj 网格文件,然后再使用 3D 打印来「复制」它。
项目通过线激光发射器和树莓派摄像头来实现计算机视觉数据采集。 激光定位的角度与激光成 45 度倾斜,同时在物体的垂直切片上投射出一条红线。
摄像头检测切片到中心的距离并给出网格切片。 物体在托盘上慢慢的旋转,通过不断的重复这个过程,扫描完成整个物体,十分的方便。

创作灵感
开始制作前,我做了一些基础研究。 发现许多 3D 扫描仪都使用旋转平台,然后使用各种不同的传感器来测量距中心的距离,建立旋转模型。 很多采用了与 Kinect 扫描仪类似的双摄像头。

我的项目是基于 Yscanner 扫描仪开发的,采用单摄像头。 它是一种低分辨率的激光扫描仪,项目简单、可行。

这种激光技术是激光相对于摄像机的偏移量来进行照射的,测量到中心的距离,如图你可以清晰的看见那条线。

视频演示:


材料清单

  • 树莓派 × 1

  • 树莓派摄像头V2 × 1

  • LED × 1

  • 电阻 × 1

  • 电线 × 若干

  • 3D 打印灯丝 × 若干

  • 木板 × 1

  • M3 硬件 × 若干

  • 步进电机 × 1

  • 线激光发射器 × 1

  • LN298 步进电机驱动器 × 1

  • 金属按钮 × 1

  • 烙铁 × 1

  • 激光切割机 × 1

  • 3D 打印机 × 1

  • 螺丝刀 × 1

  • 钳子 × 1


设计原理

该项目核心组件就是能够垂直投射在物体上的线激光发射器。 它通过树莓派摄像头获取投影,对其进行透视校正,然后在图像处理前进行过滤。 在图像处理中,收集线的每个部分到物体中心的距离。

在径向坐标中,此图片将同时产生 r 和 z 的分量,然后通过将物品的旋转得到新的切片来实 现三维效果。

为了达到设计效果,我使用树莓 派作为中央计算 单元。

1、将树莓派与步进电机和电机驱动器连接。 由外部 5V 电源供电并由树莓派的 GPIO 引脚控制。

2、将线激光发射器连接到树莓派的 3.3V 线上,将树莓派摄像头连接到摄像头的输入上。

3、安装一个简单的下拉按钮和一个用来显示状态的 LED 来向用户展示系统所处的状态。

需要注意的地方:
1、将电子设备安装到由 T 型槽和 M3 硬件搭建的激光切割盒中。

2、将电子设备隐藏在底部隔间中,盖子上放置旋转托盘,便于放置物品。 这个盖子可以最大程度地减少遗漏到系统中的光源,而这些光在最终扫描中会产生噪声。

3D 打印外壳


使用 Autodesk Fusion 360 设计出 3D 外壳模型。 外壳设计很简单,一个盒子和带活页的盖子(都是 3D 打印而成)。

设备主要分为两层: 电子设备层和主体层,两层之间有可穿电线的孔。


使用 Epilog Zing 40 W 激光切割机切割。 如图所示,外壳主要由主体层、电子设备层、两个盖子部件、前面板块、后面板块以及两个侧面板块组成。

在主体层上,有三个切口: 一个用于安装步进电机,一个用于放置激光器的电线,另一个用于放置树莓派摄像头的软排线。


底座有用于固定树莓派、面包板和电机驱动器的安装孔,以及用于放入步进电机的较大切口。
外壳的盖子可以简单地卡在一起,形成一个类似三角形状的盖子,合页宽度为侧板孔的直径长。

背面板块和其中一个侧面板块在侧面都有插槽,因此可以轻松访问树莓派的端口(HDMI、USB、以太网以及电源)。 前面板块是一个简单的部分,手动钻孔用以安装按钮和 LED。

所有的零件由 M3 硬件、 T 型接头和插槽固定在一起。 组拼时可以使用 M3 螺钉将零件固定在一起。

我使用激光切割机来处理大部分组件是因为它具有速度和便捷性的优势。 虽然 3D 的几何形状在裁纸器上却很难创建。

第一个组件是线激光发射器支架。 该组件将被安装在与摄像头视线成 45 度角的主体层上,有一个孔,可将激光器固定到位。

另外还 一个马达支架,因为马达的轴太长了。 支架产生的摩擦力不妨碍激光切割的组件,并降低了电机连接的平面,从而使旋转平台与主体层齐平。

电子部分


该项目的硬件接线部分非常简单,只需要将电机、按钮、LED、激光以及摄像头连接到树莓派。

1、将电阻与每个引脚串联,以保护引脚。 GPIO 的一个引脚专用于控制 LED,当设备准备好后,LED 会亮起,当设备运行时,它会使用 PWM 进行脉冲控制。

2、将 GPIO 的另一个引脚连接到上拉按钮上,未按下按钮时为高电平,按下按钮时为低电平。

3、GPIO 的四个引脚用来驱动步进电机。

步进电机
由于项目中的电动机只需要一定程度上的步进而无需控制速度,因此选用了一款很简单的步进电动机驱动器(L298N)。 该驱动器只需将控制线升压以馈入电动机的输入即可。

为了了解步进电机如何在非常低的水平上操作,我参考了 L298N 数据表和 Arduino 库。 步进电动机的磁芯带有可交替极性的中心轴。

使用四根线缠绕去控制两个电磁体,这两个电磁体分别为电动机中的每个相对的轴供电。 通过切换轴的极性,就可以推动步进器。

了解完步进电机的工作原理,就能够更容易地控制步进电机。 由于步进电机的最大电流约为 0.8A,超出了树莓派的供电能力,我最后选用 5V 电源而不是树莓派为其供电。

软件部分

该项目的软件部分由四个方面组成: 图像处理,电机控制,网格创建和嵌入式功能。


1、如图所示,随着系统启动 .bashrc 自动登录到树莓派并开始运行 python 代码。 系统点亮状态灯,告知用户它已正确启动,并等待按下按钮。

2、用户可以放置要扫描的物品并合上盖子。 按下按钮后,LED 会闪烁,告知用户设备正在工作。

设备将在图像处理和电机控制之间循环,直到旋转完成收集物品的所有数据为止。 最后,创建网格并通过电子邮件将文件发送到预选的电子邮箱。

3、设备可以重新启动循环,只需按一下按钮 可以执行另一次扫描。

图像处理
第一步是处理获取的图像,以便将存储在图像中的信息提取为可用于创建空间点阵列的形式。

首先拍摄了平台上物体的照片,以及由激光照射到盒子背面并分散后产生的所有背景噪声。

该图片的原始形式存在两个主要问题。 一是拍摄物体的角度较高,二是背景噪音很大。 视角的问题是第一个要考虑的,因为按原样使用照片将无法确定的物体一致高度。

如图所示,倒置的 “L” 形的高度是一致的。 但是,由于一侧比另一侧长,它们在最靠近观察者的边缘处的高度似乎不同。

为了解决此问题,我必须将图像中的工作空间从以前的梯形形状转换为矩形。 为此,我使用了链接中提供的代码。

https://www.pyimagesearch.com/2014/08/25/4-point-opencv-getperspective-transform-example/

当给定一个图像和四个点时,该代码将在四个点之间裁剪图像并补偿转换裁剪后的图像。 使用四个点来创建矩形,而不是之前的梯形形状。


下一个需要解决的问题是外部光形成的背景噪声和激光本身反射的光。 我使用 OpenCV 的 inRange() 函数过滤光。 我将阈值设置为仅在特定水平上拾取红光。

为了获得正确的值,从较大的阈值开始,不断提高阈值水平,直到唯一被拾取的光是来自扫描物体上的激光。


获得此图像后,我发现每行中最亮的像素是每行的一个像素线,该线与激光线的最左侧相接。 最后,将每个像素转换为 3D 空间中的顶点并存储在数组中,如网格创建部分所述。

电机控制
在成功处理单个图像以获取物体的切片之后,我还需要旋转物体获得不同角度的新照片。 为此要控制好扫描物体平台下的步进电机。

我通过创建一个变量来跟踪电机的状态和细分控制四个电机的输入,这些是实现步进机功能的基础。

网格创建
要从所有处理的图像创建网格,我必须首先将处理的图像中的每个白色像素转换为 3D 空间中的顶点。 我要收集具有圆柱对称性的单个对象切片,所以要收集圆柱的坐标。

图片的高度可以用 z 轴表示,到旋转台中心的距离可以用 R 轴表示,步进电机的旋转可以用 theta 轴表示。 由于我将数据存储在圆柱坐标中,因此必须将每个顶点转换为笛卡尔坐标。

顶点创建好后,将它们存储在一个列表中。 然后再将所述列表存储在另一个列表中,该列表包含为获取的每个图像创建的顶点列表。 处理完所有图像并将其转换为顶点后,在最终网格中显示顶点。

其中,最好包含顶部顶点和底部顶点,然后根据分辨率,我选择了均匀分布的顶点数以用于每个图像。 因为并非所有顶点列表的长度都相同,所以我不得不通过找到顶点数量最少的列表并将所有其他列表中的顶点移除,直到它们均等为止。

创建顶点列表后就可以创建网格。 我使用 .obj 文件标准设置网格格式,因为它很简单并且支持 3D 打印。

嵌入式功能
当设备正常运行后,我通过添加完整的嵌入式功能对其进行了完善。 这意味着移除键盘,鼠标和显示器,处理完成后以无线方式将 .obj 文件发送过去。

1、将 .bashrc 代码更改为自动登录并在启动时启动 python 主程序。 执行 sudo raspi-config 命令,设置 “Console Autologin”,并将 “sudo python /home/pi/finalProject/FINAL.py” 行添加到 /home/pi/.bashrc。

2、添加一个按钮和 LED 状态显示,用于用户输入和输出。 按钮将会告知用户设备何时开始扫描,LED 将告诉用户机器的状态。

如果 LED 点亮,则表明设备已准备好开始扫描。 如果 LED 闪烁,则表明设备当前正在扫描。 如果 LED 报错,则表明软件错误,要求重启系统。

最后,我通过电子邮件向设备发送 .obj 文件。 使用 smtplib 和 email 库来完成。 这种无线的发送方式很方便,可以将生成的文件传递给用户也可以在不同的平台上访问。

将所有的组件合在一起


完成以上步骤后,现在可以将组件组合 一起。

1、组装外壳箱体。
2、将照相机和激光安装到盒子里。
3、安装其他电子设备。







请到「今天看啥」查看全文