OpenCV-Python学习 <二> 图像像素存储和处理

像素是图像构成的基本单位,需要清晰的了解其在opencv-python的ndarray中如何存储以及如何处理的。

在opencv-python中,通常使用numpy的ndarray来存储图片数据。cv2.imread()的返回值的数据类型即为: <class 'numpy.ndarray'>

那具体是怎么存储的呢? ndarray的各个维度和图片的长宽,BGR等是如何对应的?下面就谈一谈。

1. 像素的存储方式:

1.1:灰度图:

opencv中最小的数据类型是无符号8位数。灰度图中每个像素使用8位存储空间。取值范围0-255.

import cv2


data = cv2.imread("images/test1.webp", cv2.IMREAD_GRAYSCALE)
print("type is:",type(data))
print("Shape:", data.shape)

cv2.imshow("RGB", data)

cv2.waitKey()
cv2.destroyAllWindows()

type is: <class 'numpy.ndarray'>
Shape: (576, 1024)

获取指定图片数据,图像转变为单通道灰度图片。

可以看到,imread()返回的ndarray的shape是(576, 1024)。即(行数,列数)

这个ndarray的每个元素,就是某个像素的灰度值。

例如:

data[0][100] = 255   或者:

data[0,100] = 255

就是把第0行,第100列那个点的像素值修改为白色。

data[30] =255

则表示把第30行全变为白色。(使用到广播)

2. BGR图片:

BGR格式中,每个像素点则需要3个uint8来表示。

import cv2


#data = cv2.imread("images/test1.webp", cv2.IMREAD_GRAYSCALE)
data = cv2.imread("images/test1.webp", cv2.IMREAD_COLOR)
print("type is:",type(data))
print("Shape:", data.shape)
cv2.imshow("RGB", data)

cv2.waitKey()
cv2.destroyAllWindows()

type is: <class 'numpy.ndarray'>
Shape: (576, 1024, 3)

所以ndarray是3个维度,分别为:(行数,列数,颜色通道)。

因为OpenCV使用BGR顺序,所以颜色顺序是B, G, R.

所以,data[0,1, 2]所代表的是第0行,第一列中的R 通道。

若第0行,30列的像素点为绿色:则其值应该为:[0, 255, 0]

img[0,30] 的值为[0, 255, 0]

img[0,30,0]的值为0 (B通道)

img[0,30,1]的值为255 (G通道)

img[0,30,2]的值为0 (R通道)

2. 像素的访问和修改方法:

2.1:利用numpy.arary的索引方式访问:

import cv2


#data = cv2.imread("images/test1.webp", cv2.IMREAD_GRAYSCALE)
data = cv2.imread("images/test1.webp", cv2.IMREAD_COLOR)
print("type is:",type(data))
print("Shape:", data.shape)
for i in range(data.shape[1]):
   data[30,i] = 255
data[50] =255

print("data[30,0] is:", data[30,0])
print("data[50,0,0] B is:", data[50,0,0])
print("data[50,0,1] G is:", data[50,0,1])
print("data[50,0,2] R is:", data[50,0,1])
cv2.imshow("RGB", data)

cv2.waitKey()
cv2.destroyAllWindows()

type is: <class 'numpy.ndarray'>
Shape: (576, 1024, 3)
data[30,0] is: [255 255 255]
data[50,0,0] B is: 255
data[50,0,1] G is: 255
data[50,0,2] R is: 255

说明:

data[30,i] 代表第30行的第i个元素。每个元素为:[BGR].

data[50, 0, 0]表示第50行第0列的B通道

data[50, 0, 1]表示第50行第0列的G通道

data[50, 0, 2]表示第50行第0列的R通道

即把第三十行的所有元素修改为白色:[255, 255, 255]

把第五十行的所有元素修改为白色。

2.2:使用numpy.array的item()和itemset()访问和设置

可以使用numpy的item()和itemset()函数访问和修改像素值。这两个函数都是经过优化处理的,能够更大幅度的提高处理效率,比使用索引快的多。

