Python 影象處理詳解
阿新 • • 發佈:2019-02-10
用Python做影象處理
最近在做一件比較 evil 的事情——驗證碼識別,以此來學習一些新的技能。因為我是初學,對影象處理方面就不太瞭解了,欲要利吾事,必先利吾器,既然只是做一下實驗,那用 Python 來作原型開發再好不過了。在 Python 中,比較常用的影象處理庫是 PIL(Python Image Library),當前版本是 1.1.6 ,用起來非常方便。大家可以在 http://www.pythonware.com/products/pil/index.htm 下載和學習。
在這裡,我主要是介紹一下做影象識別時可能會用到的一些 PIL 提供的功能,比如影象增強、還有濾波之類的。最後給出使用 Python 做影象處理與識別的優勢與劣勢。
基本影象處理
使用 PIL 之前需要 import Image 模組:
import Image
然後你就可以使用Image.open(‘xx.bmp’) 來開啟一個位圖檔案進行處理了。開啟檔案你不用擔心格式,也不用瞭解格式,無論什麼格式,都只要把檔名丟給 Image.open 就可以了。真所謂 bmp、jpg、png、gif……,一個都不能少。
img = Image.open(‘origin.png’) # 得到一個影象的例項物件 img
圖 1原圖
影象處理中,最基本的就是色彩空間的轉換。一般而言,我們的影象都是 RGB 色彩空間的,但在影象識別當中,我們可能需要轉換影象到灰度圖、二值圖等不同的色彩空間。 PIL 在這方面也提供了極完備的支援,我們可以:
new_img = img.convert(‘L’)
把 img 轉換為 256 級灰度影象, convert() 是影象例項物件的一個方法,接受一個 mode 引數,用以指定一種色彩模式,mode 的取值可以是如下幾種:
· 1 (1-bit pixels, black and white, stored with one pixel per byte)
· L (8-bit pixels, black and white)
· P (8-bit pixels, mapped to any other mode using a colour palette)
· RGB (3x8-bit pixels, true colour)
· RGBA (4x8-bit pixels, true colour with transparency mask)
· CMYK (4x8-bit pixels, colour separation)
· YCbCr (3x8-bit pixels, colour video format)
· I (32-bit signed integer pixels)
· F (32-bit floating point pixels)
怎麼樣,夠豐富吧?其實如此之處,PIL 還有限制地支援以下幾種比較少見的色彩模式:LA (L with alpha), RGBX (true colour with padding) and RGBa (true colour with premultiplied alpha)。
下面看一下 mode 為 ‘1’、’L’、’P’時轉換出來的影象:
圖 2 mode = '1'
圖 3 mode = 'L'
圖 4 mode = 'P'
convert() 函式也接受另一個隱含引數 matrix,轉換矩陣 matrix 是一個長度為4 或者16 tuple。下例是一個轉換 RGB 空間到 CIE XYZ 空間的例子:
rgb2xyz = (
0.412453, 0.357580, 0.180423, 0,
0.212671, 0.715160, 0.072169, 0,
0.019334, 0.119193, 0.950227, 0 )
out = im.convert("RGB", rgb2xyz)
除了完備的色彩空間轉換能力外, PIL 還提供了resize()、rotate()等函式以獲得改變大小,旋轉圖片等幾何變換能力,在影象識別方面,影象例項提供了一個 histogram() 方法來計算直方圖,非常方便實用。
影象增強
影象增強通常用以影象識別之前的預處理,適當的影象增強能夠使得識別過程達到事半功倍的效果。 PIL 在這方面提供了一個名為 ImageEnhance 的模組,提供了幾種常見的影象增強方案:
import ImageEnhance
enhancer = ImageEnhance.Sharpness(image)
for i in range(8):
factor = i / 4.0
enhancer.enhance(factor).show("Sharpness %f" % factor)
上面的程式碼即是一個典型的使用 ImageEnhance 模組的例子。 Sharpness 是 ImageEnhance 模組的一個類,用以銳化圖片。這一模組主要包含如下幾個類:Color、Brightness、Contrast和Sharpness。它們都有一個共同的介面 .enhance(factor) ,接受一個浮點引數 factor,標示增強的比例。下面看看這四個類在不同的 factor 下的效果
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/5825d40ae0f549df99e342aa0c429534.gif)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/7e93135f6fe04b87b7ada0ef04913629.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/6cc251a0067a4af5a0a46a9b175a688a.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/d36a9bd9869542f5bbb3a6f3519c8d1e.png)
圖 5 使用Color 進行色彩增強,factor 取值 [0, 4],步進 0.5
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/e1038e8403c74c08ac940babf2e64d5e.gif)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/b5d1a48f62a24d4a8607229c4c8abdf5.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/7d6bb44bcbe8423c93fafcbc8e022337.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/b32d9a55c1214c779640008df29d8064.png)
圖 6 用 Birghtness 增強亮度,factor取值[0,4],步進0.5
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/2f3db13678e64ba38c0c965697731749.gif)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/8f1018ae79dd469586c46c582f0f4870.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/a6263e65f2964f2980be436a713c8b98.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/10a23b13304c4afebb20f51f0ababfd8.png)
圖 7用 Contrast 增強對比度, factor 取值 [0,4],步進0.5
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/72bc4b5b9a944ceda41824738da20769.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/01bad57e33144a4b82177ad1f1e501a5.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/6a204aac6bf340c2ad4c95ab48074b62.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/91c4a4cf198a4ca882030481e2ccc2b7.png)
圖 8用 Sharpness 銳化影象,factor取值 [0,4],步進0.5
影象 Filter
PIL 在 Filter 方面的支援是非常完備的,除常見的模糊、浮雕、輪廓、邊緣增強和平滑,還有中值濾波、ModeFilter等,簡直方便到可以做自己做一個Photoshop。這些 Filter 都放置在 ImageFilter 模組中,ImageFilter主要包括兩部分內容,一是內建的 Filter,如 BLUR、DETAIL等,另一部分是 Filter 函式,可以指定不同的引數獲得不同的效果。示例如下:
import ImageFilter
im1 = im.filter(ImageFilter.BLUR)
im2 = im.filter(ImageFilter.MinFilter(3))
im3 = im.filter(ImageFilter.MinFilter()) # same as MinFilter(3)
可以看到 ImageFilter 模組的使用非常簡單,每一個 Filter 都只需要一行程式碼就可呼叫,開發效率非常高。
圖 9使用 BLUR
圖 10使用 CONTOUR
圖 11使用 DETAIL
圖 12使用 EMBOSS
圖 13使用 EDGE_ENHANCE
圖 14使用 EDGE_ENHANCE_MORE
圖 15使用 FIND_EDGES
圖 16使用 SHARPEN
圖 17使用 SMOOTH
圖 18使用 SMOOTH_MORE
以上是幾種內建的 Filter 的效果圖,除此之外, ImageFilter 還提供了一些 Filter 函式,下面我們來看看這些可以通過引數改變行為的 Filter 的效果:
圖 19使用 Kernel(),引數:size = (3, 3), kernel = (0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5)
圖 20使用 MaxFilter,預設引數
圖 21使用 MinFilter,預設引數
圖 22使用 MedianFilter,預設引數
圖 23使用 ModeFilter,引數 size = 3
圖 24使用 RankFilter,引數 size = 3, rank = 3
小結
到此,對 PIL 的介紹就告一段落了。總的來說,對於影象處理和識別,PIL 內建了強大的支援,從各種增強演算法到 Filter ,都讓人無法懷疑使用 Python 的可行性。 Python唯一的劣勢在於執行時間過慢,特別是當實現一些計算量大的演算法時候,需要極強的耐心。我曾用 Hough Transform(霍夫變換)來查詢影象中的直線,純 Python 的實現處理一個 340 * 100 的圖片也要花去數秒時間(P4 3.0G + 1G memory)。但使用 PIL 無需關注影象格式、內建的影象增強演算法和
Filter 演算法,這些優點使 Python 適合用於構造原型和進行實驗,在這兩方面Python 比 matlab 更加方便。商業的影象識別產品開發,可以考慮已經被 boost accepted的來自 adobe 的開源 C++ 庫 gil,可以兼顧執行效能和開發效率。
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/105b915713a74058a8b805dd5dffcceb.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/f14443bd90b74f4f9d714156dd35f6d8.gif)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/8511e85898a44bf4bd8902fe830a18f8.gif)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/586b0aefd5b84cee880676449805f843.gif)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/5825d40ae0f549df99e342aa0c429534.gif)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/d96015d0754d41f08647dc815894f5ef.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/7e93135f6fe04b87b7ada0ef04913629.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/77520434439d47e581215a982db95af4.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/6cc251a0067a4af5a0a46a9b175a688a.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/4f2df2149b454d7fa8c8bcc15170df4e.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/d36a9bd9869542f5bbb3a6f3519c8d1e.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/05e8e4288895469e9284860465e4ba37.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/b0599566b758443b983eb37a0ac4b746.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/e1038e8403c74c08ac940babf2e64d5e.gif)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/0c4ae712efb44fc7a57328c1e6fed53c.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/b5d1a48f62a24d4a8607229c4c8abdf5.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/4cd2ae28e2e049aa8db613d297087f77.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/7d6bb44bcbe8423c93fafcbc8e022337.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/7dc67787176d4e299c6f55db64c97e99.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/b32d9a55c1214c779640008df29d8064.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/36359d1eb3524bd7847b2cded7c55f00.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/376a2121991b425aa61ad3c17d8e1188.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/2f3db13678e64ba38c0c965697731749.gif)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/6f7456f4bd1f44a3a784f9c4a73cc857.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/8f1018ae79dd469586c46c582f0f4870.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/59a251551fa34309874077c816a607c5.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/a6263e65f2964f2980be436a713c8b98.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/1f10bf7cdea646cb965e808ddd1a32ef.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/10a23b13304c4afebb20f51f0ababfd8.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/e4ef2a90fe204789a6b850e5d98c90e1.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/b8648bc7943448228c2d3a371bd74ea0.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/72bc4b5b9a944ceda41824738da20769.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/6e10be3591514893b3eff5a2ac0b7a7d.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/01bad57e33144a4b82177ad1f1e501a5.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/b0e362ef4f704927a28958856dd60fea.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/6a204aac6bf340c2ad4c95ab48074b62.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/f4c61612c912488ba3be374dd2cfd4cd.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/91c4a4cf198a4ca882030481e2ccc2b7.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/c6a522c59fca412c83a9f675467734f8.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/7409f2ee93c046fdb2970750c59b9171.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/a5e65f4337a24e04a7fd275d18c2e258.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/8ec143c4358d45a390adbbc9c7698bd9.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/15d50813d32242a3b597741c2e1e5271.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/d8141bcc3ab34206939aec6014a50b28.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/ce9e7a19139e4fe084b0aef0de156f34.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/17560f5dfb644e8d9f93e050b1757b99.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/aa6b94ee9b964c89a7ad0f3b2204ccd7.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/8ae9c4fb3630455f9101756ce4432e66.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/abaae387f57c4edebbbb0b52caf3de56.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/570b17ae469645199568736b5b50e7cf.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/f18ed465b925443e84156bd27adf05d1.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/e20d44d8fa6a4ad5b0ce84688b683c05.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/a8bf4eb9e140460c8f9ea6b52849c017.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/cce283a6f92f4b0b818a2497f242cbf6.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/ef010a1a01a44ddf802c3bf1b3ac0beb.png)
![](http://p.blog.csdn.net/images/p_blog_csdn_net/lanphaday/cdf0142eb6064994a0af672de451fb2b.png)