参数: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。
电子发烧友App

















评论