【python】OpenCV—Sort the Point Set from Top Left to Bottom Right

文章目录
- 1、功能描述
- 2、代码实现
- 3、效果展示
- 4、更多例子
- 5、参考
1、功能描述

给出一张图片,里面含有各种图形,取各种图形的中心点,从左到右从上到下排序
例如

2、代码实现
import cv2
import numpy as npdef process_img(img):img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)img_canny = cv2.Canny(img_gray, 100, 100)kernel = np.ones((2, 3))img_dilate = cv2.dilate(img_canny, kernel, iterations=1)img_erode = cv2.erode(img_dilate, kernel, iterations=1)return img_erodedef get_centeroid(cnt):length = len(cnt)sum_x = np.sum(cnt[..., 0])sum_y = np.sum(cnt[..., 1])return int(sum_x / length), int(sum_y / length)def get_centers(img):contours, hierarchies = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)for cnt in contours:if cv2.contourArea(cnt) > 100:yield get_centeroid(cnt)def get_rows(img, centers, row_amt, row_h):centers = np.array(centers)d = row_h / row_amt # 每行的间距for i in range(row_amt): # 遍历行数f = centers[:, 1] - d * i # 行首纵坐标a = centers[(f < d) & (f > 0)] # 一行内的 xyield a[a.argsort(0)[:, 0]]img = cv2.imread("shape.png")
img_processed = process_img(img)cv2.imwrite("shape_processed.png", img_processed)centers = list(get_centers(img_processed))
print(centers)"""
[(478, 466), (38, 454), (478, 432), (159, 442), (646, 436), (157, 403), (317, 430), (161, 369), (139, 368), (523, 385),
(64, 381), (690, 355), (636, 366), (341, 325), (506, 329), (212, 319), (86, 283), (180, 275), (674, 283), (379, 322),
(525, 256), (299, 311), (434, 254), (634, 212), (316, 203), (233, 204), (567, 172), (148, 228), (59, 199), (418, 158),
(478, 171), (363, 109), (549, 88), (281, 89), (211, 58), (441, 50), (21, 75), (104, 62), (677, 86), (621, 39),
(485, 32), (323, 24)]
"""
print(len(centers)) # 42h, w, c = img.shape
count = 0for row in get_rows(img, centers, 4, h):cv2.polylines(img, [row], False, (255, 0, 255), 2) # 绘制每一行的点连成线for x, y in row:count += 1cv2.circle(img, (x, y), 10, (0, 0, 255), -1) # 绘制每个点cv2.putText(img, str(count), (x - 10, y + 5), 1, cv2.FONT_HERSHEY_PLAIN, (0, 255, 255), 2)# 每个点上写上序号cv2.imshow("Ordered", img)
cv2.waitKey(0)
process_img 后图像为

get_centers 函数找轮廓,面积较大的轮廓经过 get_centeroid 函数找轮廓中心
找轮廓中心的方法是遍历轮廓点,求横坐标和纵坐标的平均值
轮廓中心 centers 的长度为 42,可以看到我们找出来了图片中 42 个中心 ,也即找出来了 42 个轮廓
[(478, 466), (38, 454), (478, 432), (159, 442), (646, 436), (157, 403), (317, 430), (161, 369), (139, 368), (523, 385),
(64, 381), (690, 355), (636, 366), (341, 325), (506, 329), (212, 319), (86, 283), (180, 275), (674, 283), (379, 322),
(525, 256), (299, 311), (434, 254), (634, 212), (316, 203), (233, 204), (567, 172), (148, 228), (59, 199), (418, 158),
(478, 171), (363, 109), (549, 88), (281, 89), (211, 58), (441, 50), (21, 75), (104, 62), (677, 86), (621, 39),
(485, 32), (323, 24)]
遍历每行,排序纵坐标落在行内区间的轮廓中心
get_rows 中 f
array([466., 454., 432., 442., 436., 403., 430., 369., 368., 385., 381.,355., 366., 325., 329., 319., 283., 275., 283., 322., 256., 311.,254., 212., 203., 204., 172., 228., 199., 158., 171., 109., 88.,89., 58., 50., 75., 62., 86., 39., 32., 24.])
get_rows 中 a
array([[363, 109],[549, 88],[281, 89],[211, 58],[441, 50],[ 21, 75],[104, 62],[677, 86],[621, 39],[485, 32],[323, 24]])
a.argsort(0) 按列排序
array([[ 5, 10],[ 6, 9],[ 3, 8],[ 2, 4],[10, 3],[ 0, 6],[ 4, 5],[ 9, 7],[ 1, 1],[ 8, 2],[ 7, 0]])
取出 x 的排序索引 a.argsort(0)[:, 0]
array([ 5, 6, 3, 2, 10, 0, 4, 9, 1, 8, 7])
得到排序后的结果 a[a.argsort(0)[:, 0]]
array([[ 21, 75],[104, 62],[211, 58],[281, 89],[323, 24],[363, 109],[441, 50],[485, 32],[549, 88],[621, 39],[677, 86]])
可视化结果,同一行的点连成线,绘制点,标上序号
最终输出

