本文總結了使用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']
評論
查看更多