图像

图像是高度×宽度的像素矩阵。

如果图像是黑白的(即灰度),则每个像素可以由单个数字表示(通常在0(黑色)和255(白色)之间)。想要裁剪图像的左上角10 x 10像素部分?告诉NumPy让你image[:10,:10]。
这是一个图像文件的片段:

在这里插入图片描述
如果图像是彩色的,则每个像素由三个数字表示(RGB)。在这种情况下,我们需要第三维(因为每个单元格只能包含一个数字)。因此彩色图像由尺寸的ndarray表示:(高x宽x 3)。

在这里插入图片描述

这里我们使用 matplotlib.pyplot 的相关方法来辅助。处理图像的时候,颜色都是使用RGB三个通道进行叠加而形成的一个颜色,R:红色通道、G:绿色、B: 蓝色,可以使用三维的数组来表示一张图片。

数组的最高维度0:图片的高度,次高维1:图片的宽度,最低维2:RGB三个元素。

图像的处理

import numpy as np
import matplotlib.pyplot as plt
图像读取与显示
  • plt.imread:读取图像,返回图像的数组(三维数组)。
  • plt.imshow:显示图像。
  • plt.imsave:保存图像。
im = plt.imread("strawberry.jpg")     
# 将图片信息读取成数组信息
# 返回的信息是一个三维的数组
# 最高维度:一共有317个元素
# 次高维:一共有248个元素
# 最低维:每个像素点的颜色信R G B

im     # 使用imshow读取图片,得到数组信息,
plt.imshow(im)    #已知数组信息,使用imshow读取成图片
plt.imsave("numpy.jpg",im)    # 将数组信息存储成图片
print(im.shape)    # 利用已学过的知识显示数组a的形状
显示纯色图像
  • 显示纯色图像
  • 显示白色图像
  • 显示黑色图像
  • 显示指定颜色图像
# 颜色的存储
# 在numpy中可以有两种形式:
# RGB颜色值越大,图片就越亮
# 一种是无符号  uint8   0-255
# float类型     float   0-1
x1 = np.ones(shape=(100,200,3))     #白色图像,rgb[1,1,1]
x2 = np.zeros(shape=(100,200,3))    #黑色色图像,rgb[0,0,0]
x3 = np.full(shape=(100,200,3),fill_value=255)    #rgb[255,255,255]
plt.imshow(x1)

x4 = np.full(shape=(100,200,3),fill_value=148)    # [148,148,148],[148,148,148],[148,148,148],[148,148,148],

# 使得rgb三个值都不同,但是图像上的所有点的rgb颜色都一致,就是纯色的其他颜色的图
plt.imshow(x4)

# 每个下像素点的值[228,251,142]
x5 = np.ones(shape=(100,200,3))
# x5[:,:]                  # 获取图像中的每个rgb元素的值(列表)
# x5[:,:] = [228,251,142]
x5 = x5/255                # 格式不同,需要进行归一化
x5[:] = [228,251,142]      # 简化,因为获取的低维度全部获取。
plt.imshow(x5)
转换为灰度图

灰度图的数据可以看成是二维数组,元素取值为0 ~ 255,其中,0为黑色,255为白色。从0到255逐渐由暗色变为亮色。

灰度图转换(ITU-R 601-2亮度变换):

L = R * 299 / 1000 + G * 587 / 1000 + B * 114 / 1000

R、G、B为最低维的数据。

显示灰度图时,需要在imshow中使用参数:

cmap="gray"
 b = np.array([0.299,0.587,0.114])
 x = np.dot(im,b)  # 将上面的RGB和b数组中的每个元素进行对位相乘,再相加
 plt.imshow(x,cmap="gray")
图像颜色通道

对于彩色图像,可以认为是由RGB三个通道构成的。每个最低维就是一个通道。分别提取R,G,B三个通道,并显示单通道的图像。

