【python】OpenCV—findContours(4.5)

在这里插入图片描述

文章目录

  • 1、功能描述
  • 2、原理分析
  • 3、代码实现
  • 4、效果展示
  • 5、完整代码
  • 6、参考

1、功能描述

输入图片,计算出图片中的目标到相机间的距离

在这里插入图片描述

2、原理分析

用最简单的三角形相似性

在这里插入图片描述

已知参数,物体的宽度 W W W,物体到相机的距离 D D D,物体的宽在画面中的像素数 P P P,可以求出相机的焦距 F F F

F = P × D W F = \frac{P \times D}{W} F=WP×D

后续移动物体到不同的距离, W W W 已知, F F F 已知,通过 P P P 即可计算物体到相机间的距离 D D D

D = F × W P D = \frac{F \times W}{ P} D=PF×W

该方法缺点,物体需正对镜头,不然角度产生的物体形变会影响测量精度

可以利用标定求出相机参数,这样应用的鲁棒性会更高

3、代码实现

# import the necessary packages
from imutils import paths
import numpy as np
import imutils
import cv2# 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.png")
marker = find_marker(image)
focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH

导入必要的库函数,配置好 KNOWN_DISTANCE D,KNOWN_WIDTH W,读入图片,通过找到画面中的物体,求出来 P,计算 focalLength F

计算 P 是通过 find_marker 函数实现的

def find_marker(image):# convert the image to grayscale, blur it, and detect edgesgray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# cv2.imwrite("gray.jpg", gray)gray = cv2.GaussianBlur(gray, (5, 5), 0)# cv2.imwrite("gray-blur.jpg", gray)edged = cv2.Canny(gray, 35, 125)# cv2.imwrite("edged.jpg", edged)# 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 = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)# cnts = imutils.grab_contours(cnts)# img_copy = image.copy()# cv2.drawContours(img_copy, cnts, -1, (0,255,0))# cv2.imwrite("draw_edged.jpg", img_copy)c = max(cnts, key=cv2.contourArea)# compute the bounding box of the of the paper region and return itreturn cv2.minAreaRect(c)

输入图片,灰度化,高斯模糊,Canny 算子进行边缘检测,findContours 找出潜在轮廓,求面积最大的轮廓max(cnts, key=cv2.contourArea),求最大面积轮廓的最小外接矩阵

为什么要通过求最大面积轮廓的最小外接矩阵来定位到画面中的物品呢?这里比较灵活,可以尝试其他任何方法,核心目的是找出画面中物体的宽,只是正好样例图片可以

现在开始测试其他距离的效果

# 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.BoxPoints(marker) if imutils.is_cv2() else cv2.boxPoints(marker)box = np.intp(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)

遍历图片,求最大面积轮廓的最小外接矩阵,调用 distance_to_camera,求实际距离

绘制最大轮廓的最小外接矩阵,注释上距离

这里 12 表示下面的转换关系,foot 和 inches

在这里插入图片描述

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

根据 W、F 和 P 来求 D

4、效果展示

输入图片

在这里插入图片描述

灰度化后的结果

在这里插入图片描述

高斯模糊
在这里插入图片描述

Canny 算子计算边缘

在这里插入图片描述

找出画面中所有的轮廓

在这里插入图片描述

找出轮廓,获取到 P,结合已知的 W 和 D,求出 F

在这里插入图片描述

换一个距离,测试一下算法,计算得到 P,根据已知的 W 和 F,求出 D

在这里插入图片描述

再换一个距离,测试一下算法,计算得到 P,根据已知的 W 和 F,求出 D

在这里插入图片描述

5、完整代码

