本文总结了使用Python进行机器视觉(图像处理)编程时常用的数据结构,主要包括以下内容:
数据结构
序列操作:索引(indexing)、分片(slicing)、加(adding)、乘(multipying)等
列表:创建、list函数、基本操作:赋值、删除、分片赋值、插入、排序等
元组:创建、tuple函数、基本操作
NumPy数组:创建数组、创建图像、获取形状、维度、元素个数、元素类型、访问像素、通道分离、使用mask
1. 数据结构
数据结构是通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些数据元素可以是数字或者字符,甚至可以是其他数据结构。在Python中最基本的数据结构是序列(sequence)。序列中每个元素被分配一个序号——即元素的位置,也称为索引(index),第一个元素的索引是0,第二个是1,以此类推。
python包含6种內建序列,最常用的两种类型是:列表和元组。列表和元组的主要区别在于列表可以修改,元组不可以修改。而用于处理图像的基本数据结构是数组,由于Python标准库中的內建数组只能处理一维数组并且提供的功能较少,因此做编程时常使用NumPy模块的array()数组表示图像,并进行各类处理。
2. 通用序列操作
所有序列都可以进行某些特定操作,包括:索引(indexing)、分片(slicing)、加(adding)、乘(multipying)以及检查某个元素是否属于序列成员(成员资格),除此之外,python还有计算序列长度、找出最大元素和最小元素的內建函数。
(1)索引
序列中所有元素的编号都是从0开始递增。
>>>greeting = 'Hello'
>>>greeting[0]
'H'
>>>greeting[1]
'e'
所有序列都可以通过这种方式获取元素。最后一个元素的编号是-1
>>>greeting[-1]
'o'
如果一个函数调用返回一个序列,则可以直接对返回序列进行索引操作
>>>fourth = raw_input('Year: ')[3]
Year: 2016
>>>fourth
6
(2)分片
使用分片操作来方位一定范围内的元素。分片通过冒号隔开两个索引来实现。
>>>tag='Python web site'
>>>tag[9:30]
'"http://www.python.org '
>>>numbers=[1,2,3,4,5,6,7,8,9,10]
>>>numbers[3:6]
[4,5,6]
>>>numbers[0:1]
[1]
注意索引边界:第1个索引的元素包含在分片内,第2个索引的元素不在分片内,如果要索引最后一个元素
>>>numbers[-3:]
[8,9,10]
>>>print numbers[-1:]
[10]
这种方法同样适用于序列开始的元素:
>>>numbers[:3]
[1,2,3]
如果需要复制整个序列,可以将两个索引都置空:
>>>numbers[:]
[1,2,3,4,5,6,7,8,9,10]
我们还可以使用第三个参数设置分片的步长,下面代码为从numbers序列中选出从0到10,步长为2的元素
>>>numbers[0:10:2]
[1,3,5,7,9]
如果要将每4个元素中的第1个提取出来可以这样写
>>>numbers[::4]
[1,5,9]
步长为负数将向左提取元素,当使用负数作为步长时开始的点的索引必须大于结束点的索引
>>>number[8:3:-1]
[9,8,7,6,5]
>>>numbers[10:0:-2]
[10, 8, 6, 4, 2]
(3)序列相加
使用+运算符可以进行序列的连接操作:
>>>[1,2,3] + [4,5,6]
[1,2,3,4,5,6]
>>>'Hello, ' + 'world!'
'Hello, world!'
注意同种类型的序列才能连接到一起,列表和字符串是无法连接的。
(4)乘法
数字x乘以序列会生成新的序列。新序列中,原来的序列将被重复x次
>>>'pyhton' * 5
'pyhtonpyhtonpyhtonpyhtonpyhton'
>>>[42]*10
[42,42,42,42,42,42,42,42,42,42]
(5)None空列表和初始化
空列表可以通过两个中括号中间什么都不写表示[]
如果想创建一个占用 10个元素空间,却不包括任何有用内容的列表,可以用:
>>>[0]*10
None是一个Python的內建值,它的确切含义是这里什么都没有。
>>>[None]*10
(6)成员资格in
为了检查一个值是否在列表中,可以使用in运算符,返回布尔值真或假:
>>>permission = 'rw'
>>>'w' in permission
True
>>>'x' in permission
False
下面的例子,检查用户名和PIN码:
database = [
['albert', '1234'],
['dilbert','4242'],
['smith', '7524'],
['jones', '9843']
]
username = raw_input('User name: ')
pin = raw_input('PIN code: ')
if [username,pin] in database:
print 'Access granted'
运行结果:
User name: jones
PIN code: 9843
Access granted
(7)长度、最小值和最大值
內建函数len,min,max
>>>numbers[100,34,678]
>>>len(numbers)
3
>>>max(numbers)
678
>>>min(numbers)
34
>>>max(2,3)
3
>>>min(2,3,4,5)
2
3. 列表
(1)list函数
因为字符串不能像列表一样修改,所以有时候根据字符串创建列表很有用
>>>list('Hello')
['H','e','l','l','o']
list适用于所有类型的序列,而不只是列表。
(2)列表基本操作
元素赋值
>>>x=[1,1,1]
>>>x[1]=2
>>>x
[1,2,1]
删除元素
>>>x=[1,2,3]
>>>del x[1]
>>>x
[1,3]
del也可删除其他元素,甚至是变量。
分片赋值
>>>name=list('Perl')
>>>name
['P','e','r','l']
>>>name[2:]=list('ar')
>>>name
['P','e','a','r']
通过分片赋值插入元素和删除元素
>>>numbers=[1,5]
>>>numbers[1:1]=[2,3,4]
>>>numbers
[1,2,3,4,5]
>>>numbers[1:4]=[]
>>>numbers
[1,5]
(3)列表方法
列表方法的使用:对象.方法(参数)
append 在列表末尾追加
>>>a = [1,2,3]
>>>a.append['4']
>>>a
[1,2,3,4]
count 统计某个元素在列表中出现的次数
>>>['to','go','will','be','to','not'].count('to')
2
extend 在列表末尾一次性追加另一个序列中的多个值
>>>a = [1,2,3]
>>>b = [4,5,6]
>>>a.extend(b)
>>>a
[1,2,3,4,5,6]
>>>c = [1,2,3]
>>>d = [4,5,6]
>>>c+d
[1,2,3,4,5,6]
>>>c
[1,2,3]
index 从列表中找出某个值第一个匹配项的索引位置
>>>slogen= ['we', 'are', 'the', 'champion']
>>>slogen.index('are')
1
>>> slogen[1]
'are'
insert 将对象插入到列表中
>>>numbers=[1,2,3,4,6]
>>>numbers.insert(4,'five')
>>>numbers
[1, 2, 3, 4, 'five', 6]
第1个参数为插入的位置,在此索引前插入;
第2个参数为插入的元素内容
insert方法的操作也可用分片的方法实现元素插入
>>>numbers=[1,2,3,4,6]
>>>numbers[4:4]=['five']
>>>numbers
[1, 2, 3, 4, 'five', 6]
pop 移除列表中的一个元素
pop方法可实现一个常见的数据结构——栈。栈的原理就像堆盘子,只能在顶部放一个盘子,同样也只能从顶部拿走一个盘子。最后被放入堆栈的元素最先被移除。(此原则称为后进先出,LIFO)。
pop()方法默认移除列表中的最后一个元素,并返回该元素的值
>>>numbers=[1,2,3,4,5]
>>>numbers.pop()
5
>>> numbers
[1, 2, 3, 4]
如果想要移除列表中的第一个元素,可以用pop(0)
>>>numbers=[1,2,3,4,5]
>>>numbers.pop(0)
1
>>> numbers
[2, 3, 4, 5]
Python没有入栈操作,可以用append方法代替。
如果想要实现一个先进先出(FIFO)队列,可以使用insert(0,...)来替代append方法。或者也可以使用append方法,但必须用pop(0)替代pop()。也可使用collection模块中的deque对象。
remove 移除列表中的某个值的第一个匹配项
>>>x=['to','go','will','be','to','not']
>>>x.remove('to')
>>>x
['go','will','be','to','not']
reverse 将列表中的元素反向存放
>>>x=[1,2,3]
>>>x.reverse()
>>>x
[3,2,1]
sort 在原始位置对列表进行排序
在原始位置排序将改变原来的列表,从而让其中的元素能按一定的顺序重新排列,而不是简单的返回一个排序的列表副本。
>>>x=[3,1,2,6,4,5,7,9,8]
>>>x.sort()
>>>x
[1,2,3,4,5,6,7,8,9]
注意:sort方法只改变原始列表的排序,并没有返回值。如果需要一个重新排序的列表副本,应该如下操作:
>>>x=[3,1,2,6,4,5,7,9,8]
>>>y=x[:] #不能直接y=x
>>>y.sort()
>>>y
[1,2,3,4,5,6,7,8,9]
>>>x
[3,1,2,6,4,5,7,9,8]
注意:y=x只是让y和x指向同一个列表,而y=x[:]是复制整个x列表给y。
sorted 获取排序列表的副本
>>>x=[3,1,2,6,4,5,7,9,8]
>>>y=sorted(x)
>>>y
[1,2,3,4,5,6,7,8,9]
>>>x
[3,1,2,6,4,5,7,9,8]
sort方法的高级排序
希望列表元素能按照特定的方式排序(而不是sort函数默认的方式,即根据Python默认排序规则按升序排列元素),可以通过compare(x,y)的形式自定义比较函数。compare(x,y)函数会在xy时返回正数,如果x=y则返回0(根据自己定义)。定义好该函数后,可以提供给sort方法作为参数。內建函数cmp提供了比较函数的默认实现方式:
>>>cmp(16,12)
1
>>>cmp(10,12)
-1
>>>cmp(10,10)
0
>>>numbers=[1,4,2,9]
>>>numbers.sort(cmp)
>>>numbers
[1,2,4,9]
sort方法还有另外两个参数可选,可以通过某个名字来指定该参数(关键字参数):
参数:key
提供一个在排序中使用的函数,该函数不是直接确定对象的大小,而是为每个元素创建一个键,然后所有元素根据键来排序。
>>>x=['nor','break','if','then','present']
>>>x.sort(key=len) # 按字符串长度排序
>>>x
['if', 'nor', 'then', 'break', 'present']
评论
查看更多