【python】OpenCV—findContours(4.5)

news2024/11/26 18:52:38

在这里插入图片描述

文章目录

  • 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 edges
	gray = 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 image
	cnts, _ = 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 it
	return 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 camera
	image = 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 it
	box = 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 camera
	return (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 cv2

def find_marker(image):
	# convert the image to grayscale, blur it, and detect edges
	gray = 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 image
	cnts, _ = 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 it
	return cv2.minAreaRect(c)

def distance_to_camera(knownWidth, focalLength, perWidth):
	# compute and return the distance from the maker to the camera
	return (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 camera
	image = 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 it
	box = 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.coloradmin.cn/o/2231985.html

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

相关文章

jmeter基础01-3_环境准备-Linux系统安装jdk

Step1. 查看系统类型 打开终端,命令行输入uname -a,显示所有系统信息,包括内核名称、主机名、内核版本等。 如果输出是x86_64,则系统为64位。如果输出是i686 或i386,则系统为32位。 Step2. 官网下载安装包 https://www…

获取JSON对象的时候,值会自动带上双引号

问题:当使用下方代码,获取JsonNode对象的时候,从该对象中通过键获取的值会自动带上双引号。 JsonNode jsonNode new ObjectMapper().readTree("JSON字符串"); 注意:以上方法是获得的JsonNode对象,不是JSO…

大气污染监测系统方案:智慧环保监测的“千里眼“

​ 作为星创易联的一名工程师,我有幸参与了某市环保局的大气污染监测系统项目。该市地处我国中部地区,近年来工业发展迅速,大气污染问题日益突出。为加强环境管理,政府决定构建一套覆盖全市的大气污染在线监测系统,实时掌握各区域的空气质量状况。 我们公司凭借在物联网领域的…

leetcode-88-合并两个有序数组

题解: 解法一:从后向前同时遍历两个数组,因为nums1后面是0,从后遍历节省空间。 1、定义三个指针,分别为:len1m-1指向nums1的最后一个非0数字;len2n-1指向nums2的最后一个数字;len3…

百度文心智能体:巧用汉字笔画生成与汉字搜索插件,打造一个学习汉字的教育类智能体

这篇文章,主要介绍如何巧用汉字笔画生成与汉字搜索插件,打造一个学习汉字的教育类智能体。 目录 一、教育类智能体 1.1、智能体演示 1.2、智能体插件 1.3、智能体prompt (1)角色和目标 (2)思考路径 …

MySQL rand()函数、rand(n)、生成不重复随机数

文章目录 一、rand()与rand(n)二、rand()使用示例2.1、rand()与order by/group by使用随机排序分组2.2、round()与rand()的组合使用2.3、rand与ceiling的组合使用2.4、rand与floor组合使用2.5、rand与md5组合使用 三、总结3.1、rand()与rand(n)的区别 有时候我们想要生成一个唯…

『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC

『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC 文章目录 一. 『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC1. 介绍 二. 参考文献 一. 『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC 如何在 Ubuntu 22.04 上安装和配置 VNChttps://hub.docker.c…

ubuntu22-安装vscode-配置shell命令环境-mac安装

文章目录 1.安装vscode2.修改语言为中文3.配置bash调试环境3.1.安装插件3.2.添加配置文件 4.调试bash4.1.新建tmp.sh文件4.2.运行启动 5.mac安装6.mac卸载 1.安装vscode 从官网下载安装包Code_1.93.1-1726079302_amd64.deb。 在ubuntu系统中,安装包所在目录打开命令…

MongoDB 8.0.3版本安装教程

MongoDB 8.0.3版本安装教程 一、下载安装 1.进入官网 2.选择社区版 3.点击下载 4.下载完成后点击安装 5.同意协议,下一步 6.选择第二个Custon,自定义安装 7.选择安装路径 !记住安装路径 8.默认,下一步 9.取…

编程八种语言谁是最受市场青睐的?

你听说过"编程语言江湖"吗?在这个瞬息万变的IT世界里,各种编程语言就像武林高手,各展绝技,争夺"武林盟主"的宝座。 1. JavaScript/TypeScript: 江湖新贵的崛起江湖中有一句老话:"十年磨一剑,霜刃未曾试…

(转载)Tools for Learning LLVM TableGen

前提 最近在学习有关llvm的东西,其中TableGen占了一部分,所以想特意学习下TableGen相关的语法。这里找到了LLVM官网的一篇介绍TableGen的博客,学习并使用机器翻译为中文。在文章的最后也添加了一些学习TableGen的资源。 原文地址&#xff1…

openpnp - 在openpnp中单独测试相机

文章目录 openpnp - 在openpnp中单独测试相机概述笔记测试工装相机镜头顶部盖子到目标的距离END openpnp - 在openpnp中单独测试相机 概述 底部相机的位置不合适, 重新做了零件,准备先确定一下相机和吸嘴的距离是多少才合适。 如果在设备上直接实验,那…

联动香港、成都、武汉三所高校!“2024 深圳国际金融科技大赛”校园行圆满结束

在金融科技蓬勃发展的当下,人才培养成为推动行业前行的关键。为推进深圳市金融科技人才高地建设,向高校学子提供一个展示自身知识、能力和创意的平台,2024 FinTechathon 深圳国际金融科技大赛——西丽湖金融科技大学生挑战赛重磅开启&#xf…

【SQL Server】华中农业大学空间数据库实验报告 实验一 数据库

实验目的 熟悉了解掌握SQL Server软件的基本操作与使用方法,认识界面,了解其两个基本操作系统文件,并能熟练区分与应用交互式与T-SQL式两种方法在SQL Server中如何进行操作;学习有关数据库的基本操作,包括&#xff1a…

LeetCode:83. 删除排序链表中的重复元素 II(java) 保留一个重复的

目录 题目描述: 代码: 第一种: 第二种: 题目描述: 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 示例 1: 输入:head [1,1,2] 输出:[1,2]示例 2&#xff1a…

【快速上手】pyspark 集群环境下的搭建(Standalone模式)

目录 前言 : 一、spark运行的五种模式 二、 安装步骤 安装前准备 1.第一步:安装python 2.第二步:在bigdata01上安装spark 3.第三步:同步bigdata01中的spark到bigdata02和03上 三、集群启动/关闭 四、打开监控界面验证 前…

SpringSecurity6+OAuth2.0 从入门到熟练使用

文章目录 简介1、快速入门1.1 准备工作我们先要搭建一个SpringBoot工程① 创建工程 添加依赖② 创建启动类③ 创建Controller1.2 引入SpringSecurity2、 认证2.1 登录校验流程2.2 原理分析2.2.1 SpringSecurity完整流程2.2.2 认证流程详解概念速查:2.3 解决问题2.3.1 思路分析2…

Qt报错QOCI driver not loaded且QOCI available的解决方法

参考 Linux Qt 6安装Oracle QOCI SQL Driver插件(适用WSL) 安装 QOCI 插件完成后运行 Qt 项目报错: qt.sql.qsqldatabase: QSqlDatabase: QOCI driver not loaded qt.sql.qsqldatabase: QSqlDatabase: available drivers: QMIMER QPSQL QODBC…

【AI工作流】FastGPT - 深入解析FastGPT工作流编排:从基础到高级应用的全面指南

文章目录 一、工作流编排概述二、FastGPT的节点类型1. 基础功能插件(1) 文本输出(2) 功能调用(3) 工具(4) 外部调用(5) 其他 2. 系统插件3. 团队插件 三、工作流中的流向结语 在当今快速发展的人工智能领域,工作流编排的能力已成为提升用户体验和应用效率的关键因素…

SQL 常用语句

目录 我的测试环境 学习文档 进入数据库 基础通关测验 语句-- 查 展示数据库; 进入某个数据库; 展示表: 展示某个表 desc 查询整个表: 查询特定列: 范围查询 等于特定值 不等于 介于 特定字符查询 Li…