opencv获得图片的像素宽度_使用OpenCV实现摄像头测距

a706ac74594d34c301727214af6b5362.png

原文链接:

Find distance from camera to object using Python and OpenCV​www.pyimagesearch.com
7b06fe0ead022bcadad363ce64d0ec60.png

摄像头测距就是计算照片中的目标物体到相机的距离。可以使用相似三角形(triangle similarity)方法实现,或者使用更复杂但更准确的相机模型的内参来实现这个功能。

使用相似三角形计算物体到相机的距离

假设物体的宽度为 W,将其放到离相机距离为 D 的位置,然后对物体进行拍照。在照片上量出物体的像素宽度 P,于是可以得出计算相机焦距 F 的公式:

比如我在相机前 24 英寸距离(D=24 inches)的位置横着放了一张 8.5 x 11 英寸(W=11 inches)的纸,拍照后通过图像处理得出照片上纸的像素宽度 P=248 pixels。

所以焦距 F 等于:

此时移动相机离物体更近或者更远,我们可以应用相似三角形得到计算物体到相机的距离的公式:

原理大概就是这样,接下来使用 OpenCV 来实现。

获取目标轮廓

# import the necessary packages
from imutils import paths
import numpy as np
import imutils
import cv2def find_marker(image):# convert the image to grayscale, blur it, and detect edgesgray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)gray = cv2.GaussianBlur(gray, (5, 5), 0)edged = cv2.Canny(gray, 35, 125)# find the contours in the edged image and keep the largest one;# we'll assume that this is our piece of paper in the imagecnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)c = max(cnts, key = cv2.contourArea)# compute the bounding box of the of the paper region and return itreturn cv2.minAreaRect(c)

定义一个 find_marker 函数,接收一个参数 iamge,用来找到要计算距离的物体。

这里我们用一张 8.5 x 11 英寸的纸作为目标物体。

第一个任务是在图片中找到目标物体。

下面这三行是先将图片转换为灰度图,并进行轻微模糊处理以去除高频噪声,然后进行边缘检测。

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 35, 125)

做了这几步后图片看起来是这样的:

0369cf161231a65cf916f1cf6852bc4a.png


现在已经可以清晰地看到这张纸的边缘,接下来需要做的是找出这张纸的轮廓。

cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key = cv2.contourArea)

cv2.findContours 函数找到图片中的众多轮廓,然后获取其中面积最大的轮廓,并假设这是目标物体的轮廓。

这种假设只适用于我们这个场景,在实际使用时,在图片中找出目标物体的方法与应用场景有很大关系。

我们这个场景用简单的边缘检测并找出最大的轮廓就可以了。当然为了使程序更具有鲁棒性,也可以用轮廓近似,并剔除不是四个点的轮廓(纸张是一个有四个点的矩形),然后再找出面积最大,具有四个点的轮廓。

注意: 关于这个方法,详情可以查看这篇文章,用于构建一个移动文本扫描工具。

我们也可以根据颜色特征在图片中找到目标物体,因为目标物体和背景的颜色有着很明显的不同。还可以应用关键点检测(keypoint detection),局部不变性描述子(local invariant descriptors)和关键点匹配(keypoint matching)来寻找目标。

但是这些方法不在本文的讨论范围内,而且高度依赖具体场景。

我们现在得到目标物体的轮廓了,find_marker 函数最后返回的是包含轮廓 (x, y) 坐标、像素长度和像素宽度的边框,

计算距离

接下来该使用相似三角形计算目标到相机的距离。

def distance_to_camera(knownWidth, focalLength, perWidth):# compute and return the distance from the maker to the camerareturn (knownWidth * focalLength) / perWidth

distance_to_camera 函数传入目标的实际宽度,计算得到的焦距和图片上目标的像素宽度,就可以通过相似三角形公式计算目标到相机的距离了。

下面是调用 distance_to_camera 函数之前的准备:

# initialize the known distance from the camera to the object, which
# in this case is 24 inches
KNOWN_DISTANCE = 24.0# initialize the known object width, which in this case, the piece of
# paper is 12 inches wide
KNOWN_WIDTH = 11.0# load the furst image that contains an object that is KNOWN TO BE 2 feet
# from our camera, then find the paper marker in the image, and initialize
# the focal length
image = cv2.imread("images/2ft.jpg")
marker = find_marker(image)
focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH

首先是测量目标物体的宽度,和目标物体到相机的距离,并根据上面介绍的方法计算相机的焦距。

