Python机器视觉:01- 利用列表和切片操作 - 做一个弧线和图片相交的mask区域

news2024/10/5 12:06:45

 前言:

Python的列表处理,在机器视觉中经常被用到,这里结合基本的概念+机器视觉实践案例,成文如下:

本身将实现一个,弧线的mask填充:这个mask是我的一个天文项目的应用,目的在于将月球从图中抠出来。


 

1 基础概念 - 序列:

序列是 Python 中最基本的数据结构。

序列中的每个值都有对应的位置值,称之为索引,第一个索引是 0,第二个索引是 1,依此类推。

1.1 python 序列的类型

Python 有 6 个序列的内置类型,但最常见的是列表和元组。

 1.1.1 列表:[List]

列表是最常见的序列类型之一,它是可变的,意味着你可以添加、删除或修改其中的元素。列表使用方括号[]表示,并包含一系列以逗号分隔的值。列表中的元素可以包含不同的数据类型,不需要全部相同。列表提供了11个内置方法,用于添加、删除、查找元素等操作。

# 定义一个列表 
my_list = [1, 'apple', 3.14, True]
# 打印列表 
print(my_list)

 

 

1.1.1.1  访问列表的索引

 

#!/usr/bin/python3

list = ['red', 'green', 'blue', 'yellow', 'white', 'black']
print( list[0] )
print( list[1] )
print( list[2] )

 red
green
blue

 1.1.1.2 从后面反向索引

#!/usr/bin/python3

list = ['red', 'green', 'blue', 'yellow', 'white', 'black']
print( list[-1] )
print( list[-2] )
print( list[-3] )

 black
white
yellow

  1.1.1.3 用下标访问列表中的值
#!/usr/bin/python3

nums = [10, 20, 30, 40, 50, 60, 70, 80, 90]
print(nums[0:4])
[10, 20, 30, 40]
 

 

  1.1.1.3 截取和拼接

1.1.2  元祖(Tuple)

元组与列表类似,也是一个序列类型,但是元组是不可变的,一旦创建就不能修改。元组使用小括号()表示,也可以包含逗号分隔的值。与列表不同,元组没有提供内置的方法,但可以转换为列表进行操作

# 定义一个元组 
my_tuple = (1, 'apple', 3.14, True)
# 打印元组 
print(my_tuple)

 

 

 

 1.1.3 字符串 “string”

字符串是一个不可变的序列类型,用于处理文本数据。字符串使用单引号'或双引号"表示,可以包含一系列字符。字符串中的字符可以是字母、数字、标点符号等

# 定义一个字符串 
my_string = "Hello, World!"
# 打印字符串 
print(my_string)

 1.1.4 其他不常用。

Unicode字符串

