编译器:PyCharm 2023.2.1 (Professional Edition)
编译环境:python3.11
库:cv2,numpy
一、Numpy创建数组
1.常规array()方法
out = numpy.array(object,dtype,copy,order,subok,ndmin)
参数:
object:必选参数,类型为array_like,可以有四种类型:数组,公开数组接口的任何对象,__array__方法返回数组的对象,或任何(嵌套)序列。np.array()的作用就是按照一定要求将object转换为数组。
dtype:可选参数,用来表示数组元素的类型。通过它可以更改数组的数据类型---可将原来的整型或者其他类型进行强制转换,如果没有给出,那么类型将被确定为保持序列中的对象所需的最小类型。 注: This argument can only be used to ‘upcast’ the array. For downcasting, use the .astype(t) method.
copy:可选参数,类型为bool值。如果为true(默认值),则复制对象。否则的话只有在以下三种情况下才会返回副本:(1.if __array__ returns a copy; # (2.if obj is a nested sequence;(3.if a copy is needed to satisfy any of the other requirements (dtype, order, etc.)
order:{‘K’, ‘A’, ‘C’, ‘F’}。指定阵列的内存布局。C(行序列)/F(列序列)/A(原顺序)(默认)/k(元素在内存中的出现顺序)
subok:可选参数,类型为bool值。如果为True,则子类将被传递,否则返回的数组将被强制为基类数组(默认)。或者说,True:使用object的内部数据类型, # 这意味着对象可以包含不同类型的数据,例如整数、字符串等。这种方式可以提供更大的灵活性,但也可能导致类型错误和性能问题。False:使用object数组的数据类型
ndmin:可选参数,类型为int型。指定结果数组应具有的最小维数。
out:返回对象输出ndarray,满足指定要求的数组对象
eg:
n1 = np.array([1, 2, 3]) # 创建一维数组
n2 = np.array([0.1, 0.2, 0.3]) # 包含小数的一维数组
n3 = np.array([[2, 3], [4, 5]]) # 二维数组
n1 = np.array(n1, dtype=np.float_) # 强制转化为浮点型数组 或者 n1 = np.array(n1, dtype=float)
n1 = np.array(n1, ndmin=3) # 三维数组
2.创建指定维度和数据类型为初始化的数组:
empty()方法此方法用来创建一个指定维度(shape)、数据类型(dtype)的未初始化的数组。
out = numpy.empty(shape, dtype order)
参数:
shape:一个表示数组维度的元组(大小与形状)
dtype:数据类型 # order:有 “C” 和 “F” 两个选项
注:np.empty并没有给出真正的随机值。(empty()数组在定义普通NumPy数组后不提供随机浮点) 那么,未初始化或任意表示什么呢?要理解,当您创建对象(任何对象)时,您需要向某人(某个人可以是NumPy内部人员、Python或您的操作系统)请求所需的内存。 因此,当您创建一个空数组时,NumPy请求内存。NumPy数组的内存量将是对象的一些开销,以及包含数组值的一定数量的内存量。那种记忆可能包含任何东西。因此,“未初始化值”意味着它只包含内存中的任何内容。 这里发生的一切只是巧合。您创建了一个包含一个浮点数的数组,然后打印它,然后它再次被销毁,因为您没有保存对它的引用(尽管这是特定于CPython的,但是其他的Python实现可能不会立即释放内存,它们最终只是释放它)。 然后创建一个包含一个浮点数的空数组。第二个数组的内存量与第一个内存刚刚释放的内存量相同。这是巧合的地方:所以可能有什么东西(NumPy、Python或您的操作系统)决定再次给出相同的内存位置。
eg: n4 = np.empty([2, 3])
3.创建用0填充的数组
numpy.zeros(shape, dtype=float,order)
参数:
shape:创建的新数组的形状(维度)。
dtype:创建新数组的数据类型,可选参数,默认numpy.float64
order:可选参数,C代表行优先;F代表列优先 # 返回值:给定维度的全零数组。
eg: n5 = np.zeros((3, 3), np.uint8)
4.创建用1填充的数组
n6 = np.ones((3, 3), np.uint8) #
注:np.ones定义图像时,如果没有定义类型,他默认输出的是浮点数型, print(n6)
5.创建随机数组
np.random.randint() 根据参数中所指定的范围生成随机 整数。
numpy.random.randint(low, high=None, size=None, dtype=int)
参数 :
low: int 生成的数值的最小值(包含),默认为0,可省略。
high: int 生成的数值的最大值(不包含!)。
size: int or tuple of ints 随机数的尺寸, 默认是返回单个,输入 10 返回 10个,输入 (3,4) 返回的是一个 3*4 的二维数组。(可选)。
dtype:想要输出的结果类型。默认值为int。(可选,一般用不上)。
print("随机生成10个1~3且不包括3的整数:", np.random.randint(1, 3, 10))
print("size:数组大小为空随机返回一个整数:", np.random.randint(5, 10))
print("随机生成5以内的二维数组:", np.random.randint(5, size=(2, 5)))
注: 省略low参数,后续参数要声明eg: size=(),dtype=...等
二、 Numpy操作数组
1.加、减、乘、除、幂、比较运算
n1 = np.array([1, 2])
n2 = np.array([3, 4])
print("n1-n2=", n1-n2)
print("n1+n2=", n1+n2)
print("n1*n2=", n1*n2)
print("n1/n2=", n1/n2)
print("n1**n2=", n1**n2)
print(">=", n1 >= n2) # 比较运算的结果是布尔值数组 eg: [False False]
print("==", n1 == n2)
print("<=", n1 <= n2)
print("!=", n1 != n2)
2.复制运算
1)深度拷贝
n2 = np.array(n1, copy=True) 或者n2 = np.array(n1) 效果也行,可选参数 copy:,类型为bool值。默认值为:true
n3 = n1.copy()
以上二种复制为 对对象的副本所做的任何更改都不反映在原始对象中
2)浅度拷贝,一个浅副本意味着构造一个新地集合对象,然后用对原始中找到的子对象的引用填充它。 复制过程不会重复,因此不会创建子对象本身的副本。
在浅拷贝的情况下,对象的引用被复制在另一个对象中。 这意味着对对象的副本所做的任何更改都会在原始对象中反映。
eg:
1. view()函数来实现浅副本。
2. 用 = 运算符创建一个共享原始对象引用的新变量。
三、Numpy数字索引和切片
1.一维数组的索引和切片
n1 = np.array([1, 2, 3, 4, 5, 6])
print(n1[1]) # 标准python语法x[obj]的语法对数组进行索引
print(n1[0:5:2]) # 切片索引[start:shop:step],左闭右开区间!!step不能为0
print(n1[0:6]) # 步长step默认1, 其正负表示索引方向
print(n1[:5]) # 起始索引start,若不写且step>0,为0
print(n1[0:]) # 终止索引stop,若不写且step>0,为数组正向的最后一位
print(n1[::-1]) # 起始索引start,若不写且step<0,为-1;终止索引stop,若不写且step<0,为数组逆向的最后一位
print(n1[-1:-5:-1]) # 逆向时,step必写
2.二维数组的索引和切片 与一维数组的索引和切片大同小异
四、Numpy创建图像
1.创建纯黑图像
image = np.zeros((100, 100), np.uint8) # 数组元素格式为无符号8位整数
2.创建纯白图像
image = np.ones((100, 200), np.uint8)*255 # 或者 image[:, :] = 255 # 改纯黑图像像素为255
3.创建黑白相间的图像
for i in range(0, 200, 20):
image[:, i:i+10] = 0
4.创建彩色图像# 纯蓝图像# 纯绿图像# 纯红图像
# opencv 中彩色图像的通道顺序为B->G->R
image = np.zeros((100, 200, 3), np.uint8)
blue = image.copy() blue[:, :, 0] = 255
green = image.copy() green[:, :, 1] = 255
red = image.copy() red[:, :, 2] = 255
5.创建随机图像#雪花图像#彩点图像
snow = np.random.randint(256, size=(100, 200), dtype=np.uint8)
color = np.random.randint(256, size=(100, 200, 3), dtype=np.uint8)
五、Numpy拼接图象
1.水平拼接数组:
array = numpy.hstack(tup) tup:要拼接的数组元组,array:将参数元组中的数组水平拼接后生成的新数组
2.垂直拼接数组:
array = numpy.vstack(tup) tup:要拼接的数组元组,array:将参数元组中的数组垂直拼接后生成的新数组
# 注:二者可拼接多个数组,但每个数组要“形状相同”
eg:
a = np.array([1, 1, 1])
b = np.array([2, 2, 2])
c = np.array([3, 3, 3])
result_hstack = np.hstack((a, b, c)) r
esult_vstack = np.vstack((a, b, c))
# 此处图像同数组操作一致
六、代码
import numpy as np
import cv2
# Numpy创建数组
# 1.常规array()方法
# numpy.array(object,dtype,copy,order,subok,ndmin)
# object:必选参数,类型为array_like,可以有四种类型:数组,公开数组接口的任何对象,__array__方法返回数组的对象,或任何(嵌套)序列。np.array()的作用就是按照一定要求将object转换为数组。
# dtype:可选参数,用来表示数组元素的类型。通过它可以更改数组的数据类型---可将原来的整型或者其他类型进行强制转换,如果没有给出,那么类型将被确定为保持序列中的对象所需的最小类型。
# 注: This argument can only be used to ‘upcast’ the array. For downcasting, use the .astype(t) method.
# copy:可选参数,类型为bool值。如果为true(默认值),则复制对象。否则的话只有在以下三种情况下才会返回副本:(1.if __array__ returns a copy;
# (2.if obj is a nested sequence;(3.if a copy is needed to satisfy any of the other requirements (dtype, order, etc.)
# order:{‘K’, ‘A’, ‘C’, ‘F’}。指定阵列的内存布局。C(行序列)/F(列序列)/A(原顺序)(默认)/k(元素在内存中的出现顺序)
# subok:可选参数,类型为bool值。如果为True,则子类将被传递,否则返回的数组将被强制为基类数组(默认)。或者说,True:使用object的内部数据类型,
# 这意味着对象可以包含不同类型的数据,例如整数、字符串等。这种方式可以提供更大的灵活性,但也可能导致类型错误和性能问题。False:使用object数组的数据类型
# ndmin:可选参数,类型为int型。指定结果数组应具有的最小维数。
# 返回对象
# out:输出ndarray,满足指定要求的数组对象
n1 = np.array([1, 2, 3]) # 创建一维数组
n2 = np.array([0.1, 0.2, 0.3]) # 包含小数的一维数组
n3 = np.array([[2, 3], [4, 5]]) # 二维数组
print(n1, '\n', n2, '\n', n3)
n1 = np.array(n1, dtype=np.float_) # 强制转化为浮点型数组
# 或者 n1 = np.array(n1, dtype=float)
print(n1, '\n', n1.dtype, '\n', type(n1[0]))
n1 = np.array(n1, ndmin=3) # 三维数组
print(n1)
# 2.创建指定维度和数据类型为初始化的数组:empty()方法
n4 = np.empty([2, 3])
# numpy.empty(shape, dtype order)
# 此方法用来创建一个指定维度(shape)、数据类型(dtype)的未初始化的数组。
# 参数:
# shape:一个表示数组维度的元组(大小与形状)
# dtype:数据类型
# order:有 “C” 和 “F” 两个选项
# 注:np.empty并没有给出真正的随机值。(empty()数组在定义普通NumPy数组后不提供随机浮点)
# 那么,未初始化或任意表示什么呢?要理解,当您创建对象(任何对象)时,您需要向某人(某个人可以是NumPy内部人员、Python或您的操作系统)请求所需的内存。
# 因此,当您创建一个空数组时,NumPy请求内存。NumPy数组的内存量将是对象的一些开销,以及包含数组值的一定数量的内存量。那种记忆可能包含任何东西。因此,“未初始化值”意味着它只包含内存中的任何内容。
# 这里发生的一切只是巧合。您创建了一个包含一个浮点数的数组,然后打印它,然后它再次被销毁,因为您没有保存对它的引用(尽管这是特定于CPython的,但是其他的Python实现可能不会立即释放内存,它们最终只是释放它)。
# 然后创建一个包含一个浮点数的空数组。第二个数组的内存量与第一个内存刚刚释放的内存量相同。这是巧合的地方:所以可能有什么东西(NumPy、Python或您的操作系统)决定再次给出相同的内存位置。
print(n4)
# 3.创建用0填充的数组
n5 = np.zeros((3, 3), np.uint8)
# numpy.zeros(shape, dtype=float,order)
# 各个参数意义:
# shape:创建的新数组的形状(维度)。
# dtype:创建新数组的数据类型,可选参数,默认numpy.float64
# order:可选参数,C代表行优先;F代表列优先
# 返回值:给定维度的全零数组。
print(n5)
# 4.创建用1填充的数组
n6 = np.ones((3, 3), np.uint8)
# 注:np.ones定义图像时,如果没有定义类型,他默认输出的是浮点数型,
print(n6)
# 5.创建随机数组
# np.random.randint() 根据参数中所指定的范围生成随机 整数。
# numpy.random.randint(low, high=None, size=None, dtype=int)
# 参数
# low: int 生成的数值的最小值(包含),默认为0,可省略。
# high: int 生成的数值的最大值(不包含!)。
# size: int or tuple of ints 随机数的尺寸, 默认是返回单个,输入 10 返回 10个,输入 (3,4) 返回的是一个 3*4 的二维数组。(可选)。
# dtype:想要输出的结果类型。默认值为int。(可选,一般用不上)。
print("随机生成10个1~3且不包括3的整数:", np.random.randint(1, 3, 10))
print("size:数组大小为空随机返回一个整数:", np.random.randint(5, 10))
print("随机生成5以内的二维数组:", np.random.randint(5, size=(2, 5)))
# 省略low参数,后续参数要声明eg: size=(),dtype=...等
# Numpy操作数组
# 1.加、减、乘、除、幂、比较运算
n1 = np.array([1, 2])
n2 = np.array([3, 4])
print("n1-n2=", n1-n2)
print("n1+n2=", n1+n2)
print("n1*n2=", n1*n2)
print("n1/n2=", n1/n2)
print("n1**n2=", n1**n2)
print(">=", n1 >= n2) # 比较运算的结果是布尔值数组
print("==", n1 == n2)
print("<=", n1 <= n2)
print("!=", n1 != n2)
# 2.复制运算
n2 = np.array(n1, copy=True) # n2 = np.array(n1) 效果也行,可选参数 copy:,类型为bool值。默认值为:true
print("==", n1 == n2)
n2[0] = 9
print("==", n1 == n2)
n3 = n1.copy()
print("==", n1 == n3)
n3[0] = 9
print("==", n1 == n3)
# 以上二种复制为 深度拷贝 对对象的副本所做的任何更改都不反映在原始对象中
# 浅度拷贝,一个浅副本意味着构造一个新地集合对象,然后用对原始中找到的子对象的引用填充它。 复制过程不会重复,因此不会创建子对象本身的副本。
# 在浅拷贝的情况下,对象的引用被复制在另一个对象中。 这意味着对对象的副本所做的任何更改都会在原始对象中反映。
# eg: 1. view()函数来实现浅副本。2. 用 = 运算符创建一个共享原始对象引用的新变量。
# Numpy数字索引和切片
# 1.一维数组的索引和切片
n1 = np.array([1, 2, 3, 4, 5, 6])
print(n1[1]) # 标准python语法x[obj]的语法对数组进行索引
print(n1[0:5:2]) # 切片索引[start:shop:step],左闭右开区间!!step不能为0
print(n1[0:6]) # 步长step默认1, 其正负表示索引方向
print(n1[:5]) # 起始索引start,若不写且step>0,为0
print(n1[0:]) # 终止索引stop,若不写且step>0,为数组正向的最后一位
print(n1[::-1]) # 起始索引start,若不写且step<0,为-1;终止索引stop,若不写且step<0,为数组逆向的最后一位
print(n1[-1:-5:-1]) # 逆向时,step必写
print(n1[:-5:-1])
print(n1[-2::-1])
# 2.二维数组的索引和切片
n1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(n1)
print(n1[0])
print(n1[-1])
print(n1[1, 2])
print(n1[-1, -2])
print(n1[0:2, 1:])
print(n1[0:3, 2])
print(n1[:, 2:3])
# Numpy创建图像
# 1.创建纯黑图像
image = np.zeros((100, 100), np.uint8) # 数组元素格式为无符号8位整数
cv2.imshow("black", image)
cv2.waitKey()
# 2.创建纯白图像
image = np.ones((100, 200), np.uint8)*255
# 或者 image[:, :] = 255
# 改纯黑图像像素为255
cv2.imshow("white", image)
cv2.waitKey()
# 3.创建黑白相间的图像
for i in range(0, 200, 20):
image[:, i:i+10] = 0
cv2.imshow("black_white", image)
cv2.waitKey()
cv2.destroyAllWindows()
# 4.创建彩色图像# 纯蓝图像# 纯绿图像# 纯红图像
# opencv 中彩色图像的通道顺序为B->G->R
image = np.zeros((100, 200, 3), np.uint8)
blue = image.copy()
blue[:, :, 0] = 255
cv2.imshow("blue", blue)
cv2.waitKey()
green = image.copy()
green[:, :, 1] = 255
cv2.imshow("green", green)
cv2.waitKey()
red = image.copy()
red[:, :, 2] = 255
cv2.imshow("red", red)
cv2.waitKey()
cv2.destroyAllWindows()
# 5.创建随机图像#雪花图像#彩点图像
snow = np.random.randint(256, size=(100, 200), dtype=np.uint8)
cv2.imshow("snow", snow)
cv2.waitKey()
color = np.random.randint(256, size=(100, 200, 3), dtype=np.uint8)
cv2.imshow("color", color)
cv2.waitKey()
cv2.destroyAllWindows()
# Numpy拼接图象
# 水平拼接数组:array = numpy.hstack(tup) tup:要拼接的数组元组,array:将参数元组中的数组水平拼接后生成的新数组
# 垂直拼接数组:array = numpy.vstack(tup) tup:要拼接的数组元组,array:将参数元组中的数组垂直拼接后生成的新数组
# 注:二者可拼接多个数组,但每个数组要“形状相同”
a = np.array([1, 1, 1])
b = np.array([2, 2, 2])
c = np.array([3, 3, 3])
result_hstack = np.hstack((a, b, c))
result_vstack = np.vstack((a, b, c))
print(result_hstack)
print(result_vstack)
# 此处图像同数组操作一致