Python库之numpy库

4 篇文章 0 订阅

numpy库处理的是最起初数据类型是由同种元素构成的多维数组,也就是所谓的数组。数组中的所有元素的类型必须相同,数组中元素可以用整数索引,序号从0开始。

数组类型的维度叫做轴(axes),轴的个数叫做秩(rank)。例如,一维数组的秩为1,二维数组的秩为2。

通常用import numpy as np引入numpy库,以免混淆

一、numpy介绍

  • numpy库常用创建数组函数有以下7个
函数描述
np.array([x, y, z], dtype = int)从python列表和元组创建数组
np.arange(x, y, i)创建一个由x到y,步长为i的数组
np.linspace(x, y, n)创建一个由x到y,等分成n个元素的数组
np.indices((m, n))创建一个m行n列的矩阵
np.random.rand(m, n)创建一个m行n列的随机数组
np.ones((m, n), dtype)创建一个m行n列全1的数组,dtype是数据类型
np.empty((m, n), dtype)创建一个m行n列全0的数组,dtype是数据类型
>>>import numpy as np
>>>a = np.ones((4,5))
>>>a
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
  • 在创建好数组后,通过以下方法查看基本属性
属性描述
ndarray.ndim数组轴的个数
ndarry.shape数组在每个维度上大小的整数元祖
ndarray.size数组元素的总个数
ndarray.dtype数组元素的数据类型,dtype类型可以用于创建数组
ndarray.itemsize数组中每个元素的字节大小
ndarray.data包含实际数组元素的缓冲区地址
ndarray.flat数组元素的迭代器
>>>a.ndim
2
>>>a.shape
(4, 5)
>>>a.size
20
>>>a.dtype
dtype('float64')
>>>a.itemsize
8
>>>a.data
<memory at 0x00000269B5FB5708>
>>>a.flat
<numpy.flatiter at 0x269b5780460>
  • 改变数组基础形态的操作方法

数组在numpy中被当做对象,可以采用以下方法进行操作。(其中flatten()用于数组降维,在矩阵运算及图像处理中用处很大)

方法描述
ndarray.reshape(n, m)不改变数组ndarray,返回一个维度为(n, m)的数组
ndarray.resize(new_size)与reshape()作用相同,直接修改数组ndarray
ndarray.swapaxes(ax1, ax2)将数组n个维度中任意两个维度进行调换
ndarray.flatten()对数组进行降维,返回一个折叠后的一维数组
ndarray.ravel()作用同flatten()相同,但是返回的是一个数组的视图
>>>a.ravel()
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1.])
  • numpy类的索引和切片

数组切片得到的是原始数组的视图,所有修改都会直接反映到源数组

方法描述
x[i]索引第i个元素
x[-i]从后向前索引第i个元素
x[n:m]默认步长为1,从前往后索引,不包含m
x[-m:-n]默认步长为1,从后往前索引,结束位置为n
x[n:m :i]指定i步长的由n到m的索引
>>>b = np.random.rand(5,3);b
array([[0.59532428, 0.72198343, 0.31319579],
       [0.53958629, 0.01385479, 0.35459807],
       [0.06605026, 0.78682018, 0.16177456],
       [0.37520112, 0.93865079, 0.9332923 ],
       [0.97885532, 0.06937877, 0.925661  ]])
>>>b[2]
array([0.06605026, 0.78682018, 0.16177456])
>>>b[1:3]
array([[0.53958629, 0.01385479, 0.35459807],
       [0.06605026, 0.78682018, 0.16177456]])
  • numpy的算术及比较运算函数

numpy的算术运算函数有以下8个