2.2.1: 灰度图的访问和修改:

#像素的访问2
data = cv2.imread("images/test1.webp", cv2.IMREAD_GRAYSCALE)
print("Type is: {}. sharp is:{}".format(type(data), data.shape))
for i in range(data.shape[1]):
   data.itemset((50,i), 255)
cv2.imshow("Demo", data)
print("data[50,0] is:", data.item(50,0))

cv2.waitKey()
cv2.destroyAllWindows()

对于灰度图,因为data的shape是二维array.  所以:

data.item(行数,列数) 获取指像素(行列指定)的值。

data.itemset((行数,列数), val) 把val值赋予指定行数和列数的像素。

2.2.2: BGR图像的访问和修改:

#像素的访问3--BGR
data = cv2.imread("images/test1.webp", cv2.IMREAD_COLOR)
print("data type:{}. shape is:{}".format(type(data), data.shape))

cv2.imshow("Before", data)

for i in range(data.shape[1]):
   #for j in range(3):
   data.itemset((50, i,0), 0)

cv2.imshow("After B=0", data)

for i in range(data.shape[1]):
   #for j in range(3):
   data.itemset((50, i,1), 0)

cv2.imshow("After B,G=0", data)

for i in range(data.shape[1]):
   #for j in range(3):
   data.itemset((50, i,2), 0)

cv2.imshow("After B,G,R=0", data)

for i in range(data.shape[1]):
   for j in range(3):
      data.itemset((50, i, j), 255)
cv2.imshow("After B,G,R=255", data)

cv2.waitKey()
cv2.destroyAllWindows()

因为BGR图像是三维ndarray. [行,列,颜色通道]。 所以data.item(行,列,通道)

data.itemset((行,列,通道), val).

3. ROI区域数据的访问和修改:

在图像处理过程中,我们可能会需要对一块特定区域(Region of Interest)感兴趣.

要获取这块区域的数据。 opencv-python利用了numpy array的切片来做此动作。

data_des = cv2.imread("images/test1.webp", cv2.IMREAD_GRAYSCALE)
data_src = cv2.imread("images/test2.png", cv2.IMREAD_GRAYSCALE)
print("src file. data type:{}. data shape:{}".format(type(data_src), data_src.shape))
print("des file. data type:{}. data shape:{}".format(type(data_des), data_des.shape))
cv2.imshow("Src Before", data_src)
cv2.imshow("des Before", data_des)

rect_roi = data_src[300:400, 600:800]
cv2.imshow("Rect ROI", rect_roi)

data_des[200:200+rect_roi.shape[0], 400:400+rect_roi.shape[1]] = rect_roi
cv2.imshow("des after", data_des)

利用numpy的切片获取其中一部分数据的访问权。

4. BGR图像通道操作:

4.1:通道拆分

在RGB图像中,一张图像是由R,G,B三个通道构成的。OpenCV中,通道是B,G,R顺序存储的。

若要拆分成三个通道可以有两种方法:

4.1.1:利用numpy array的索引:

b = img[:,:,0]

g = img[:,:,1]

r = img[:,:,2]

#通道拆分:
image_src = cv2.imread("images/test1.webp", cv2.IMREAD_COLOR)
b = image_src[:, :, 0]
g = image_src[:, :, 1]
r = image_src[:, :, 2]

print("b , g, r shape: {} {} {}".format(b.shape, g.shape, r.shape))

cv2.imshow("Orz", image_src)
cv2.imshow("B", b)
cv2.imshow("G", g)
cv2.imshow("R", r)

image_src[:, :, 0] = 0
image_src[:, :, 1] = 0
cv2.imshow("After", image_src)

cv2.waitKey()
cv2.destroyAllWindows()

可以看到,拆分后,每份数据均为:(行x列)

若把B通道,G通道均值0. 则只剩下R通道的数据,所以变红色。