我们设置的 4 行,可以看到有 4 条直线
3、效果展示
get_rows(img, centers, 4, h) 配置不同的行数看看效果
1 行

2 行

3 行

4 行

5 行

6 行

7 行

4、更多例子
输入图片

前处理后的图片

2 行输出结果

输入图片

前处理后的图片

2 行输出结果

可以看到没有闭合的轮廓被舍弃掉了
输入图片

前处理后的图片

10 行输出结果

输入图片

前处理后的图片

4 行输出结果

输入图片

前处理后的图片

6 行输出结果

输入图片

前处理后的图片

2 行输出结果

5、参考
- 使用OpenCV对点集从左上到右下排序
相关文章:
【python】OpenCV—Sort the Point Set from Top Left to Bottom Right
文章目录 1、功能描述2、代码实现3、效果展示4、更多例子5、参考 1、功能描述 给出一张图片,里面含有各种图形,取各种图形的中心点,从左到右从上到下排序 例如 2、代码实现 import cv2 import numpy as npdef process_img(img):img_gray c…...
LeetCode 1493.删掉一个元素以后全为1的最长子数组
题目: 给你一个二进制数组 nums ,你需要从中删掉一个元素。 请你在删掉元素的结果数组中,返回最长的且只包含 1 的非空子数组的长度。 如果不存在这样的子数组,请返回 0 。 思路:不定长滑动窗口,将问题…...
php常用设计模式之工厂模式
引言 在日常开发中,我们一些业务场景需要用到发送短信通知。然而实际情况考虑到不同厂商之间的价格、实效性、可能会出现的情况等 我们的业务场景往往会接入多个短信厂商来保证我们业务的正常运行,而不同的短信厂商(如阿里云短信、腾讯云短信…...
通用软件版本标识
软件版本标识:了解不同的版本类型 在软件开发和发布过程中,版本号和标识扮演着重要的角色。它们不仅帮助开发者追踪软件的演变,还让用户了解软件的稳定性和功能。以下是一些常见的软件版本标识,以及它们的含义和用途。 Alpha&am…...
(计算机毕设)基于SpringBoot的就业平台开题报告
一、立题依据(国内外研究进展或选题背景、研究意义等) 国内外研究进展或选题背景 在全球化的大背景下,就业问题一直是各国政府和社会各界关注的焦点。随着互联网技术的普及和发展,网络招聘已成为求职者和企业招聘的主要渠道。据相关数据显示࿰…...
STM32G4系列MCU的ADC模块标定方法和采样时间
目录 概述 1 ADC模块标定 1.1 功能介绍 1.2 软件程序校准ADC 1.2.1 标定步骤 1.2.2 标定时序框图 1.3 软件程序重新注入校准因子到ADC 1.3.1 标定步骤 1.3.2 更新ADC校准因子 1.4 用单个ADC转换单端和差分模拟输入 1.4.1 标定流程 1.4.2 混合单端和差分通道 2 通道…...
NVIDIA Jetson支持的神经网络加速的量化平台
NVIDIA Jetson支持的神经网络加速的量化工具、技术 NVIDIA Jetson 是专为边缘计算和嵌入式系统设计的高性能计算平台,它支持多种深度学习模型的部署和推理。对于神经网络加速的量化平台,Jetson 支持以下技术和工具: TensorRT:Ten…...
MySQL 免密登录的几种配置方式
文章目录 MySQL 免密登录的几种配置方式使用操作系统用户实现免密登录具体步骤:Step 1: 修改 MySQL 配置文件Step 2: 重启 MySQL 服务Step 3: 使用系统用户登录 MySQL优点:缺点: 使用 mysql_config_editor 配置免密文件具体步骤:S…...
html全局属性、框架标签
常用的全局属性: 属性名含义id 给标签指定唯一标识,注意:id是不能重复的。 作用:可以让label标签与表单控件相关联;也可以与css、JavaScript配合使用。 注意:不能再以下HTML元素中使用:<hea…...
ARL 灯塔 | CentOS7 — ARL 灯塔搭建流程(Docker)
关注这个工具的其它相关内容:自动化信息收集工具 —— ARL 灯塔使用手册 - CSDN 博客 灯塔,全称:ARL 资产侦察灯塔系统,有着域名资产发现和整理、IP/IP 段资产整理、端口扫描和服务识别、WEB 站点指纹识别、资产分组管理和搜索等等…...
抖音列表页采集-前言
准备工作: 1.关于selenium介绍: python自动化入门的话,selenium绝对是最方便的选择,基本逻辑即为:程序模拟人的行为操作浏览器,这样的操作需要借用浏览器驱动,我选用的是chrome浏览器ÿ…...
Linux 端口占用 kill被占用的端口 杀掉端口
1、yum install lsof 2、输入netstat -tln,查看系统当前所有被占用端口 3、根据端口查询进程,输入lsof -i :9555,切记不要忘了添加冒号 4、 既然知道进程号了,那杀死当前进程就简单多了,直接 kill -9 PID 回车...
爬虫之数据解析
数据解析 数据解析这篇内容, 很多知识涉及到的都是以前学习过的内容了, 那这篇文章我们主要以实操为主, 来展开来讲解关于数据解析的内容。 360搜索图片 请求的url大家不需要再找了, 相信大家都会找请求了, 寻找请求从我的第一篇爬虫的博客开始到现在一直都在写,这边的话, 我已…...
本地缓存少更改、小数据、低一致表的思考
对于那些少更改、小数据的表,以及对一致性要求不高的业务,其实完全可以通过本地缓存将表数据缓存到本地内存中,然后通过定时机制拉取表更新数据 直接从内存中获取数据,将会使得查询性能得到巨大的提升,并且由于更改少…...
redis 使用
打开redis 前台启动 同路径下打开redis-server 出现窗口,即启动成功 此时关闭窗口,redis关闭; 不管有没有使用密码,或者使用了什么密码,都能连上 如果使用下文提到的redis cli增加密码,就只能使用你设置的…...
使用 Pake 一键打包网页为桌面应用 / 客户端
项目 项目:https://github.com/tw93/Pake/ 免费ICO图片:https://icon-icons.com/zh/ 设置环境 以下教程仅针对windows系统适用 请确保您的 Node.js 版本为 18 或更高版本 文档:https://v1.tauri.app/zh-cn/v1/guides/getting-started/prerequ…...
vue.js【常用UI组件库】
Element Plus组件库 Element Plus是基于Vue 3开发的优秀的PC端开源UI组件库,它是Element的升级版,对于习惯使用Element的人员来说,在学习Element Plus时,不用花费太多的时间。因为Vue 3不再支持IE 11,所以Element Plu…...
基于vue框架的的地铁站智慧管理系统的设计n09jb(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
系统程序文件列表 项目功能:用户,上班打卡,下班打卡,人员管理,交接班,视频巡检,车辆巡检,车辆管理 开题报告内容 基于Vue框架的地铁站智慧管理系统的设计开题报告 一、研究背景与意义 随着城市化进程的加速,地铁站作为城市交通系统的重要组成部分&am…...
《南京师大学报(自然科学版)》
《南京师大学报(自然科学版)》刊载内容主要包括:数学;物理学;化学;地理学;海洋科学;生物学;生态学;力学;电子科学与技术;计算机科学与…...
考研读研生存指南,注意事项
本视频课程,涉及考研读研的方方面面,从考研初试→复试面试→研究生生活→导师相处→论文专利写作混毕业,应有尽有。有了他,你的研究生生涯稳了。 读研考研注意事项,研究生生存指南。_哔哩哔哩_bilibili 一、考研初试注…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
