<背景> 算法
滤镜处理是图像处理中一种很是常见的方法。好比photoshop中的滤镜效果,除了自带的滤镜,还扩展了不少第三方的滤镜效果插件,能够对图像作丰富多样的变换;不少手机app实现了实时滤镜功能,最有名的当属Instagram。app
PIL中主要涉及到卷积滤镜,其原理是针对数字图像的像素矩阵,使用一个nxn的方形矩阵作滤波器(即卷积核kernel,常见的如3x3,5x5等),对该图像像素进行卷积遍历(即截取和卷积核同等大小的像素矩阵进行卷积运算),每个输出像素都是必定区域像素按必定权重组合计算出的结果(像素不独立,受到邻近像素的影响,邻近像素区域能够调整,选取范围越大,计算量越大,图像处理时间越长),遍历后的图像就是输出图像。若是算法通过优化,遍历的速度足够快,那就是实时滤镜(live filter),能够实时预览图像过滤后的效果。dom
ImageFilter是Python PIL的滤镜模块,当前版本支持10种增强滤镜,经过这些预约义的滤镜,能够方便的对图片进行一些过滤操做,从而去掉图片中的噪音(部分的消除),这样能够下降图像处理算法的复杂度(如模式识别等),更方便的实现和预览一些算法的效果。
本文脚本包含如下所有滤镜, 实现了10种图像处理滤镜的效果预览和JPEG文件保存。源码分析
ImageFilter.BLUR 优化 |
模糊滤镜 |
ImageFilter.CONTOUR |
轮廓 |
ImageFilter.DETAIL |
细节滤镜 |
ImageFilter.EDGE_ENHANCE |
边界增强 |
ImageFilter.EDGE_ENHANCE_MORE |
边界增强(阀值更 大) |
ImageFilter.EMBOSS |
浮雕滤镜 |
ImageFilter.FIND_EDGES |
边界滤镜 |
ImageFilter.SMOOTH |
平滑滤镜 |
ImageFilter.SMOOTH_MORE |
平滑滤镜(阀值更大) |
ImageFilter.SHARPEN |
锐化滤镜 |
<效果> ui
原图:spa
模糊滤镜:插件
锐度加强滤镜: 3d

细节滤镜:code
轮廓滤镜:
边界提取滤镜:
边界加强滤镜:
边界加强滤镜-增强版:
平滑滤镜:
平滑滤镜-增强版:
浮雕滤镜:
<源码分析>
PIL库的滤镜算法能够在Python\Lib\site-packages\PIL路径下找到,以下所示:
在PIL路径下,咱们看到了三个同名但后缀不一样的文件:ImageFilter.py ,ImageFilter.pyc ,ImageFilter.pyo 。
.py文件:存放的是脚本源代码;
.pyc文件 :是同名的.py编译后的字节码文件,用来供解释器解释执行;
.pyo文件 :是同名的.pyc文件通过优化后的字节码文件,一般体积更小,运行更快。
滤镜算法在ImageFilter.py文件中。
如前文所述,每个滤镜一般对应着一个滤波器(即kernel),PIL中的kernel均为常见的3x3和5x5方形矩阵,下面是PIL中9种滤镜对应的矩阵:
模糊滤镜:
class BLUR(BuiltinFilter):
name =
"
Blur
"
filterargs = (5, 5), 16, 0, (
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1
)
轮廓滤镜:
class CONTOUR(BuiltinFilter):
name =
"
Contour
"
filterargs = (3, 3), 1, 255, (
-1, -1, -1,
-1, 8, -1,
-1, -1, -1
)
细节滤镜:
class DETAIL(BuiltinFilter):
name =
"
Detail
"
filterargs = (3, 3), 6, 0, (
0, -1, 0,
-1, 10, -1,
0, -1, 0
)
边缘加强滤镜:
class EDGE_ENHANCE(BuiltinFilter):
name =
"
Edge-enhance
"
filterargs = (3, 3), 2, 0, (
-1, -1, -1,
-1, 10, -1,
-1, -1, -1
)
边缘加强滤镜-加强版:
该加强版和原滤镜仅仅是矩阵2行2列的一个参数大小不一样,实际是修改了中心像素的权重。这个数值能够任意修改以自定义边缘加强的幅度。
class EDGE_ENHANCE_MORE(BuiltinFilter):
name =
"
Edge-enhance More
"
filterargs = (3, 3), 1, 0, (
-1, -1, -1,
-1, 9, -1,
-1, -1, -1
)
浮雕滤镜
class EMBOSS(BuiltinFilter):
name =
"
Emboss
"
filterargs = (3, 3), 1, 128, (
-1, 0, 0,
0, 1, 0,
0, 0, 0
)
边缘提取滤镜:
class FIND_EDGES(BuiltinFilter):
name =
"
Find Edges
"
filterargs = (3, 3), 1, 0, (
-1, -1, -1,
-1, 8, -1,
-1, -1, -1
)
平滑滤镜:
class SMOOTH(BuiltinFilter):
name =
"
Smooth
"
filterargs = (3, 3), 13, 0, (
1, 1, 1,
1, 5, 1,
1, 1, 1
)
平滑滤镜-增强版:
平滑滤镜的增强是增长了滤镜窗口的尺寸,有3x3扩展到5x5, 这样每个新像素的产生会包含25个周围原始像素的加权贡献(离得越近,贡献越大),这样的结果会更加平滑天然,代价是处理速度会明显的变慢。
class SMOOTH_MORE(BuiltinFilter):
name =
"
Smooth More
"
filterargs = (5, 5), 100, 0, (
1, 1, 1, 1, 1,
1, 5, 5, 5, 1,
1, 5, 44, 5, 1,
1, 5, 5, 5, 1,
1, 1, 1, 1, 1
)
锐化滤镜:
class SHARPEN(BuiltinFilter):
name =
"
Sharpen
"
filterargs = (3, 3), 16, 0, (
-2, -2, -2,
-2, 32, -2,
-2, -2, -2
)
此外,这些滤镜不只能够独立使用,还能够自由组合,好比边缘提取+平滑滤镜,能够获得更加干净的边缘提取图像等等,此处不一一列举。
左图为原始边界提取图,右侧为平滑后的边界图。
<脚本源码>
#
start
#
-*- coding: cp936 -*-
import Image,ImageDraw
import ImageFilter,random,sys
img = Image.open(
"
1.jpg
")
#
#图像处理##
#
转换为RGB图像
img = img.convert(
"
RGB
")
#
通过PIL自带filter处理
imgfilted_b = img.filter(ImageFilter.BLUR)
imgfilted_c = img.filter(ImageFilter.CONTOUR)
imgfilted_ee = img.filter(ImageFilter.EDGE_ENHANCE)
imgfilted_ee_m = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
imgfilted_em = img.filter(ImageFilter.EMBOSS)
imgfilted_fe = img.filter(ImageFilter.FIND_EDGES)
imgfilted_sm = img.filter(ImageFilter.SMOOTH)
imgfilted_sm_m = img.filter(ImageFilter.SMOOTH_MORE)
imgfilted_sh = img.filter(ImageFilter.SHARPEN)
imgfilted_d = img.filter(ImageFilter.DETAIL)
#
#组合使用filter
group_imgfilted = img.filter(ImageFilter.CONTOUR)
group_imgfilted = group_imgfilted.filter(ImageFilter.SMOOTH_MORE)
#
#图像保存##
imgfilted_b.save(
"
1b.jpg
")
imgfilted_c.save(
"
1c.jpg
")
imgfilted_ee.save(
"
1ee.jpg
")
imgfilted_ee_m.save(
"
1eem.jpg
")
imgfilted_em.save(
"
1em.jpg
")
imgfilted_fe.save(
"
1fe.jpg
")
imgfilted_sm.save(
"
1sm.jpg
")
imgfilted_sm_m.save(
"
1smm.jpg
")
imgfilted_sh.save(
"
1sh.jpg
")
imgfilted_d.save(
"
1d.jpg
")
group_imgfilted.save(
"
1group.jpg
")
#
#图像显示##
imgfilted_b.show()
imgfilted_c.show()
imgfilted_ee.show()
imgfilted_ee_m.show()
imgfilted_em.show()
imgfilted_fe.show()
imgfilted_sm.show()
imgfilted_sm_m.show()
imgfilted_sh.show()
imgfilted_d.show()
group_imgfilted.show()
#
end