用Python三步就学会滤镜的实现原理,轻松上手!

640?wx_fmt=png

2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑


作者 | 神秘的铁头娃  

来源 | AI算法与图像处理(id:AI_study)DAT-2017


过几天就是清明节了,作为传统节日,特别是一个有放假的传统节日,肯定要安排一下。正好最近学习一些新知识,并拿来做了一些有意思的小实验,在这里与大家分享。今天的教程不难,大家可以学习了解到如何用 LUT(查找表)实现为图片增加滤镜的效果。


一 清明节简介


明节,又称踏青节、行清节、三月节、祭祖节,节期在仲春与暮春之交。清明兼具自然与人文两大内涵,既是自然节气点,也是传统节日。清明节是传统的重大春祭节日,扫墓祭祀、缅怀祖先,是中华民族数千年以来的优良传统,不仅有利于弘扬孝道亲情、唤醒家族共同记忆,还可促进家族成员乃至民族的凝聚力和认同感。清明节融汇自然节气与人文风俗为一体,是天时地利人和的合一,充分体现了中华民族先祖们追求“天、地、人”的和谐合一,讲究顺应天时地宜、遵循自然规律的思想。清明节的节俗丰富,扫墓祭祖与踏青郊游是清明节的两大礼俗主题,这两大传统礼俗主题在中国自古传承,至今不辍。


——嗯,没错,百度百科说的


二 清明上河图


说起“清明节”,我会想到《清明上河图》,但大家都知道,“清明节”和《清明上河图》是无关的... ....(别批评我,我就是联想到了~)


清明上河图,中国十大传世名画之一。为北宋风俗画,北宋画家张择端仅见的存世精品,属国宝级文物,现藏于北京故宫博物院。清明上河图宽 24.8 厘米、长 528.7厘米,绢本设色。作品以长卷形式,采用散点透视构图法,生动记录了中国十二世纪北宋都城东京(又称汴京,今河南开封)的城市面貌和当时社会各阶层人民的生活状况,是北宋时期都城汴京当年繁荣的见证,也是北宋城市经济情况的写照。


640?wx_fmt=jpeg


为什么要介绍介绍这么多《清明上河图》呢?因为它就是今天主角!最近,我正好学习了 LUT 相关的知识,如果大家对 LUT 不太熟悉的,可以先告诉大家一个最典型的应用——滤镜,没错,可以利用 LUT 转换成不同效果的图像。在初步学习后,就在《清明上河图》上小试牛刀操作了一把~别走,咱们往下看~


三、LUT介绍——查找表


LUT(look up table)基本思想是查表,既将矩阵中所有可能遇到的值都计算一遍储存在数组中,在遍历过程中只是将对应的查表值进行赋值即可,这样可以避免大量的重复计算,这是典型的使用存储空间换取速度的做法。例如以下图展示了一个查找表实现将低对比度的图转变为高对比度的原理图:


640?wx_fmt=png


会是什么效果呢?比如下面两张图:


640?wx_fmt=jpeg

原图


640?wx_fmt=jpeg

加滤镜后的效果图


四、滤镜原理


我们都知道常见的色彩空间有 RGB、CMY、HSV 等等,其中最经常用到的当属 RGB了,当然这些色彩空间之间是可以互相转换的。


RGB 色彩空间源于使用阴极射线管(CRT)的彩色电视。RGB 色彩空间是相对色彩标准的一个例子。基色(R-红,G-绿,B-蓝)模拟在 CRT 荧光材料中的荧光物质。RGB 模型使用加性色彩混合以获知需要发出什么样的光来产生给定的色彩。具体色彩的值用三个元素的向量来表达——三个基色的亮度。


640?wx_fmt=jpeg


而滤镜实际上就是通过对RGB三个通道的值进行一定的运算得到一个新的值,然后再显示出来。例如,“流年”滤镜就是通过对R通道的数值开平方,然后乘以一个参数得到的结果,其他通道的值保持不变。实际上就是类似于LUT(查找表)所实现的功能。


五、代码实现


为了让大家能够重现效果并理解底层的原理,这里使用了三种方法进行实现分别如下所示:本人所用的环境:python3.6;所需要的导入的库:cv2、numpy 与 PIL。


1、对图像的三个通道亮度值进行直接修改的方法实现——实现“流年”滤镜效果。思路如下:


  • 以RGB格式读入图片;

  • 将 R 通道的值提取出来并进行运算用im1存储(图像的矩阵*[1.0,0,0]让另外两个通道的值变成0),同理另外两个通道的值用im2存储;

  • 最后将im1和im2相加,并转换一下可以显示的格式即可。


def fleeting(self):        src=Image.open(self.path)        src.show()        img=np.asarray(Image.open(self.path).convert('RGB'))        img1=np.sqrt(img*[1.0,0.0,0.0])*self.params        img2=img*[0.0,1.0,1.0]        img=img1+img2        img=Image.fromarray(np.array(img).astype('uint8'))        img.show()

640?wx_fmt=png

“流年”效果图


2、利用 opencv 中的函数实现。opencv 中可以直接调用:


cv2.applyColorMap(img, cv2.COLORMAP)# 其中img为输入图片,cv2.COLORMAP为可选的效果


如下所示:可以将cv2.COLORMAP替换为下面的英文单词或者对应的数字皆可


640?wx_fmt=png


cv2.applyColorMap(img, cv2.COLORMAP_COLL)


640?wx_fmt=png

cool风格的清明上河图


3、利用 PIL 中函数实现


PIL 中通过调用 filter 函数,参数传递 ImageFilter 下的滤镜参数即可实现各种滤镜效果的图案

def lut_PIL(self):        src=Image.open(self.path)        im2 = src.filter(ImageFilter.BLUR)  # 模糊滤镜        im2.save("qm_1.jpg")
im2 = src.filter(ImageFilter.EMBOSS) # 浮雕效果滤镜 im2.save("qm_2.jpg")
im2 = src.filter(ImageFilter.EDGE_ENHANCE) # 凸显边界 im2.save("qm_3.jpg")
im2 = src.filter(ImageFilter.EDGE_ENHANCE_MORE) # 加倍凸显边界 im2.save("qm_4.jpg")
im2 = src.filter(ImageFilter.FIND_EDGES) # 只保留边界 im2.save("qm_5.jpg")
im2 = src.filter(ImageFilter.CONTOUR) # 铅笔画效果 im2.save("qm_6.jpg")
im2 = src.filter(ImageFilter.SMOOTH_MORE) # 平滑滤镜(阀值更大)

img.filter(ImageFilter.EMBOSS) #实现浮雕效果


640?wx_fmt=png

浮雕效果的清明上河图


六、总结


  • 清明将至,学一下传统的文化

  • 了解 LUT(look up table 查找表)和滤镜的原理

  • 通过对图片的三个通道值进行改变和利用 opencv 和 PIL 的函数三种方法实现不同的滤镜效果

  • 完整代码:

    https://github.com/SCUTPZW/opencv/blob/master/LUT_qm


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


精彩推荐

「2019 Python开发者日」全日程揭晓这一次我们依然“只讲技术,拒绝空谈”10余位一线Python技术专家共同打造一场硬核技术大会。更有深度培训实操环节,为开发者们带来更多深度实战机会。更多详细信息请咨询13581782348(微信同号)。

640?wx_fmt=jpeg

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值