目录

前言

一、代码展示

二、代码讲解

1.灰度图和高斯模糊

2.素描图生成

总结


前言

素描的一大特点是线条丰富,是以线条来画出物体明暗的单色画。而普通照片大多由色块堆积而成。素描像是一匹黑马,独树一帜。虽然乍一看平平无奇,仔细端详却是耐人寻味。让我们了解一下如何通过程序将普通的色彩图片转换成素描风格的画作吧。


一、代码展示

from PIL import Image, ImageOps, ImageFilter
import matplotlib.pyplot as plt
img=Image.open("soldier1.jpg")
width,height=img.size#序列解包

_,axes=plt.subplots(1,2,figsize=(30,30))
axes[0].imshow(img)
axes[0].set_title("original")

#灰度图
img_gray=img.convert("L")#L是灰度图的表示,这行代码生成灰度图
plt.rcParams["image.cmap"]="gray"
img_invert=ImageOps.invert(img_gray)#反色功能
img_gaussian=img_invert.filter(ImageFilter.GaussianBlur(10))#高斯模糊功能

for x in range(width):
    for y in range(height):
        pos=(x,y)
        A=img_gray.getpixel(pos)
        B=img_gaussian.getpixel(pos)
        img_gray.putpixel(pos, min(int(A+A*B/(255-B)), 255))

axes[1].imshow(img_gray)
axes[1].set_title("sketch")
img_gray.save("sketch.png")

plt.show()

二、代码讲解

1.这个代码的核心公式是颜色减淡公式:min(int(A+A*B/(255-B)),255),其中A是灰度,B是高斯模糊。通过这个公式我们把代码分成两个部分,第一个是求算A,B的阶段,第二个是利用条件绘制出素描图

1.灰度图和高斯模糊

我们在打开图片后将原图展示到用plt.subplots()创建的子画布中。创建两个子画布后,先将原图贴上去,再用set_title()设置展示图片的名字。我这里使用的是soldier1.jpg图片,大家可以加载自己喜欢的图片并将他和文件保存到一个文件夹里面。

接下来就是做素描图的过程了。根据公式,为了的到理想的高斯模糊,我们要先将彩色的画变成灰度图,然后给他进行反色再高斯模糊。

什么是灰度图?很好理解,就是由只有黑白灰的颜色构建出来的图片,他只有明度变化。因为matplotlib 有自己的颜色规则,所以单用convert()不一定会生成灰度图,还需要:plt.rcParams["image.cmap"] ="gray"  才能将其转化为灰度图模式。

那什么又是反色呢?简单地说就是黑变成了白,白变成了黑。浅色变成了相应的深色。其中他们的对应关系是:255-其中一种颜色=对应反色。接下来就是高斯模糊,其实就是模糊图片。GaussianBlur()这里面填入的是模糊程度,数字越大越模糊。

2.素描图生成

我们用getpixel()方法结合嵌套循环,分别取出灰度图,高斯模糊中的每一个像素RGB值,然后套入我们的颜色减淡公式,每个像素通过公式计算得到减淡后的像素RGB之后,使用putpixel()将该RGB值转化成相应色块并重新贴回img_gray图片里面,覆盖掉之前的内容。

其实这个公式一开始只有A+A*B/(255-B),可惜因为RGB不接受小数,所以要将结果整化,然后又怕结果超过255颜色最大值,就得用python自带的min()方法在该公式结果和255中取较小的一个。这样不管公式结果多大,返回值都可以控制在255以内。至于这个公式怎么来的嘛。。。要不就是实验,要不就是高度抽象的证明,这个不重要呗。

接下来就是imshow()加载图片,set_title()给素描图起名,save()保存,然后show()展示画布,大功告成!


总结

以上就是今天要讲的内容,本文介绍了如何将普通颜色图片转换成素描风格图片。其中涉及到了一些图片处理的知识,希望大家多多学习。