參數:reverse
另一個關鍵字參數reverse是簡單的布爾值,用于指明是否要進行反向排序
>>> x=[3,1,2,6,4,5,7,9,8]
>>> x.sort(reverse=True)
>>>x
[9, 8, 7, 6, 5, 4, 3, 2, 1]
注意:cmp,key,reverse參數都可用于sorted函數。
4. 元組
元組與列表一樣,也是一種序列,但元組是不可變列表,元組不能修改。
元組的作用
體現在映射(和集合的成員)中當做鍵使用——列表不行
元組在很多內建函數的返回值存在,也就是說我們必須對元組進行處理
(1)創建元組
創建一個元組
>>>1,2,3
(1,2,3)
元組大部時候通過圓括號括起來
>>>x=(1,2,3)
>>>x
(1,2,3)
創建一個空元組
空元組可以用沒有內容的空括號括起來
>>>()
()
創建一個包含一個元素的元組
>>>(10,)
(10,)
是的,一個元素也需要用逗號。逗號很重要,看下面的例子
>>>2*(3+2)
10
>>>2*(3+2,)
(5, 5)
不加逗號為數字,加逗號就是元組。
(2)tuple函數
tuple函數以一個序列作為參數并轉換為元組,如果參數本身就是元組,則不發生變化。
>>>tuple([1,2,3])
(1,2,3)
>>>tuple(['a','b','c'])
('a','b','c')
>>>tuple((1,2,3))
(1,2,3)
(3)元組基本操作
元組除了創建和訪問其元素外,沒有太多其他操作,元組操作與操作其他序列類似。
>>>x=1,2,3
>>>x[1]
2
>>>x[0:2]
(1,2)
5. NumPy的array(數組)對象
NumPy模塊用于python計算機視覺編程時的向量、矩陣的表示與操作,是opencv for python的主要數據結構模塊。NumPy中的數組對象array是多維的,可以用來表示向量、矩陣和圖像。一個數組對象很像一個列表(或者是列表的列表),但數組中的元素必須具有相同的數據類型。除非創建數組對象時指定數據類型,否則數據類型會按照數據的類型自動確定。
本節代碼假定已經以如下形式導入OpenCV和NumPy兩個庫
import cv2
import numpy as np
(1)np.array()創建數組
>>> a = np.array([1, 2, 3, 4])
>>> b = np.array((5, 6, 7, 8))
>>> c = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])
>>> b
array([5, 6, 7, 8])
>>> c
array([[1, 2, 3, 4],
[4, 5, 6, 7],
[7, 8, 9, 10]])
>>> d = np.arange(15).reshape(3, 5)
>>> d
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
(2)np.array()創建黑白圖像
使用np.zeros()創建一幅圖像,dtype為元素數據類型,下文有具體分析,8位灰度圖像為uint8型。接著用np.ones()創建一幅圖像,通過賦值稱為一幅白色圖像。
img1 = np.ones((100,200),dtype=np.uint8)
img2 = np.ones((100,200),dtype=np.uint8)
img2[:]=255;
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.waitKey(0)
?
彩色圖像的創建需要指定一個3維數組,具體方法請看下文。
(3)ndarray.shape屬性獲得/修改數組形狀
獲取數組 shape 屬性
數組的形狀可以通過其shape 屬性獲得,它是一個描述數組各個軸長度的元組(tuple),看看上文定義的a,c數組的shape屬性:
>>> a.shape
(4,)
>>> c.shape
(3, 4)
數組a的shape 屬性只有一個元素,因此它是一維數組。而數組c的shape屬性有兩個元素,因此它是二維數組,其中第0軸的長度為3,第1軸的長度為4。
獲取圖像的寬高
圖像本質是矩陣,因此可以使用shape屬性獲取圖像矩陣的行、列和通道數,如果圖像是灰度圖,則沒有第3個參數。我們也可以用ndim方法判斷圖像通道數:
img = cv2.imread('f:/images/cow.jpg')
rows,cols,channels = img.shape
print 'rows,cols,channels = ',rows,cols,channels
print 'demension = ',img.ndim
cv2.imshow('test',img)
cv2.waitKey(0)
運行結果:
rows,cols,channels = 400 600 3
demension = 3
修改數組 shape 屬性
可以通過修改數組的shape 屬性,在保持數組元素個數不變的情況下,改變數組每個軸的長度。下面的例子將數組c的shape 屬性改為(4,3),注意:從(3,4)改為(4,3)并不是對數組進行轉置,而只是改變每個軸的大小,數組元素在內存中的位置并沒有改變。
>>> c = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])
>>> c.shape = 4,3
>>> c
array([[ 1, 2, 3],
[ 4, 4, 5],
[ 6, 7, 7],
[ 8, 9, 10]])
當設置某個軸的元素個數為-1 時,將自動計算此軸的長度。由于數組c 中有12 個元素,因此下面的程序將數組c 的shape 屬性改為了(2,6):
>>> c.shape = 2,-1
>>> c
array([[ 1, 2, 3, 4, 4, 5],
[ 6, 7, 7, 8, 9, 10]])
使用數組的reshape()方法,可以創建指定形狀的新數組,而原數組的形狀保持不變
>>> a = np.array([1, 2, 3, 4])
>>> e = a.reshape((2,2)) # 也可以用a.reshape(2,2)
>>> e
array([[1, 2],
[3, 4]])
>>> a
array([1, 2, 3, 4])
注意:數組a 和e 其實共享數據存儲空間,因此修改其中任意一個數組的元素都會同時修改另外一個數組的內容:
>>> a[1] = 100 # 將數組a 的第一個元素改為100
>>> e # 注意數組d 中的2 也被改為了100
array([[ 1, 100],
[3, 4]])
(4)ndarray.ndim屬性:數組維度
返回數組的軸數量,即維度。在Python中維度稱為rank
(5)ndarray.dtype屬性:數組元素類型
數組的元素類型可以通過dtype 屬性獲得。前面例子中,創建數組所用序列的元素都是整數,因此所創建的數組的元素類型是整型,并且是32bit 的長整型:
>>> c.dtype
dtype('int32')
>>>print img1.dtype
uint8
NumPy 中的數據類型都有幾種字符串表示方式,字符串和類型之間的對應關系都存儲在typeDict 字典中,例如'd'、'double'、'float64'都表示雙精度浮點類型:
>>> np.typeDict["d"]
>>> np.typeDict["double"]
>>> np.typeDict["float64"]
完整的類型列表可以通過下面的語句得到,它將typeDict字典中所有的值轉換為一個集合,從而去除其中的重復項:
>>> print set(np.typeDict.values())
set([, ,
, ,
, ,
, ,
, ,
, ,
, ,
, ,
, ,
, ,
, ,
, ])
(6)ndarray.size屬性:數組元素個數
數組中所有元素的個數。這個參數等于shape屬性返回的參數的乘積。
>>>print img1.shape
(100,200)
>>>print img1.size
20000
(7)ndarray.itemsize屬性:單個數組元素所占字節數
數組單個元素所占的字節數。例如,數組元素為float64型時,其itemsize=8 (=64/8)。如果是復數complex32類型,則itemsize 4 (=32/8)。
>>>print img1.itemsize
1
(8)ndarray.data屬性:實際數組元素的緩存
通常用不到這個屬性,因為可以通過下標方位數組元素。
(9)訪問像素/訪問多維數組元素
NumPy的array數組對象與Python中的序列一樣,可以通過下標、切片的方式訪問。
多維數組的存取和一維數組類似,因為多維數組有多個軸,因此它的下標需要用多個值表示。NumPy 采用元組(tuple)作為數組的下標,元組中的每個元素和數組的每個軸對應。下圖顯示了一個形狀為(6,6)的數組a,圖中用不同顏色和線型標識出各個下標對應的選擇區域。
>>> a = np.arange(0, 60, 10).reshape(-1, 1) + np.arange(0, 6)
>>> a
array([[ 0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
?
Python 的下標語法(用[]存取序列中的元素)本身并不支持多維,但是由于可以使用任何對象作為下標,因此NumPy 使用元組作為下標存取數組中的元素,使用元組可以很方便地表示多個軸的下標。雖然在Python 程序中,經常用圓括號將元組的元素括起來,但其實元組的語法只需要用逗號隔開元素即可,例如“x,y=y,x”就是用元組交換變量值的一個例子。因此a[1,2]和a[(1,2)]完全相同,都是使用元組(1,2)作為數組a 的下標。
(10)np.array()創建彩色圖像
下面的例子通過創建一個3維數組作為3通道彩色圖像,并給不同通道賦值,創建兩幅不同的色彩圖像:
import cv2
import numpy as np
import random
# create a blue image
img3 = np.zeros((100,200,3),dtype=np.uint8)
img3[:,:,0]=255 # blue channel
# create a random color image
img4 = np.zeros((100,200,3),dtype=np.uint8)
seq = xrange(0,255)
ch0 = random.sample(seq,200)
ch1 = random.sample(seq,200)
ch2 = random.sample(seq,200)
img4[0:200,:,0] = ch0
img4[0:200,:,1] = ch1
img4[0:200,:,2] = ch2
# display image
cv2.imshow('img3',img3)
cv2.imshow('img4',img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
?
(11)通道分離
下面的代碼實現BGR通道分離:
img = cv2.imread('f:/images/Lena.jpg')
b = np.zeros((img.shape[0],img.shape[1]), dtype=img.dtype)
g = np.zeros((img.shape[0],img.shape[1]), dtype=img.dtype)
r = np.zeros((img.shape[0],img.shape[1]), dtype=img.dtype)
b[:,:] = img[:,:,0]
g[:,:] = img[:,:,1]
r[:,:] = img[:,:,2]
cv2.imshow("Blue", r)
cv2.imshow("Red", g)
cv2.imshow("Green", b)
cv2.waitKey(0)
cv2.destroyAllWindows()
?
(12)設置mask屏蔽不感興趣區域
img = cv2.imread('f:/images/Lena.jpg',0)
mask = np.zeros((img.shape[0],img.shape[1]),dtype=img.dtype)
mask[img.shape[0]/4:3*img.shape[0]/4,img.shape[1]/4:3*img.shape[1]/4] = 255
img_mask = img.copy()
img_mask[mask==0]=0
cv2.imshow('mask',mask)
cv2.imshow('Lena_mask',img_mask)
cv2.imshow('Lena',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
讀取彩色或黑白圖像都可已使用上述代碼。讀取彩色圖像cv2.imread()的可選標志為置1。
評論