LoginSignup
5
5

More than 5 years have passed since last update.

Python matplotlibでグラフを作る(Image tutorialを翻訳)

Last updated at Posted at 2018-08-03

matplotlib

Image tutorial

Matplotlibで画像をプロットするための短いチュートリアル。
https://matplotlib.org/tutorials/introductory/images.html#sphx-glr-download-tutorials-introductory-images-py

をGoogle翻訳で翻訳したものです。

Startup commands

まず、IPythonを起動しましょう。標準的なPythonプロンプトに対して最も優れた拡張機能であり、特にMatplotlibとの結びつきがあります。シェルでIPythonを起動するか、IPython Notebookを起動してください。

IPythonを起動したら、GUIイベントループに接続する必要があります。これはIPythonにプロットを表示する場所(そしてその方法)を伝えます。 GUIループに接続するには、IPythonプロンプトで%matplotlibマジックを実行します。 これが何をするのかについての詳細は、 IPython’s documentation on GUI event loops.

IPythonノートブックを使用している場合は、同じコマンドを使用できますが、一般的に人々は%matplotlibマジックに対する特定の引数を使用します。

In [1]: %matplotlib inline

注)上記はUbuntuでは、使用出来ません。(Ubuntuじゃなくて、普通のPythonでは、使用できません。か?知識不足で申し訳ない。)
代わりに、グラフを描画するために、plt.show()が必要です。

Ipythonをインストールしても、'ipykernel'が無いと言われ、'ipykernel'をインストールしてもUnknownBackend: No event loop integration for 'inline'. Supported event loops are: qt, qt4, qt5, gtk, gtk2, gtk3, tk, wx, pyglet, glut, osxとなります。
Ubuntuではやっぱり無理なんでしょうか?

インラインプロットがオンになり、プロットグラフィックがノートブックに表示されます。これは対話性に重要な意味を持ちます。インラインプロットの場合、プロットを出力するセルの下のセルのコマンドはプロットに影響しません。たとえば、プロットを作成するセルの下のセルからカラーマップを変更することはできません。しかし、Qt5などの別のバックエンドで別のウィンドウを開くと、プロットを作成するものの下のセルがプロットを変更します。これはメモリ内のライブオブジェクトです。

このチュートリアルでは、matplotlibの命令形式の作図インタフェース、pyplotを使用します。このインターフェイスはグローバルな状態を維持し、さまざまなプロット設定をすばやく簡単に試すのに非常に便利です。その代わりに、オブジェクト指向のインターフェイスもあります。これは非常に強力で、大規模なアプリケーション開発に適しています。 オブジェクト指向のインターフェイスについて知りたい場合は、まずは FAQ on usage. 今のところ、命令的スタイルのアプローチを試してみましょう。

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

Numpy配列へのイメージデータのインポート

画像データの読み込みは、 Pillow library. ネイティブに、MatplotlibはPNG画像のみをサポートします。以下のコマンドは、ネイティブの読み込みが失敗した場合にピローに戻ります。

この例で使用されている画像はPNGファイルですが、自分のデータには枕の要件を念頭に置いてください。

ここで私たちがやり遂げる予定のイメージは次のとおりです。

image.png

それは24ビットのRGB PNG画像です(R、G、Bそれぞれ8ビット)。データを取得する場所によって、最も遭遇する可能性のある他の種類の画像は、透過性または単一チャネルのグレースケール(光度)画像を可能にするRGBA画像です。このチュートリアルの残りの部分を右クリックし、「画像を別名で保存」を選択してコンピュータにダウンロードすることができます。

さあ、いくぞ…

