python解析图像的手绘效果(numpy库与Image类的交互使用)------程序员的独特艺术

Raissa ·
更新时间:2024-09-21
· 996 次阅读

图像是有规律的二维数据,利用numpy库可以将图像转换为数组对象,那我们又知道图像也是由很多很多的像素点构成,那我们如果操作这些像素点,对其转变,是不是可以改变这个图像呢?没错,下面我分享一下如何操作。
__________________________________________________________
如果安装numpy函数库遇到问题建议用清华镜像安装
__________________________________________________________
本次测试图:在这里插入图片描述
效果图:
在这里插入图片描述
因为这次要用到numpy库和image库,由于这二个库的知识点有点多,我就不做介绍,在这里只讲需要的函数,达到这个效果就好
image中:

函数名 作用
Image.open() 打开图片 转换为image类
Image.show() 显示图片
convert() 操作对象是Image类 一般转换’L’模式即灰度,图像将由彩色变成带有灰度的黑白色
Image.fromarray() 可以将像素点重新转换成图像
Image.save() 保存图片

numpy中:

函数名 作用
np.asarray() 将数据类型转换为ndarray类型 但不会复制该对象
np.astype() 改变数据类型
np.gradient() 直接提取灰度图像梯度
np.cos() 内置的cos函数
np.sin() 内置的sin函数
np.pi 内置的圆周率
np.sqrt() 内置的开方函数
clip() 防止溢出,参数为元组
# -*- coding : utf-8 -*- # @Time : 2020/3/20 13:55 # @author : 沙漏在下雨 # @Software : PyCharm import numpy as np from PIL import Image def main(): vec_fu = np.pi / 2.2 # 光源的俯视角,弧度 vec_fa = np.pi / 4.0 # 光源的方位角,弧度 depth = 20.0 # 深度权值 越大 背景颜色越深 im = Image.open("D://py词云//lol.jpg").convert('L') # 打开并转换为灰度 am = np.asarray(im).astype('float') # 图片转换为数组, 类型转换为单精度 tm = np.gradient(am) # 获取图像灰度的梯度值 是一个元组类型 tm_x, tm_y = tm # 将梯度值分别赋值 tm_x = tm_x * depth / 100 # x轴 y轴 梯度变化 tm_y = tm_y * depth / 100 # 得到x轴 和y轴的 总梯度值 dx = np.cos(vec_fu) * np.sin(vec_fa) dy = np.cos(vec_fu) * np.sin(vec_fa) dz = np.sin(vec_fu) # 光源对x y z 轴的 加权向量 a = np.sqrt(tm_x ** 2 + tm_y ** 2 + 1.0) # 梯度幅值 uni_x = tm_x / a # x轴每个像素单元的梯度值 uni_y = tm_y / a # y轴每个像素单元的梯度值 uni_z = 1.0 / a # z轴每个像素单元的梯度值 a2 = 255 * (dx * uni_x + dy * uni_y + dz * uni_z) # 合成灰度值 a2 = a2.clip(0, 255) # 灰度值保持在0,255 防止溢出 im2 = Image.fromarray(a2.astype('uint8')) # 重构图像 im2.save("D://py词云//lol_draw.jpg") # 保存展示 im2.show() if __name__ == '__main__': main()

思路:我们利用numpy中的gradient()这个函数提取灰色图像的梯度,然后对梯度值进行操作,重构每个像素值,我们加了一个光源,建立了光源对各点梯度值的函数,进行新的运算,最后重构图像。说实话,这里确实很难理解,涉及到了三维空间映射,对数学的要求有点,觉得好玩就直接copy就行。


作者:沙漏在下雨



NumPy 艺术 程序 image 程序员 Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号