Matplotlib 中文用戶指南 3.2 圖像教程

圖像教程

原文:Image tutorial

譯者:飛龍

協(xié)議:CC BY-NC-SA 4.0

啟動(dòng)命令

首先,讓我們啟動(dòng) IPython。 它是 Python 標(biāo)準(zhǔn)提示符的最好的改進(jìn),它與 Matplotlib 配合得相當(dāng)不錯(cuò)。 在 shell 或 IPython Notebook 上都可以啟動(dòng) IPython。

隨著 IPython 啟動(dòng),我們現(xiàn)在需要連接到 GUI 事件循環(huán)。 它告訴 IPython 在哪里(以及如何顯示)繪圖。 要連接到 GUI 循環(huán),請(qǐng)?jiān)?IPython 提示符處執(zhí)行%matplotlib魔法。 在 IPython 的 GUI 事件循環(huán)文檔中有更多的細(xì)節(jié)。

如果使用 IPython Notebook,可以使用相同的命令,但人們通常以特定參數(shù)使用%matplotlib

In [1]: %matplotlib inline

這將打開內(nèi)聯(lián)繪圖,繪圖圖形將顯示在筆記本中。 這對(duì)交互性有很重要的影響。 對(duì)于內(nèi)聯(lián)繪圖,在單元格下方的單元格中輸出繪圖的命令不會(huì)影響繪圖。 例如,從創(chuàng)建繪圖的單元格下面的單元格更改顏色表是不可能的。 但是,對(duì)于其他后端,例如 qt4,它們會(huì)打開一個(gè)單獨(dú)的窗口,那些創(chuàng)建繪圖的單元格下方的單元格將改變繪圖 - 它是一個(gè)內(nèi)存中的活對(duì)象。

本教程將使用matplotlib的命令式繪圖接口pyplot。 該接口維護(hù)全局狀態(tài),并且可用于簡單快速地嘗試各種繪圖設(shè)置。 另一種是面向?qū)ο蟮慕涌冢@也非常強(qiáng)大,一般更適合大型應(yīng)用程序的開發(fā)。 如果你想了解面向?qū)ο蠼涌冢?a target="_blank" rel="nofollow">使用上的常見問題是一個(gè)用于起步的不錯(cuò)的頁面。 現(xiàn)在,讓我們繼續(xù)使用命令式方式:

In [2]: import matplotlib.pyplot as plt
In [3]: import matplotlib.image as mpimg
In [4]: import numpy as np

將圖像數(shù)據(jù)導(dǎo)入到 NumPy 數(shù)組

加載圖像數(shù)據(jù)由 Pillow 庫提供支持。 本來,matplotlib只支持 PNG 圖像。 如果本機(jī)讀取失敗,下面顯示的命令會(huì)回退到 Pillow。

此示例中使用的圖像是 PNG 文件,但是請(qǐng)記住你自己的數(shù)據(jù)的 Pillow 要求。

下面是我們要擺弄的圖片:

它是一個(gè) 24 位 RGB PNG 圖像(每個(gè) R,G,B 為 8 位)。 根據(jù)你獲取數(shù)據(jù)的位置,你最有可能遇到的其他類型的圖像是 RGBA 圖像,擁有透明度或單通道灰度(亮度)的圖像。 你可以右鍵單擊它,選擇Save image as(另存為)為本教程的剩余部分下載到你的計(jì)算機(jī)。

現(xiàn)在我們開始...

In [5]: img=mpimg.imread('stinkbug.png')
Out[5]:
array([[[ 0.40784314,  0.40784314,  0.40784314],
        [ 0.40784314,  0.40784314,  0.40784314],
        [ 0.40784314,  0.40784314,  0.40784314],
        ...,
        [ 0.42745098,  0.42745098,  0.42745098],
        [ 0.42745098,  0.42745098,  0.42745098],
        [ 0.42745098,  0.42745098,  0.42745098]],

       ...,
       [[ 0.44313726,  0.44313726,  0.44313726],
        [ 0.4509804 ,  0.4509804 ,  0.4509804 ],
        [ 0.4509804 ,  0.4509804 ,  0.4509804 ],
        ...,
        [ 0.44705883,  0.44705883,  0.44705883],
        [ 0.44705883,  0.44705883,  0.44705883],
        [ 0.44313726,  0.44313726,  0.44313726]]], dtype=float32)

