本教程將使用matplotlib的命令式繪圖界面pyplot。該界面保持全局狀態,對於快速輕鬆地嘗試各種繪圖設置非常有用。另一種方法是面向對象的界面,它也非常強大,通常更適合於大型應用程序開發。如果您想了解面向對象的界面,那麼我們的用法指南是一個很好的起點。
一、開始
現在,讓我們繼續使用命令式方法,首先導入相關庫
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
二、 將圖像數據導入到Numpy數組中
Pillow庫支持加載圖像數據。Matplotlib本機僅支持PNG圖像。如果本機讀取失敗,則下面顯示的命令將退回到Pillow上。
本示例中使用的圖像是JPG文件,但請記住您對自己的數據的“ Pillow”要求。
這是我們要處理的圖像:
現在我們將他加載到內存當中:
img = mpimg.imread('cat.jpg')
print(img)
[[[248 247 252]
[248 247 252]
[248 247 252]
...
[253 252 255]
[253 252 255]
[253 252 255]]
[[248 247 252]
[248 247 252]
[248 247 252]
...
[253 252 255]
[253 252 255]
[253 252 255]]
[[248 247 252]
[248 247 252]
[248 247 252]
...
它輸出的是這樣一個三維的數組。每個內部列表代表一個像素。在此,對於RGB圖像,有3個值。對於RGBA圖像(其中A是alpha或透明度),每個內部列表具有4個值,而簡單的亮度圖像僅具有一個值(因此,它只是一個2-D數組,而不是3-D數組)。對於RGB和RGBA圖像,matplotlib支持float32和uint8數據類型。對於灰度,matplotlib僅支持float32。如果您的陣列數據不符合以下描述之一,則需要重新調整其大小。
三、將numpy數組繪製爲圖像
我們可以將數據存儲在numpy數組中(通過導入或生成),然後通過渲染可以生成圖像。在Matplotlib中,這是使用imshow()函數執行的。在這裏,我們將獲取繪圖對象。該對象爲您提供了一種從提示操作圖形的簡便方法。
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img = mpimg.imread('cat.jpg')
imgplot = plt.imshow(img)
plt.show()
將僞彩色方案應用於圖像圖
僞彩色是增強對比度和更輕鬆地可視化數據的有用工具。當使用投影儀進行數據演示時,這特別有用-它們的對比度通常很差。
僞彩色僅與單通道,灰度,發光度圖像有關。我們目前有一個RGB圖像(數組形式)(請參見上方或數據中的內容),我們可以選擇一個數據通道:
lum_img = img[:, :, 0]
plt.imshow(lum_img)
plt.show()
這時候我們的小貓看起來有點詭異了
對於亮度(2D,無顏色)圖像,將應用默認的顏色圖【cmap】(又名查找表,LUT)。默認名稱爲viridis。還有很多其他可供選擇。
plt.imshow(lum_img, cmap="hot")
此外,您還可以使用set_cmap()方法更改現有打印對象上的顏色圖,作用跟上述是一致的,例如:
imgplot = plt.imshow(lum_img)
imgplot.set_cmap('nipy_spectral')
plt.show()
色標參考
瞭解顏色代表什麼價值會很有幫助。我們可以通過在您的圖形上添加一個顏色條來做到這一點:
imgplot = plt.imshow(lum_img)
imgplot.set_cmap('hot')
plt.colorbar()
plt.show()
檢查特定的數據範圍
對於稍微有點攝影基礎的小夥伴應該都知道圖像的直方圖。有時您想增強圖像的對比度,或擴大特定區域的對比度,同時犧牲顏色的差異,這些顏色變化不大或無關緊要。直方圖是找到有趣區域的好工具。要創建圖像數據的直方圖,可以使用hist()函數。
plt.hist(img.ravel(), bins=256, range=(0.0, 255), fc='k', ec='k')
大多數情況下,圖像的“有趣”部分位於峯值周圍,並且可以通過裁剪峯值上方和/或下方的區域來獲得額外的對比度。在我們的直方圖中,高端似乎沒有太多有用的信息(圖像中有很多白色的東西)。讓我們調整上限,以便有效地“放大”直方圖的一部分。爲此,我們將clim參數傳遞給了imshow。您也可以通過調用set_clim()圖像繪圖對象的方法來執行此操作 也可以通過傳入clim
參數
imgplot = plt.imshow(lum_img, clim=(100, 255))
我們把兩張圖放在一起比較一下,完整代碼:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img = mpimg.imread('cat.jpg')
lum_img = img[:, :, 0]
fig1 = plt.figure()
plt.subplot(121)
plt.title('before')
imgplot = plt.imshow(lum_img)
plt.colorbar(orientation='horizontal')
plt.subplot(122)
plt.title('after')
imgplot2 = plt.imshow(lum_img, clim=(100, 255))
plt.colorbar(orientation='horizontal')
plt.show()
圖像:
圖像插值(縮放)
一個常見應用是調整圖像大小時,像素數會變化,因此我們需要根據不同的數學方案計算增加(或刪去)的像素的值。由於像素是離散的,因此缺少空間。插值法是您填充該空間的方式。這就是爲什麼當您炸燬圖像時有時會顯得像素化的原因。當原始圖像和擴展圖像之間的差異更大時,效果會更加明顯。讓我們來縮小形象。我們實際上是在丟棄像素,只保留少數像素。現在,當我們繪製它時,該數據將爆炸到屏幕上的大小。舊的像素不再存在,計算機必須提取像素來填充該空間。
我們將使用用於加載圖像的Pillow庫來調整圖像的大小。
from PIL import Image
img = Image.open('cat.jpg')
img.thumbnail((64, 64), Image.ANTIALIAS) # resizes image in-place
imgplot = plt.imshow(img)
plt.show()
這裏沒有默認的插值法,即雙線性,因爲我們沒有給出imshow()傳入任何插值參數。
我們嘗試其他方法。這是“最近”,不進行插值。
imgplot = plt.imshow(img, interpolation="nearest")
可以看出與上圖並無區別,接下來嘗試其他參數,放大照片時經常使用雙三次插值法-人們傾向於模糊而不是像素化:
imgplot = plt.imshow(img, interpolation="bicubic")