【Python】画像データから必要な部分だけ数値データを取得してみる

【Python】画像データから必要な部分だけ数値データを取得してみる

画像データを数値データとして扱う方法は以前解説しましたが、画像の一部分の情報だけ取得したいという場合はどうすればよいかを本記事では解説していきます。

動作環境
macOS Catalina(10.15.7), python 3.7.6, Sublime Text (3.2.2)

画像の一部分の情報だけ取得してどうするのか?

画像データから一部分の数値情報を取得できるようになると、次のような図が作れるようになります。

画像の上から140px目の数値だけを取得して、matplotlibでplotしています。
画像はホタルが発光している様子の白黒画像です。

これ以外では、例えば次の様に、動画の白枠内の数値だけを取得して、時間発展を表現できたりもします。

画像データから必要な部分だけ数値データを取得する方法

手順

  1. 画像の読み込み
  2. 空の1次元リストを作成。
  3. 画像データから必要な部分の数値だけを取得
  4. 取得した数値を1次元リストに格納
  5. 図をプロット

3, 4はほぼ同時に行います。
具体的に見ていきましょう。

画像データの用意

画像データとして次のホタルの白黒画像(FireFly_gray.jpg)を用意しました。
右クリックでダウンロードしてください。

Pillow(PIL)とNumpyを使うための準備

Pillow(PIL)というライブラリを用いれば画像データから数値データを取得することができます。
Numpyというライブラリを用いれば一次元リストを簡単に作ることができます。

pipコマンドを用いれば簡単にPillow(PIL), Numpyがインストールできます。
次のようにターミナルにコマンドを入力して、returnキーを押してください。

pip install pillow
pip install numpy

最終的にSuccessfullyというワードが書かれていれば、無事にインストール完了です。
すでにインストールされている場合は、already satisfiedというワードが表示されると思います。

プログラムの実装(サンプルコード)

ホタルの白黒画像の一部だけを取得してグラフを描画するコードは次のようになります。
getImagePartial.pyという名前でDesktop/Dr.code/python/data-analysis/get-partial-imageに置きます。

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image


# image data
image_name = 'FireFly_gray.jpg'
image = Image.open(image_name)
width, height = image.size

# input image data
imageHorizontalArray = np.empty((width), dtype=int)

VerticalPosition = 139  # (pixel)
for y in range(height):
    for x in range(width):
        if y == VerticalPosition:
            imageHorizontalArray[x] = image.getpixel((x, y))

# plot images
plt.plot(imageHorizontalArray, color='red')
plt.xlim(0, width)
plt.xlabel('Horizontal position (px)', fontsize=10)
plt.ylabel('Light intensity (a.u.)', fontsize=10)

# save as pdf
plt.savefig('horizontal_light_intensity.png', dpi=600)

# show
plt.show()

ここに書かれているコードのほとんどは、【Python】画像データを数値データとして扱うには?で記載したものと同じです。
異なる点かつ重要な点は、forループ内にあるif y == VerticalPosition: の部分になります。
この条件分岐により、上から140px目(=VerticalPosition)のみをimage.getpixel((x, y))で数値を取得しています。
取得した数値はimageHorizontalArray[x] = image.getpixel((x, y))で一次元配列imageHorizontalArrayに代入されます。

コードが書けたら、ターミナル上でcwdを$ cd Desktop/Dr.code/python/data-analysis/get-partial-imageで変更し、$ python getImagePartial.pyとコマンド入力し、プログラムを実行しましょう。

出力結果

以下の様なグラフ(horizontal_light_intensity.png)がDesktop/Dr.code/python/data-analysis/get-partial-imageに出力されるはずです。
140px目はちょうどホタルが発効している部分になるので、水平位置の100px目近傍で発効強度が高くなっているのがわかりますね。

以上のように、forループの中にif文で条件分岐を付け加えるだけで、必要な部分のみの数値を取得することが可能になります。