注意這里的dtype - float32。 Matplotlib 已將每個(gè)通道的8位數(shù)據(jù)重新定標(biāo)為 0.0 和 1.0 之間的浮點(diǎn)數(shù)。 作為旁注,Pillow 可以使用的唯一數(shù)據(jù)類型是uint8。 Matplotlib 繪圖可以處理float32uint8,但是對(duì)于除 PNG 之外的任何格式的圖像,讀取/寫入僅限于uint8數(shù)據(jù)。 為什么是 8 位呢? 大多數(shù)顯示器只能渲染每通道 8 位的顏色漸變。 為什么他們只能渲染每通道 8 位呢? 因?yàn)檫@會(huì)使所有人的眼睛可以看到。 更多信息請(qǐng)見(從攝影的角度):Luminous Landscape 位深度教程。

每個(gè)內(nèi)部列表表示一個(gè)像素。 這里,對(duì)于 RGB 圖像,有 3 個(gè)值。 由于它是一個(gè)黑白圖像,R,G 和 B 都是類似的。 RGBA(其中 A 是阿爾法或透明度)對(duì)于每個(gè)內(nèi)部列表具有 4 個(gè)值,而且簡單亮度圖像僅具有一個(gè)值(因此僅是二維數(shù)組,而不是三維數(shù)組)。 對(duì)于 RGB 和 RGBA 圖像,matplotlib支持float32uint8數(shù)據(jù)類型。 對(duì)于灰度,matplotlib只支持float32。 如果你的數(shù)組數(shù)據(jù)不符合這些描述之一,則需要重新縮放它。

將 NumPy 數(shù)組繪制為圖像

所以,你將數(shù)據(jù)保存在一個(gè)numpy數(shù)組(通過導(dǎo)入它,或生成它)。 讓我們渲染它吧。 在 Matplotlib 中,這是使用imshow()函數(shù)執(zhí)行的。 這里我們將抓取plot對(duì)象。 這個(gè)對(duì)象提供了一個(gè)簡單的方法來從提示符處理繪圖。

In [6]: imgplot = plt.imshow(img)

你也可以繪制任何 NumPy 數(shù)組。

對(duì)圖像繪圖應(yīng)用偽彩色方案

偽彩色可以是一個(gè)有用的工具,用于增強(qiáng)對(duì)比度和更易于可視化你的數(shù)據(jù)。 這在使用投影儀對(duì)你的數(shù)據(jù)進(jìn)行演示時(shí)尤其有用 - 它們的對(duì)比度通常很差。

偽彩色僅與單通道,灰度,亮度圖像相關(guān)。 我們目前有一個(gè)RGB圖像。 由于R,G 和 B 都是相似的(見上面或你的數(shù)據(jù)),我們可以只選擇一個(gè)通道的數(shù)據(jù):

In [7]: lum_img = img[:,:,0]

這是數(shù)組切片,更多信息請(qǐng)見NumPy 教程。

In [8]: plt.imshow(lum_img)

現(xiàn)在,亮度(2D,無顏色)圖像應(yīng)用了默認(rèn)顏色表(也稱為查找表,LUT)。 默認(rèn)值稱為jet。 有很多其他方案可以選擇。

In [9]: plt.imshow(lum_img, cmap="hot")

請(qǐng)注意,你還可以使用set_cmap()方法更改現(xiàn)有繪圖對(duì)象上的顏色:

In [10]: imgplot = plt.imshow(lum_img)
In [11]: imgplot.set_cmap('spectral')

但是,請(qǐng)記住,在帶有內(nèi)聯(lián)后端的 IPython notebook 中,你不能對(duì)已經(jīng)渲染的繪圖進(jìn)行更改。 如果你在一個(gè)單元格中創(chuàng)建了imgplot,你不能在以后的單元格中調(diào)用set_cmap(),并且改變前面的繪圖。 請(qǐng)確保你在相同單元格中一起輸入這些命令。plt命令不會(huì)更改先前單元格的繪圖。

