<背景>
濾鏡處理是圖像處理中一種非常常見的方法。比如photoshop中的濾鏡效果,除了自帶的濾鏡,還擴展了很多第三方的濾鏡效果插件,可以對圖像做豐富多樣的變換;很多手機app實現了實時濾鏡功能,最有名的當屬Instagram。
PIL中主要涉及到卷積濾鏡,其原理是針對數字圖像的像素矩陣,使用一個nxn的方形矩陣做濾波器(即卷積核kernel,常見的如3x3,5x5等),對該圖像像素進行卷積遍歷(即截取和卷積核同等大小的像素矩陣進行卷積運算),每一個輸出像素都是一定區域像素按一定權重組合計算出的結果(像素不獨立,受到鄰近像素的影響,鄰近像素區域可以調整,選取范圍越大,計算量越大,圖像處理時間越長),遍歷后的圖像就是輸出圖像。如果算法經過優化,遍歷的速度足夠快,那就是實時濾鏡(live filter),可以實時預覽圖像過濾后的效果。
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 | 銳化濾鏡 |
<效果>
原圖:
模糊濾鏡:
銳度增強濾鏡:
細節濾鏡:
輪廓濾鏡:
邊界提取濾鏡:
邊界增強濾鏡:
邊界增強濾鏡-加強版:
平滑濾鏡:
平滑濾鏡-加強版:
浮雕濾鏡:
<源碼分析>
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種濾鏡對應的矩陣:
模糊濾鏡:
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
)
輪廓濾鏡:
name = " Contour "
filterargs = (3, 3), 1, 255, (
-1, -1, -1,
-1, 8, -1,
-1, -1, -1
)
細節濾鏡:
name = " Detail "
filterargs = (3, 3), 6, 0, (
0, -1, 0,
-1, 10, -1,
0, -1, 0
)
邊緣增強濾鏡:
name = " Edge-enhance "
filterargs = (3, 3), 2, 0, (
-1, -1, -1,
-1, 10, -1,
-1, -1, -1
)
邊緣增強濾鏡-增強版:
該增強版和原濾鏡僅僅是矩陣2行2列的一個參數大小不同,實際是修改了中心像素的權重。這個數值可以任意修改以自定義邊緣增強的幅度。name = " Edge-enhance More "
filterargs = (3, 3), 1, 0, (
-1, -1, -1,
-1, 9, -1,
-1, -1, -1
)
浮雕濾鏡
name = " Emboss "
filterargs = (3, 3), 1, 128, (
-1, 0, 0,
0, 1, 0,
0, 0, 0
)
邊緣提取濾鏡:
name = " Find Edges "
filterargs = (3, 3), 1, 0, (
-1, -1, -1,
-1, 8, -1,
-1, -1, -1
)
平滑濾鏡:
name = " Smooth "
filterargs = (3, 3), 13, 0, (
1, 1, 1,
1, 5, 1,
1, 1, 1
)
平滑濾鏡-加強版:
平滑濾鏡的加強是增加了濾鏡窗口的尺寸,有3x3擴展到5x5, 這樣每一個新像素的產生會包含25個周圍原始像素的加權貢獻(離得越近,貢獻越大),這樣的結果會更加平滑自然,代價是處理速度會明顯的變慢。
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
)
銳化濾鏡:
name = " Sharpen "
filterargs = (3, 3), 16, 0, (
-2, -2, -2,
-2, 32, -2,
-2, -2, -2
)
此外,這些濾鏡不僅可以獨立使用,還可以自由組合,比如邊緣提取+平滑濾鏡,可以得到更加干凈的邊緣提取圖像等等,此處不一一列舉。
左圖為原始邊界提取圖,右側為平滑后的邊界圖。
<腳本源碼>
# -*- 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