【python】OpenCV—Point Polygon Test

在这里插入图片描述

文章目录

  • 1、完整代码
  • 2、涉及到的库
    • cv2.pointPolygonTest
    • cv2.minMaxLoc

1、完整代码

from __future__ import print_function
from __future__ import division
import cv2 as cv
import numpy as np
# Create an image
r = 100
src = np.zeros((4*r, 4*r), dtype=np.uint8)
# 创建六边形的6个顶点
vert = [None]*6
vert[0] = (3*r//2, int(1.34*r))
vert[1] = (1*r, 2*r)
vert[2] = (3*r//2, int(2.866*r))
vert[3] = (5*r//2, int(2.866*r))
vert[4] = (3*r, 2*r)
vert[5] = (5*r//2, int(1.34*r))
# 根据六个顶点画6边形
for i in range(6):cv.line(src, vert[i],  vert[(i+1)%6], ( 255 ), 3)
# 获取六边形的轮廓
contours, _ = cv.findContours(src, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# 计算图上点到六边形的距离(带符号)
raw_dist = np.empty(src.shape, dtype=np.float32)
for i in range(src.shape[0]):for j in range(src.shape[1]):raw_dist[i,j] = cv.pointPolygonTest(contours[0], (j,i), True)
# 查找带符号的最大最小值
minVal, maxVal, _, maxDistPt = cv.minMaxLoc(raw_dist)
minVal = abs(minVal)
maxVal = abs(maxVal)
# 用图形表示距离
drawing = np.zeros((src.shape[0], src.shape[1], 3), dtype=np.uint8)
for i in range(src.shape[0]):for j in range(src.shape[1]):if raw_dist[i,j] < 0:drawing[i,j,0] = 255 - abs(raw_dist[i,j]) * 255 / minValelif raw_dist[i,j] > 0:drawing[i,j,2] = 255 - raw_dist[i,j] * 255 / maxValelse:drawing[i,j,0] = 255drawing[i,j,1] = 255drawing[i,j,2] = 255
cv.circle(drawing,maxDistPt, int(maxVal),(255,255,255), 1, cv.LINE_8, 0)
cv.imshow('Source', src)
cv.imshow('Distance and inscribed circle', drawing)
cv.waitKey()

在这里插入图片描述
在这里插入图片描述

带符号的最大值,为六边形的中心,到六边形轮廓的距离最远

以此点位中心,画了个圆

六边形外的点,蓝色随着距离变大递减

六边形内的点,红色随着距离变大递减

六边形上的点,白色

2、涉及到的库

cv2.pointPolygonTest

用于判断一个点是否位于一个多边形内部、外部还是边上。这个函数在图像处理、计算机视觉和形状分析等领域中非常有用。以下是关于 cv2.pointPolygonTest() 函数的详细解析:

函数定义

cv2.pointPolygonTest(contour, pt, measureDist=False)
  • contour:输入的多边形轮廓,通常是一个由点构成的数组(numpy数组),这些点定义了多边形的边界。这些点可以通过如 cv2.findContours 等函数从图像中提取。
  • pt:需要检测的点,通常是一个包含 x 和 y 坐标的元组或 numpy.ndarray。
  • measureDist:一个布尔值参数,指定是否计算点到多边形边界的最短距离。
    1)如果为 True,则函数返回点到边界的带符号距离。当点在多边形内部时,距离为正;当点在多边形外部时,距离为负;当点在多边形边上时,距离为0。距离的绝对值表示点到多边形边界的实际最短距离。
    2)如果为 False(默认值),则函数返回一个整数,表示点相对于多边形的位置。返回值为 -1 表示点在多边形外部,0 表示点在多边形边上,+1 表示点在多边形内部。

使用场景

  • 形状分析:通过检测点是否在多边形内部,可以分析形状的属性和特征。
  • 物体检测:在图像处理中,可以检测物体边界框内的点是否在多边形内部,从而判断物体是否被完全包含在多边形内。
  • 图像分割:在图像分割任务中,可以使用该函数来判断像素点是否属于某个特定的区域或对象。

示例代码

import cv2  
import numpy as np  # 定义一个多边形的顶点  
pts = np.array([[0, 0], [100, 0], [100, 100], [0, 100]], np.int32)  
pts = pts.reshape((-1, 1, 2))  # 将点集转换为 (n, 1, 2) 的形状  # 待检测的点  
pt_inside = (50, 50)  # 多边形内部的一个点  
pt_on_edge = (100, 0)  # 多边形边上的一个点  
pt_outside = (150, 50)  # 多边形外部的一个点  # 调用 pointPolygonTest  
dist_inside = cv2.pointPolygonTest(pts, pt_inside, measureDist=True)  
dist_on_edge = cv2.pointPolygonTest(pts, pt_on_edge, measureDist=True)  
dist_outside = cv2.pointPolygonTest(pts, pt_outside, measureDist=True)  position_inside = cv2.pointPolygonTest(pts, pt_inside, measureDist=False)  
position_on_edge = cv2.pointPolygonTest(pts, pt_on_edge, measureDist=False)  
position_outside = cv2.pointPolygonTest(pts, pt_outside, measureDist=False)  print(f"Inside distance: {dist_inside}")  
print(f"On edge distance: {dist_on_edge}")  
print(f"Outside distance: {dist_outside}")  print(f"Inside position: {position_inside}")  
print(f"On edge position: {position_on_edge}")  
print(f"Outside position: {position_outside}")

output

Inside distance: 50.0
On edge distance: -0.0
Outside distance: -50.0
Inside position: 1.0
On edge position: 0.0
Outside position: -1.0

注意事项

  • 确保传入的轮廓(contour)是正确的,即它应该是一个由点构成的数组,这些点定义了多边形的边界。

  • 当 measureDist 为 True 时,返回的距离值是带符号的,正值表示点在多边形内部,负值表示在多边形外部,绝对值表示最短距离。

  • cv2.pointPolygonTest() 函数不会直接修改输入的图像或轮廓,它只是返回一个表示点位置的数值或距离。

cv2.minMaxLoc

用于寻找一维数值数组(例如,灰度图像的某一行或列)中的全局最小值和最大值,以及它们的位置。这个函数对于图像处理中的阈值设置、特征检测等场景非常有用。

cv2.minMaxLoc(src, mask=None)
  • src:输入的单通道数值数组。这可以是一个灰度图像,或者图像的某个部分(如一行或一列)。

  • mask:可选的与 src 同样大小和类型的操作掩码。如果提供了掩码,则函数仅在没有被掩码标记为忽略的元素中查找最小值和最大值。掩码中的非零值表示对应位置的元素需要考虑在内。

返回值

函数返回一个包含四个元素的元组 (minVal, maxVal, minLoc, maxLoc):

  • minVal:找到的最小值。
  • maxVal:找到的最大值。
  • minLoc:最小值的坐标(以元组形式给出,如 (x, y))。注意,对于一维数组(如图像的单个行或列),坐标将是 (col, 0),因为 y 坐标在这种情况下没有意义。
  • maxLoc:最大值的坐标(同样以元组形式给出)。

使用示例

import cv2  
import numpy as np  # 加载图像(转换为灰度,如果它还不是)  
img = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)  # 查找最小值和最大值以及它们的位置  
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(img)  print(f"Minimum value: {minVal}, at location: {minLoc}")  
print(f"Maximum value: {maxVal}, at location: {maxLoc}")

如果你只对图像的某一行或列感兴趣,你可以先通过索引该行或列来创建一个一维数组,然后再调用 cv2.minMaxLoc。

注意:对于二维图像(如灰度图像),返回的坐标 (x, y) 是以图像的左上角为原点((0, 0))的坐标系统。但是,对于一维数组(如通过索引得到的行或列),y 坐标总是 0,因为此时我们实际上是在处理一维数据。

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

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

相关文章

3 Go语言的变量声明

本专栏将从基础开始&#xff0c;循序渐进&#xff0c;由浅入深讲解Go语言&#xff0c;希望大家都能够从中有所收获&#xff0c;也请大家多多支持。 查看相关资料与知识库 专栏地址:Go专栏 如果文章知识点有错误的地方&#xff0c;请指正&#xff01;大家一起学习&#xff0c;…

前端学习3——自学习梳理

1.学习一下盒子模型(盒子就是元素&#xff0c;标签) 盒子模型又分为4种&#xff1a;块级&#xff0c;内联级&#xff0c;内联块级&#xff0c;弹性盒子 (弹性盒子续在下一节) 2.元素的结构 1.盒子模型 <!DOCTYPE html> <html lang"en"> <head>&l…

【嵌入式开发 Linux 常用命令系列 7.7 -- find 和 sed 配合使用介绍】

请阅读【嵌入式及芯片开发学必备专栏】 文章目录 使用背景注意事项使用示例 使用背景 当时想在 linux 环境下 使用 find 命令找到 .c 和 .h 文件&#xff0c;并使用xargs 加 sed 命令将文件中所有"demo" 字符串替换为 “hello” 命令实现&#xff1a; 使用 find 命…

【C++杂货铺】智能指针

目录 &#x1f308; 前言&#x1f308; &#x1f4c1; 内存泄漏 &#x1f4c2; 概念 &#x1f4c2; 分类 &#x1f4c2; 如何避免 &#x1f4c1; RAII &#x1f4c1; C11智能指针 &#x1f4c2; auto_ptr &#x1f4c2; unique_ptr &#x1f4c2; shared_ptr &#x1…

电子电器架构 --- 智能汽车的大脑(域控制器)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

QT--进程

一、进程QProcess QProcess 用于启动和控制外部进程&#xff0c;管理其输入输出流。 使用方法 start()&#xff1a;启动一个新进程。setStandardInputFile()&#xff1a;将文件作为标准输入。将进程的标准输入&#xff08;stdin&#xff09;重定向到指定的文件。换句话说&am…

AV1技术学习:Constrained Directional Enhancement Filter

CDEF允许编解码器沿某些(可能是倾斜的)方向应用非线性消阶滤波器。它以88为单位进行。如下图所示&#xff0c;通过旋转和反射所示的三个模板来定义八个预设方向。 Templates of preset directions and their associated directions. The templates correspond to directions of…

筑牢数字防线:从微软蓝屏事件看网络安全与系统韧性建设

引言 近期&#xff0c;由微软视窗系统软件更新引发的全球性“微软蓝屏”事件&#xff0c;不仅给全球用户带来了前所未有的挑战&#xff0c;也深刻暴露了当前IT基础设施在面对潜在威胁时的脆弱性。此次事件&#xff0c;如同一面镜子&#xff0c;映照出我们在网络安全与系统稳定…

MATLAB: ode45 求解常微分方程

引入 ode45 是 MATLAB 中用于求解非刚性常微分方程&#xff08;ODE&#xff09;的数值方法。它基于 Runge-Kutta 方法&#xff0c;并具有自适应步长调整机制&#xff0c;能够在一定误差控制范围内高效地计算 ODE 的数值解。 下面我们通过这个包含详细注释的代码&#xff0c;一…

Windows 11 系统对磁盘进行分区保姆级教程

Windows 11磁盘分区 磁盘分区是将硬盘驱动器划分为多个逻辑部分的过程&#xff0c;每个逻辑部分都可以独立使用和管理。在Windows 11操作系统中进行磁盘分区主要有以下几个作用和意义&#xff1a; 组织和管理数据&#xff1a;分区可以帮助用户更好地组织他们的数据&#xff0c…

无人机之降落操作及紧急情况处理

一、无人机降落操作 1、选择降落地点 a.提前选择一个平坦且没有障碍物的降落点&#xff1b; b.确认降落点周围没有行人或障碍物&#xff0c;保证降落的安全性。 2、降低飞行高度 a.缓慢降低飞行高度&#xff0c;尽量保持匀速下降&#xff0c;防止因下降过快导致无人机受损…

学习vue第一天

文章目录 1.什么是 Vue?2.渐进式框架3.如何新建一个vue项目 1.什么是 Vue? Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0…

Day20 | 39. 组合总和 40.组合总和II 131.分割回文串

语言 Java 39. 组合总和 组合总和 题目 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidate…

最新可用度盘不限速后台系统源码_去授权开心版

某宝同款度盘不限速后台系统源码&#xff0c;验证已被我去除&#xff0c;两个后端系统&#xff0c;账号和卡密系统 第一步安装宝塔&#xff0c;部署卡密系统&#xff0c;需要环境php7.4 把源码丢进去&#xff0c;设置php7.4&#xff0c;和伪静态为thinkphp直接访问安装就行 …

探索WebKit的CSS表格布局:打造灵活的网页数据展示

探索WebKit的CSS表格布局&#xff1a;打造灵活的网页数据展示 CSS表格布局是一种在网页上展示数据的强大方式&#xff0c;它允许开发者使用CSS来创建类似于传统HTML表格的布局。WebKit作为许多流行浏览器的渲染引擎&#xff0c;提供了对CSS表格布局的全面支持。本文将深入探讨…

qt 如何制作动态库插件

首先 首先第一点要确定我们的接口是固定的&#xff0c;也就是要确定 #ifndef RTSPPLUGIN_H #define RTSPPLUGIN_H #include "rtspplugin_global.h" typedef void (*func_callback)(uint8_t* data,int len,uint32_t ssrc,uint32_t ts,const char* ipfrom,uint16_t f…

【前端学习笔记】CSS基础一

一、什么是CSS 1.CSS 介绍 CSS&#xff08;Cascading Style Sheets&#xff0c;层叠样式表&#xff09;是一种用来控制网页布局和设计外观的样式语言。它使得开发者可以分离网页的内容&#xff08;HTML&#xff09;和表现形式&#xff08;样式&#xff09;&#xff0c;提高了…

Spring Security 介绍

1.概要 Spring Security是一个用于在Java应用程序中实现身份验证和访问控制的强大框架。它可以轻松地集成到任何基于Spring的应用程序中&#xff0c;提供了一套丰富的功能来保护应用程序的安全性。 https://spring.io/projects/spring-security/ demo:https://docs.spring.i…

unity2D游戏开发02添加组件移动玩家

添加组件 给PlayGame和EnemyObject添加组件BoxCollider 2D碰撞器&#xff0c;不用修改参数 给PlayGame添加组件Rigibody 2D 设置数据 添加EnemyObject&#xff0c;属性如下 Edit->project setting->Physics 2D 将 y的值改为0 给playerObject添加标签 新建层 将PlayerObj…

美团后端二面

美团后端二面 ……………………………… 两道场景 一道 数字转中文读法&#xff08;1000-》一千&#xff09; 0八股0自我介绍 反问 “您觉得我能过吗&#xff1f;” “这个需要横行对比之后才能有结果” ……………………………… 什么时候到岗 场景题 1 假设我有一个…