Skip to content

一.numpy数组学习 (1)numpy函数基础学习

【【python教程】数据分析——numpy、pandas、matplotlib-哔哩哔哩】 https://b23.tv/0dLxGaK

注:只需要看关于numpy数组部分即可

关键点:numpy的多维数组操作,广播机制,数组切片与函数索引,线性代数运算

(2)opencv与numpy数组结合

1.引入库函数

import numpy as np 2.numpy导入图片

cv2.imread读取的是图片的像素矩阵,矩阵单元是RGB的向量形式,在图像的矩阵中,第一纬度是行,第二纬度是列,最后一个维度代表的是颜色通道。

image=cv2.imread("D://image.jepg")#imread()内是图片路径

(在OpenCV中,JPEG(通常写为jpg或jpeg)与PNG格式的图片处理上存在一些关键区别,但JPEG与JPG本质上是同一种格式,只是文件扩展名的大小写不同。

jpeg与png区别:png可以存储透明的图片,因为png图片的像素单元,是4个数值的元组进行存储,分别对应 Red、Green、Blue、透明度)

cv2转换图片颜色通道:img = cv2.cvtColor(img, cv.COLOR_RGB2BGR)#2可以音译为two即to,即是颜色通道顺序变化,便于理解。

等同于img[:,:,[0,2]]=img[:,:,[2,0]]#蓝色通道与红色通道互换

等同于img=img[:,:,::-1]#第一个:取所有行,第二个:取所有列,第三个:颜色通道取反即RGB-BGR

3.array()方法

np.array()是NumPy库中的一个函数,它用于创建一个多维数组对象。它的基本用法是从一个列表或元组创建一个数组。其语法如下:

numpy.array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0)

其中:

object:用于构造数组的输入数据。它可以是Python的列表、元组、数组、生成器等,常见(如二维数组(【1,2,3】,【4,5,6】));

dtype:可选参数,指定数组的数据类型。默认情况下,它会自动推断数据类型,常指定uint8类型。opencv的image数据格式就是用numpy unit8 格式存储的。两者之间可以相互装换;想用cv2.imshow格式输出,array格式一定用转换为uint8的格式。(用array.astype(np.uint8)强制转换为uint8的格式。)对于彩色图像有三个通道,每一个通道都是一样的操作,最后用cv2.merge(r,g,b)函数将三个通道的值何在一起就行。

copy:可选参数,指定是否复制输入数据。默认为True,即表示复制;

order:可选参数,指定数组在内存中的存储顺序。默认为“K”,即表示按照元素在内存中出现的顺序存储;

subok:可选参数,指定返回的数组是否允许子类。默认为False;

ndmin:可选参数,指定返回的数组的最小维度。默认为0,表示最小维度为1

(常用只有object,dtype参数,即可解决大部分问题)

4.item()方法

NumPy提供了一种更加高效快速的访问像素点的方法,即item() 方法

我们来看下面这个实例:

NumPy中的item()函数用于获取数组中的单个元素的值或数组标量。它的语法是这样的 numpy.ndarray.item(index)

其中,index表示要获取的元素的索引。如果数组对象不是标量,该方法将引发ValueError。

该函数返回数组对象中指定索引处的值(标量)。

下面是一个简单的使用示例:

arr = np.array([[1, 2], [3, 4], [5, 6]]) # 获取第3行第2列的元素 # 除此之外,我们还能使用 arr.item((3,2))来实现读取 element = arr.item(5) print(element) # 6 

在上面的示例中,我们通过item()函数获取了numpy数组arr中的第3行第2列的元素。由于数组是按行存储的,因此该元素的索引为5。

需要注意的是,item()函数返回的标量值是一个副本,而不是原始数组中的元素。这意味着对返回值所做的任何更改都不会影响原始数组中相应的元素。

总的来说,item()函数的主要作用是将数组中的一个标量元素返回为Python的标量值,以便于进行后续的处理。

也就是说,当我们创建好了一个数组之后,我们只需要在item()中传入它的索引值,我们就可以愉快地访问了。

5.itemset()方法

了解了访问某一像素点的高效方法之后,我们再来了解一下修改像素点的方法。这个方法同样也是非常好玩的哦~

itemset() 是 NumPy 数组的一个方法,它允许您更改指定位置的元素值。它与 item() 一起使用,item()允许您获取指定位置的元素。

itemset() 方法接受三个参数:行、列和值。如果您在使用一维数组,则只需要提供一个参数,即索引。

下面是 itemset() 的使用示例:

