当前位置: 首页 > news >正文

【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_rowsf

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_rowsa

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、功能描述 给出一张图片&#xff0c;里面含有各种图形&#xff0c;取各种图形的中心点&#xff0c;从左到右从上到下排序 例如 2、代码实现 import cv2 import numpy as npdef process_img(img):img_gray c…...

LeetCode 1493.删掉一个元素以后全为1的最长子数组

题目&#xff1a; 给你一个二进制数组 nums &#xff0c;你需要从中删掉一个元素。 请你在删掉元素的结果数组中&#xff0c;返回最长的且只包含 1 的非空子数组的长度。 如果不存在这样的子数组&#xff0c;请返回 0 。 思路&#xff1a;不定长滑动窗口&#xff0c;将问题…...

php常用设计模式之工厂模式

引言 在日常开发中&#xff0c;我们一些业务场景需要用到发送短信通知。然而实际情况考虑到不同厂商之间的价格、实效性、可能会出现的情况等 我们的业务场景往往会接入多个短信厂商来保证我们业务的正常运行&#xff0c;而不同的短信厂商&#xff08;如阿里云短信、腾讯云短信…...

通用软件版本标识

软件版本标识&#xff1a;了解不同的版本类型 在软件开发和发布过程中&#xff0c;版本号和标识扮演着重要的角色。它们不仅帮助开发者追踪软件的演变&#xff0c;还让用户了解软件的稳定性和功能。以下是一些常见的软件版本标识&#xff0c;以及它们的含义和用途。 Alpha&am…...

(计算机毕设)基于SpringBoot的就业平台开题报告

一、立题依据(国内外研究进展或选题背景、研究意义等) 国内外研究进展或选题背景 在全球化的大背景下&#xff0c;就业问题一直是各国政府和社会各界关注的焦点。随着互联网技术的普及和发展&#xff0c;网络招聘已成为求职者和企业招聘的主要渠道。据相关数据显示&#xff0…...

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 是专为边缘计算和嵌入式系统设计的高性能计算平台&#xff0c;它支持多种深度学习模型的部署和推理。对于神经网络加速的量化平台&#xff0c;Jetson 支持以下技术和工具&#xff1a; TensorRT&#xff1a;Ten…...

MySQL 免密登录的几种配置方式

文章目录 MySQL 免密登录的几种配置方式使用操作系统用户实现免密登录具体步骤&#xff1a;Step 1: 修改 MySQL 配置文件Step 2: 重启 MySQL 服务Step 3: 使用系统用户登录 MySQL优点&#xff1a;缺点&#xff1a; 使用 mysql_config_editor 配置免密文件具体步骤&#xff1a;S…...

html全局属性、框架标签

常用的全局属性&#xff1a; 属性名含义id 给标签指定唯一标识&#xff0c;注意&#xff1a;id是不能重复的。 作用&#xff1a;可以让label标签与表单控件相关联&#xff1b;也可以与css、JavaScript配合使用。 注意&#xff1a;不能再以下HTML元素中使用&#xff1a;<hea…...

ARL 灯塔 | CentOS7 — ARL 灯塔搭建流程(Docker)

关注这个工具的其它相关内容&#xff1a;自动化信息收集工具 —— ARL 灯塔使用手册 - CSDN 博客 灯塔&#xff0c;全称&#xff1a;ARL 资产侦察灯塔系统&#xff0c;有着域名资产发现和整理、IP/IP 段资产整理、端口扫描和服务识别、WEB 站点指纹识别、资产分组管理和搜索等等…...

抖音列表页采集-前言

准备工作&#xff1a; 1.关于selenium介绍&#xff1a; python自动化入门的话&#xff0c;selenium绝对是最方便的选择&#xff0c;基本逻辑即为&#xff1a;程序模拟人的行为操作浏览器&#xff0c;这样的操作需要借用浏览器驱动&#xff0c;我选用的是chrome浏览器&#xff…...

Linux 端口占用 kill被占用的端口 杀掉端口

1、yum install lsof 2、输入netstat -tln,查看系统当前所有被占用端口 3、根据端口查询进程,输入lsof -i :9555,切记不要忘了添加冒号 4、 既然知道进程号了,那杀死当前进程就简单多了,直接 kill -9 PID 回车...

爬虫之数据解析

数据解析 数据解析这篇内容, 很多知识涉及到的都是以前学习过的内容了, 那这篇文章我们主要以实操为主, 来展开来讲解关于数据解析的内容。 360搜索图片 请求的url大家不需要再找了, 相信大家都会找请求了, 寻找请求从我的第一篇爬虫的博客开始到现在一直都在写,这边的话, 我已…...

本地缓存少更改、小数据、低一致表的思考

对于那些少更改、小数据的表&#xff0c;以及对一致性要求不高的业务&#xff0c;其实完全可以通过本地缓存将表数据缓存到本地内存中&#xff0c;然后通过定时机制拉取表更新数据 直接从内存中获取数据&#xff0c;将会使得查询性能得到巨大的提升&#xff0c;并且由于更改少…...

redis 使用

打开redis 前台启动 同路径下打开redis-server 出现窗口&#xff0c;即启动成功 此时关闭窗口&#xff0c;redis关闭&#xff1b; 不管有没有使用密码&#xff0c;或者使用了什么密码&#xff0c;都能连上 如果使用下文提到的redis cli增加密码&#xff0c;就只能使用你设置的…...

使用 Pake 一键打包网页为桌面应用 / 客户端

项目 项目&#xff1a;https://github.com/tw93/Pake/ 免费ICO图片&#xff1a;https://icon-icons.com/zh/ 设置环境 以下教程仅针对windows系统适用 请确保您的 Node.js 版本为 18 或更高版本 文档&#xff1a;https://v1.tauri.app/zh-cn/v1/guides/getting-started/prerequ…...

vue.js【常用UI组件库】

Element Plus组件库 Element Plus是基于Vue 3开发的优秀的PC端开源UI组件库&#xff0c;它是Element的升级版&#xff0c;对于习惯使用Element的人员来说&#xff0c;在学习Element Plus时&#xff0c;不用花费太多的时间。因为Vue 3不再支持IE 11&#xff0c;所以Element Plu…...

基于vue框架的的地铁站智慧管理系统的设计n09jb(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,上班打卡,下班打卡,人员管理,交接班,视频巡检,车辆巡检,车辆管理 开题报告内容 基于Vue框架的地铁站智慧管理系统的设计开题报告 一、研究背景与意义 随着城市化进程的加速&#xff0c;地铁站作为城市交通系统的重要组成部分&am…...

《南京师大学报(自然科学版)》

《南京师大学报&#xff08;自然科学版&#xff09;》刊载内容主要包括&#xff1a;数学&#xff1b;物理学&#xff1b;化学&#xff1b;地理学&#xff1b;海洋科学&#xff1b;生物学&#xff1b;生态学&#xff1b;力学&#xff1b;电子科学与技术&#xff1b;计算机科学与…...

考研读研生存指南,注意事项

本视频课程&#xff0c;涉及考研读研的方方面面&#xff0c;从考研初试→复试面试→研究生生活→导师相处→论文专利写作混毕业&#xff0c;应有尽有。有了他&#xff0c;你的研究生生涯稳了。 读研考研注意事项&#xff0c;研究生生存指南。_哔哩哔哩_bilibili 一、考研初试注…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...