t = im.copy()
# 进行红色通道的提取:就是将每个像素点中的g和b,设置成0
# (1)获取素有的像素点。
# (2)将每个像素点中的第1个元素和第二个元素(g,b)设置成0
# [r,g,b]
# t[:,:,1:3]=0
# plt.imshow(t)

# 对蓝色通道进行提取
# 将b不变,其余都设置成0
#[r,g,b]
# t[:,:,0:2]=0
# plt.imshow(t)

# 对绿色通道进行提取
# 将g不变,其余都设置成0
#[r,g,b]
# t[:,:,0:3:2]=0
# t[:,:,::2]=0
# plt.imshow(t)

# 获取绿色通道,如果不使用切片,只使用索引
# 通过提供整数索引
# a=np.array([1,2,3,4,5])
# a[1],a[3],a[4]
# index=[1,3,4]  #形成索引列表
# a[index]
t
# greenindex=[0,2]
# t[:,:,greenindex]=0
# 以下三种方法都可以
t[:,:,[0,2]]=0
t[:,:,0:3:2]=0
t[:,:,::2]=0
# plt.imshow(t)

# 一起显示
red = im.copy()
green = im.copy()
blue = im.copy()
red[:,:,1:3]=0
green[:,:,::2]=0
blue[:,:,:2]=0
fig,ax=plt.subplots(2,2)
fig.set_size_inches(15,15)
ax[0,0].imshow(im)
ax[0,1].imshow(red)
ax[1,0].imshow(green)
ax[1,1].imshow(blue)
图像重复
  • 将图像沿着水平方向重复三次。
  • 将图像沿着垂直方向重复两次。
  • 将图像沿着水平方向重复两次,垂直重复三次。
t = im.copy()
# 先水平方向两次,再垂直方向3次
r1 = np.concatenate((t,t),axis=1)
r2 = np.concatenate((r1,r1,r1),axis=0)
plt.imshow(r2)
图像镜面对称
  • 将图像水平镜面转换。
  • 将图像垂直镜面转换。
# li=[1,2,3,4,5]
# li[::-1]

# 获得ndarray数组下的每一列
# x=np.array([[1,2,3,4],[5,6,7,8]])
# x[1]
# x[:,1]
t = im.copy()
t[:,::-1]
plt.imshow(t[:,::-1])

# 水平镜面
# 相当于进行行交换,让原来第0行,显示在第n行
t = im.copy()
fig,ax = plt.subplots(2)
fig.set_size_inches(10,10)
ax[0].imshow(t)
ax[1].imshow(t[:,::-1])
左右旋转
  • 将图像向左旋转90 / 180度。
  • 将图像向右旋转90 / 180度。
t = im.copy()
fig,ax = plt.subplots(2,3)
fig.set_size_inches(12,12)

# 向左旋转90度
# (1)先tranpose
# (2)再做水平镜面
r = t.transpose(1,0,2)
r = r[::-1]

# 向左旋转180度
r2 = r.transpose(1,0,2)
r2 = r2[::-1]

ax[0,0].imshow(t)
ax[0,1].imshow(r)
ax[0,2].imshow(r2)

# 右旋转90度
# (1)转置
# (2)做垂直镜面
r3 = t.swapaxes(0,1)
r3 = r3[:,::-1]

# 向右旋转180度
r4 = r3.transpose(1,0,2)
r4 = r4[:,::-1]

ax[1,0].imshow(t)
ax[1,1].imshow(r3)
ax[1,2].imshow(r4)
图像遮挡 / 叠加
  • 在指定的区域使用特定的纯色去遮挡图像。
  • 在指定的区域使用随机生成的图像去遮挡图像。
  • 使用小图像放在大图像上。
# 图像的替换
# 思路一:对原图片的相应位置,转变为灰度图,在进行乱序
# 思路二:用打码图片替换原图片的相应位置

re = plt.imread("msk.jpg")     # 用于覆盖的图片
t = im.copy()
st = np.array([150,100])       # 替换起始点的位置
t[st[0]:st[0] + re.shape[0],st[1]:st[1] + re.shape[1],:] = re

plt.imshow(t)
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