arr = np.array([1, 2, 3, 4, 5]) # 使用 itemset 更改第三个元素的值 arr.itemset(2, 100)

print(arr)# 输出结果: [ 1 2 100 4 5] 

在上面的示例中,我们创建了一个包含 5 个元素的一维 NumPy 数组 arr。我们使用 itemset()

方法将数组中第三个元素的值更改为 100,并使用 print() 方法查看更改后的数组。

如果您想在二维数组中使用 itemset() 方法,则需要指定行和列索引:

创建一个 3x3 的二维数组

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 使用 itemset 更改第三行第二列的元素值

arr.itemset((2, 1), 100)

print(arr)

输出结果: # [[ 1 2 3] # [ 4 5 6] # [ 7 100 9]]

在上面的示例中,我们使用 (2, 1) 表示要更改第三行第二列的元素值,并将值更改为 100。

4.numpy进行图像多通道拆分和合并

导入前需要改一下图片默认通道顺序

cv2默认的是bgr顺序

img = cv2.imread('./xx.jpeg')[:, :, [2, 1, 0]]

Red = img[:, :, 0]

Green = img[:, :, 1]

Blue = img[:, :, 2]

new_img=np.stack((Red,Green,Blue),axis=2)#axis=2指定第三纬度,即颜色通道,若使用np.dstack则不需要指定axis,专指沿第三轴即颜色通道堆叠,常用于合并图像颜色通道

或者new_img=cv2.merge((Blue,Green,Red))

此时new_img的形状即是(height,width,3)#表示高度为height,宽度为width,具有3颜色通道的彩色图像

注:

np.dstack和cv2.merge合并颜色通道顺序不一样的原因主要是它们遵循的默认颜色通道顺序不同:

np.dstack:这是一个NumPy库中的函数,用于沿着第三个轴(深度轴)堆叠数组序列。在合并颜色通道时,你需要按照RGB(红、绿、蓝)的顺序来堆叠数组,因为NumPy本身不特定于图像处理,它按照通用数组操作的逻辑来执行堆叠。

cv2.merge:这是OpenCV库中的一个函数,专门用于合并颜色通道。在OpenCV中,默认使用BGR(蓝、绿、红)顺序来存储图像的颜色通道。因此,当你使用cv2.merge合并颜色通道时,需要按照BGR的顺序来传递数组。

总结来说,np.dstack和cv2.merge合并颜色通道顺序不一样是因为它们遵循的默认颜色通道顺序不同:np.dstack遵循通用的RGB顺序,而cv2.merge遵循OpenCV特有的BGR顺序。这是由它们所属库的设计理念和用途决定的。在图像处理时,如果需要在NumPy和OpenCV之间转换图像,需要注意这种颜色通道顺序的差异,并相应地进行调整,这在以后学习中需要重点关注。

5.图像运算

加减乘除运算

包括加,减,乘,除,加权,对图像进行这些操作时,必须将图片大小统一,不然无法实现

图像的相加      cv2.add(img1,img2)  使得图像更亮

(1) 两个像素相加 + 大于256,则会将其按256取模 (2) 两个像素相加 cv2.add() 大于256,则取255(白色)

图像的相减        cv2.subtract(A,B)     含义是 A 减 B   使得图像更亮

图像的乘除        cv2.multiply (A,B)      cv2.divide(A,B)    

multiply()遵循饱和运算规则,比如uint8类型的数据如果超过255会被截断到255。当除数为0时,其计算结果记为0,如果被除数和除数都为0,结果也仍然为0,有0参与的除法运算都为0

图像加权/溶合  cv2.addWeighted(src1, alpha, src2, beta, gamma)

src1:图像1,背景图;

alpha:图像1加权;

src2:图像2;

beta:图像2加权;

gamma:附加常数

'''

一个小问题:

两个图片相加再减去其中一张图片还能得到另外一张图片吗?

答案是不能!(根据像素值范围在0-255之间思考)

'''

与或非运算

AND,与操作,有黑就变黑 image1 = cv2.bitwise_and(rectangle, circle)

OR,或操作,有白就变白 image2 = cv2.bitwise_or(rectangle, circle)

NOT, 非操作,颜色取反 image3 = cv2.bitwise_not(circle)

XOR,异或操作,黑白变白,黑黑和白白变黑 image4 =cv2.bitwise_xor(rectangle, circle)

cv2.imshow('and', image1)

cv2.imshow('or', image2)

cv2.imshow('not', image3)

cv2.imshow('xor', image4) 附效果图https://img-blog.csdnimg.cn/4565f885d7f644b5a7023cb5020246d2.png

​