使用普通网络摄像头和低功率激光拍摄的图像计算距离

laser_range_finder的Python项目详细描述


#激光测距仪 使用普通网络摄像头和低功率激光拍摄的图像计算距离

#概述

此软件包实现了一个python类,该类计算给定相机拍摄的两幅图像与相机的距离,其中一幅图像包含平行于相机焦平面的激光线投影,另一幅图像不包含激光投影。

此方法与[此处]描述的方法非常相似(https://sites.google.com/site/toddanko/home/webcam_laser_ranger" rel="nofollow">https://sites.google.com/site/toddanko/home/webcam_laser_ranger),尽管它已扩展到应用于一条线而不是单点

#安装

建议通过PIP安装(最好是在VirtualEnv中):

< Buff行情> 安装激光测距仪

#用法

在你使用这门课之前,你需要校准你的相机。计算您的相机:

  • 垂直视野(度)
  • 水平视野(度)
  • 摄像机中心和激光中心之间的距离,单位为毫米
  • 弧度偏移

然后,在实例化类时传递这些值:

< Buff行情> 从激光测距仪进口激光测距仪 lrf=激光测距仪(垂直视野=50,水平视野=40,旋转角度=0.01,高度=30)

该包不知道如何捕获图像,但假设您可以将其作为文件名或pil图像实例提供:

< Buff行情> distances=lrf.get_distance(off_img='~/laser off.png',on_img='~/laser on.png')

get_distance()返回的值将是一个长度等于源图像像素宽度的列表,每个元素将是距相机的估计距离(以毫米为单位)。值为-1表示无法在相关列中进行可靠的距离测量。

如果您不需要每像素距离测量的特殊性,但只需要对图像中n个块中的距离进行更一般的估计,那么您可以将这些距离传递到函数压缩列表(lst,bins)

< Buff行情> 从激光测距仪导入压缩列表 距离=lrf.get_距离(off_img='~/laser off.png',on_img='~/laser on.png') 距离=压缩列表(距离,存储箱=10)

#方法论

该方法假设我们从两个图像开始,一个已知不包含激光线的参考图像a,和一个确定包含激光线但可能失真的图像b。我们可能只使用包含激光线的单个图像,但有一个负图像大大帮助我们去除噪声。因此,我们从以下示例图像开始:

< P>![示例图像a](docs/images/sample-a-0.jpg)![示例图像b](docs/images/sample-b-0.jpg)

请注意,这两幅图像的亮度差别很大。稍后,我们将通过找出两幅图像之间的差异来隔离激光线,但总亮度的这种差异会干扰这一点。因此,我们使用utils.normalize()来解决这个问题,给出:

< P>![示例图像a](docs/images/sample-a-1.jpg)![示例图像b](docs/images/sample-b-1.jpg)

由于这些图像是RGB,但激光是红色的,因此我们使用utils剥离蓝色和绿色通道,从而消除一些噪声。仅限于红色(),给出:

< P>![示例图像a](docs/images/sample-a-2.jpg)![示例图像b](docs/images/sample-b-2.jpg)

现在我们计算图像的差异。如果图像之间的唯一变化是激光线,则生成的图像应为完全黑色,激光显示为亮白色。实际上,仍然会有相当大的噪音,但差异会消除大部分噪音,这给了我们:

< P>![差分图像](docs/images/sample-diff-3.jpg)

最后,我们对激光线的位置做了一个"最佳猜测"。自从我们知道这条线大致是水平的,激光线现在应该对应于图像中最亮的像素,我们扫描每一列,找到像素最亮的行,得到:

< P>![行估计1](docs/images/sample-line-1.jpg)

请注意,估计值非常接近,但仍有一些噪声,主要是在图像的左侧,激光线被亚光黑色表面吸收。我们通过计算直线的平均值和标准偏差亮度来解决这个问题,忽略任何小于平均值-stddev的内容,得到:

< P>![行估计2](docs/images/sample-line-2.jpg)

这消除了很多噪音,但请注意图像左上角仍有一点噪音。在这个设置中,激光被放置在摄像机下方,这意味着直线永远不会出现在中间一行的上方。所以可以假设在中间行上方检测到的任何激光线像素都是噪声。这就是我们的最终图像,它几乎可以完美地检测激光投影:

< P>![行估计3](docs/images/sample-line-3.jpg)

然后,我们可以使用一点三角法将白色像素从中间一行的偏移量转换为激光投影的物理距离。

作为参考,本示例中使用的源图像由连接到覆盆子Pi 2的5Mp Noir相机和安装在相机22.5 mm处并直接由覆盆子Pi GPIO引脚控制的1MW 3V红色激光线二极管捕获。

#测试

运行测试:

< Buff行情> 毒性

或:

< Buff行情> py.test-s

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
具有泛型的对象的oop Java数组   爪哇丑陋的数字找到第1500名UVA在线评委   SpringJava。lang.IllegalStateException:自动连线批注至少需要一个参数   java为什么我的系统找不到我的属性文件?   java有没有办法让Maven同时构建1.5和1.6字节码JAR?   java通过Sailfin中的header进行操作   使用向量、距离和图形   如果提供的登录信息是错误的,为什么java控件不进入else部分和Toast?   java如何为电子商务安卓应用程序存储产品列表   java保存声音首选项Libgdx Android   java无法在测试单元中调用JpaRepository   java使用批处理更新Cassandra表中的选定列,而不将其他列值设为null   java如何在log4j2中的手动代码配置中向appender添加级别?   从ImageIO返回的java Null。读取(新的ByteArrayInputStream(bs));   java不确定如何防止此Arraylist处于可编辑状态   netbeans中的java更改清单(TrustedLibrary=true属性)   java无法使用RestTemplate和Spring数据REST发布具有关系的新实体