# USAGE
# python distance_to_camera.py# 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)# cv2.imwrite("gray.jpg", gray)gray = cv2.GaussianBlur(gray, (5, 5), 0)# cv2.imwrite("gray-blur.jpg", gray)edged = cv2.Canny(gray, 35, 125)# cv2.imwrite("edged.jpg", edged)# 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 = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)# cnts = imutils.grab_contours(cnts)# img_copy = image.copy()# cv2.drawContours(img_copy, cnts, -1, (0,255,0))# cv2.imwrite("draw_edged.jpg", img_copy)c = max(cnts, key=cv2.contourArea)# compute the bounding box of the of the paper region and return itreturn cv2.minAreaRect(c)def distance_to_camera(knownWidth, focalLength, perWidth):# compute and return the distance from the maker to the camerareturn (knownWidth * focalLength) / perWidth# 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.png")
marker = find_marker(image)
focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH# 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.BoxPoints(marker) if imutils.is_cv2() else cv2.boxPoints(marker)box = np.intp(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)

6、参考

  • 使用Python和OpenCV查找相机到物体/标记物的距离(1)
  • https://pyimagesearch.com/2015/01/19/find-distance-camera-objectmarker-using-python-opencv/
  • 【python】OpenCV—findContours(4.1)
  • 【python】OpenCV—findContours(4.2)
  • 【python】OpenCV—findContours(4.3)
  • 【python】OpenCV—findContours(4.4)

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

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

相关文章

【华为HCIP实战课程二十八】中间到中间系统协议IS-IS邻居关系排错,网络工程师

一、ISIS邻居关系条件 1、同一层次(比如Level-2路由器不能和Level-1路由器形成邻居关系) 2、同一区域(L1必须同一区域) 3、同一网段 R1和R2之间分别配置如下IP地址和掩码: R1 的接口S1/0/0掩码为/24 R2的接口S1/0/0配置成掩码/28: 此时R1和R2依然可以建立ISIS邻居关系…

文件操作和 IO(一):文件基础知识 文件系统操作 => File类

目录 1. 什么是文件 1.1 概念 1.2 硬盘, 内存, 寄存器之间的区别 1.3 机械硬盘和固态硬盘 2. 文件路径 2.1 绝对路径 2.2 相对路径 3. 文件分类 4. File 类 4.1 属性 4.2 构造方法 4.3 方法 1. 什么是文件 1.1 概念 狭义上的文件: 保存在硬盘上的文件广义的上的文…

Flutter Color 大调整,需适配迁移,颜色不再是 0-255,而是 0-1.0,支持更大色域

在之前的 3.10 里, Flutter 的 Impeller 在 iOS 上支持了 P3 广色域图像渲染,但是当时也仅仅是当具有广色域图像或渐变时,Impeller 才会在 iOS 上显示 P3 的广色域的颜色,而如果你使用的是 Color API,会发现使用的还是…

web自动化测试平台开发之核心执行器

web自动化测试平台开发之核心执行器 一、如何从自动化框架到核心执行器二、核心执行器框架逻辑梳理三、核心执行器利用命令驱动执行 一、如何从自动化框架到核心执行器 脚本:底层用了三个内容:pythonpytestselenium,线性脚本,只是单纯的把功能测试用例转…

Rust 力扣 - 2090. 半径为 k 的子数组平均值

