Python3 用PIL处理图像(二)——将图片装换成素描

Stella981
• 阅读 578

今儿一朋友发了一张我的照片,经过了处理,转换成素描照了,随后又发了一段代码给我,这个其实说新奇也不是太新奇,但是也挺有意思的,那我们就来分析一下这段代码,看看是如何将一张图片转换成素描图的;

我们先来看一下发给我的代码是怎么样的:

from PIL import Image,ImageFilter,ImageOps

img = Image.open("苹果.jpg")

def dodge(a,b,alpha):
    return min(int(a*255/(256-b*alpha)),255)

def draw(img,blur=10,alpha=1.0):
    img1 = img.convert('L')

    img2 = img1.copy()
    img2 = ImageOps.invert(img2)

    for i in range(blur):
        img2 = img2.filter(ImageFilter.BLUR)

    width,height = img1.size
    for x in range(width):
        for y in range(height):
            a = img1.getpixel((x,y))
            b = img2.getpixel((x,y))
            img1.putpixel((x,y),dodge(a,b,alpha))

    img1.save("素描.jpg")

draw(img)

OK,我们首先来总结一下,要实现图片到素描的转化,有哪些步骤:

  1. 打开目标图片
  2. 因为素描是黑白的,所以我们要转换成灰度模式
  3. 对像素点进行处理
  4. 保存

那么接下来,我们就一点一点来实现:

  1. 打开目标图片
    Python3 用PIL处理图像(二)——将图片装换成素描

    from PIL import Image
    
    image = Image.open('人.jpg')
    
    image.show()
    
  2. 转换成灰度模式
    Python3 用PIL处理图像(二)——将图片装换成素描

    from PIL import Image
    
    image = Image.open('人.jpg')
    image = image.convert('L')
    image.show()
    
  3. 我们需要复制一层,然后将其反色,方便我们后面对照片进行处理
    Python3 用PIL处理图像(二)——将图片装换成素描

    from PIL import Image,ImageOps
    
    image = Image.open('人.jpg')
    image = image.convert('L')
    
    image2 = image.copy()    # 复制一层
    image2 = ImageOps.invert(image2)    # 将图片反相
    image2.show()
    

    我们发现,现在与之前相比,黑的变成白的,白的变成黑的了,通过 Python3 用PIL处理图像(一)——PIL的基础运用 应该知道,灰度模式就是8位的黑白照片,其中8位就是 0-255级别的黑白变化,我们后面可以看见,上图和本图同一个像素点位置的颜色值相加刚好是255

  4. 对image2添加模糊滤镜
    Python3 用PIL处理图像(二)——将图片装换成素描

    from PIL import Image,ImageOps,ImageFilter
    
    image = Image.open('人.jpg')
    image = image.convert('L')
    
    image2 = image.copy()
    image2 = ImageOps.invert(image2)
    
    for i in range(10):
        image2 = image2.filter(ImageFilter.BLUR)
    
    image2.show()
    

    会发现这里用了循环,说明我们添加了10层滤镜,这里关于添加滤镜次数对最后效果的影响,这里能说的是,次数越多,最后素描的阴影效果就越强;

  5. 遍历每个像素点,改变其颜色
    Python3 用PIL处理图像(二)——将图片装换成素描

    from PIL import Image,ImageOps,ImageFilter
    
    image = Image.open('人.jpg')
    image = image.convert('L')
    
    image2 = image.copy()
    image2 = ImageOps.invert(image2)
    
    for i in range(10):
        image2 = image2.filter(ImageFilter.BLUR)
    
    width,height = image.size    # 获得图片的长和宽
    for x in range(width):       # 遍历图片的每一个像素点
        for y in range(height):
            a = image.getpixel((x,y))    # 获取像素点的值
            b = image2.getpixel((x,y))
            image.putpixel((x,y),min(int(a*255/(256-b)),255))
            # image.putpixel(位置,值)函数就是用来修改像素点的值的
            # 其中 a*255/(256-b) 这个公式为什么出来之后就能够达到素描的效果,恕我还没有研究明白
            # 至于说这里为什么还要用min()函数,这是因为我们才计算过程中,可能会超过255,而我们最大值就是255
    
    image.show()
    

    我们发现现在的效果已经出来了,这里是主要的实现,我们需要好好掰扯掰扯;
    Python3 用PIL处理图像(二)——将图片装换成素描
    这里把每个像素点的处理后的值都显示出来了,大家可以看到,同一个像素点反相之后和反色之前相加一直为255;
    至于最后一个一直是在255左右变化,恕我没整明白;

  6. 最后将图片保存,完工!

