利用PIL (pillow)來讀取影像檔是一件簡單又好用的套件,但對於影像處理而言,PIL提供的方法過於簡單,且效率不夠好。對於矩陣運算而言,numpy就提供了高效率且多元的運算方法。因此想要提高影像處理的運算效能,並能夠簡化程式設計,最好的方法就是將影像檔案讀取的陣列移轉到numpy來處理。
↓先檢視一下影像檔案的基本的屬性:
這個測試影像的mode=L,代表它是灰階影像;寬度為100,高度為200
現在我們要將此影像載入到numpy的二維陣列之中。在使用numpy之前當然要確定已經安裝好此套件
↓點選《Tools》→《Manage packages ...》查看是否已安裝numpy,畫面顯示這台電腦已安裝numpy 版本為1.13.3
↓利用numpy載入影像資料
第二行:載入numpy 並命名為np
第四行:透過numpy內建的方法array()將影像資料複製到np的陣列,名為data
第五行:顯示data的形狀,也就是各維度的大小,結果是一個200x100的陣列
第六行:顯示data的資料屬性,結果為uint8
在numpy中的陣列,第一個維度是Y軸,第二維度是X軸。一般而言,我們說這個影像是 1024X768,代表影像的寬度是1024,高度是768;可是我們說這個矩陣是1024X768,卻代表矩陣的高度是1024,寬度是768,這件事在不同的程式語有不同的講法,要特別小心。
因此當我們要存取影像某個位置的像素值時,在PIL中使用im.getpixel((x,y)),在numpy的陣列中卻是data[y,x]。總之,在本例中就是
im.getpixel((x,y)) = data[y,x]
↓im.getpixel((0,y)) 等於 data[y,0]
現在作一個簡單處理,就是反白,然後將結果儲存於另一個影像檔
↓反白再存檔
反白只要一個指令就是 255-data,再透過Image.fromarray()將numpy的陣列儲存於imout中,最後透過save()將反白陣列儲存於test2.png中。
這樣的作法比getpixel一個像素、一個像素處理要快得多呢!這也是為什麼要將影像資料由PIL轉換到numpy來處理的原因。
最後講一個小地方,最後存檔的類型是PNG,並非原始格式JPG;另外,我們在存檔的時候並沒有指定路徑,結果就是跟程式檔放在同一資料夾下,也就是d:/temp/mypython下。
-- end --
沒有留言:
張貼留言