本文主要內容來源於書籍《python計算機視覺編程》
我是一名初學者,若是你發現文中有錯誤,請留言告訴我,謝謝python
PIL模塊全程爲Python Imaging Library,是python中一個免費的圖像處理模塊。編程
PIL模塊經常使用到它的Image類,打開圖像首先要導入Image類
from PIL import Image
,
而後調用Image
的open
方法。
例如markdown
from PIL import Image image = Image.open("smallpi.jpg") # 返回一個Image圖像對象 print(image) # 結果 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=800x450 at 0x4731348>
圖像保存用的是Image對象的save()
方法,傳入的參數爲保存圖像文件的名字。
當傳入不一樣的擴展名時,它會根據擴展名自動轉換圖像的格式。
例如函數
from PIL import Image image = Image.open("smallpi.jpg") # 打開jpg圖像文件 image.save("smallpi.png") # 保存圖像,並轉換成png格式
得到Image對象後,調用其convert()
方法,傳入參數"L"
,便可以返回該圖像的灰度圖像對象。atom
from PIL import Image image = Image.open("smallpi.jpg") image_gray = image.convert("L") # 轉化成灰度圖像 print(image_gray) # 結果 <PIL.Image.Image image mode=L size=800x450 at 0x46AD648>
Image對象轉化成圖像矩陣只要將Image對象做爲numpy.array()
參數便可。spa
import numpy as np from PIL import Image image = Image.open("smallpi.jpg") image_array = np.array(image) print(image_array) # 結果 [[[177 177 177] [177 177 177] [176 176 176] ..., #此處省略 ..., [232 232 232] [232 232 232] [232 232 232]]]
圖像矩陣轉化成Image對象經過Image
模塊的fromarray()
方法。3d
import numpy as np from PIL import Image image = Image.open("smallpi.jpg") image_array = np.array(image.convert("L")) image_array = 255 - image_array # 圖像矩陣處理,將灰度圖像反相 # 反相指的是,黑變白,白變黑 image2 = Image.fromarray(image_array) print(image2) # 結果 <PIL.Image.Image image mode=RGB size=800x450 at 0x4753748>
圖像的顯示須要用到matplotlib模塊。
首先須要導入matplotlib.pyplot
import matplotlib.pyplot as plt
而後,調用pyplot的imshow()
方法,傳入Image對象便可code
from PIL import Image import matplotlib.pyplot as plt image = Image.open("smallpi.jpg") plt.imshow(image) # 繪製圖像image plt.show() # 須要調用show()方法,否則圖像只會在內存中而不顯示出來
圖像顯示結果(帶座標軸)
orm
若是想把座標軸去掉只須要調用pyplot的axis()
方法,傳入"off"
參數對象
from PIL import Image
import matplotlib.pyplot as plt
image = Image.open("smallpi.jpg")
plt.imshow(image) # 繪製圖像image
plt.axis("off") # 去掉座標軸
plt.show() # 須要調用show()方法,否則圖像只會在內存中而不顯示出來
圖像顯示結果(不帶座標軸)
若是要顯示灰度圖像,須要導入matplotlib的cm模塊
import matplotlib.cm as cm
而後在調用pyplot.show()
時,傳入關鍵字參數cmap=cm.gray
。
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm
image = Image.open("smallpi.jpg") # 打開圖像
image_gray = image.convert("L") # 轉化成灰度圖像
plt.subplot(2,1,1)
plt.imshow(image_gray) # 沒傳入關鍵字參數cmap=cm.gray
plt.axis("off") # 去掉座標軸
plt.subplot(2,1,2)
plt.imshow(image_gray, cmap=cm.gray) # 指明 cmap=cm.gray
plt.axis("off") # 去掉座標軸
plt.show() # 顯示圖像
顯示結果
上:沒指定cmap , 下:指定cmap=cm.gray
建立圖像縮略圖能夠經過Image的thumbnail()
方法,參數傳入一個元組,指明縮略圖的大小,如thumbnail((128,128))
。
例如
from PIL import Image
image = Image.open("smallpi.jpg")
image_thumbnail = image.thumbnail((128,128))
image.save("thumbnail.jpg")
結果爲
複製區域是指截取圖像中的一部分,並將這一部分做爲一個新的Image對象。
複製區域的方法爲crop()
,參數爲一個含4個元素的元組,用來指定截取區域的左上角點和右下角點。
from PIL import Image image = Image.open("smallpi.jpg") # 打開圖像 box = (300,100,500,300) # 截取區域 image_crop = image.crop(box) # 按指定截取區域對圖像進行截取複製 image_crop.save("image_crop.jpg") # 保存
保存的截取區域圖像爲
粘貼區域是指在指定圖像中放入另外一個圖像,其方法爲paste()
。該方法有兩個參數,第一個參數爲須要粘貼進去的圖像,第二個參數爲粘貼區域。
from PIL import Image image = Image.open("smallpi.jpg") box = (300,100,500,300) # 先截取一部分 image_crop = image.crop(box) # 爲了看到粘貼效果,現將截取部分轉180度 image_crop = image_crop.transpose(Image.ROTATE_180) # 轉180度 image.paste(image_crop,box) # 將轉180度後的圖像粘貼到原圖像 image.save("image_paste.jpg")
粘貼後原圖像變成
尺寸調整方法爲resize()
,參數爲一元組,指定調整後的大小,如resize((128,128))。
rotate()
圖像旋轉的方法爲,參數爲旋轉角度(數值,單位爲度),逆時針方向,如
rotate(45)`
from PIL import Image image = Image.open("smallpi.jpg") image_resize = image.resize((200,200)) # 尺寸調整 image_rotate = image.rotate(45) # 圖像旋轉 # image.transpose()也能夠旋轉圖像,但只能旋轉90度的整數倍 # 參數爲 Image.ROTATE_90 旋轉90度 # 180度,270度可類推 image_resize.save("image_resize.jpg") image_rotate.save("image_rotate.jpg")
尺寸調整爲200*200
圖像逆時針旋轉45度
圖像直方圖用來統計圖像中像素值的分佈狀況,即統計不一樣像素值出現的次數。方法爲調用matplotlib.pyplot
的hist
方法,參數傳入圖像像素序列和統計區間個數。
from PIL import Image import matplotlib.pyplot as plt import matplotlib.cm as cm #打開圖像,並轉化成灰度圖像 image = Image.open("smallpi.jpg").convert("L") image_array = np.array(image) plt.subplot(2,1,1) plt.imshow(image,cmap=cm.gray) plt.axis("off") plt.subplot(2,1,2) plt.hist(image_array.flatten(),256) #flatten能夠將矩陣轉化成一維序列 plt.show()
結果爲
對於一張灰度圖像,其每一個像素點都用一個0-255之間的值表示,0表示黑色,越接近0越黑;255表示白色,越接近255越白。
灰度變換就是經過一個特定的函數,使灰度值從一個值轉換成另一個值。
這裏列出3種灰度變換
1. 【反相】變換後的灰度值= 255−原灰度值
2.【轉換到100-200】變換後的灰度值 =(原灰度值/255)*100+100
3. 【像素平方】變換後的灰度值 = 255*(原灰度值/255)2
2
from PIL import Image import matplotlib.pyplot as plt import matplotlib.cm as cm image = Image.open("smallpi.jpg").convert("L") image_array = np.array(image) x = np.arange(255) # 反相 plt.subplot(3,2,1) plt.plot(x,255-x) # 畫出變換函數圖像 plt.subplot(3,2,2) plt.imshow(Image.fromarray(255-image_array),cmap=cm.gray) plt.axis("off") # 轉換到 100-200 plt.subplot(3,2,3) plt.plot(x,(x/255.0)*100+100) # 畫出變換函數圖像 plt.subplot(3,2,4) plt.imshow( Image.fromarray((image_array/255.0)*100+100), cmap=cm.gray ) plt.axis("off") # 像素平方 plt.subplot(3,2,5) plt.plot(x,255*(x/255.0)**2) # 畫出變換函數圖像 plt.subplot(3,2,6) plt.imshow( Image.fromarray(255*(image_array/255.0)**2), cmap=cm.gray ) plt.axis("off") plt.show()
`結果以下,(左邊是變換函數,右邊是圖像變換結果)
由上面圖像的直方圖能夠看出,通常狀況下,圖像上某些灰度值較多,有些灰度值較少,直方圖均衡化爲的是使灰度值較爲均衡。
直方圖均衡化是利用直方圖的累積函數做爲灰度變換函數,對圖像進行轉換。直方圖均衡化能夠加強圖像的對比度。
累積函數和機率論中的累積分佈函數相似。例如對於還有5個數的序列[1,2,3,4,5],其累積函數含有5個數,第一個數是1,第二個是1+2=3,……,第五個數是1+2+3+4+5=15,因此其累積函數是[1,3,6,10,15]。
咱們把直方圖均衡化的過程封裝在一個函數裏面,函數名字叫作histeq,輸入原圖像矩陣和直方圖分塊數,輸出均衡化後的圖像矩陣和累積函數。
import numpy as np from PIL import Image import matplotlib.pyplot as plt import matplotlib.cm as cm def histeq(image_array,image_bins=256): # 將圖像矩陣轉化成直方圖數據,返回元組(頻數,直方圖區間座標) image_array2,bins = np.histogram(image_array.flatten(),image_bins) # 計算直方圖的累積函數 cdf = image_array2.cumsum() # 將累積函數轉化到區間[0,255] cdf = (255.0/cdf[-1])*cdf # 原圖像矩陣利用累積函數進行轉化,插值過程 image2_array = np.interp(image_array.flatten(),bins[:-1],cdf) # 返回均衡化後的圖像矩陣和累積函數 return image2_array.reshape(image_array.shape),cdf image = Image.open("pika.jpg").convert("L") image_array = np.array(image) plt.subplot(2,2,1) plt.hist(image_array.flatten(),256) plt.subplot(2,2,2) plt.imshow(image,cmap=cm.gray) plt.axis("off") a = histeq(image_array) # 利用剛定義的直方圖均衡化函數對圖像進行均衡化處理 plt.subplot(2,2,3) plt.hist(a[0].flatten(),256) plt.subplot(2,2,4) plt.imshow(Image.fromarray(a[0]),cmap=cm.gray) plt.axis("off") plt.show()
結果以下圖所示,第一行爲原圖像直方圖和原圖像,第二行爲均衡化後的直方圖和圖像。能夠看出均衡化後圖像對比度加強了,原先灰色區域的細節變得清晰。