4.1.2:通过函数拆分:

使用cv2.split()

b,g,r = cv2.split(image)

#通道拆分2:
image_src = cv2.imread("images/test2.png", cv2.IMREAD_COLOR)
cv2.imshow("Before", image_src)
b,g,r = cv2.split(image_src)
cv2.imshow("B", b)
cv2.imshow("G", g)
cv2.imshow("R", r)

b1 = cv2.split(image_src)[0]
g1 = cv2.split(image_src)[1]
r1 = cv2.split(image_src)[2]

cv2.waitKey()
cv2.destroyAllWindows()

注意:有两个方式。

b,g,r = cv2.split(image_src)

b1 = cv2.split(image_src)[0]

g1 = cv2.split(image_src)[1]

r1 = cv2.split(image_src)[2]

两种方式等价。

4.2:通道合并:

通道合并是通道拆分的逆过程。

使用cv2.merge([b,g,r])

#通道合并
image_src = cv2.imread("images/test1.webp", cv2.IMREAD_COLOR)
cv2.imshow("Before", image_src)
b,g,r = cv2.split(image_src)
bgr = cv2.merge([b,g,r])

cv2.imshow("BGR", bgr)

rgb = cv2.merge([r,g,b])
cv2.imshow("RGB", rgb)

cv2.waitKey()
cv2.destroyAllWindows()

可以看到,把三个通道的数据,合并成BGR顺序的和RGB顺序的。

5. 图片的拷贝:

ndarray如果只是赋值,则其实另一个ndarray和src ndarray是同一份内存。

所以若需要copy.

img_copy = img_src.copy()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Opencv-python图像变换是通过使用不同的变换矩阵来实现的。其中,平移是一种最简单的空间变换。使用Opencv的函数cv2.warpAffine()可以实现平移操作。在代码中,我们需要定义一个变换矩阵M,这个矩阵是一个2行3列的矩阵,决定了平移的方式。其中,M矩阵中的tx和ty分别表示在x和y方向上平移的距离。更具体地说,如果我们向右平移tx个像素,向下平移ty个像素,那么变换矩阵M的定义如下: import numpy as np rows, cols = img.shape[:2] M = np.float32([[1, 0, tx], [0, 1, ty]]) dst = cv2.warpAffine(img, M, (cols, rows)) 在上述代码中,我们使用了NumPy库来创建一个2x3的浮点型变换矩阵M,并将其传递给cv2.warpAffine()函数,该函数会将图像img按照定义的方式进行平移,并生成一个新的图像dst。最后,我们可以通过cv2.imshow()函数显示平移后的图像。 除了平移之外,Opencv还提供了其他的图像变换操作,比如缩放。缩放可以按照指定的宽度和高度来调整图像的大小,也可以按照比例来进行缩放。通过cv2.resize()函数可以实现缩放操作。在代码中,我们可以使用下面的方式来进行缩放操作: import cv2 img = cv2.imread('drawing.jpg') # 按照指定的宽度、高度缩放图片 res = cv2.resize(img, (width, height)) # 按照比例缩放图片 res2 = cv2.resize(img, None, fx=scale_x, fy=scale_y, interpolation=cv2.INTER_LINEAR) 在上面的代码中,我们首先使用cv2.imread()函数读取图像,并将其存储在变量img中。然后,我们可以使用cv2.resize()函数来调整图像的大小。其中,如果我们指定了宽度和高度,那么图像将按照这些指定的大小进行缩放;如果我们指定了fx和fy的比例因子,那么图像将按照这些比例进行缩放。最后,我们可以使用cv2.imshow()函数来显示缩放后的图像。 总结起来,Opencv-python提供了多种图像变换操作,包括平移、缩放等。通过使用相应的函数和变换矩阵,我们可以实现对图像的各种变换操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [opencv-python 详解图像的几何变换缩放、平移、旋转、翻转](https://blog.csdn.net/RayChiu757374816/article/details/120036004)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值