天天看点

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

作者 | 丁彦军

来源 | 恋习Python(ID:sldata2017)

责编 | swallow

13日早晨,当北京市民拉开窗帘时发现,窗外雪花纷纷扬扬在空中飘落,而且越下越大,树上、草地、屋顶、道路上,都落满雪花。京城银装素裹,这是今冬以来北京迎来的第二场降雪。

一下雪,北京就变成了北平,故宫就变成了紫禁城。八万张门票在雪花飘下来之前,便早已预订一空。

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

(图片来源:故宫官网 版权归故宫官网所有)

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

看着朋友圈、微博好友都在纷纷晒图,小编只能羡慕不已。

不过,突然想到,可以通过Python将故宫的建筑物图片,转化为手绘图(素描效果)。效果图如下:

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

一、概念与原理

我们都知道手绘图效果的特征主要有:

  • 黑白灰色;边界线条较重;相同或相近色彩趋于白色;略有光源效果

核心原理:利用像素之间的梯度值和虚拟深度值对图像进行重构,根据灰度变化来模拟人类视觉的模拟程度

把图像看成二维离散函数,灰度梯度其实就是这个二维离散函数的求导,用差分代替微分,求取图像的灰度梯度。常用的一些灰度梯度模板有:Roberts 梯度、Sobel 梯度、Prewitt 梯度、Laplacian 梯度。

以Sobel 梯度计算来解释:

首先计算出 

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

,然后计算梯度角 

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

梯度方向及图像灰度增大的方向,其中梯度方向的梯度夹角大于平坦区域的梯度夹角。如下图所示,灰度值增加的方向梯度夹角大,此时梯度夹角大的方向为梯度方向。对应在图像中寻找某一点的梯度方向即通过计算该点与其8邻域点的梯度角,梯度角最大即为梯度方向。

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

二、图像的数组形式与变换

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

其中,需要用到的方法:

  • Image.open( ): 打开图片
  • np.array( ) : 将图像转化为数组
  • convert("L"): 将图片转换成二维灰度图片
  • Image.fromarray( ): 将数组还原成图像uint8格式

代码如下:

from PIL import Imageimport numpy as np im = Image.open(r"C:\Users\Administrator\Desktop\gugong\微信图片_20190216152248.jpg").convert('L') a=np.asarray(im).astype('float') print(a.shape,a.dtype) (1080, 608) float64#(1080, 608)分别表示高度,宽度

三、图像的手绘效果处理

实现思路步骤:

1、梯度的重构

numpy的梯度函数的介绍

np.gradient(a) : 计算数组a中元素的梯度,f为多维时,返回每个维度的梯度 

离散梯度: xy坐标轴连续三个x轴坐标对应的y轴值:a, b, c 其中b的梯度是(c-a)/2 

而c的梯度是: (c-b)/1

当为二维数组时,np.gradient(a) 得出两个数组,第一个数组对应最外层维度的梯度,第二个数组对应第二层维度的梯度。 

代码如下:

grad=np.gradient(a) grad_x,grad_y=grad grad_x = grad_x * depth / 100.#对grad_x值进行归一化 grad_y = grad_y * depth / 100.#对grad_y值进行归一化

2、构造guan光源效果

设计一个位于图像斜上方的虚拟光源

光源相对于图像的视角为Elevation,方位角为Azimuth

建立光源对各点梯度值的影响函数

运算出各点的新像素值

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

其中:

np.cos(evc.el) : 单位光线在地平面上的投射长度

dx,dy,dz :光源对x,y,z三方向的影响程度

3、梯度归一化

  • 构造x和y轴梯度的三维归一化单位坐标系;
  • 梯度与光源相互作用,将梯度转化为灰度。

4、图像生成

具体详情代码如下:

from PIL import Imageimport numpy as npimport osimport joinimport timedef image(sta,end,depths=10):     a = np.asarray(Image.open(sta).convert('L')).astype('float')     depth = depths  # 深度的取值范围(0-100),标准取10     grad = np.gradient(a)  # 取图像灰度的梯度值     grad_x, grad_y = grad  # 分别取横纵图像梯度值     grad_x = grad_x * depth / 100.#对grad_x值进行归一化     grad_y = grad_y * depth / 100.#对grad_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     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(end)def main():     xs=10     start_time = time.clock()     startss = os.listdir(r"C:\Users\Administrator\Desktop\gugong")     time.sleep(2)for starts in startss:         start = ''.join(starts)         sta = 'C:/Users/Administrator/Desktop/gugong/' + start         end = 'C:/Users/Administrator/Desktop/gugong/' + 'HD_' + start         image(sta=sta,end=end,depths=xs)     end_time = time.clock()     print('程序运行了  ----' + str(end_time - start_time) + '   秒')     time.sleep(3) main() 程序运行了  ----43.01828205879955   秒  #一共35张图片

最终效果图对比:

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

最后,你自己动手试试吧?通过此代码为自己画一张手绘图,也可以为自己的家乡或母校画。

参考资料:

http://www.icourse163.org/learn/BIT-1001870002?tid=1001963001#/learn/announce

代码链接:

https://pan.baidu.com/s/1E_aZTRQWOzGV-2GV_iH43w

提取码:64z9

(本文仅代表作者观点,转载请联系原作者)

python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

推荐阅读:

  • 5行代码就能入门爬虫?
  • Python助你抢红包
  • 情人节送什么?Python告诉你
  • 3分钟实现9种经典排序算法的可视化|Python
  • 用Python挖一挖知乎宅男最喜欢的1000个妹子 
  • Python爬取了猫眼47858万条评论,告诉你《飞驰人生》值不值得看?! 
  • 从零开始用Python搭建推荐引擎(附代码)
  • 赵本山:我的时代还没有结束 | Python告诉你
  • 代码测试意味着完全消灭了Bug?

    python array按行归一化_只需45秒,Python 给故宫画一组手绘图!

继续阅读