其实这些并不是真正的摄像机标定。真正的摄像机标定包括摄像机的内参,相关知识可以可以查看这里。

使用 cv2.imread 函数从磁盘加载图片,然后通过 find_marker 函数得到图片中目标物体的坐标和长宽信息,最后根据相似三角形计算出相机的焦距。

现在有了相机的焦距,就可以计算目标物体到相机的距离了。

# loop over the images
for imagePath in sorted(paths.list_images("images")):# load the image, find the marker in the image, then compute the# distance to the marker from the cameraimage = cv2.imread(imagePath)marker = find_marker(image)inches = distance_to_camera(KNOWN_WIDTH, focalLength, marker[1][0])# draw a bounding box around the image and display itbox = cv2.cv.BoxPoints(marker) if imutils.is_cv2() else cv2.boxPoints(marker)box = np.int0(box)cv2.drawContours(image, [box], -1, (0, 255, 0), 2)cv2.putText(image, "%.2fft" % (inches / 12),(image.shape[1] - 200, image.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX,2.0, (0, 255, 0), 3)cv2.imshow("image", image)cv2.waitKey(0)

使用 for 循环遍历每个图片,计算每张图片中目标对象到相机的距离。

在结果中,我们根据得到的轮廓信息将方框画了出来,并显示出了距离。

下面是得到的几个结果图:

774b204de586a03ddcb5dcd7bf21e828.png

1c2e37e74dfcd96fbb90dda6459753e4.png

总结

通过这篇文章,我们学会了使用相似三角形计算图片中一个已知物体到相机的距离。

需要先测量出目标物体的实际宽度和目标物体到相机的距离,然后使用图像处理的方法自动计算图片中目标物体的像素宽度,并使用相似三角形计算出相机的焦距。

根据相机的焦距就可以计算图片中的目标物体到相机的距离。

zxdefying/OpenCV_project​github.com
88518f12fcb9bfb71818fc0161f7dc03.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/534656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ios下js复制到粘贴板_EXCEL被你忽视的粘贴板-11

这一节我们来聊聊粘贴板的用途,什么?你居然没用过粘贴板?平时只是ctrlc,然后ctrlv,好吧,那我们看看粘贴板到底能干些啥。1、提取区域内的内容有时我们选择一块区域发给同事,但当他需要编辑时发现居然是图片…

ros构建机器人运动学模型_ROS入门学习之八机器人综合应用

1.ROS机器人实例介绍(PR2,Turtlebot,HRMRP,Kungfu Arm)1).PR2:造就了ROS的机器人平台,完全基于ROS开发,功能丰富、强大2).Turtlebot:ROS社区中最流行的高性价比机器人平台,前后工发布三代3).Universal Robot:工业领域的协作机器人定义者4).HR…

微人事项目实战的数据库脚本_EMP微前端实战之cocos2d线上项目

团队原文:efoxTeam/emp​github.com一.背景目前cocos2d游戏最主要的开发方式是通过官方提供的GUI图形界面工具——creator,通过 creator 开发者无需关注构建本身,只需通过界面操作即可对游戏代码进行构建打包。但是这样也存在着以下几个问题&…

线粒体和叶绿体的基因组特点_如何组装植物叶绿体基因组

可能出现的问题:*个人电脑上遇到不能collect memery的情况,是电脑内存较少,建议分成用2G左右的数据进行组装。* Seed.fasta #用于起始组装的种子序列,NOVOPlasty安装软件目录下有这个文件,就叫这个名字,作者…

f3arra1n3.4.1版本_Sysmon v11.1新版本功能测试报告

一、概述根据微软文档的介绍,Sysmon v11新增了监控文件删除的功能,并支持对删除的文件进行存储备份,极大提高了主机威胁检测的能力。同时增加禁用反向DNS查询的功能,可以有效降低噪音数据。Sysmon从v10.0到目前的v11.1共经历了5个…

maya导出fbx没动画_Maya学习方法总结

关注我,一起来了解建模吧!今天小编就来总结一下Maya学习过程中遇到的困难和解决方法,我相信有一些应该也是普遍性问题,注意:小编说的版本是Maya2018。(1)一次性删除所有帧的方法import的文件如果…

dev 中 gridcontrol1 滚动条重绘_浏览器的重绘和回流(Repaint amp; Reflow)

参考文献:https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction?hlzh-cn​developers.google.com你真的了解回流和重绘吗 Issue #4 chenjigeng/blog​github.com前言:重绘:由于…

矿井通风计算c语言_矿井通风机主要参数的含义

