你在用什麼軟體進行圖像處理呢?厭倦了滑鼠和手指的拖拖點點,想不想用程式和代碼進行圖像的高效處理,Python作為簡單高效又很強大的一門程式設計語言,對于圖像的處理自然也是輕松拿下,聽起來是不是很酷很極客,那麼就跟着我來看看吧!
一、Python的強大圖像處理庫——Pillow
工欲善其事必先利其器, Python的标準庫中雖然沒有直接支援圖像處理操作的子產品,但我們可以通過Python生态圈中的第三方庫來完成這些操作。
1 什麼是Pillow:
Pillow作為python的第三方圖像處理庫,提供了廣泛的檔案格式支援,強大的圖像處理能力,主要包括圖像儲存、圖像顯示、格式轉換以及基本的圖像處理操作等。
2 Pillow與PIL的關系:
PIL(Python Image Library)是python的第三方圖像處理庫,因其強大的功能與衆多的使用人數,幾乎已經被認為是python官方圖像處理庫了。但由于PIL僅支援到Python 2.7,加上年久失修,于是一群志願者在PIL的基礎上建立了相容的版本,名字叫Pillow,支援最新Python 3.x,又加入了許多新特性,是以,我們可以直接安裝使用Pillow。
二、安裝Pillow
如果安裝了Anaconda,Pillow就已經可用了。
否則,需要在指令行下通過pip安裝:
pip install pillow
三、基本操作
1 使用 Image 類:
PIL最重要的類是Image class, 讀取和處理圖像都要通過這個類來完成。我們可以通過多種方法建立這個類的執行個體,你可以從檔案加載圖像,或者處理其他圖像, 或者從 scratch 建立。
要從檔案加載圖像,請使用Image子產品中的open函數:
from PIL import Image
# 打開一個jpg圖像檔案,注意是目前路徑:
im = Image.open('cat.jpg')
(溫馨提示:向左滑動可檢視完整代碼~)
如果成功,這個函數傳回Image對象。您現在可以使用執行個體屬性來檢查檔案内容:
print(im.format, im.size, im.mode)
JPEG (1920, 1200) RGB
format屬為圖像來源。如果不是從檔案讀取就是None。
size屬性是包含寬度和高度(像素)的二進制組)。
mode屬性定義了圖像中波段的數量和名稱,以及像素類型和深度。常見模式為灰階圖像為“L”(亮度),真彩色圖像為“RGB”,印刷四色為“CMYK”。
獲得了Image類的執行個體,就可以使用此類定義的方法來處理和操作圖像。例如讓我們顯示剛剛加載的圖像:
im.show()
接下來讓我們看看一些具體的圖像處理操作吧~
2 儲存指定格式的圖像
save(filename,format) :
im.save("cat.jpg",'png')
上面的代碼将圖像重新儲存成png格式
3 剪裁矩形區域 crop(box)
box是一個有四個數字的元組(upper_left_x,upper_left_y,lower_right_x,lower_right_y),分别表示裁剪矩形區域的左上角x,y坐标,右下角的x,y坐标,規定圖像的最左上角的坐标為原點(0,0),寬度的方向為x軸,高度的方向為y軸,每一個像素代表一個坐标機關。
crop()傳回的仍然是一個Image對象。
im = Image.open("cat.jpg","r")
box = (300,300,800,800)
region = im.crop(box)
region.show()
im.crop()
上面的代碼在im圖像上裁剪了一個box矩形區域,然後顯示出來,效果如圖:
4 圖像粘貼 paste(region,box,mask)
region是要粘貼的Image對象,box是要粘貼的位置,可以是一個兩個元素的元組,表示粘貼區域的左上角坐标,也可以是一個四個元素的元組,表示左上角和右下角的坐标。如果是四個元素元組的話,box的size必須要和region的size保持一緻,否則将會被convert成和region一樣的size。
im.paste(region,(100,100),None)
im.show()
上面的代碼将region圖像粘貼到左上角為(100,100)的位置,效果如圖所示:
5 生成縮略圖 thumbnail(size,resample)
thumbnail可以建立一個指定大小(size)的縮略圖,需要注意的是,thumbnail方法是原地操作,傳回值是None。第一個參數是指定的縮略圖的大小,第二個是采樣的,有Image.BICUBIC,PIL.Image.LANCZOS,PIL.Image.BILINEAR,PIL.Image.NEAREST這四種采樣方法。預設是Image.BICUBIC。
im.thumbnail((200,200),resample=Image.BICUBIC)
im.show()
上面的代碼形成了一個200×200的縮略圖,效果如圖:
6 旋轉和翻轉 transpose(method)
method是transpose的參數,表示選擇什麼樣的翻轉或者旋轉方式,可以選擇的值有:
- Image.FLIP_LEFT_RIGHT,表示将圖像左右翻轉
- Image.FLIP_TOP_BOTTOM,表示将圖像上下翻轉
- Image.ROTATE_90,表示将圖像逆時針旋轉90°
- Image.ROTATE_180,表示将圖像逆時針旋轉180°
- Image.ROTATE_270,表示将圖像逆時針旋轉270°
- Image.TRANSPOSE,表示将圖像進行轉置(相當于順時針旋轉90°)
- Image.TRANSVERSE,表示将圖像進行轉置,再水準翻轉
im_rotate_180 = im.transpose(Image.ROTATE_180)
im_rotate_180.show()
上面的代碼将im逆時針旋轉180°,然後顯示出來,效果如下圖:
7 顔色通道分離split())
split()方法可以原來圖像的各個通道分離,比如對于RGB圖像,可以将其R,G,B三個顔色通道分離。
r,g,b = im.split()
r.show()
g.show()
b.show()
上面的代碼将小貓圖像的RGB顔色通道分離,效果如圖:
8 顔色通道合并merge(mode,channels)
merge方法和split方法是相對的,其将多個單一通道的序列合并起來,組成一個多通道的圖像,mode是合并之後圖像的模式,比如"RGB",channels是多個單一通道組成的序列。
im_merge = Image.merge("RGB",[b,r,g])
im_merge.show()
上面的代碼将小貓圖像的顔色通道合并,效果如下圖:
9 顔色模式轉換
convert(mode,matrix,dither,palette,colors)
convert方法可以改變圖像的模式(mode),一般是在'RGB'(真彩圖)、'L'(灰階圖)、'CMYK'(壓縮圖)之間轉換。
im_L = im.convert ("L")
im_L .show()
上面的代碼就是将圖像轉化為灰階圖。效果如下圖:
10 圖像過濾器 filter(filter)
filter方法可以将一些過濾器操作應用于原始圖像,比如模糊,邊緣增強、浮雕等。filter是過濾器函數,在PIL.ImageFilter函數中定義了大量内置的filter函數,比如BLUR(普通模糊),GaussianBlur(高斯模糊) FIND_EDGES(查找邊)等
from PIL import Image, ImageFilter
im = Image.open('cat.jpg')
# 高斯模糊
im_gaussianblur = im.filter(ImageFilter.GaussianBlur)
im_gaussianblur.show()
# 普通模糊
im_blur = im.filter(ImageFilter.BLUR)
im_blur.show()
# 找到邊緣
im_find_edge = im.filter(ImageFilter.FIND_EDGES)
im_find_edges.show()
# 浮雕
im_emboss = im.filter(ImageFilter.EMBOSS)
im_emboss.show()
# 輪廓
im_contour = im.filter(ImageFilter.CONTOUR)
im_contour.show()
# 銳化
im_sharpen = im.filter(ImageFilter.SHARPEN)
im_sharpen.show()
# 平滑
im_smooth = im.filter(ImageFilter.SMOOTH)
im_smooth.show()
# 細節
im_detail = im.filter(ImageFilter.DETAIL)
im_detail.show()
下圖依次為浮雕與輪廓效果:
11 圖像增強ImageEnhance()
圖像增強也是圖像預進行中的一個基本技術,Pillow中的圖像增強函數主要在ImageEnhance子產品下,通過該子產品可以調節圖像的白平衡(Color)、亮度(Brightness)、對比度(Contrast)和銳化(Sharpness)等。
from PIL import ImageEnhance
brightness = ImageEnhance.Brightness(im)
im_brightness = brightness.enhance(1.5)
im_brightness.show()
上面的代碼将原來圖像的亮度增加50%,效果如下圖:
四、練習項目——圖檔轉字元畫
看完了上面的操作是不是手癢癢呢,下面我們一起來做一個有趣的練手項目吧~
主要思路
讀取彩色圖檔的RGB值,利用公式轉化為灰階值,将圖檔的灰階值與你自己設定的字元集之間建立映射關系,不同區間的灰階值對應不同的字元。最後将每個像素對應的字元按照原位置列印出來
測試圖檔與結果:
操作代碼:
# -*- coding: utf-8 -*-
from PIL import Image
codeLib = '''@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'. '''#生成字元畫所需的字元集
count = len(codeLib)
def transform1(image_file):
image_file = image_file.convert("L") #轉換為黑白圖檔,參數"L"表示黑白模式
codePic = ''
for h in range(0,image_file.size[1]): #size屬性表示圖檔的分辨率,'0'為橫向大小,'1'為縱向
for w in range(0,image_file.size[0]):
gray = image_file.getpixel((w,h)) #傳回指定位置的像素,如果所打開的圖像是多層次的圖檔,那這個方法就傳回一個元組
codePic = codePic + codeLib[int(((count-1)*gray)/256)]#建立灰階與字元集的映射
codePic = codePic+'\r\n'
return codePic
def transform2(image_file):
codePic = ''
for h in range(0,image_file.size[1]):
for w in range(0,image_file.size[0]):
g,r,b = image_file.getpixel((w,h))
gray = int(r* 0.299+g* 0.587+b* 0.114)
codePic = codePic + codeLib[int(((count-1)*gray)/256)]
codePic = codePic+'\r\n'
return codePic
fp = open(u'gray.jpg','rb')
image_file = Image.open(fp)
image_file=image_file.resize((int(image_file.size[0]*0.75), int(image_file.size[1]*0.5)))#調整圖檔大小
print(u'Info:',image_file.size[0],' ',image_file.size[1],' ',count)
tmp = open('tmp.txt','w')
tmp.write(transform1(image_file))
tmp.close()