我们看下,模糊滤镜对最后效果的影响:
Python3 用PIL处理图像(二)——将图片装换成素描 Python3 用PIL处理图像(二)——将图片装换成素描 Python3 用PIL处理图像(二)——将图片装换成素描 Python3 用PIL处理图像(二)——将图片装换成素描
从左到右,分别添加了1、10、20、30次滤镜,其效果就像轮廓和上色的差别,大家有兴趣可以修改参数好好试一下;

点赞
收藏
评论区
推荐文章
红橙Darren 红橙Darren
3年前
Android Studio插件开发之 - 基础入门篇
1.概述上一期我们已经。如何才能像ButterKnife一样自动给我们生成代码呢?所以我们不得不去了解AndroidStudio的插件开发了。我们在开发的过程中对AndroidStudio的插件应该并不陌生,我们也时常用到比如:  :现在大多数服务端api都以json数据格式返回,而客户端需要根据api接口生成相应的实体类,这个插件把这个过程自动
Wesley13 Wesley13
3年前
java如何获取一个double的小数位数
前言看标题是不是觉得这是一个很简单的问题,我一开始也是这么认为的,但是实际情况下,在各种情况下我们都进行了测试,发现很多实际情况是无法不尽如人意的。方法分析当前能想到的比较容易有下面几种1、直接使用double处理2、将double转换成String进行处理方法一:直接对double进行处理,进行计算通过计算后的结
Stella981 Stella981
3年前
Canvas + JavaScript 制作图片粒子效果
学习canvas,javascript的小伙伴,可以跟着我这篇文章的思路一起做一个小效果出来,代码都齐全了。首先看一下源图和转换成粒子效果的对比图:!CanvasJavaScript制作图片粒子效果(https://oscimg.oschina.net/oscnet/ded02015391ee81719a21ffa584785e84c2.
Wesley13 Wesley13
3年前
Java字符拼成图片(image
@TOC背景用Java实现字符拼成一个图片,先看一下效果:左边是原图,右边是用字符拼成的效果,即写好代码,读入一张图片,然后用指定的字符把这个图片的轮廓拼出来!左边是原图(https://oscimg.oschina.net/oscnet/c06b8c38969b4a45a0640cc3c2678d63260.png)放大之
wnm wnm
2年前
万能码齐绽放(安全扫码专业委员会)
万能码齐绽放(安全扫码专业委员会)薄薄的一张二维码拥有这多种功能,虽然市面上大多是一码一用的二维码,但是多种功能的二维码并非是没有,要想凸显出来,那必然是需要的有独特支出的,通常的聚合码就是将这种东西放在一张码上,但是这个并不是,而是自己研发了多种功能,这个码只是为了功能而存在的,相当于一个平台,为功能服务,同时也兼具了聚合码的功能效用,可以把人们想要的功能
Stella981 Stella981
3年前
Cocos Creator基础教程(12)—精灵变身
在CocosCreator中使用率最高的非精灵(Sprite)莫属了,在游戏中我们经常会遇到将一张图片替换成另一张图片的情况,或者是在不同状态时来回切换图片。实现这个功能对程序员同学来说并不难,但是!回头检视一下编写的代码,能否让美术、策划同学使用上吗?如果不能的话,相信这篇教程可能对你和你的伙伴有更多启发!1\.SpriteIndex组件
铁扇公主 铁扇公主
1年前
图像能转换成其他艺术风格吗?
图像能转换成其他艺术风格吗?回答是肯定的,入手AlienSkinSnapArt4汉化激活版轻松帮您完成操作哟,AlienSkinSnapArt4是一款专业的图像转换软件,可以将普通的照片和图像转换成艺术风格的图片,如油画、水彩、铅笔画等,让您的照片更具有艺
崇恩圣帝 崇恩圣帝
5个月前
用Python破解滑块验证码的方法详解
步骤一:获取验证码图像首先,我们需要获取网站上的滑块验证码图像。可以通过网络爬虫或者直接从网站上获取图像数据。在这个示例中,我们将使用一张模拟的滑块验证码图片进行演示。python复制代码importcv2读取验证码图片captchaimagecv2.im
崇恩圣帝 崇恩圣帝
5个月前
使用Python识别滑块验证码缺口的方法及实现步骤详解
步骤一:获取验证码图像首先,我们需要获取网站上的滑块验证码图像。可以使用网络爬虫或直接从网站上获取图像数据。在这个示例中,我们将使用一张模拟的滑块验证码图片进行演示。python复制代码importcv2读取滑块验证码图片captchaimagecv2.i
崇恩圣帝 崇恩圣帝
5个月前
使用Python识别滑块验证码缺口的方法及实现步骤详解
步骤一:获取验证码图像首先,我们需要获取网站上的滑块验证码图像。可以使用网络爬虫或直接从网站上获取图像数据。在这个示例中,我们将使用一张模拟的滑块验证码图片进行演示。python复制代码importcv2读取滑块验证码图片captchaimagecv2.i