有許多可選的其它顏色表,請(qǐng)見顏色表的列表和圖像

顏色刻度參考

了解顏色代表什么值對(duì)我們很有幫助。 我們可以通過添加顏色條來做到這一點(diǎn)。

In [12]: imgplot = plt.imshow(lum_img)
In [13]: plt.colorbar()

這會(huì)為你現(xiàn)有的圖形添加一個(gè)顏色條。 如果你更改并切換到不同的顏色映射,則不會(huì)自動(dòng)更改 - 你必須重新創(chuàng)建繪圖,并再次添加顏色條。

檢查特定數(shù)據(jù)范圍

有時(shí),你想要增強(qiáng)圖像的對(duì)比度,或者擴(kuò)大特定區(qū)域的對(duì)比度,同時(shí)犧牲變化不大,或者無所謂的顏色細(xì)節(jié)。 找到有趣區(qū)域的最好工具是直方圖。 要?jiǎng)?chuàng)建我們的圖像數(shù)據(jù)的直方圖,我們使用hist()函數(shù)。

In [14]: plt.hist(lum_img.ravel(), bins=256, range=(0.0, 1.0), fc='k', ec='k')

通常,圖像的『有趣』部分在峰值附近,你可以通過剪切峰值上方和/或下方的區(qū)域獲得額外的對(duì)比度。 在我們的直方圖中,看起來最大值處沒有太多有用的信息(圖像中有很多不是白色的東西)。 讓我們調(diào)整上限,以便我們有效地『放大』直方圖的一部分。 我們通過將clim參數(shù)傳遞給imshow來實(shí)現(xiàn)。 你也可以通過對(duì)圖像繪圖對(duì)象調(diào)用set_clim()方法來做到這一點(diǎn),但要確保你在使用 IPython Notebook 的時(shí)候,和plot命令在相同的單元格中執(zhí)行 - 它不會(huì)改變之前單元格的圖。

In [15]: imgplot = plt.imshow(lum_img, clim=(0.0, 0.7))

數(shù)組插值方案

插值根據(jù)不同的數(shù)學(xué)方案計(jì)算像素『應(yīng)有』的顏色或值。 發(fā)生這種情況的一個(gè)常見的場景是調(diào)整圖像的大小。 像素的數(shù)量會(huì)發(fā)生變化,但你想要相同的信息。 由于像素是離散的,因此存在缺失的空間。 插值就是填補(bǔ)這個(gè)空間的方式。 這就是當(dāng)你放大圖像時(shí),你的圖像有時(shí)會(huì)出來看起來像素化的原因。 當(dāng)原始圖像和擴(kuò)展圖像之間的差異較大時(shí),效果更加明顯。 讓我們加載我們的圖像并縮小它。 我們實(shí)際上正在丟棄像素,只保留少數(shù)幾個(gè)像素。 現(xiàn)在,當(dāng)我們繪制它時(shí),數(shù)據(jù)被放大為你屏幕的大小。 由于舊的像素不再存在,計(jì)算機(jī)必須繪制像素來填充那個(gè)空間。

我們將使用用來加載圖像的 Pillow 庫來調(diào)整圖像大小。

In [16]: from PIL import Image
In [17]: img = Image.open('../_static/stinkbug.png')
In [18]: img.thumbnail((64, 64), Image.ANTIALIAS) # resizes image in-place
In [19]: imgplot = plt.imshow(img)

這里我們使用默認(rèn)插值,雙線性,因?yàn)槲覀儧]有向imshow()提供任何插值參數(shù)。

讓我們?cè)囋囈恍┢渌臇|西:

最鄰近

In [20]: imgplot = plt.imshow(img, interpolation="nearest")

雙立方

In [21]: imgplot = plt.imshow(img, interpolation="bicubic")

雙立方插值通常用于放大照片 - 人們傾向于模糊而不是過度像素化。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容