【opencv】二维面找角点/关键点 实现

news2024/11/22 15:06:51

every blog every motto: You can do more than you think.

0. 前言

二维面找角点/关键点 实现

1. 正文

1.1 前提

1.1.1 显示函数

def show(arr):
    plt.imshow(arr)
    plt.show()


def cvshow(arr):
    cv2.namedWindow('a', 0)
    cv2.imshow('a', arr)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

1.1.2 数据

数据准备

img1 = np.zeros((1080, 1920, 3), np.uint8)
img2 = np.zeros((1080, 1920, 3), np.uint8)
area1 = np.array([[250, 200], [300, 100], [750, 800], [100, 1000]])
area2 = np.array([[0, 200], [1500, 200], [1500, 400], [0, 400]])

填充

m1 = cv2.fillPoly(img1, [area1], (255, 255, 255))
m2 = cv2.fillPoly(img2, [area2], (255, 255, 255))

在这里插入图片描述
交集

res = cv2.bitwise_and(m1, m2)

在这里插入图片描述

1.2 方法一: 先找轮廓再找凸包

前置:

凸包: 简单解释,给定二位平面上的点击,凸包就是将最外层的点链接起来构成凸多边形,它包含所有的点

最终要的一点,可以实现对点集排序!!!!

默认是顺时针,先左上。若点出现偏移可能会右下开始,只要求点有序即可,可以不做深入研究。

例子:

import cv2
hull = cv2.convexHull(points, clockwise, returnpoints)
  • hull : 输出凸包结果,n * 1 * 2 数据结构,n为外包围圈点数
  • points: 输入的坐标点,通常为1 * n * 2 结构,n为所有的坐标点的数目
  • clockwise:转动方向,TRUE为顺时针,否则为逆时针;
  • returnPoints:默认为TRUE,返回凸包上点的坐标,如果设置为FALSE,会返回与凸包点对应的轮廓上的点。
a. 找轮廓
gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)  # 转灰度
_, bin = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)  # 阈值
# 找轮廓
contours, hierarchy = cv2.findContours(bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 轮廓画在图上
cv2.drawContours(res, contours, -1, (0, 0, 255), 5)
cvshow(res)

在这里插入图片描述

b. 找凸包
hull = cv2.convexHull(contours[0])
c. 显示凸包

这里我们遍历凸包点,将点画在原图上。这里是以点画圆,值得注意的是,点的颜色随着次序改变而改变,具体来说,(opencv中是BRG)红色逐渐减弱,绿色逐渐加深,渐变的大小为20,可以根据点数自己设定,如10等。

color_offset = 20
for idx, i in enumerate(hull):
    x, y = i.ravel()
    cv2.circle(res, (x, y), 1, (0, color_offset * idx, 255 - color_offset * idx), -1)
d. 显示

注意:需要将cv2.drawContours注释,否则会有遮挡

cvshow(res)

如下图所示,我们看到点是按顺序排列的!!!!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

e. 方法一总代码
# 方法一:先找轮廓再找凸包
gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)  # 转灰度
_, bin = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)  # 阈值
# 找轮廓
contours, hierarchy = cv2.findContours(bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 轮廓画在图上
cv2.drawContours(res, contours, -1, (0, 0, 255), 5)
hull = cv2.convexHull(contours[0])

1.3 方法二:先找角点再找凸包

a. 找角点
gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)  # 转灰度
corners = cv2.goodFeaturesToTrack(gray, 0, 0.01, 10) # 寻找角点
b. 显示一下角点
color_offset = 20
for idx, i in enumerate(corners):
    x, y = i.ravel()
    cv2.circle(res, (x, y), 1, (0, color_offset * idx, 255 - color_offset * idx), 3)

cvshow(res)

如下图所示,点是没有顺序的,这是 因为上面的角点检测算法返回的点的结果是点的质量返回的,即点检测质量越好约靠前。下图我们可以看到四个角上点质量最好排在前面,我们实际应用需要这些点有序。
在这里插入图片描述

c. 凸包
corners = np.int0(corners)
hull = cv2.convexHull(corners)
d. 显示凸包
color_offset = 20
for idx, i in enumerate(corners):
    x, y = i.ravel()
    cv2.circle(res, (x, y), 1, (0, color_offset * idx, 255 - color_offset * idx), 3)

