用Python实现图像的手绘化

点击原文地址以获得更好的阅读体验。

手绘风图片因其简约而典雅的线条,清晰而自然的纹理和充满艺术的情趣感一直是许多人的热宠。这种专注于图形个性化和艺术化的表达方式深受人们的喜爱。

下面,我来介绍一下如何用Python代码实现图片的手绘化效果。

本文所用到的Python库:

PIL库

PIL:Python Imaging Library,是Python一个强大而方便的图像处理库。不过PIL目前只支持到Python 2.7,而且从09年至今再也没更新过
Pillow:PIL的一个派生分支,但如今已经发展得比PIL本身更具活力,并且支持最新的Python3。

Numpy库

Numpy:Numerrical Python, 是一个开源的Python科学计算库,可用来存储和处理大型矩阵,据说NumPy将Python相当于变成一种免费的更强大的MatLab系统。

在命令行使用PIP安装:

pip install Pillow
pip install Numpy

然后通过

from PIL import Image
import numpy as np

就可以使用了

Image类的图片模式

PIL中的Image类有9种不同图片模式,分别为

  • 1 : 一位二值图像

  • L : 8位灰色图像

  • P : 8位彩色图像

  • RGB:24位彩色图像,红绿蓝三种色彩

  • RGBA : 32位彩色图像,红绿蓝三种色彩加Alpha通道

  • CMYK : 32位彩色图像,青、洋红、黄、黑四种色彩的印刷四分色模式

  • YCbCr: 24位彩色图像,彩色视频格式

  • I : 32位整型灰色图像

  • F : 32位浮点灰色图像

在手绘化图片前,我们要将图片转化为灰色图像,进行图像的灰度化预处理。用PIL中的convert函数非常容易实现:

img = img.convert("L")

模式“L”即为灰色图像,它的每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。

一般来说,图像灰度化的方法有四种:

  • 分量法
    将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。
  • 最大值法
    将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。
  • 平均值法
    将彩色图像中的三分量亮度求平均得到一个灰度值。
  • 加权平均法
    根据重要性及其它指标,将三个分量以不同的权值进行加权平均。

在PIL中,这个从“RGB”模式到“L模式的转换公式为

L = R * 299/1000 + G * 587/1000+ B * 114/1000

这里,我以存储位置为F:\python\Image-Freehand\中的tupian.jpg为例:


使用

Image.open(r'F:\python\Image-Freehand\tupian.jpg').convert('L')

将图片tupian.jpg 转换为灰色图像,效果为:


数据的获取与存储

通过Numpy中的asarray函数将图片的灰度值以浮点型矩阵的形式存储起来,再用gradient函数得出图片灰度值的梯度

L=np.asarray(Image.open(r'F:\python\Image-Freehand\tupian.jpg').convert('L')).astype('float')
grad = np.gradient(L)

我们来观察一下L矩阵

可以看出L是一个853*1280的二维浮点型矩阵,因此它的梯度grad里应该有两个数组矩阵,分别对应两层维度的梯度。
现取最外层维度梯度为x方向的梯度值grad_x,取第二层维度梯度值为y方向梯度值grad_y

grad_x, grad_y = grad

这时我们已经取得了图像的梯度值,就可以通过改变像素的梯度值来改变图像的灰度变化,对图像进行重构了

图像的转换

我们先设一个深度值depth,取值范围为(0,100),然后利用深度调整x和y方向的梯度值。
我们使

grad_x = grad_x*depth/100.
grad_y = grad_y*depth/100.

深度值越小,重构后的图像梯度值越小,即图像灰度值变化越小,画面线条越少,整体更显洁净。

比如当depth=1时:

反之,深度值越大,重构后的图像梯度值越大,即图像灰度值变化越大,画面线条越多,整体更显肮脏。

比如当depth=100时

因此我们需要通过改变depth,找到最符合人类视觉远近程度的深度值。

经过多次测试发现,当深度值为10左右时,即图像灰度梯度变为原来的10%左右时,画面最接近手绘化效果。(当然,对于不同的图片,这个最佳深度值不一定相同)

在本文中我们取depth=10

制造光源效果

此时图像的效果是这样的:

类似版画的效果,这是因为此时的图像还没有光源效果,跟我们实际观察事物的感觉不一样,因此我们还需要为图像制造光源效果。

如图,我们先假设一个光源位于图像斜上方,设俯视角为el,方位角为az,则单位光线在x,y,z方向上的投影长度分别为:

dx = cos(el)*cos(az)
dy = cos(el)*sin(az)
dz = sin(el)

通过多次调整发现,当俯视角el=π/2.2, 方位角az=π/4时光照效果最好。(当然对于不同图像两个角度的选取不一定相同)

实现代码为:

el = np.pi/2.2                             
az = np.pi/4                              
dx = np.cos(el)*np.cos(az)              
dy = np.cos(el)*np.sin(az)              
dz = np.sin(el)

所以,此时图像的灰度值变为

gd = 255*(dx*uni_x + dy*uni_y + dz*uni_z)

我们将这个过程叫做光源的归一化

重构图像

由于灰度值的选取范围为(0,255),为了避免数据越界,需要将生成的灰度值裁剪至0-255之间

gd = gd.clip(0,255)

由新的灰度值重构图像

im = Image.fromarray(gd.astype('uint8'))

其中uint8是一种数据类型

  • u : 正数
  • int : 整数
  • 8 : 8位信息,即最大值为255,最小值为0

这时图像的手绘化效果已经完成了

最后保存图像:

im.save(r'F:\python\Image-Freehand\tupianHD.jpg')

完整代码已经托管到我的github仓库
https://github.com/Leotemp/Image-Freehand

本示例来源于北京理工大学嵩天老师的Python数据分析课程
老师讲的特别好,在此安利给大家。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容