你在用什么軟件進行圖像處理呢?厭倦了鼠標和手指的拖拖點點,想不想用程序和代碼進行圖像的高效處理,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+'rn'return codePicdef 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+'rn'return codePicfp = 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()