cvshow(res)

在这里插入图片描述

e. 方法二总代码
# 方法二:先找角点再找轮廓
gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)  # 转灰度
corners = cv2.goodFeaturesToTrack(gray, 0, 0.01, 10) # 寻找角点
corners = np.int0(corners)
hull = cv2.convexHull(corners)

1.4 找轮廓点(角点、关键点)(附)

显示找到的点,点的颜色代表顺序。我们这里是点的顺序按从红色到绿色

color_offset = 20
for idx, i in enumerate(points):
    x, y = i.ravel()
    cv2.circle(res, (x, y), 1, (0, color_offset * idx, 255 - color_offset * idx), 3)

cvshow(res)

后续的案例图,放在这里提前看下,可以不深究,后续会逐步讲解
在这里插入图片描述

参考

[1] https://www.cnblogs.com/01black-white/p/16070686.html

[2] https://blog.csdn.net/weixin_44690935/article/details/109008946

[3] https://blog.csdn.net/lovetaozibaby/article/details/103214672

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

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

相关文章

通关算法题之 ⌈链表⌋

链表 删除元素 203. 移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例: 输入:head [1,2,6,3,4,5,6], val 6 输出:[1,2,3,4,5]c…

2022 IoTDB Summit:宝武智维徐少锋《Apache IoTDB 在宝武装备远程智能运维平台中的使用案例》...

12 月 3 日、4日,2022 Apache IoTDB 物联网生态大会在线上圆满落幕。大会上发布 Apache IoTDB 的分布式 1.0 版本,并分享 Apache IoTDB 实现的数据管理技术与物联网场景实践案例,深入探讨了 Apache IoTDB 与物联网企业如何共建活跃生态&#…

01【Vector CP】- 详解PN局部网络管理

Partial Networking概述 Partial Networking适用的ECU类型: 总线上依然有通信ECU关闭通信堆栈ECU要求降低功耗 Note:Partial Networking功能及其所有子功能是可选的,必须进行配置。为了控制此类ECU的关断和唤醒,CAN NM提供了一种额外的算法: NM PDU 消息中的用户数据部分…

java命名规范

Java总体命名规范1、项目名全部小写2、包名全部小写3、类名首字母大写,其余组成词首字母依次大写,驼峰命名4、变量名,方法名首字母小写,如果名称由多个单词组成,除首字母外的每个单词的首字母都要大写,保证…

企业数字化转型的关键一步,建立数据意识

数字化给社会带来的巨大的科技革命和产业革命,让数字经济成为新的高速增长的国民经济支柱,让数据变为第五大生产要素,发挥巨大价值,成为企业重要资产。不仅如此,在数字化的影响下,数字化转型成为了个人、机…

ue4.27空项目打包不卡ue5.1空项目打包运行卡的要命研究测试

知乎上有人提问 lumen是如何做到不卡顿的,我却不以为然,我的显卡虽然算不上好显卡,但是也不至于独立显卡一个空项目都玩不起吧,打个cf,玩腾讯模拟器和平精英吃鸡肯定还是会很流畅的. 一个空项目都卡,怎么能说是我电脑配置问题呢??? 再来看提示 image.pngimage.png反射设置的…

2023 过春年,烟花依然了无缘;这能难倒程序猿?一键三连过大年!

效果图镇楼 序 不知道是在什么时候,济南就开始都在传:“今年不再限制放烟花啦!”。一些集市上也开始有了售卖烟花的摊子 大家都很兴奋,很多小伙伴开始购买烟花。特别是今年特别火的 “加特林 😱” 但是大家兴奋劲还没…

<C++>红黑树

文章目录1. 红黑树的概念2. 红黑树的性质3. 红黑树节点定义4. 红黑树的插入操作5. 红黑树的验证6. 红黑树与AVL树的比较7. 红黑树模拟实现STL中的map与set1. 红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色&#xf…

小程序管理还能这样做,让小程序管理更高效

说起小程序,作为开发者或者企业用户不得不面临一个问题就是,需要小程序承载的业务越来越多的时候,小程序的数量也呈现增长,随之而来的就是小程序开发、维护等一系列管理中会出现的问题。 包括到小程序的代码包管理、小程序上下架…

