计算图片中的物体的实际尺寸的一种方法

2024-08-25 23:08

本文主要是介绍计算图片中的物体的实际尺寸的一种方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

计算图片中的物体的实际尺寸的一种方法

标签: 图片物体尺寸测量地平线交比射影几何
  1630人阅读  评论(0)  收藏  举报
从一幅图像中无法测出物体的长度,因为缺乏参照物,但可以测出两个平行物体的长度比例。如果已知一个物体的实际大小(比如在图片中放上一枚1元硬币或者知道某个柜子有多高),那么就可以通过长度比和参照物的已知长度测出物体长度。具体方法见文献[1],因为需要一些矩阵运算和摄像头成像方面的推导,这里只大概说说原理。楼上诸位所述也是这种原理。


图像测量利用了摄像头成像也就是小孔成像的几个性质[2]:
第一,摄像头把平行的直线映射为图像上相交直线,笔直的铁轨在远处相交就是这个道理,这个交点被称为消隐点(vanish point)。可以认为平行空间直线在无穷远处相交,消隐点则是这一交点的像。所有水平的平行直线族都各自相交于无穷远处的一点,这些点构成无穷远直线,这条直线在图像上的像叫地平线。我们所居住的三维空间中存在三组相互垂直的直线(例如水平两组,x轴和y轴方向,竖直一组,z轴方向),所有x、y、z方向上的平行直线在一张图片上会分别相交于各自的一个消隐点。并且水平直线对应的两个消隐点如果连起来,连线就是地平线。测量的关键,就是要得到这些消隐点,因此有很多竖直线(如书架)或水平线(如地板砖)的图片就容易测量。

第二,摄像头把三维空间投影到二维的图像上,保持直线交比不变,交比是四个点两两“比例的比例”。所以如果在三维空间中的一条直线上有四个点,那么它们映射到图片上的四个点后,这四个点的交比不变。




文献[1]通过这些条件,给出了从图片上计算长度比的公式。通过示意图我们可以更加直观地看出它是如何工作的:


首先,假设我们已知蓝色小人Bob的身高,要求出红色小人John的身高,只需要知道两人的身高比值就可以:

我们用大写字母表示真实的坐标,随后用小写字母表示图片上的像素坐标。两人的身高比值BE/AF可以这么求:首先连接AB,然后过E点做AB的平行线交AF于点D,因为ABED是个矩形,所以要求的比值就等于AD/AF。然而,这种判断是在三维空间中做出的,当物体成像为图片,所有点的位置都会发生变化(不要问我圆头为什么会变成方头):

其中最显著的变化是平行线相交了,由此我们可以找到三个方向的消隐点,这可以通过对竖直和两组水平平行线求延长线获得:

注意我们把水平平行线对应的两个消隐点连接起来,得到了一条在(无穷)远处的直线,每个人都熟悉它,它就是地平线。地平线上所有的点都有一个性质:从其上一个点引出的所有直线都是相互水平平行的。


因此点D在图上的坐标d是这么求出的:
1. 画出地平线
2. 延长ab,交地平线于点c
3. 延长ce,交af,也就是John于点d
因为点c在无穷远处,所以cd和ca在空间中是平行直线,abed也就是上面说述真实空间中矩形ABED的像。
(转载者说明:如果cd也是水平面上一直线,那么cd和ca互相平行是正确的,但是本文中cd是不在水平面上的)
然而,知道了某些点在图像上的像,它们的实际长度比是无法直接从图上测得的,因为大家的深度不一样,这时就要利用成像前后一条直线上四个点交比不变的性质,考察红色小人John身上的三个点A、D、F以及其延长到无穷远处的点G,就可以得到(大写字母换成小写字母):
(AD/AF)/(GD/GF)=(ad/af)/(gd/gf)
因为已经求出了点d,等式右边所有的量都可以从图像上测出。等式左边的点G在真实空间是所有垂直直线的交点,这个点在无穷远,和无穷相比点F和点D的差异可以忽略不计,所以GD/GF=1,这样就得到最终结果:
AD/AF = (ad/af)/(gd/gf)

[1] Criminisi A, Reid I, Zisserman A. Single view metrology[J]. International Journal of Computer Vision, 2000, 40(2): 123-148.
[2] Hartley R, Zisserman A. Multiple view geometry in computer vision[M]. Cambridge university press, 2003.

这篇关于计算图片中的物体的实际尺寸的一种方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1106906

相关文章

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python

Apache Tomcat服务器版本号隐藏的几种方法

《ApacheTomcat服务器版本号隐藏的几种方法》本文主要介绍了ApacheTomcat服务器版本号隐藏的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1. 隐藏HTTP响应头中的Server信息编辑 server.XML 文件2. 修China编程改错误

Java中switch-case结构的使用方法举例详解

《Java中switch-case结构的使用方法举例详解》:本文主要介绍Java中switch-case结构使用的相关资料,switch-case结构是Java中处理多个分支条件的一种有效方式,它... 目录前言一、switch-case结构的基本语法二、使用示例三、注意事项四、总结前言对于Java初学者

使用Python实现大文件切片上传及断点续传的方法

《使用Python实现大文件切片上传及断点续传的方法》本文介绍了使用Python实现大文件切片上传及断点续传的方法,包括功能模块划分(获取上传文件接口状态、临时文件夹状态信息、切片上传、切片合并)、整... 目录概要整体架构流程技术细节获取上传文件状态接口获取临时文件夹状态信息接口切片上传功能文件合并功能小

Oracle Expdp按条件导出指定表数据的方法实例

《OracleExpdp按条件导出指定表数据的方法实例》:本文主要介绍Oracle的expdp数据泵方式导出特定机构和时间范围的数据,并通过parfile文件进行条件限制和配置,文中通过代码介绍... 目录1.场景描述 2.方案分析3.实验验证 3.1 parfile文件3.2 expdp命令导出4.总结

更改docker默认数据目录的方法步骤

《更改docker默认数据目录的方法步骤》本文主要介绍了更改docker默认数据目录的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1.查看docker是否存在并停止该服务2.挂载镜像并安装rsync便于备份3.取消挂载备份和迁

使用C#如何创建人名或其他物体随机分组

《使用C#如何创建人名或其他物体随机分组》文章描述了一个随机分配人员到多个团队的代码示例,包括将人员列表随机化并根据组数分配到不同组,最后按组号排序显示结果... 目录C#创建人名或其他物体随机分组此示例使用以下代码将人员分配到组代码首先将lstPeople ListBox总结C#创建人名或其他物体随机分组

JavaScript DOM操作与事件处理方法

《JavaScriptDOM操作与事件处理方法》本文通过一系列代码片段,详细介绍了如何使用JavaScript进行DOM操作、事件处理、属性操作、内容操作、尺寸和位置获取,以及实现简单的动画效果,涵... 目录前言1. 类名操作代码片段代码解析2. 属性操作代码片段代码解析3. 内容操作代码片段代码解析4.

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO