<背景> 算法
濾鏡處理是圖像處理中一種很是常見的方法。好比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
![](http://static.javashuo.com/static/loading.gif)
細節濾鏡: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