Toolwtech Graphics3D.NET 2.0.x专业版Crack

您是否正在寻找一种易于使用、功能强大且 100% 托管的 .NET 组件来快速开发 3D 图形或 3D 数据可视化应用程序?请尝试 Graphics3D.NET。使用 Graphics3D.NET,您可以在几分钟内开发出专业的 3D 可视化应用程序。 Graphics3D.NET 特点: * 100% …

点亮 LED

1.在 Linux 系统下,一切皆文件!应用层如何操控底层硬件,同样也是通过文件 I/O 的方式来实现。设备文件通常在/dev/目录下,我们也把/dev 目录下的文件称为设备节点。设备节点并不是操控硬件设备的唯一途径,除此之外&…

Vue模板语法(二)

Vue条件语句 1、v-if、v-else、v-else-if v-if、v-else、v-else-if用于根据条件来渲染某一块的内容: 这些内容只有在条件为true时,才会被渲染出来;这三个指令与JavaScript的条件语句if、else、else if类似; v-if的渲染原理&a…

单片机开发---ESP32-S3模块上手

背景介绍 想起来之前做的半成品单片机游戏机,又想继续做一个,不过之前那个单片机驱动屏幕速率太低,已经无法改进了。所以这次斥巨资购买了一款顶配的ESP32S开发板,做个简单的游戏机,没问题。 完整介绍链接 这花花绿绿…

通过logstash将Redis数据写入ElasticSearch

点击上方蓝字关注我使用logstash将Redis中数据自动同步至ES中1. 部署Redis上传编译好的Redis二级制安装包,使用redis用户启动redis即可具体编译安装过程可参考https://mp.weixin.qq.com/s/RaWy0sqRxcAti1qbv-GbZQ2. 部署logstash下载二进制安装包wget https://ar…

HTTP FLV交互流程及实例解析

HTTP FLV交互流程及实例解析 文章目录HTTP FLV交互流程及实例解析HTTP FLV传输方式HTTP FLV 抓包分析结束语HTTP FLV传输方式 前文已经介绍过,HTTP FLV利用了一个HTTP的协议约定,http 的content-length头字段如果不存在,则客户端就会一直接收…

ESP32-Camera性能(简单)测试评估

TOC 1. ESP32-Camera简介 最近因为接触了ESP32摄像头相关的资料和信息,稍微简单整理下,希望对该方案有兴趣的朋友可以有所帮助。 1.1 资料&信息 The Internet of Things wit ESP32ESP32-S Series开发模组Github: ESP32-Camera 1.2 ESP-EYE摄像头…

别忘记我:通过局部-全局内容建模进行文本擦除方法

本文简要介绍了发表于ECCV 2022的论文“Don’t Forget Me: Accurate Background Recovery for Text Removal via Modeling Local-Global Context”的相关工作。该论文针对文本擦除中存在的复杂背景修复的问题,提出了CTRNet,它利用局部和全局的语义建模提…

一个 go-sql-driver 的离奇 bug

文|郝洪范京东技术专家Seata-go 项目共同发起人微服务底层技术的探索与研究。本文 3482 字 阅读 7 分钟对于 Go CURD Boy 来说,相信 github.com/go-sql-driver/mysql 这个库都不会陌生。基本上 Go 的 CURD 都离不开这个特别重要的库。我们在开发 Seata-g…

LabVIEW将现有数据文件映射至TDMS数据文件格式

LabVIEW将现有数据文件映射至TDMS数据文件格式在某些情况下,可能无法使用TDMS文件格式,例如客户或供应商指定必须使用某种格式存储数据。有些传统仪器可能会自动使用某种自定义格式提供数据输出文件。此外,已经用某种方式收集的传统测量数据无…

PyQt6快速入门-自定义Widget

自定义Widget 文章目录 自定义Widget1、准备工作2、重写paintEvent事件3、Position策略4、更新显示5、绘制条形框5.1 绘制计算5.2 绘制条形框6、自定义样式7、添加鼠标交互能力8、完整代码QPainter是Qt中所有小部件绘制的基础。在本文中,详细介绍如何构建一个全新的自定义 GUI…