Python, NumPyでグラデーション画像を生成

画像をNumPy配列ndarrayとして扱うことで、NumPyの豊富な機能を使って既存の画像を処理したり新たな画像を生成したりすることができます。 画像の読み込み・保存などの詳細は以下の記事参照。

ここではグラデーション画像を生成します。

np.tile()とnp.linspace() グラデーション画像を生成するコード例

np.tile()とnp.linspace()

いろいろな方法が考えられるが、ここでは以下の流れでグラデーション画像を作成します。

numpy.linspace()で等間隔で増加または減少する一次元配列を生成 numpy.tile()でそれを二次元に並べる

グラデーションの方向は縦または横のみ。斜めや放射線状(円形)はサポートしない。

np.linspace()

np.linspace()は開始値start、終了値stop、サンプル数(ポイント数)numを指定すると、等間隔の一次元配列(等差数列)を返す関数。

numpy.linspace — NumPy v1.13 Manual

range()やnp.arange()と違って、間隔(ステップ)を自動的に計算してくれるので便利。

import numpy as np

print(np.linspace(0, 10, 3))
# [ 0.  5. 10.]

print(np.linspace(0, 10, 4))
# [ 0.          3.33333333  6.66666667 10.        ]

print(np.linspace(0, 10, 5))
# [ 0.   2.5  5.   7.5 10. ]

start > stopでも適切に処理してくれる。

print(np.linspace(10, 0, 5))
# [10.   7.5  5.   2.5  0. ]

詳細は以下の記事を参照。

np.tile()

np.tile()は配列を縦横に並べる関数。

numpy.tile — NumPy v1.13 Manual

パターンを繰り返す配列を作成するのに便利。 引数に元の配列と繰り返し回数を指定します。二次元に並べる場合は、繰り返し回数を(行(縦)の繰り返し回数, 列(横)の繰り返し回数)とします。

import numpy as np

a = np.array([0, 1, 2, 3])

print(np.tile(a, 2))
# [0 1 2 3 0 1 2 3]

print(np.tile(a, (3, 2)))
# [[0 1 2 3 0 1 2 3]
#  [0 1 2 3 0 1 2 3]
#  [0 1 2 3 0 1 2 3]]

print(np.tile(a, (2, 1)))
# [[0 1 2 3]
#  [0 1 2 3]]

元の配列が二次元でも同じ。

a = np.array([[11, 12], [21, 22]])

print(np.tile(a, 2))
# [[11 12 11 12]
#  [21 22 21 22]]

print(np.tile(a, (3, 2)))
# [[11 12 11 12]
#  [21 22 21 22]
#  [11 12 11 12]
#  [21 22 21 22]
#  [11 12 11 12]
#  [21 22 21 22]]

print(np.tile(a, (2, 1)))
# [[11 12]
#  [21 22]
#  [11 12]
#  [21 22]]

np.tile()についての詳細は以下の記事を参照。

グラデーション画像を生成するコード例

縦または横方向に等間隔で増加または減少する二次元のndarrayを生成する関数を準備。このndarrayが単色のグラデーション画像に相当します。 is_horizontalがTrueのときは横方向、Falseのときは縦方向に階調が変化します。.Tで転置行列を作って縦方向にしています。

def get_gradation_2d(start, stop, width, height, is_horizontal):
    if is_horizontal:
        return np.tile(np.linspace(start, stop, width), (height, 1))
    else:
        return np.tile(np.linspace(start, stop, height), (width, 1)).T

これを三次元に拡張します。各色に対するstart, stop, is_horizontalをリストで設定し、上の二次元版を呼び出してそれぞれのチャンネルにグラデーション画像を生成します。

def get_gradation_3d(width, height, start_list, stop_list, is_horizontal_list):
    result = np.zeros((height, width, len(start_list)), dtype=np.float)

    for i, (start, stop, is_horizontal) in enumerate(zip(start_list, stop_list, is_horizontal_list)):
        result[:, :, i] = get_gradation_2d(start, stop, width, height, is_horizontal)

    return result

実際にグラデーション画像を生成し保存します。

array = get_gradation_3d(512, 256, (0, 0, 0), (255, 255, 255), (True, True, True))
Image.fromarray(np.uint8(array)).save('data/dst/gradation_h.jpg', quality=95)


array = get_gradation_3d(512, 256, (0, 0, 0), (255, 255, 255), (False, False, False))
Image.fromarray(np.uint8(array)).save('data/dst/gradation_v.jpg', quality=95)

RGB毎にグラデーション方向を変えたりすることも可能。

array = get_gradation_3d(512, 256, (0, 0, 192), (255, 255, 64), (True, False, False))
Image.fromarray(np.uint8(array)).save('data/dst/gradation_color.jpg', quality=95)

シェア

関連カテゴリー

Python NumPy 画像処理

Python, NumPy(OpenCV)で画像を二値化処理 NumPy配列ndarrayをタイル状に繰り返し並べるnp.tile Python, NumPyで画像処理(読み込み、演算、保存) NumPy配列ndarrayをシフト(スクロール)させるnp.roll NumPyでRGB画像の色チャンネルを分離して単色化、白黒化、色交換 Pythonでの画像処理、Pillow, NumPy, OpenCVの違いと使い分け Python, OpenCV, Pillow(PIL)で画像サイズ(幅、高さ)を取得 Python, OpenCV, NumPyで画像のアルファブレンドとマスク処理 Python, OpenCVで図形描画(線、長方形、円、矢印、文字など) NumPy配列ndarrayを結合(concatenate, stack, blockなど) NumPy配列ndarrayをバイナリファイル(npy, npz)で保存 NumPy配列ndarrayとPython標準のリストを相互に変換 NumPy配列ndarrayの表示形式(桁数や指数表記、0埋めなど)を指定 pandasからNumPyの関数などを使う方法(pd.np) NumPyでCSVファイルを読み込み・書き込み(入力・出力)

Last Updated: 6/26/2019, 10:34:03 PM