函数描述
np.add(x1, x2, [,y])y = x1 + x2
np.subtract(x1, x2, [,y])y = x1 - x2
np.multiply(x1, x2, [,y])y = x1 * x2
np.divide(x1, x2, [,y])y = x1 / x2
np.floor_divide(x1, x2, [,y])y = x1 // x2
np.negative(x, [,y]y = -x
np.power(x1, x2, [,y])y = x1 ** x2
np.remainder(x1, x2, [,y])y = x1 % x2

numpy的比较运算函数有以下7个

函数描述
np.equal(x1, x2, [,y])y = x1 == x2
np.not_equal(x1, x2, [,y])y = x1 != x2
np.less(x1, x2, [,y])y = x1 < x2
np.less_equal(x1, x2, [,y])y = x1 <= x2
np.greater(x1, x2, [,y])y = x1 > x2
np.greater_equal(x1, x2, [,y])y = x1 >= x2
np.where(condition[x, y])根据给出的条件判断输出x还是y
  • numpy还有其他一些实用的函数
函数描述
np.abs(x)计算基于元素的整型、浮点型或复数的绝对值
np.sqrt(x)计算每个元素的平方根
np.squre(x)计算每个元素的平方
np.sign(x)计算每个元素的符号:1(+)、0、-1(-)
np.ceil(x)计算大于或等于每个元素的最小值
np.floor(x)计算小于或等于每个元素的最大值
np.rint(x, [,out])圆整、取每个元素为最近的整数,保留数据类型
np.exp(x, [,out])计算每个元素的指数值
np.log(x), np.log10(x), np.log2(x)计算自然对数(e),基于10/2的对数

二、实例操作

下面将numpy与之前的PIL结合来提取图像特征形成手绘效果

  • 图像的基本处理
>>>from PIL import Image
>>>import numpy as np
>>>im = np.array(Image.open(r'C:\Users\acer\Desktop\flash.jpg'))#加载图像并转换成数组对象
>>>print(im.shape, im.dtype)
(553, 960, 3) uint8

其中(553,960,3)分别表示长度、宽度(单位是像素)以及RGB值

>>>im = np.array(Image.open(r'C:\Users\acer\Desktop\flash.jpg').convert('L'))
>>>print(im.shape, im.dtype)
(553, 960) uint8

通过convert()将图片转换成带有灰度的黑白色,ndarray也变为二维数据

>>>im0 = np.array(Image.open(r'C:\Users\acer\Desktop\flash.jpg').convert('L'))
>>>im1 = 255 - im0 #反变换
>>>im2 = (100/255)*im0 + 150 #区间变换
>>>im3 = 255 * (im1/255) ** 2 #像素平方处理
>>>pil_im1 = Image.fromarray(np.uint(im1))
>>>pil_im2 = Image.fromarray(np.uint(im2))
>>>pil_im3 = Image.fromarray(np.uint(im3))#分别对im1、im2、im3执行
>>>pil_im1.show()
>>>pil_im2.show()
>>>pil_im3.show()

效果图:(左上为原图)
在这里插入图片描述

  • 手绘效果处理

为了实现手绘风格,首先需要读取原图像的明暗变化。通常可以使用梯度计算来提取图像轮廓,在numpy中即使用gradient()函数

附上代码

from PIL import Image
import numpy as np
vec_el = np.pi/2.2                   #光源的俯视角度,弧度值
vec_az = np.pi/4.                    #光源的方位角度,弧度值
depth = 10.                             #(0-100)
im = Image.open(r'C:\Users\acer\Desktop\flash.jpg').convert('L')
a = np.asarray(im).astype('float')
grad = np.gradient(a)                #取图像灰度的梯度值
grad_x, grad_y = grad                #分别取横纵图像梯度值
grad_x = grad_x * depth / 100.
grad_y = grad_y * depth / 100.
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轴的影响
A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
uni_x = grad_x / A
uni_y = grad_y / A
uni_z = 1. / A
a2 = 255 * (dx*uni_x + dy*uni_y +dz*uni_z)  #光源归一化
a2 = a2.clip(0, 255)
im2 = Image.fromarray(a2.astype('uint8'))   #重构图像
im2.save(r'C:\Users\acer\Desktop\flashHandDraw.jpg')

在上述代码中,利用梯度重构图像时,对应不同梯度取0~255之间不同的灰度值,depth的作用在于调节这个对应关系。当depth较小时,背景区接近白色,显示轮廓描绘;当depth较大时,整体画面灰度值较深,显示浮雕效果

最后附上图片效果
原图:
在这里插入图片描述
效果图1(depth = 10):
在这里插入图片描述
效果图2(depth = 40):
在这里插入图片描述

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值