基于python实现把图片转换成素描
这篇文章主要介绍了基于python实现把图片转换成素描,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
导语:
你是否还在为当时年少时没有选择自己的梦想而伤心,是否还在为自己的无法成为绘画名家而苦恼,这一切都不需要担心。python都能帮你实现,诶!python怎么能画画呢,一些简单的图案没问题,但是我要是想画素描那肯定没有办法了呀!
需求分析:
通过python代码脚本,实现绘制素描
安装工具
pipinstallpillow pipinstallnumpy
代码实现
首先我们需要看一下我们需要的原图:
这是一头大水牛,那我们要如何将它变成一幅素描画呢?
来看我们第一种方案:
#-*-coding:utf-8-*-
fromPILimportImage
fromrandomimportrandint
old=Image.open(r"da.jpg")
new=Image.new('L',old.size,255)
w,d=old.size
old=old.convert('L')
PEN_SIZE=3
COLOR_DIFF=7
LINE_LEN=2
foriinrange(PEN_SIZE+1,w-PEN_SIZE-1):
forjinrange(PEN_SIZE+1,d-PEN_SIZE-1):
originalcolor=255
lcolor=sum([old.getpixel((i-r,j))
forrinrange(PEN_SIZE)])//PEN_SIZE
rcolor=sum([old.getpixel((i+r,j))
forrinrange(PEN_SIZE)])//PEN_SIZE
ifabs(lcolor-rcolor)>COLOR_DIFF:
originalcolor-=(255-old.getpixel((i,j)))//4
forpinrange(-LINE_LEN+randint(-1,1),LINE_LEN+randint(-1,1)):
new.putpixel((i,j+p),originalcolor)
ucolor=sum([old.getpixel((i,j-r))
forrinrange(PEN_SIZE)])//PEN_SIZE
dcolor=sum([old.getpixel((i,j+r))
forrinrange(PEN_SIZE)])//PEN_SIZE
ifabs(ucolor-dcolor)>COLOR_DIFF:
originalcolor-=(255-old.getpixel((i,j)))//4
forpinrange(-LINE_LEN+randint(-1,1),LINE_LEN+randint(-1,1)):
new.putpixel((i+p,j),originalcolor)
lucolor=sum([old.getpixel((i-r,j-r))
forrinrange(PEN_SIZE)])//PEN_SIZE
rdcolor=sum([old.getpixel((i+r,j+r))
forrinrange(PEN_SIZE)])//PEN_SIZE
ifabs(lucolor-rdcolor)>COLOR_DIFF:
originalcolor-=(255-old.getpixel((i,j)))//4
forpinrange(-LINE_LEN+randint(-1,1),LINE_LEN+randint(-1,1)):
new.putpixel((i-p,j+p),originalcolor)
rucolor=sum([old.getpixel((i+r,j-r))
forrinrange(PEN_SIZE)])//PEN_SIZE
ldcolor=sum([old.getpixel((i-r,j+r))
forrinrange(PEN_SIZE)])//PEN_SIZE
ifabs(rucolor-ldcolor)>COLOR_DIFF:
originalcolor-=(255-old.getpixel((i,j)))//4
forpinrange(-LINE_LEN+randint(-1,1),LINE_LEN+randint(-1,1)):
new.putpixel((i+p,j+p),originalcolor)
new.save(r"pencil_drawing.jpg")
我们这第一份素描图案时以线条为单位进行素描的,而且还增加了随机函数,图案中线条的长度不确定,这样创作的素描看上去更加柔和,看起来更加接近真实的人类作画的风格。
但是这个方法有一些弊端,
一是代码量较多
二是执行速度过慢
你想通过这个方式实现一个素描图案,需要等待很长时间。
那么有没有更好的方式呢?
来,我们再来看,接下来我们要用一种更友好的方式来实现这个需求
fromPILimportImage
importnumpyasnp
a=np.asarray(Image.open('牛.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('new.jpg')
可能细心一点,大家可以看到我使用的是,数据分析,金融量化,机器学习,人工智能的必备工具包numpy,而且代码量缩短的二十几行了,效果相较于上面那种方式,还要更好一些,运行的速度也要快很多倍。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。