矿井通风机的作用就是把地面新鲜空气送到井下,供工人呼吸,同时把有害气体从井下排出,使有害气体的浓度降到对人体无害的程度,在现代化煤矿中称通风机为“矿井的肺脏”,可见其重要性。风机的参数是风机选型的唯一依据&a…

行健设计_行健要闻|“第四届‘天行健创新创业设计大赛”培训班成功举办

10月9日下午,由院团委主办、商学部承办第四届“天行健”创新创业设计大赛动员大会暨首场培训讲座在教学楼4-103室成功启动。院团委副书记唐典巧参加动员会,并颁发了第九届“挑战杯”广西大学生课外学术科技作品竞赛荣誉证书,动员会由商学部辅…

ip地址转换pta题目_PTA「实验2-3-5 输出华氏-摄氏温度转换表」

PTA是浙江大学设计类实验辅助教学平台。题目描述输入2个正整数lower和upper(lower≤upper≤100),请输出一张取值范围为[lower,upper]、且每次增加2华氏度的华氏-摄氏温度转换表。温度转换的计算公式:C5(F−32)/9&#…

语言爬虫字段为空_我为什么建议前端将Python 作为第二语言?

前言本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。作者: 前端劝退师PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http://note.youdao.com/noteshare?id3054c…

5 获取当前访问的控制名称_LabVIEW编程技巧:网络通信中如何获取计算机名称、IP地址等信息...

问题引出在网络通讯编程中,经常需要获取当前主机的名称、IP地址等信息,在LabVIEW中如何获取这些信息呢?下面以本机为例进行说明,先看一下本机的信息。在Windows系统中打开控制台程序,输入“ipconfig /all”指令&#x…

postman生成python代码_别再用手敲了,这个工具可以自动生成python爬虫代码

我们在写爬虫代码时,常常需要各种分析调试,而且每次直接用代码调试都很麻烦所以今天给大家分享一个工具,不仅能方便模拟发送各种http请求,还能轻松调试,最重要的是,可以将调试最终结果自动转换成爬虫代码&a…

电工结业试卷_电工技术基础结业考试试卷

电工技术基础结业考试试卷适用年级2016级秋6班电子、计算机专业班级 姓名 学号一、 判断题(每题2分,共30分)1、 电位越高则电压越大。2、万用表的电压、电路及电阻档的刻度都是均匀的。3、 在任何情况下,电压源和电流源之间总是可以等效变换的。 4、 电容…

表格里面怎么打多个√_Excel怎样在表格里打√?

我们做表的时候有时会遇到输入对或错的情况。Excel表格里面输入√和,普通的方法是直接插入特殊符号来进行对勾的输入。这样输入起来1个2个还可以接受,但是如果频繁输入,那我们得想想简单方法。比如我们直接在excel单元格里面输入1显示√&…

@value 默认值为null_JAVA8之妙用Optional解决判断Null为空的问题

引言在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException.假设我们有两个类,他们的UML类图如下图所示在这种情况下,有如下代码user.getAddress().getProvince();这种写法,…

mysql百万数据根据索引查询_mysql创建多列索引查询百万表数据的性能优化经验分享...

最近发现最代码网站中的收到的评论,提到我的,心情被赞的查询异常缓慢,通过nginx日志发现响应时间快的在5s,慢的有13s,终于忍无可忍花时间来解决了。执行explain之后的截图如下:可以看到possible_keys中有很…

php用到的mysql语句_PHP中常用到的一些MySQL语句_php

在php开发中,经常会使用到mysql语句,下面就为您列举了一些经常使用的MySQL语句,希望对您平时的学习和开发工作能起到些许的作用。MySQL语句显示数据库或表:show databases;//然后可以use database_name;show tables;MySQL语句更改表名:alter …

mysql执行计划性能_MySQL SQL性能分析Explain执行计划

一. 执行计划返回信息详解①. 执行计划所含字段输出列含义id查询标识select_type查询类型table查询涉及的表partitions匹配到的分区信息type连接类型possible_keys可能选择的索引key实际使用的索引key_len实际使用的索引的长度ref和索引进行比较的列rows需要被检索的大致行数fi…

mysql定时作业_mysql 让一个存储过程定时作业的代码(转)

1、在mysql 中建立一个数据库 test1语句:create database test12、创建表examinfocreate table examinfo(id int auto_increment not null,endtime datetime,primary key(id));3 插入数据:insert into examinfo values(‘1‘,‘2011-4-23 23:26:50‘);4 …