Unicode字符串与字符串类似,也是不可变的序列类型,但它支持多字节字符编码,可以表示全球各地的语言字符。Unicode字符串使用三个单引号'''或三个双引号"""

# 定义一个Unicode字符串 
my_unicode = """你好,世界!"""
# 打印Unicode字符串 
print(my_unicode)

缓冲区对象(Buffer Object)

缓冲区对象是一个较不常见的序列类型,它主要用于低级编程,如文件操作或内存映射。缓冲区对象使用方括号[]表示,但内部是通过缓冲区接口进行操作的13。

xrange对象

xrange对象是一个生成器类型,它用于生成一个整数序列。与列表不同,xrange不会占用大量的内存空间,它只生成序列的一部分。xrange对象使用三个参数表示范围,如xrange(start, stop, step)

 

# 使用xrange生成一个序列 
for i in xrange(10):
    print(i)

 


2 实践:

2.1 获取一个图片的四个顶点

2.1.1 拿到图片的尺寸

对应彩色的图片,通过如下的代码,可以先获取图片的尺寸:

import cv2
# 读取图像
image = cv2.imread('path_to_image.jpg')

# 获取图像尺寸
height, width, channels = image.shape

# 打印尺寸信息
print(f'Width: {width}, Height: {height}, Channels: {channels}')

 【案,

在OpenCV中,可以通过多种方式获取图像的尺寸信息。当你使用 cv2.imread() 函数读取图像后,图像会被存储在一个NumPy数组中,你可以通过该数组的 shape 属性来获取图像的尺寸。

对于彩色图像,shape 属性返回一个三元组 (height, width, channels),分别表示图像的高度、宽度和通道数(RGB三个颜色通道)。对于灰度图像,它返回的是二元组 (height, width),因为灰度图像只有一个通道。】

【案,这里图像的属性通过元祖来表示,原因是元祖他可以集成多种数据格式,同时元祖是不可以改变的】

import cv2
# 读取图像
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)

# 获取图像尺寸
height, width = image.shape

# 打印尺寸信息
print(f'Width: {width}, Height: {height}')

 【图像是灰度图像,那么 channels 将不存在】

2.1.2 拿到图片的四个顶点

上小节,拿到尺寸后,我们通过这个嵌套的列表,来表示图片的四个顶点坐标,

    # 获取矩形框的四个角点
    corners = np.array([
        [0, 0],
        [width - 1, 0],
        [width - 1, height - 1],
        [0, height - 1]
    ])

那么,如果是右侧的顶点
 

    # 获取矩形框的右侧两个角点
    right_corners = np.array([
        [width - 1, 0],
        [width - 1, height - 1]
    ])

2.2 构建一个弧段(含和图片的交点)这里略-将在其他章节介绍

假设弧段的点集为:

arc_points 

 我们可以拿到弧的起始点的坐标。

交点为:

intersection_points

2.3 现在构建mask区域

要构建一个mask,就必须构建一个封闭的区域。简单的想法,就是通过弧与图像边界的交点,来构建。

 # 构建一个封闭区域,包括弧段和右侧顶点
    polygon_points = np.vstack((arc_points, [arc_end_point], right_corners, [arc_start_point]))

    # 填充封闭区域为白色
    cv2.fillPoly(mask, [polygon_points], (255))

但是,问题出来,很明显,在构建MASK区域的时候,顶点的选择,由于顺序的问题,发生了交叉,大家可以看到下面的图片,因为交叉,所以,就出现,下面这个交织的情况。

而,我们希望是将弧段+边界构成MASK区域。 

 【案,问题的根源就是,我们构建参考点的时候,点的选取顺序也许发生了问题,

【案,这个图的标号,反映了红色错误的情况,和绿色正确的情况】

 于是,我们有了下面的修改,

 # 构建一个封闭区域,包括弧段和右侧顶点
    polygon_points = np.vstack((arc_points, [arc_end_point], right_corners[::-1], [arc_start_point]))

    # 填充封闭区域为白色
    cv2.fillPoly(mask, [polygon_points], (255))

【案,这里将构建封闭区域的点,构成一个封闭的点集,然后,利用fillPoly函数进行填充,形成mask】

【这里, right_corners[::-1] 反转了右侧顶点的顺序,这里就要用到我们前面关于python的列表的高级应用知识】


理论和实践的结合

  • right_corners: 这是一个变量名,代表一个列表或数组。这个列表中存储着一些表示右侧顶点的元素。
  • [::-1]: 这是Python列表切片的一种特殊用法,用于反转列表。

切片操作的详细解释:

  • :: 表示从列表的开头开始。
  • :: 表示到列表的末尾结束。
  • -1: 表示步长为-1,即从后向前取元素。

 

结合起来看:

  • right_corners[::-1] 的意思是:从 right_corners 列表的末尾开始,以步长-1的方式,一直取到列表的开头,从而形成一个新的列表,这个新列表中的元素顺序与原列表正好相反。
示例:
假设 right_corners 的值为 [1, 2, 3, 4],那么 right_corners[::-1] 的结果就是 [4, 3, 2, 1]。

调整结果:

 


参考:

Python3 列表 | 菜鸟教程

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

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

相关文章

冥想第一千三百零一天(1301)

1.今天上午溪溪和小侄子写作业,我带着桐桐去了惠济区的裕华广场永辉,给家人买了好吃的,下午4点半左右去了妈妈朋友家里摘石榴。 2.感谢父母,感谢朋友,感谢家人,感谢不断进步的自己。

JavaWeb 14.详解TCP协议的三次握手和四次挥手

目录 一、TCP协议与UDP协议 二、TCP协议 1、建立连接(三次握手) 过程 2、断开连接(四次挥手) 过程 国庆节快乐! 一文详解TCP协议中的三次握手建立连接和四次挥手断开连接 —— 24.10.3 一、TCP协议与UDP协议 tcp协议与…

【可答疑】基于51单片机的智能台灯(含仿真、代码、报告、演示视频等)

✨哈喽大家好,这里是每天一杯冰美式oh,985电子本硕,大厂嵌入式在职0.3年,业余时间做做单片机小项目,有需要也可以提供就业指导(免费)~ 🐱‍🐉这是51单片机毕业设计100篇…

MATLAB中minres函数用法

目录 语法 说明 示例 线性系统的迭代解 使用指定了预条件子的 minres 提供初始估计值 使用函数句柄代替数值矩阵 minres函数的功能是求解线性系统 - 最小残差法。 语法 x minres(A,b) x minres(A,b,tol) x minres(A,b,tol,maxit) x minres(A,b,tol,maxit,M) x mi…

CPU性能篇-平均负载-Day 01

1. 平均负载 1.1 什么是平均负载 平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。 1.1.1 什么是可运行状态 指正在使用 CPU 或者正在等待 CPU 的进程&#xff…

如何轻松查看你的 Windows 版本? 检查电脑Windows版本号五种方法

很多朋友发现windows拥有许多版本,比如如家庭版、企业版、专业版和教育版等,而每个版本都有相应的版本号,那么,怎么知道电脑windows版本呢?下面分享五种查看方法 自 1985 年首次推出以来,Windows 操作系统…

IntelliJ IDEA 2024.2 新特性概览

文章目录 1、重点特性:1.1 改进的 Spring Data JPA 支持1.2 改进的 cron 表达式支持1.3 使用 GraalJS 作为 HTTP 客户端的执行引擎1.4 更快的编码时间1.5 K2 模式下的 Kotlin 性能和稳定性改进 2、用户体验2.1 改进的全行代码补全2.2 新 UI 成为所有用户的默认界面2.3 Search E…

利用CRITIC客观权重赋权法进行数值评分计算——算法过程

1、概述 ‌CRITIC客观评价法是一种基于指标的对比强度和指标之间的冲突性来确定指标客观权数的方法。‌ 该方法适用于判断数据稳定性,并且适合分析指标或因素之间有着一定的关联的数据‌。 CRITIC方法的基本原理包括两个主要概念:对比强度和指标之间的…

Linux学习笔记(六):服务管理,监控,RPM包管理,yum包管理工具,Linux启动管理,网络管理

Linux学习笔记(六):服务管理,监控,RPM包管理,yum包管理工具,Linux启动管理,网络管理 1. 服务管理 1.1 service 启动/停止服务 service 命令是最常用的服务管理工具之一&#xff0c…

介质的分类

在有损的麦克斯韦方程中等效介电常数如下 所以理想介质的介电常数接近于实数,导体介电常数接近于复数 介质分类中不规定εμσ是实数还是复数,带入这个麦克斯韦方程组就行。不过在有损介质的电磁波公式推导中老师做出εμσ是实数的假设

【微服务】负载均衡 - LoadBalancer(day4)

下述所有代码都是在订单服务中修改的,商品服务并不需要修改,只需要启动多个实例即可。 引入 在介绍Eureka组件的最后,留下了一个问题就是,无论启动多少个实例,只能调用第一个。原因是因为服务调用时获取的是一个实例…

LM74912-Q1用作电源开关

LM74912电路设计及开发 LM74912-Q1,此芯片集成过压和短路保护以及故障输出功能的汽车理想二极管。正常的型号如下:LM74912QRGERQ1。 注: Q1的后缀指示此器件满足车规级器件/芯片要求。 一、原理框图 如下为芯片的简单应用框图;…

【可答疑】基于51单片机的数字时钟(含仿真、代码、报告等)

✨哈喽大家好,这里是每天一杯冰美式oh,985电子本硕,大厂嵌入式在职0.3年,业余时间做做单片机小项目,有需要也可以提供就业指导(免费)~ 🐱‍🐉这是51单片机毕业设计100篇…

脱口秀演员调侃王楚钦引争议

听说脱口秀演员调侃王楚钦输球,野生喜剧回应暂停演出合作,这不仅引发了关于脱口秀表演冒犯边界的讨论,也让我们反思言论自由与尊重他人之间的界限。 脱口秀作为一种艺术形式,其核心在于通过幽默、讽刺的方式,对社会现象…

畅享免费服务:PDF 转图片在线转换软件的魅力

为了方便在社交媒体上分享文档内容,还为了更好地适应特定的编辑需求,将 PDF 文件转换为图片格式都具有重要的意义。而如今,幸运的是,有许多pdf转图片在线转换免费工具为我们提供了便捷、高效的 PDF 转图片服务。接下来&#xff0c…

如何使用ssm实现基于SSM的宠物服务平台的设计与实现+vue

TOC ssm779基于SSM的宠物服务平台的设计与实现vue 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大,随着当前时代的信息化,科学化发展,让社会各行业领域都争相使用新的信息技术,对行业内的各种相关数据进行科学化&#x…

浅谈模型量化:非对称 vs 对称

模型量化的背后究竟做了什么?本文将以 INT8 为例,结合计算和代码演示,向你展示其中的一些原理。 相关论文: LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale 相关文章: 《07. 模型参数与显存的关系,以及不同精…

【机器学习】探索GRU:深度学习中门控循环单元的魅力

目录 🍔 GRU介绍 🍔 GRU的内部结构图 2.1 GRU结构分析 2.2 GRU工作原理 2.4 Bi-GRU介绍 2.3 使用Pytorch构建GRU模型 2.5 GRU优缺点 🍔 小结 学习目标 🍀 了解GRU内部结构及计算公式. 🍀 掌握Pytorch中GRU工具…

map和 set

[本节目标] 关联式容器 键值对 树形结构的关联式容器 底层结构 🏷️ 关联式容器 序列式容器:vector list 栈 队列 (类似以前学习的线性表)… 关联式容器: map set … 关联式容器,数据与数据之间有很强的关联,并…

C++函数指针类型

// // Created by 徐昌真 on 2024/10/5. // #include <iostream>//函数指针类型 指针变成了一个类型 类似int这种 用于反复调用这个函数指针的情况 避免频繁创建一堆的函数指针using namespace std;typedef void (*fptr)(int a, double b, char c); //typedef 将fptr定义…