img = mpimg.imread('../../doc/_static/stinkbug.png')
print(img)
Out:
[[[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.4117647  0.4117647  0.4117647 ]
  [0.4117647  0.4117647  0.4117647 ]
  [0.4117647  0.4117647  0.4117647 ]
  ...
  [0.42745098 0.42745098 0.42745098]
  [0.42745098 0.42745098 0.42745098]
  [0.42745098 0.42745098 0.42745098]]

 [[0.41960785 0.41960785 0.41960785]
  [0.41568628 0.41568628 0.41568628]
  [0.41568628 0.41568628 0.41568628]
  ...
  [0.43137255 0.43137255 0.43137255]
  [0.43137255 0.43137255 0.43137255]

そこにdtypeがあることに注意してください - float32。 Matplotlibは、各チャンネルからの8ビットデータを0.0〜1.0の浮動小数点データにリサイズしました。補足として、Pillowが扱える唯一のデータ型はuint8です。 Matplotlibのプロットはfloat32とuint8を処理できますが、PNG以外の形式の画像の読み書きはuint8データに制限されています。なぜ8ビットですか?ほとんどのディスプレイは、チャネルごとに8ビットの色階調しか表示できません。なぜ8ビット/チャンネルしかレンダリングできないのですか?それは人間の目のすべてが見ることができるからです。詳細はこちら(写真の視点から): Luminous Landscape bit depth tutorial.

各内側のリストはピクセルを表します。ここでは、RGB画像には3つの値があります。それは白黒画像なので、R、G、Bはすべて似ています。 RGBA(Aはアルファまたは透明)はインナーリストごとに4つの値を持ち、単純な輝度画像はちょうど1つの値を持ちます(したがって3D配列ではなく2-D配列のみです)。 RGBおよびRGBA画像の場合、matplotlibはfloat32およびuint8データ型をサポートします。グレースケールの場合、matplotlibはfloat32のみをサポートします。配列データがこれらの記述のいずれかを満たしていない場合は、それを再スケーリングする必要があります。

numpy配列を画像としてプロットする

そのため、データをインポートするか、生成するかのどちらかで、データを配列に並べます。それをレンダリングしましょう。 Matplotlibでは、これは imshow() function. ここでは、プロットオブジェクトを取得します。このオブジェクトは、プロンプトからプロットを操作する簡単な方法を提供します。

imgplot = plt.imshow(img)

image.png

任意の数値配列をプロットすることもできます。

イメージプロットに疑似カラースキームを適用する

疑似カラーは、コントラストを強調し、データをより簡単に視覚化するための便利なツールになります。これは、プロジェクターを使用してデータをプレゼンテーションするときに特に便利です。コントラストは通常​​非常に貧弱です。

疑似カラーは、シングルチャンネル、グレースケール、光度画像にのみ関連します。私たちは現在、RGB画像を持っています。 R、G、Bはすべて類似しているので(データの上または自分のデータを参照)、データの1つのチャンネルだけを選択できます。

lum_img = img[:, :, 0]

# これは配列スライスです。 `Numpyチュートリアル
# <https://docs.scipy.org/doc/numpy/user/quickstart.html>`_.

plt.imshow(lum_img)

image.png

現在、光度(2D、カラーなし)の画像では、デフォルトのカラーマップ(別名ルックアップテーブル、LUT)が適用されます。デフォルトはviridisと呼ばれます。選ぶべき人がたくさんあります。

plt.imshow(lum_img, cmap="hot")

image.png

set_cmap()メソッドを使用して、既存のプロットオブジェクトのカラーマップを変更することもできます。

imgplot = plt.imshow(lum_img)
imgplot.set_cmap('nipy_spectral')

image.png



Note

ただし、インラインバックエンドを持つIPythonノートブックでは、すでにレンダリングされているプロットを変更することはできません。ここで1つのセルにimgplotを作成した場合、それ以降のセルではset_cmap()を呼び出すことができず、以前のプロットを変更することはできません。これらのコマンドを1つのセルにまとめて入力してください。 pltコマンドは、以前のセルからプロットを変更しません。 

他にも多くのカラーマップスキームが用意されています。 See the list and images of the colormaps.

カラースケールリファレンス

色がどのような価値を表しているかを知ることは有益です。カラーバーを追加することでこれを行うことができます。

imgplot = plt.imshow(lum_img)
plt.colorbar()

image.png

これにより、既存のFigureにカラーバーが追加されます。別のカラーマップに切り替えると、自動的に変更されません。プロットを再作成して、カラーバーを再度追加する必要があります。

特定のデータ範囲を調べる

場合によっては、画像のコントラストを強調したり、特定の領域のコントラストを拡大したり、色の違いを犠牲にしたり、重要でない色を犠牲にすることがあります。興味深い領域を見つけるための良いツールは、ヒストグラムです。 画像データのヒストグラムを作成するには、 hist() function.

plt.hist(lum_img.ravel(), bins=256, range=(0.0, 1.0), fc='k', ec='k')

image.png

ほとんどの場合、画像の「興味深い」部分はピークの周りにあり、頂点の上および/または下の領域をクリッピングすることによって余分なコントラストを得ることができます。私たちのヒストグラムでは、ハイエンドにはあまり有益な情報がないように見えます(画像の白い物はあまりありません)。上限を調整して、ヒストグラムの一部を効果的に「拡大」しましょう。これを行うにはclim引数をimshowに渡します。また、イメージプロットオブジェクトのset_clim()メソッドを呼び出すことでこれを行うこともできますが、IPythonノートブックで作業するときは、プロットコマンドと同じセルで行うようにしてください。

plotの呼び出しでclimを指定することができます。

imgplot = plt.imshow(lum_img, clim=(0.0, 0.7))

image.png

返されたオブジェクトを使用してclimを指定することもできます

fig = plt.figure()
a = fig.add_subplot(1, 2, 1)
imgplot = plt.imshow(lum_img)
a.set_title('Before')
plt.colorbar(ticks=[0.1, 0.3, 0.5, 0.7], orientation='horizontal')
a = fig.add_subplot(1, 2, 2)
imgplot = plt.imshow(lum_img)
imgplot.set_clim(0.0, 0.7)
a.set_title('After')
plt.colorbar(ticks=[0.1, 0.3, 0.5, 0.7], orientation='horizontal')

image.png

配列補間スキーム

補間は、異なる数学的スキームに従って、ピクセルの色または値が何であるべきかを計算する。これが起こる1つの一般的な場所は、画像のサイズを変更するときです。ピクセル数は変わりますが、同じ情報が必要です。ピクセルは離散的なので、スペースがありません。補間はその空間をどのように埋めるかです。これは、あなたの画像が吹き飛ばされたときに時々ピクセル化して見えるようになる理由です。この効果は、元の画像と拡大された画像との差が大きい場合に顕著である。私たちのイメージを取り、縮小しましょう。効果的にピクセルを破棄しているだけで、少数の選択肢しか保持しません。今私たちがそれをプロットすると、そのデータは画面上のサイズまで吹き飛ばされます。古いピクセルはもはや存在せず、コンピュータはその空間を埋めるためにピクセルで描画する必要があります。

画像の読み込みに使用したPillowライブラリを使用して、画像のサイズを変更します。

from PIL import Image

img = Image.open('../../doc/_static/stinkbug.png')
img.thumbnail((64, 64), Image.ANTIALIAS)  # resizes image in-place
imgplot = plt.imshow(img)

image.png

ここでは、デフォルトの補間、bilinearを使用しています。 imshow() 任意の補間引数。

いくつか他のものを試してみましょう。ここでは補間を行わない "nearest"があります。

imgplot = plt.imshow(img, interpolation="nearest")

image.png

バイキュービック:

imgplot = plt.imshow(img, interpolation="bicubic")

image.png

バイキュービック補間は、写真を吹き飛ばすときによく使用されます。人々は、ピクセル化されたものに比べてぼやける傾向があります。

Download Python source code: images.py
https://matplotlib.org/_downloads/images.py

Download Jupyter notebook: images.ipynb
https://matplotlib.org/_downloads/images.ipynb

5
5
11

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5