Python -- 图像的手绘风格

**

Python – 图像的手绘风格

**
今天在mooc上了解到python可以做出手绘风格的图片,感觉很惊奇,很想知道python对于图片是如何处理的,因此上网搜了一些博主的文章,总结了一下。

手绘效果图有一下几个特征:
1、图像中仅有黑白灰色
2、边界线条较重
3、相同或相近色彩趋于白色
4、略有光源效果

写这个程序会用到两个库,一个是PIL(Python Imaging Library,),还有一个是numpy。PIL(Python Image Library)是python的第三方图像处理库,但是由于其强大的功能与众多的使用人数,几乎已经被认为是python官方图像处理库了。PIL历史悠久,原来是只支持python2.x的版本的,后来出现了移植到python3的库pillow,pillow号称是“friendly fork for PIL”,其功能和PIL差不多,但是支持python3。

那么我们如何安装PIL呢,(其实是安装pillow啦,因为我的电脑是Windows10 版本,并且Python是3.7.2版本的)(PS:如果使用Pycharm的话直接在软件内下载即可)
首先>>>我们先打开命令行窗口输入pip install pillow即可(PS:由于版本更新的问题,可能有些人需要更新一下pip,命令行输入“python -m pip install --upgrade pip”即可)
Python -- 图像的手绘风格
同样的>>>我们安装numpy库
Python -- 图像的手绘风格
然后>>>我们可以在python IDLE中测试一下是否安装成功
Python -- 图像的手绘风格
Python -- 图像的手绘风格
安装成功>>>我们可以继续进行程序的编写了,下面展出代码:

from PIL import Image
import numpy as np

a = np.asarray(Image.open("hit_example.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('hit_exampleHD.jpg')
print("图像手绘化已完成")

其中
np.asarray(Image.open(’./beijing.jpg’).convert(‘L’)).astype(‘float’)意思是将图像以灰度图的方式打开并将数据转为float存入np中.

np.gradient(a) 是求a的梯度,返回的是二元信息,可分别赋值给grad_x,grad_y,将梯度按照深度等级计算并且归一化处理。

建立光源效果

建立模型后可分析出np.cos(vec_el)为单位光线在地平面上的投影长度,dx,dy,dz是光源对x/y/z三方向的影响程度.

将梯度归一化

构造x和y轴梯度的三维归一化单位坐标系 A = np.sqrt(grad_x2 + grad_y2 + 1)

梯度和光源相互作用,将梯度转化为灰度 b = 255*(dxuni_x + dyuni_y + dz*uni_z)

之前为了处理方便,我们梯度值调为0-1之间,梯度与光源相互作用后,还原为0-255,但仍然可能会有部分溢出,因此,为避免越界,将生成的灰度值剪裁至0-255区间b = b.clip(0,255)

最后就能得到手绘效果的图啦~

最后贴图:
Python -- 图像的手绘风格
Python -- 图像的手绘风格