文章目录 题目描述题解思路题解代码题解链接 题目描述 题解思路 半径为 k 的子数组平均值 等价于 子数组长度为2 * k 1的总和 除于 2 * k 1 我们遍历长度为2 * k 1的窗口,我们只需要记录窗口内的平均值即可 题解代码 impl Solution {pub fn get_averages(num…

直接内存、死锁、方法句柄

直接内存 1. 不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域 2. 直接内存是在Java堆外、直接向系统申请的内存区间 3. 来源于NIO,通过存在堆中的DirectByteBuffer操作Native内存 4. 通常,访问直接内存的速度会优于Java堆&am…

C++《list》

在本篇当中我们将学习STL中的list,在此list就是我们之前在数据结构学习过的链表,在本篇中我们要来了解list当中的成员函数该如何使用,由于list各个函数的接口和之前学习过的vector类型,因此在学习list的使用就较为轻松。在lis篇章…

【牛客刷题实战】二叉树遍历

大家好,我是小卡皮巴拉 文章目录 目录 牛客题目: 二叉树遍历 题目描述 输入描述: 输出描述: 示例1 解题思路 问题理解 算法选择 具体思路 解题要点 完整代码(C语言) 兄弟们共勉 !&…

vmvare启动freebsd操作系统密码忘记了怎么办?

本章教程,主要介绍,通过vmvare安装的freebsd操作系统,密码忘记了,如何重置密码。 一、重启虚拟机 在重启过程中,按键盘中是数字2,进入单用户模式。 二、进入到shell界面 在出现“Enter full pathname of shell or RETURN for /bin/sh:”直接按回车键。 三、输入命令 mou…

【设计模式系列】代理模式(八)

一、什么是代理模式 代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理模式在不直接访问实际对象的情况下,提供了对目标对象的间接访问。通过引入一个代理对象来间接操作实际对…

WPS查询函数VLOOKUP,匹配寻找值自动带入值

想实现在下表输入物料名称后,把上表中的单位自动带入 那就要用到VLOOKUP函数,获取第2个表第1列的值后去第1个表的第1列匹配,匹配到后得到行数值,把第1个表的第2列赋值给第2个表的第2列。 Vlookup函数参数为Vlookup(查找值&#…

sqoop问题汇总记录

此篇博客仅记录在使用sqoop时遇到的各种问题。持续更新,有问题评论区一起探讨,写得有不足之处见谅。 Oracle_to_hive 1. main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTr…

简单说明vuex

vuex 知识结构配置调用 知识结构 vue用于管理公共数据的仓库 配置 state:所有公共数据的初始状态(初始值) export default {state: {count: 0,} };mutations:修改state内容的方法(必须为同步方法) export …

分类算法——决策树 详解

决策树的底层原理 决策树是一种常用的分类和回归算法,其基本原理是通过一系列的简单决策,将数据集划分为多个子集,从而实现分类。决策树的核心思想是通过树形结构表示决策过程,节点代表特征,边代表决策,叶子…

Nature Electronics 用于语音识别的液体声传感器,基于悬浮在载液的钕-铁-硼磁性纳米颗粒

近年来,工程师们开发了一系列越来越复杂的传感器,用于机器人、便携式、可穿戴甚至植入式监测。然后,可以使用最先进的机器学习来分析这些传感器收集的数据,使设备能够识别音频中的特定声音、图像中的对象或其他信息。加州大学洛杉…

NVR批量管理软件/平台EasyNVR多个NVR同时管理支持视频投放在电视墙上

在当今智能化、数字化的时代,视频监控已经成为各行各业不可或缺的一部分,无论是公共安全、交通管理、企业监控还是智慧城市建设,都离不开高效、稳定的视频监控系统的支持。而在这些应用场景中,将监控视频实时投放到大屏幕电视墙上…

【GeoJSON在线编辑平台】(0)项目启动与前言

前言 事情是这样的…… 有这么一个项目,需要开发一个在线的标注平台。以天地图为底图,在天地图上标注出一些特征地物,比如描出农田耕地房屋建筑之类的要素。 这个需求简化一下其实就是一个在线的矢量编辑平台,通过绘制多边形功能…

豆包,攻克数字是个什么工具?《GKData-挖掘数据的无限可能》(数据爬虫采集工具)

豆包,攻克数字是个什么工具? “攻克数字” 指的是 “攻克数字(GKData)” 这样一款工具。是一款针对网页、APP中数据自动解析转表存入数据库的软件,为数据工作者而生。它是一个不会编程也能用的可视化数据解析为标准二…

【成都新篇】龙信科技电子取证实验室,引领科技取证新时代

文章关键词:电子数据取证实验室、手机取证、介质取证、云取证、现场勘查、电子物证 在科技创新的浪潮中,龙信科技成都实验室以其卓越的电子数据取证服务,成为了中西部地区一颗璀璨的明珠。随着新址的搬迁,我们不仅扩大了业务范围…

【C/C++】字符/字符串函数(1)——由string.h提供

零.导言 什么是字符/字符串函数呢? 其实就是一类用于处理字符和字符串的函数。 而其中一部分函数包含在头文件 string.h 中,有 strlen strcpy strcat strcmp strncpy strncat strncmp strstr strtok strerror 等等 接下来我将逐个讲解这些函数。 一.str…