图像的本质是什么?–numpy和图像基础
使用jupyterLab 进行前期的学习,首先进行软件的安装。如下图所示:
安装步骤
1.创建一个python虚拟环境
conda create --name demo_py3.8 python=3.8
2.根据换源的情况进行安装。
3. 运行jupyter-lab,打开,然后会弹出网址。
http://localhost:8888/lab
学习使用numpy
# 为了了解图像本质,我们需要先了解一下数组和矩阵的概念
# 首先回忆一下,如何创建一个列表
list_a = [1,2,3,4,5]
# 使用type命令查看数据类型,是list类型
type(list_a)
# 再创建一个列表,使这个列表的元素仍然是列表
list_b = [ [1,2], [3,4], [5,6] ]
# 打印列表 [[1, 2], [3, 4], [5, 6]]
list_b
# 通过找数字索引,打印第list_b第2个元素的第1个元素 3
list_b[1][0]
# 这种结构我们也叫数组,比如list_a是一维数组,list_b是二维数组
# 为了更高效的处理数组,我们常用numpy在这个包
# 首先导入numpy包,重命名一下
import numpy as np
# 那numpy如何创建数组呢?
# 可以用Python列表直接转换
# 首先创建一个Python 列表
list_c = [1,2,3,4]
# 在使用np.array()将Python列表转换为numpy的数组 numpy.ndarray
my_array = np.array(list_c)
# 打印一下 array([1, 2, 3, 4])
my_array
# 那numpy还有一些内置函数可以快速地创建数组
# 比如我们使用np.arange()可以快速创建连续数字的数组
# 比如我创建一个0~9 的一维数组 array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(0,10)
# jupyterlab中使用shift+tab可以查看函数的帮助文档(查看一下,此刻输入np.arange(),弹出对应函数帮助文档)
# 可以看到这个arange()函数有start、stop和step参数,分别代表了起始值,终止值,以及步长
# 如果我希望创建0~10中连续偶数的数组,只需将步长设为2(此刻输入np.arange(0,10,2))
# array([0, 2, 4, 6, 8])
np.arange(0,10,2)
# 还可以用np.ones创建全是1的数组,(此时输入np.ones(),弹出帮助说明)
# 比如我要创建一个大小为3*3的全1数组
np.ones(shape=(3,3))
# 再创建一个大小为10*3的全1数组
# 可以看到10是行数,3是列数
np.ones(shape=(10,3))
# 或者使用np.zeros()全0数组
# 比如创建大小为5*5的全0数组
np.zeros(shape=(5,5))
# 首先使用np.randint函数一些随机整数 array([53, 86, 55, 17, 87, 12, 28, 95, 2, 44])
arr = np.random.randint(0,100,10)
# 使用max获取最大值
arr.max()
# 再使用argmax() 获取最大值的索引
arr.argmax()
# 使用min函数获取最小值
arr.min()
# 使用argmin获取最小值索引
arr.argmin()
# 使用mean()方法获取取平均值
arr.mean()
# 如果要获取humpy数组的大小,使用numpy.shape, (10,)
arr.shape
# 也可以使用reshape函数转换数组的形状,比如我将arr转换成5*2的数组
arr.reshape((5,2))
# 再变形成2行5列
arr.reshape((2,5))
# 如果尝试变形为大小为2*10呢?会报错:ValueError: cannot reshape array of size 10 into shape (2,10)
arr.reshape((2,10))
# 那二维数组,我们在数学上也称为矩阵,我们再看一下numpy对矩阵的操作
# 首先创建一个10*10 的矩阵
matrix = np.arange(0,100).reshape((10,10))
# 查看一下大小:(10, 10)
matrix.shape
# 使用中括号中加索引方式,获取矩阵对应元素,比如我获取第3行第5列元素
matrix[2,4]
# 如果要获取某一行所有元素,我们需要使用numpy的切片:
# 比如我要获取第3行所有元素,只需将第二个位置变成冒号:
matrix[2,:]
# 类似的,比如我要获取第6列所有元素,只需将第一个位置变成冒号:
matrix[:,5]
# 比如我要获取第1~3行,第2~4列矩阵,我们可以用数字配合冒号的方式来获取
matrix[0:3,1:4]
# 当然我们可以使用等号赋值语句,比如我将这些位置赋值0
matrix[0:3,1:4] = 0
# 好,以上就是numpy对数组和矩阵的操作用法
二维矩阵是先行后列,可以对比理解一下为啥图片是先计算高,在计算宽,本质就是个三维矩阵。
猫咪图理解图像
# 首先导入numpy
import numpy as np
# 为了在notebook中显示图片,导入matplotlib库
import matplotlib.pyplot as plt
# 加这行在Notebook显示图像
%matplotlib inline
# 再使用一个PIL库,用于读取图像
from PIL import Image
# 我在img文件夹下放了一张图片(演示一下)
# 我们用PIL库读取图片,注意路径要正确
img = Image.open('./img/cat.jpg')
# 显示图像
img
# 查看一下变量的类型:PIL.JpegImagePlugin.JpegImageFile
type(img)
# 可以看到这个不是numpy的数组格式,那numpy还不能处理它
# 首先我们需要将它转化为numpy 数组,使用numpy.asarray()函数
img_arr = np.asarray(img)
# 查看类型:numpy.ndarray
type(img_arr)
# 我们查看大小:(1253, 1880, 3) 高度,宽度,RGB三通道
img_arr.shape
# 再使用matplot的imshow()方法显示Numpy数组形式的图片
plt.imshow(img_arr)
# 可以看到横坐标和纵坐标显示了图片的长度是1800多,高度是1200多
# 我们继续对这个图片操作,先使用numpy的copy方法复制一份原图
img_arr_copy = img_arr.copy()
# 检查一下大小:(1253, 1880, 3)
img_arr_copy.shape
# 首先使用numpy切片,将R,G,B三个颜色通道中的R红色通道显示出来
plt.imshow(img_arr_copy[:,:,0])
# 大家会发现这个颜色很奇怪,都是翠绿色,为什么会显示成这样呢?
# 我们打开matplot的官网关于颜色表colormap的说明:
# https://matplotlib.org/stable/gallery/color/colormap_reference.html
# 可以看到默认的颜色:是翠绿色(viridis )。那这个颜色方便色盲观看的
# 我们也可以将cmap颜色设置成火山岩浆样式:magma
plt.imshow(img_arr_copy[:,:,0],cmap='magma')
# 我们打印一下红色R通道的数组
img_arr_copy[:,:,0]
# 好,我们知道,计算机是分不清到底哪一个通道是红色的,每一个颜色通道其实都是一个灰度图,我们首先将cmap颜色设置为gray灰度
# 看一下
plt.imshow(img_arr_copy[:,:,0],cmap='gray')
# 我们知道,红色通道中的 0呢就是没有红色,代表纯黑色,而越接近255呢,就代表越红,255就纯红色
# 那看这个灰度图,颜色越浅,表示这里越红
# 我们可以看一下红色通道的灰度图上颜色最浅的就是这个吊坠(鼠标指示)
# 那回到原来彩色图片,可以看到这个吊坠确实是最红的
# 类似的,我们将绿色通道也显示为灰度模式
plt.imshow(img_arr_copy[:,:,1],cmap='gray')