numpy学习-day0
今日知识点总结
关于numpy的作用
说到作用,基本就可以理解为为什么需要写出这么一个第三方 的库,而且这个库他还受到了大家的热捧,这就很厉害了。
- 第一点
底层由C++实现,这就使得对于数据存储的时候,可以根据数据的特点,节省存储空间,并且处理速度上也会非常快。
- 第二点
功能全面的库函数,在囊括了C++中STD函数的同时,也增加了扩展库的内容,包括但不限于正态分布,总的来说,对于需要进行科学运算分析的用户非常的友善,点赞。
具体库函数的记录
这里就只是今天学习视频中出现的函数,写这一部分的内容是为了加深自己的映像,也便于后续的使用。
- 关于numpy模块的引入
出于方便编程的目的的一般会使用这样的语句
import numpy as np
用两个字符np来表示numpy,好处是可以减少打字的内容,缩短时间。至于为什么是np这两个字符呢,答案是约定俗成,这样对于第二次阅读代码的人来说会比较的友善。
- 关于数组的初始化和使用
在numpy中,使用
np.array(list)
这样的语句来完成对于多维数组的初始化,在完成初始化之后,就和C++的数组一样了,支持下标访问,从0编号,负编号可以从后向前走这样子,就是C+++ 。[:)]
- 基本属性的访问
通过以下成员对象,获得当前数组的相关参数
成员名称 | 说明 |
---|---|
ndim | 返回一个数值,表示维度,比如是一个二维的数组,那么返回值就是2 |
shape | 返回tuple类型,表示每一维的大小,比如3*5的二维矩阵,返回(3, 5) |
size | 返回总的元素个数,也就是每一维大小的成绩 |
dtype | 返回一个类型值,也就是存储在数组中的数值类型 |
itemsize | 返回一个数值,也就是dtype的字节数,比如int32,那就是4字节 |
- 生成函数
讲一下numpy中构建特殊数组的方法
函数名称 | 说明 |
---|---|
arange | 生成一个从0到n-1的数组 |
ones(shape) | 生成一个shape[tuple类型]形状的全1数组 |
zeros(shape) | 生成一个shape形状的全0数组 |
full(shape, val) | 用val填充shape形状的数组 |
eye(n) | 生成一个n*n的单位矩阵 |
linspace(start, end, n) | 从start到end等间距的生成n个数字的数组 |
- 操作函数
主要包括对于数组的操作
函数名称 | 说明 |
---|---|
concatenate | 连接,合并多个序列 |
reshape | 不改变现有数组,返回一个新形状的数组 |
resize | 改变现有数组的形状 |
flatten | 对于现有的数组进行降维处理,直接变成一维 |
其他四则运算 | 与C++一致,完全支持数组和数值、数组之间的运算 |
- 存取数组
对于数组数据的存取
1.文件保存/文件读取
保存数据
savetxt(fname, X, fmt='%.18e', delimiter=' ', newline=' ', header='',
footer='', comments='# ', encoding=None)
读取数据
loadtxt(fname, dtype=float, comments='#', delimiter=None,
converters=None, skiprows=0, usecols=None, unpack=False,
ndmin=0, encoding='bytes', max_rows=None)
这一方法的问题是,需要自己记录下,文件中数组的维度,精度等等问题
2.默认保存/默认读取
直接保存为.npy格式
save(file, arr, allow_pickle=True, fix_imports=True):
直接读取
load(file, mmap_mode=None, allow_pickle=False, fix_imports=True,
encoding='ASCII'):
好处是,所有的格式都是默认处理好的
练习
问题描述
使用pillow图像处理库和numpy数组处理库,完成对于图像的线条化,也就是实现素描的效果
SOLUTION
1. 方案一
这个办法是网课中的代码,但是我对于这段代码的理解不太到位,不明白归一操作和
加权计算的原因,所以又自己想了一个办法。
a = np.asarray(Image.open('./beijing.jpg').convert('L')).astype('float')
depth = 10. # (0-100)
grad = np.gradient(a) #取图像灰度的梯度值
grad_x, grad_y = grad #分别取横纵图像梯度值
grad_x = grad_x*depth/100.
grad_y = grad_y*depth/100.
A = np.sqrt(grad_x**2 + grad_y**2 + 1.)
uni_x = grad_x/A
uni_y = grad_y/A
uni_z = 1./A
vec_el = np.pi/2.2 # 光源的俯视角度,弧度值
vec_az = np.pi/4. # 光源的方位角度,弧度值
dx = np.cos(vec_el)*np.cos(vec_az) #光源对x 轴的影响
dy = np.cos(vec_el)*np.sin(vec_az) #光源对y 轴的影响
dz = np.sin(vec_el) #光源对z 轴的影响
b = 255*(dx*uni_x + dy*uni_y + dz*uni_z) #光源归一化
b = b.clip(0,255)
im = Image.fromarray(b.astype('uint8')) #重构图像
im.save('./beijingHD.jpg')
2. 方案二
由于gradient的作用是求处数组的梯度,而我们现在将图片转化成了一个灰度图,那么我们就可以想对于连个区域之间如果梯度过大,那就是两个不同的区域,也就是两个区域之间应该是有线条的。
from PIL import Image
import numpy as np
a = np.asarray(Image.open('1.jpg').convert('L')).astype('float')
depth = 4. # (0-100)
grad = np.gradient(a) #取图像灰度的梯度值
grad_x, grad_y = grad #分别取横纵图像梯度值
grad_x = grad_x*depth/100.
grad_y = grad_y*depth/100.
b = np.full(a.shape, 255)
for i in range(a.shape[0]):
for j in range(a.shape[1]):
if(abs(grad_x[i][j]) >= 0.7 or abs(grad_y[i][j]) >= 0.7):
b[i][j] = 0
b = b.clip(0,255)
im = Image.fromarray(b.astype('uint8')) #重构图像
im.save('2.jpg')
最终效果如下