Python实现图片手绘效果

时间:2022-07-23
本文章向大家介绍Python实现图片手绘效果,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

图片手绘

概述

在家闲来无事看了会MOOC上的数据分析相关视频,以下部分内容来自于北京理工大学MOOC上的《Python数据分析与展示》。

项目综述

其实就是利用numpy对图片进行操作。借助PIL读入图片,利用numpy对图片进行一系列操作,接着把结果存储到本地。

代码的核心思想为:利用像素之间的梯度值对图像重构,根据灰度变化来模拟人类视觉明暗程度。

效果展示

原图

手绘效果图

部分代码

from PIL import Image
import numpy as np


a = np.asarray(Image.open("D://python_pycharm//MyPy//IMG_20191020_152247R.jpg").convert('L')).astype('float')
depth = 10
# 获取图片的像素梯度
grad = np.gradient(a)
# 获取图片像素x、y方向的梯度(像素值差),明暗相近的地方梯度值会很小,
# 明暗相差大的地方梯度值会很大。
grad_x, grad_y = grad
# 根据虚拟深度值来对x、y方向的梯度值进行归一化
grad_x = grad_x * depth / 100
grad_y = grad_y * depth / 100
# 计算像素间x、y方向的梯度值,并进行合并计算,再重新获得x、y方向的梯度值
a = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
uni_x = grad_x / a
uni_y = grad_y / a
uni_z = 1. / a

# 光源设计,即模拟自然光源,示意图见图四,设立一个位于图像斜上方的光源,
# 官员相对于图像的俯视角为elevation,方位角为azimuth
vec_el = np.pi / 2.2  # 82度
vec_az = np.pi / 4.  # 45度
# 建立光源对个点梯度值的影响函数
dx = np.cos(vec_el) * np.cos(vec_az)
dy = np.cos(vec_el) * np.sin(vec_az)
dz = np.sin(vec_el)

b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)
# 剔除0<n<255区间之外的值
b = b.clip(0, 255)
# 根据数组生成图片
im = Image.fromarray(b.astype('uint8'))
im.save('D://python_pycharm//MyPy//IMG_20191020_152247R1.jpg')