python圖像處理中,常被使用的有cv2, PIL等套件,本文介紹如何使用PIL module實作圖片濾鏡,實作的濾鏡包括彩色轉灰階、圖片高亮、柔焦效果、減少色調(ex:RED)、反相圖片等算法。
本站相關文章:[Python] PIL基本介紹
1. Install PIL module (Pillow)
使用pip安裝python PIL模組。pip3 install Pillow
2. Import module
from PIL import Image
3. Python code
以下透過PIL取得圖片pixel的RGB數值,並藉調整pixel RGB實做幾種濾鏡。
- 彩色轉灰階
- 高亮
- 柔焦
- 減少色調
- 反相
取圖片每個pixel的RGB值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Read image im = Image.open("targetImage.png") # Get the width and height of the image im_width, im_height = im.size # Load image pixels as array(im_width, im_height) pixels = im.load() # Traverse the image pixels for i in range(im_width): for j in range(im_height): # Get pixel RGB information r, g, b = pixels[i, j] print(r, g, b) # Close image file im.close() |
Implement Image Filters
以下介紹個濾鏡的實作算法。
其中有用到math套件,記得需先import math。
1 |
import math |
– 彩色轉灰階
彩色轉灰階最原本的公式為:
Gray = R x 0.299 + G x 0.587 + B x 0.114
若調整為整數處理:
這個方式是32位整數乘除方式(RGB的精度是8位)。
Gray = (R x 299 + G x 587 + B x 114 + 500) / 1000
加上500是為了四捨五入。
最後是16位整數乘除運算方式:
Gray = (R x 30 + G x 59 + B x 11 + 50) / 100
1 2 3 4 5 6 7 8 9 |
def RGBtoGRAY(im): im_width, im_height = im.size pixels = im.load() for i in range(im_width): for j in range(im_height): r, g, b = pixels[i, j] gray = math.floor((r*30 + g*59 + b*11 + 50)/100) pixels[i,j] = (gray, gray, gray) im.save("gray.png", "PNG") |
– 高亮
將原圖RGB分別加上45,提高亮度。
1 2 3 4 5 6 7 8 9 10 11 |
def softlightFilter(im): im_width, im_height = im.size pixels = im.load() for i in range(im_width): for j in range(im_height): r, g, b = pixels[i, j] r = 250 if r+30>250 else r+45 g = 250 if g+30>250 else g+45 b = 250 if b+30>250 else b+45 pixels[i,j] = (r, g, b) im.save("softlightFilter.png", "PNG") |
– 柔焦
這邊簡單對每個將每個pixel的RGB值改為周圍9×9 matrix的平均值,存為新的pixel matrix後輸出。
此演算法沒有特別處理邊緣pixel,如有要求的話要特別對邊緣值做處理。
第一種code直觀取3×3 matrix值平均。程式碼較長。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
def blur(im): im_width, im_height = im.size pixels = im.load() pixels_new = im.load() for i in range(im_width): for j in range(im_height): if(i>0 and j>0 and i < im_width-1 and j < im_height-1): r1, g1, b1 = pixels[i-1, j-1] r2, g2, b2 = pixels[i, j-1] r3, g3, b3 = pixels[i+1, j-1] r4, g4, b4 = pixels[i-1, j] r5, g5, b5 = pixels[i, j] r6, g6, b6 = pixels[i+1, j] r7, g7, b7 = pixels[i-1, j+1] r8, g8, b8 = pixels[i, j+1] r9, g9, b9 = pixels[i+1, j+1] r = math.floor((r1+r2+r3+r4+r5+r6+r7+r8+r9)/9) g = math.floor((g1+g2+g3+g4+g5+g6+g7+g8+g9)/9) b = math.floor((b1+b2+b3+b4+b5+b6+b7+b8+b9)/9) pixels_new[i, j] = (r, g, b) else: pixels_new[i, j] = pixels[i, j] im.save("blur.png", "PNG") |
第二種直接操作pixel tuple。較簡短。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def blur(im): im_width, im_height = im.size pixels = im.load() pixels_new = im.load() for i in range(im_width): for j in range(im_height): if(i>0 and j>0 and i < im_width-1 and j < im_height-1): tmp_pixel = (0,0,0) for idx in range(-1,2): for idy in range(-1,2): tmp_pixel = (tmp_pixel[0] + pixels[i+idx,j+idy][0], tmp_pixel[1] + pixels[i+idx,j+idy][1], tmp_pixel[2] + pixels[i+idx,j+idy][2]) pixels_new[i, j] = tuple(ele1 // ele2 for ele1, ele2 in zip(tmp_pixel, (9, 9, 9))) else: pixels_new[i, j] = pixels[i, j] im.save("blur.png", "PNG") |
– 減少色調
此範例演示減少紅色(R)後的圖。
1 2 3 4 5 6 7 8 9 10 11 |
def rmRED(im): im_width, im_height = im.size pixels = im.load() for i in range(im_width): for j in range(im_height): r, g, b = pixels[i, j] r = 0 if (g < 60 and b < 60) else r g = 250 if g+30>250 else g+45 b = 250 if b+30>250 else b+45 pixels[i,j] = (r, g, b) im.save("removeRED.png", "PNG") |
– 反相
用255扣掉原RGB值,取得新的RGB值即為反相圖。
1 2 3 4 5 6 7 8 9 10 11 |
def inverted(im): im_width, im_height = im.size pixels = im.load() for i in range(im_width): for j in range(im_height): r, g, b = pixels[i, j] r = 255-r g = 255-g b = 255-b pixels[i,j] = (r, g, b) im.save("inverted.png", "PNG") |
4. DEMO
原圖
原圖 | 灰階 | 高亮 |
---|---|---|
柔焦 | 減少色調(減少紅) | 反相 |
後續將實作更多濾鏡。
留言